Monopoly Simulation Part 2: Hack Go To Jail using Python

By Russell Barnes. Posted

Hack Monopoly in Python by adding Go To Jail to our board game simulation

We are hacking the Monopoly board game by recreating it in code (using Python). This simulation enables us to discover which squares are worth the most.

In our last Monopoly tutorial we built the board game in code. In this feature we add Go To Jail.

Veteran players of the Monopoly board game will have noticed the effect of the “Go To Jail” square. Just as a player is hoping to reach “Go” and collect some more money to pay for more houses or unmortgage some cards, the player is sent back to jail.

This has the nasty effect that the player then has to pass by the second and third street, hoping to avoid any houses or hotels on those properties. The “Go To Jail” square changes the probability density function for the board, implying that some properties are a better choice.

A Monopoly board game is a game of chance, where each player is moved around the board by rolling two dice, by drawing cards from the Community Chest or Chance decks, or by landing on Go To Jail square. Before the rules surrounding the two decks of cards, rolling a double and the Go To Jail square are introduced, a player is as likely to land on any square over the course of a game.

See also:

On the first turn of a game, the player starts from the Go square and is more likely to role a seven than any other number. However, since the probably of rolling other values is not zero, after a few turns the player’s position on the board becomes more evenly distributed.

Whenever a player is sent to start from a particular square, the player is most likely to land seven squares away from this position. If the player lands on Go To Jail square, then they are sent straight to jail. The player can then leave jail by paying a fine or rolling a double. Therefore, players that have been sent to jail always start their turn from the jail square. They are then most likely to land on the seventh square from the jail square.

Add Go To Jail to Monopoly Simulation

In the last tutorial, a basic framework for describing the Monopoly board was introduced. This framework consists of using the standard Python random number generator and a list to count when the player lands on a square. The values in the list are then divided by the total number of counts, such that the list contains the probability density function for the Monopoly board. This list is then displayed as a barchart using Matplotlib.
If the board squares are numbered from zero to 39, then Go To Jail is 29 and the Jail square is 9 square. Therefore, when a player lands on 29 they should be moved straight to 9 square. This effect has been added to the goToJail.py program.

#!/usr/bin/env python

# Import the random package
import random

# Import the matplotlib pyplot package
import matplotlib.pyplot as pyplot

# A function to generate two random numbers within the range 1 <= i <= 6 and add them together
def rollTwoDice():
  return random.randint(1,6) + random.randint(1,6)

#---------------------------

# A function to create a histogram
def plot(x, y):
  pyplot.bar(x, y)
  pyplot.show()

#---------------------------

# A function to normalise the counters by the sum of the counts
def normalise(counters):

  # Count the total number of entries
  total = 0.
  for counter in counters:
    total = total + counter

  # Divide each counter value by the total
  for i in range(len(counters)):
    counters[i] = counters[i] / total

#---------------------------

# The number of squares on the board
nsquares = 40

# A list to contain the total value rolled.
counters=[0.]*nsquares

# A variable to hold the current position
currentPosition = 0

# Set the number of rolls
nRolls = 1000000

# Print a message
print("Rolling two dice " + str(nRolls) + " times...")

# Roll the dice
for i in range(nRolls):
  # roll the dice
  totalValue = rollTwoDice()

  # Move the player to the next position
  currentPosition = currentPosition + totalValue

  # If the player has moved past the last square, wrap the board around.
  if currentPosition >= nsquares:
    currentPosition = currentPosition - nsquares

  # Count the current position on the board
  counters[currentPosition] = counters[currentPosition] + 1.

  # Check if the player should go to jail
  if currentPosition == 30:

    # Send them to the jail square
    currentPosition = 10

    # Count landing on the jail square
    counters[currentPosition] = counters[currentPosition] + 1.

# Total probability is always defined as 1.
# Therefore, have to divide by the total number of counted values.
normalise(counters)
  
# Now print out the probabilities for each of the combinations
print("The probabilities of landing on a given Monopoly square after " + str(nRolls) + " rolls")
for i in range(len(counters)):
  # Need to add one, since Python counts from zero.
  print(" P("+str(i)+")="+str(counters[i]))
print("where P(n) is the probability of landing on the nth Monopoly board square")

# Create a bar chart display
plot(range(len(counters)),counters)

 

The goToJail.py program contains three functions that simulate rolling two six sided dice, plot the data as a barchart and normalise the values counted. The rollTwoDice function was introduced last time and calls the randint function twice, returning the sum value. The plot function is a simple function to create a plot with Matplotlib. Finally, the normalise function sums the counter list and divides the list by the total value, resulting in the probability density function.

The program starts by setting the players position to be the “GO” square, which has the number zero in the simulation. Then the simulated dice are rolled one million times, to reduce the effect of statistical fluctuations on the probability density function. Within the main for loop, the rollTwoDice function is called to retrieve the next dice roll. Then the player is moved by this number of squares. If the player is moved beyond the end of the board numbering scheme, the total number of squares on the board is removed to bring the player around the board again. Then the players new position is counted.

Go To Jail square condition is made by checking the players new position. If the player has landed on the Go To Jail square, which is the 29th square, they are moved to the 9th square and their new position is also counted. The main loop then continues until all of the dice rolls have finished, which can take several seconds. Once the program has finished, the distribution is normalised and plotted on the screen.

To run the goToJail.py program, type

./goToJail.py

Then wait for the Matplotlib window to appear.

goToJail in MatPlotLib

The effect of adding Go to Jail is quite noticable. The first nine squares have a similar probability, but the jail square is twice as likely to be landed on. This is because a player might land on this square when going around the board or might be sent to this square by Go To Jail. Since the jail square cannot be board as a property, it is not as interesting as the distribution that follows it.Other than the jail square, the most likely square for the player to land on is seven squares after the jail square. By the second dice roll, the player is as likely to land on any square, including the Go To Jail. After the “GO TO JAIL” square, the probability drops. This is because players that are sent to jail cannot completely go around the board.

Other than the jail square, the most likely square for the player to land on is seven squares after the jail square. By the second dice roll, the player is as likely to land on any square, including the Go To Jail. After the “GO TO JAIL” square, the probability drops. This is because players that are sent to jail cannot completely go around the board.

In the next article, the effect of the two decks of cards will be added, building up to a complete simulation of the game.

From The MagPi store

Subscribe

Subscribe to the newsletter

Get every issue delivered directly to your inbox and keep up to date with the latest news, offers, events, and more.