Updated 2007-09-02 18:04:08 by Zarutian

GWM: Who has not played Monopoly?

This is NOT a monopoly simulator; it is a page about how to simulate the game probabilities, leading to items about Markov Chains, Markov Algorithms, Markov Matrices, Markov, and so on. It is not a way to waste 3-4 hours pretending to buy houses and hotels on improbably cheap streets.

The technique is simple - look at the game - there are 40 squares you can land on. What happens?

A player throws 2 dice throw a dice - result: you are most likely to move 7 spaces. This space may be:

  • a property, opportunity to buy it or pay rent (including station, utility)
  • a chance card (draw a card which might give you money or take it or tell you where to go)
  • a community chest (draw a card but different results)
  • pay a tax or receive income (at Go) or even free parking.
  • be in or visiting Jail

The next throw you move on more spaces (again most likely 7) and so on.

Where are you most likely to end up? After a large number of throws you would expect - anywhere after all randomness will even out. But this is NOT so - every now and then you are sent to Jail (square 30 on the board, 2 cards = 1 in Community Chest one in Chance, and throw 3 doubles...) from which you start afresh, moving most likely 7 squares. The result is (as many of us supposed after empirical 'work') that you are most likely to arrive in the Orange set (Bow St, Vine St, Marlborough St when playing with a British set) and pay the rent to whoever owns it. Or receive said rent if you own it. How do we calculate the probability? A Markov Chain. Start with the owner on Go (square 0 in the simulation) and toss the dice some 20000 times obeying the rules for each square you land on, it only takes a few seconds. The average frequency for all cells is 0.025 of course (1/40 squares) with the most common visited being Jail or visiting (every visit to square 30 forces a visit to Jail, doubling its frequency, plus the go to jail cards & rules).

The likelihood looks like: Orange set: about 0.0305 of all turns land on the 9th square (Vine st, most expensive of the set) with Marlborough st (its neighbour ) close behind (0.0295). But most frequent is square 24 (Trafalgar Sq- 0.031, however other red set members are less frequent than orange, reducing its value). Perhaps most surprising is the Chance after free parking - way down at 0.0155 while its neighbours either side are at .028 - this is partly explained by Chance re-directing the person landing to another square 7 out of 16 times.

I really enjoyed playing on a Dutch Monopoly set where the cheapest properties are 'Onze Dorp' & 'Onze Straat' = 'our village' and 'our street' - far more personal than the Old Kent Road I grew up using (but didn't live on).

Enough of this already! here is a code which emulates the frequency of visiting each square.
 # monotony.tcl --
 #    module for analysing frequency of landing on various squares in the
 # game of monopoly ((c) Waddingtons).
 #    This code does not infringe on their copyright because it only analyses the rules
 # it is not a player or emulator for the game.
 #
 # Basic facts:
 # every turn a player tosses 2 dice, giving equal chance of each number (1-6).
 # therefore every pair of numbers can score:
 # 2 1&1  -once in 36
 # 3 1&2 or 2&1 (2 in 36) etc.
 #

 namespace eval ::monopoly {
 # code for each square: pi=property of set i
 # c:community chest; C chance; s station; j jail J go to Jail
 # f free parking; t=100 tax, T 200 tax; g-go
	array set squares { 1 p1 2 Chest 3 p1 4 T 5 Station 6 p2 7 Chance 8 p2 9 p2 10 jail \
		11 p3 12 electric 13 p3 14 p3 15 Station 16 p4 17 Chest 18 p4 19 p4 20 freePark \
		21 p5 22 Chance 23 p5 24 p5 25 Station 26 p6 27 water 28 p6 29 p6 30 toJail \
		31 p7 32 Chest 33 p7 34 p3 35 Station 36 Chance 37 p8 38 t 39 p8 0 Go}
 #    namespace export + - / * conj exp sin cos tan real imag mod arg log pow sqrt tostring
 }

 # dice thrower

 proc getchance {pos} {
 # 16 chance cards; 1 takes you to Pall Mall (sq 11), 1 to Jail, 1 to Go
	set luck [expr int(16*rand())]
	if {$luck>6} {return $pos} ;# no change
	if {$luck==0} {return 11} ;# Pall Mall forward
	if {$luck==1} {return 39} ;# mayfair
	if {$luck==2} {return 10} ;# Jail
	if {$luck==3} {return 15} ;# marylebone Sta
	if {$luck==4} {return [expr $pos-3]} ;# back 3 spp
	if {$luck==5} {return 24} ;# Trafalgar sq
	if {$luck==6} {return 0} ;# Go
 # all others are 'make repairs' receive money etc
	return $pos ;# no change
 }
 proc getcc {pos} {
 # 15 cards; 1 takes you to Old Kent Rd (sq 1), 1 to Jail, 1 to Go
	set luck [expr int(15*rand())]
	if {$luck>2} {return $pos} ;# no change
	if {$luck==0} {return 1} ;# Old Kent Road (go back)
	if {$luck==1} {return 0} ;# Go
	if {$luck==2} {return 10} ;# Jail
	return $pos ;# no change
 }
 proc throwdice {} {
	set ok 0
	while {!$ok} {
		set sc [expr 1+int(6*rand())]
		if {$sc<7} {set ok 1}
	}
	return $sc
 }
 proc throw2dice {} {
	lappend all  [throwdice]
	lappend all  [throwdice]
	return $all
 }

 proc monotony {nthr} {
	set bins { 1 2 3 4 5 6 7 8 9 10 11 12}
	array set throes {}
	foreach bin $bins {
		set throes($bin) 0
	}

	set i 0
	while {$i<40} {
		set landss($i) 0
		incr i
	}
	set pos 40 ;# at Go
	set ndubs 0 ;# when 3 doubles in a row, go to jail!
	set n3s 0
	while {$i<$nthr} {
		set thr [throw2dice]
		set s1 [lindex $thr 0]
		set s2 [lindex $thr 1]
		set total [expr $s1 + $s2 ]
		set pos [expr ($pos+$total)%40]
		incr throes($total)
		if {$s1==$s2} { ;#count doubles
			incr ndubs
		} else {
			set ndubs 0
		}
		if {$ndubs>=3} { ;# when 3 doubles in a row, go to jail!
			set ndubs 0
			set pos 10 ;# jail
			incr n3s
		} else {
		# handle special squares
		    if {[string compare $::monopoly::squares($pos) "toJail"]==0} {
			set pos 10
		    }
		    if {[string compare $::monopoly::squares($pos) "Chest"]==0} {
			set pos [getcc $pos]
		    }
		     if {[string compare $::monopoly::squares($pos) "Chance"]==0} {
			set pos [getchance $pos]
		    }
		}
		incr landss($pos)
		incr i
	}
	set i 1
	while {$i<13} {
		puts "Threw $i [expr $throes($i)/double($nthr)]"
		incr i
	}
	set i 0
	while {$i<40} {
		puts "Landed on $i $::monopoly::squares($i) [expr $landss($i)/double($nthr)]"
		incr i
	}
	puts "Sent to jail $n3s times from $nthr [expr double($nthr)/double($n3s)]"
 }

 monotony 200000

The end result shows the slightly distorted frequency of visiting each square:
 Landed on 0 g 0.031275
 Landed on 1 p1 0.026454
 Landed on 2 Chest 0.0174255
 Landed on 3 p1 0.0221405
 Landed on 4 T 0.023662
 Landed on 5 Station 0.022662
 Landed on 6 p2 0.023248
 ...

where pN means one of the properties N (N=1-8, Old Kent Road to Mayfair) and so on.

The reference [1] quotes slightly different probabilities - this is due to 2 effects:

  • reference used 32 billion dice rolls, the above only 200,000.
  • reference [2] suggests there are 10 chance cards which move your position; my set only has 7.

There will be a slight distortion due to the startup effect (on first roll, the most likely place to land is square 7 and so on). Do other people's sets of monopoly have 10 cards? If so which languages?

Analyse at your leisure, and win the game.

For parents wising to thrash their children at something, try analysing snakes and ladders in the same way, it is the same kind of game without the added incentive of buying the squares other people might land on. (Throw dice, land on square, get sent to other square.) If you are designing a new game, please analyse it this way - you won't sell a game that never ends!

Zarutian: Monopoly is also known as Matador

[ Category Games | Category Education ]