rec.puzzles Archive

In Monopoly, you are most likely to land on which property?

competition/games/monopoly New

New entry, edited from material collected for the archive and not yet in a released version.

Problem

In Monopoly, you are most likely to land on which property?
Show solution
The most frequent is Illinois Avenue, which benefits from being 13
squares away from jail and the destination of a Chance card.

-- Matthew Daly <daly@PPD.Kodak.COM>

Correct.  There is also a chance card that says back up three spaces
and Illinois Avenue happens to be three spaces away from a chance.

-- Glenn Rhoads <rhoads@george.rutgers.edu> (October 1996)

[ Editor: numbering the squares of the standard (Atlantic City) board
from Go = 0, Jail is 10, Illinois Avenue 24 and the Chance squares 7,
22 and 36.  So Illinois is 14 squares from Jail, and "go back three
spaces" from a Chance square lands on 4, 19 or 33, not on Illinois. ]

[ Editor: from "Monopoly Statistics in C" by Wei-Hwa Huang
<whuang@ugcs.caltech.edu>, May 1997, a C program that simulates 10
players for 9,000,000 turns and counts how often each square is landed
on; its opening comment gives its assumptions and a sample of its
output.  The simulation counts "Jail" (being sent there) separately
from "Just Visiting", and acts only on the Chance and Community Chest
cards that move a player. ]

#include <stdio.h>
#include <string.h>
#include <math.h>

/* A Program to calculate Monopoly Probabilities */
/* (C) Copyright 1997 Wei-Hwa Huang (whuang@ugcs.caltech.edu) */

/* Strange assumptions:
   Players always roll to get out of jail, never paying early.
   Get out of Jail Free cards are not collected, but treated as "blank." */

/*

Sample output page:

Results after turn  9000000
(89=01)01 Jail                : 381826; (56=22)22 Go to Jail          : 255479;
(89=02)02 Illinois Avenue     : 309709; (56=23)23 Boardwalk           : 255266;
(90=03)03 Go                  : 299430; (66=24)24 North Carolina Ave. : 254647;
(89=04)04 B & O Railroad      : 297123; (87=25)25 Virginia Avenue     : 249822;
(00^06)05 Free Parking        : 291223; (84=26)26 Marvin Gardens      : 248508;
(00v05)06 Tennessee Avenue    : 291192; (89=27)27 Pennsylvania Avenue : 242869;
(29=07)07 New York Avenue     : 288464; (89=28)28 Short Line          : 235503;
(14=08)08 Chance 2            : 288190; (22=29)29 States Avenue       : 224365;
(14=09)09 Reading Railroad    : 287949; (22=30)30 Chance 3            : 224218;
(87=10)10 St. James Place     : 276192; (17=31)31 Vermont Avenue      : 223874;
(85=11)11 Water Works         : 274485; (17=32)32 Chance 1            : 223271;
(85=12)12 Community Chest 2   : 269457; (09=33)33 Connecticut Avenue  : 223149;
(83=13)13 Pennsylvania RR     : 268118; (09=34)34 Income Tax          : 223034;
(70=14)14 Electric Company    : 267318; (86=35)35 Just Visiting       : 220267;
(70=15)15 Kentucky Avenue     : 266235; (89=36)36 Oriental Avenue     : 219329;
(08=16)16 St. Charles Place   : 263432; (07=37)37 Park Place          : 211296;
(08=17)17 Atlantic Avenue     : 263392; (07=38)38 Luxury Tax          : 210947;
(66=18)18 Indiana Avenue      : 261767; (53=39)39 Baltic Avenue       : 209632;
(66=19)19 Community Chest 3   : 260672; (53=40)40 Community Chest 1   : 209208;
(75=20)20 Pacific Avenue      : 257632; (80=41)41 Mediterranean Avenue: 205765;
(74=21)21 Ventnor Avenue      : 256628;
 ^^ ^^ ^^                       ^^^^^^
  |  |  +-- Current Placing          +-- Number of turns landed on this space
  |  +----- Previous Placing
  +-------- Number of consecutive times in this placing
*/

#define PLAYERS 10
/* The number of players */
#define JAIL_PREF 50
/* The number of moves before the players decide that staying in
  Jail is preferable */
#define SEED 12
/* seed for the random number generator */
#define DEBUGMODE 0
/* set to 1 for debugging mode */
#define DICEMODE 0
/* set to 1 for debugging dice mode */
#define TTS 9000000
/* Number of Turns */
#define MOD 100000
/* Number of Turns per report*/

/*char names[40][21];
char cnames[16][21];
char ccnames[16][21];
*/
char names[41][21] = {
"Go                  ",
"Mediterranean Avenue",
"Community Chest 1   ",
"Baltic Avenue       ",
"Income Tax          ",
"Reading Railroad    ",/*5*/
"Oriental Avenue     ",
"Chance 1            ",
"Vermont Avenue      ",
"Connecticut Avenue  ",
"Just Visiting       ",/*10*/
"St. Charles Place   ",
"Electric Company    ",
"States Avenue       ",
"Virginia Avenue     ",
"Pennsylvania RR     ",/*15*/
"St. James Place     ",
"Community Chest 2   ",
"Tennessee Avenue    ",
"New York Avenue     ",
"Free Parking        ",/*20*/
"Kentucky Avenue     ",
"Chance 2            ",
"Indiana Avenue      ",
"Illinois Avenue     ",
"B & O Railroad      ",
"Atlantic Avenue     ",
"Ventnor Avenue      ",
"Water Works         ",
"Marvin Gardens      ",
"Go to Jail          ",/*30*/
"Pacific Avenue      ",
"North Carolina Ave. ",
"Community Chest 3   ",
"Pennsylvania Avenue ",
"Short Line          ",
"Chance 3            ",
"Park Place          ",
"Luxury Tax          ",
"Boardwalk           ",
"Jail                ",};
char cnames[16][21] = {
"Pay Poor Tax of $15 ",
"Make General Repairs",
"Advance to Illinois ",
"Advance to Utility  ",
"Bank Pays U Dividend",
"Bldg and Loan Mature",/*5*/
"Walk on Boardwalk   ",
"Elected Chairman    ",
"Take a Ride on Rdng ",
"Go Back 3 Spaces    ",
"Advance 2 St.Charles",
"Advance 2 Nearest RR",
"Advance 2 Nearest RR",
"Go Directly to Jail ",
"Advance 2 Go        ",
"Get out of Jail Free"};
char ccnames[16][21] = {
"You Inherit $100    ",
"Xmas Fund Matures   ",
"Get out of Jail Free",
"Pay School Tax      ",
"Grand Opera Opening ",
"Advance to Go       ",
"Second Prize in Cont",
"Pay Hospital $100   ",
"Doctor's Fee        ",
"From Sale of Stock  ",
"Income Tax Refund   ",
"Bank Error in Favor ",
"Life Insrnce Matures",
"Assessed for Repairs",
"Go to Jail          ",
"Receive for Services"};

int ppos[PLAYERS],injail[PLAYERS];
long hits[41];  /* 40 is Jail */
int roll,dbl;
long rolld[13],dbld[2];
int dbls; /* number of stacked doubles */
int playerup;
int cccardorder[16];
int curcccard=0;
int ccardorder[16];
int curccard=0;
int makemove;
  int order[41];
  int oldorder[41];
  int hold[41];


void shufflecards () {
  int lcv,place;
  for (lcv=0;lcv<16;lcv++) 
    ccardorder[lcv]= -1;
  for (lcv=0;lcv<16;lcv++) {
    place = floor(rand()/32768.0*16);
    while (ccardorder[place] != -1) place = floor(rand()/32768.0*16);
    ccardorder[place]=lcv;
  }
  for (lcv=0;lcv<16;lcv++) 
    cccardorder[lcv]= -1;
  for (lcv=0;lcv<16;lcv++) {
    place = floor(rand()/32768.0*16);
    while (cccardorder[place] != -1) place = floor(rand()/32768.0*16);
    cccardorder[place]=lcv;
  }
}

void gotojail() {
  ppos[playerup]=10;
  injail[playerup]=1;  
  hits[40]++;
  if (DEBUGMODE) printf (" Goes to Jail\n");
  makemove=0; /* Doubles are canceled */
}

void cccard() {
  int a;
  a=cccardorder[curcccard];
  if (DEBUGMODE) printf (" %s\n",ccnames[a]);
  if (a==5)  /* Advance to Go */ {
    ppos[playerup]=0;
    hits[0]++;
    if (DEBUGMODE) printf (" Advances to Go\n");
  } else if (a==15)
    gotojail();
  curcccard++;
  if (curcccard==16) curcccard=0;
}

void ccard() {
  int a,b;
  a=ccardorder[curccard];
  b = -1;
  if (DEBUGMODE) printf (" %s\n",cnames[a]);
  if (a==13) {
    gotojail();
  } else {
    if (a==2) /* Illinois */  b=24;
    else if (a==3)  /* Utility */
      b=((ppos[playerup]>12) && (ppos[playerup]<28)) ? 28 : 12;
    else if (a==6)  /* Boardwalk */  b=39;
    else if (a==8)  /* Reading */  b=5;
    else if (a==9) { /* Back 3 Spaces */
      b=ppos[playerup]-3;
      if (b<0) b+=40;
    } else if (a==10) /* St. Charles */ b=11;
    else if ((a==11) || (a==12)) /* RR */
      b = (ppos[playerup]==7) ? 15 : (ppos[playerup]==22) ? 25 : 5;
    else if (a==14)  /* Advance to Go */ b=0;
    if (b!=-1) {
      ppos[playerup]=b;
      hits[b]++;
      if (DEBUGMODE) printf (" Goes to %s\n",names[b]);    
      if (ppos[playerup]==33) cccard();
    }
  }
  curccard++;
  if (curccard==16) curccard=0;
}

void ssss (int a, int b) {
  int left;
  int right,temp;
   /* bubble */
    for (left=a;left<b;left++) for (right=b-1;right>=left;right--) {
      if (hits[order[right]]<hits[order[right+1]]) {
       temp = order[right+1];
      order[right+1] = order[right];
      order[right] = temp;
    }
  }
}

char cmp(int a, int b) {
  if (a<b) { hold[b]=0; return 'v'; }
  if (a==b) { hold[b]++; return '='; }
  else {/* if (a>b) */ hold[b]=0; return '^';}
}

void printdist () {
  /* Prints out dice roll distributions */
  long total;
  int lcv;
  total = dbld[0]+dbld[1];
  printf("Result   ");
  for (lcv=2;lcv<8;lcv++) printf("%6.0f ",lcv*1.0);
  printf("\nActual   ");
  for (lcv=2;lcv<8;lcv++) printf("%6.0f ",rolld[lcv]*1.0);
  printf("\nExpected ");
  for (lcv=2;lcv<8;lcv++) printf("%6.0f ",total*1.0/36*(lcv-1));
  printf("\nResult   ");
  for (lcv=8;lcv<13;lcv++) printf("%6.0f ",lcv*1.0); printf("  dbles");
  printf("\nActual   ");
  for (lcv=8;lcv<13;lcv++) printf("%6.0f ",rolld[lcv]*1.0);
  printf("%6.0f ",dbld[1]*1.0);
  printf("\nExpected ");
  for (lcv=8;lcv<13;lcv++) printf("%6.0f ",total*1.0/36*(13-lcv));
    printf("%6.0f ",total*1.0/6);
  printf("\n");
}

void finalresults (long turns) {
  int lcv,nut;
  char symbol;
  for (lcv=0;lcv<41;lcv++) {
    oldorder[order[lcv]]=lcv;
    order[lcv]=lcv;
  }
  ssss(0,40);
  printf ("\nResults after turn %8.0f \n",1.0*turns);
  for (lcv=0;lcv<20;lcv++) {
    /* if (oldorder[order[lcv]] */
    symbol = cmp (oldorder[order[lcv]],lcv);
    printf("(%02d%c%02d)%02d %s: %06.0f; ",hold[lcv],symbol,
       oldorder[order[lcv]]+1,lcv+1,names[order[lcv]],1.0*hits[order[lcv]]);
    symbol = cmp (oldorder[order[lcv+21]],lcv+21);
    printf("(%02d%c%02d)%02d %s: %06.0f; ",hold[lcv+21],symbol,
       oldorder[order[lcv+21]]+1, 
       lcv+22,names[order[lcv+21]],1.0*hits[order[lcv+21]]);
    printf("\n");
  }
    symbol = cmp (oldorder[order[20]],20);
    printf("(%02d%c%02d)%02d %s: %06.0f; \n",hold[lcv],symbol,
       oldorder[order[20]]+1,21,names[order[20]],1.0*hits[order[20]]);
}

void dieroll () {
  /* Rolls a die.  Modifies global variables roll to be 2-12 and dbl to be
   true when a double is rolled.  */
  int a,b;  a = floor(rand()/32768.0*6)+1; b = floor(rand()/32768.0*6)+1;
  roll = a+b; dbl = a==b;
  rolld[roll]++;
  dbld[dbl]++; 
}

void main () {
  int lcv,a,nut;
  long turns;
  playerup=PLAYERS-1;
  srand(SEED);
  shufflecards();
  for (lcv=0;lcv<13;lcv++) rolld[lcv]=0;
  for (lcv=0;lcv<2;lcv++) dbld[lcv]=0;
  for (lcv=0;lcv<PLAYERS;lcv++) {
    ppos[lcv]=0; injail[lcv]=0;
  }
  for (lcv=0;lcv<41;lcv++) {
    hits[lcv]=0; order[lcv]=lcv;
    hold[lcv]=lcv;
  }
  for (turns=0;turns<TTS;turns++) {
    playerup++;  if (playerup==PLAYERS) playerup=0;
    if (DEBUGMODE) printf ("Player %d Up at %s\n",
            playerup,names[ppos[playerup]]);
    dbls=0;
    makemove=1;
    dieroll();
    if (DEBUGMODE && dbl) printf (" Rolls a %d - Double!\n",roll);
    if (DEBUGMODE && !dbl) printf (" Rolls a %d\n",roll);
    if (injail[playerup]>0) {
      if (DEBUGMODE) printf (" Takes %d turn in jail\n",injail[playerup]);
      if (injail[playerup]==3) {
        injail[playerup]=0;
        if (DEBUGMODE) printf (" Gets out of Jail\n");
      } else {
        /* must roll doubles */
        makemove = dbl;
        if (!dbl) {
          injail[playerup]++;
          if (DEBUGMODE) printf (" Stuck in Jail\n");
        } else {
          if (DEBUGMODE) printf (" Gets out of Jail\n");
        }
      }
      dbl = 0; /* No double free move */
    }
    while (makemove) {
      if (dbl) {
        dbls ++;
        makemove=1;
      } else
        makemove=0;
      ppos[playerup]+=roll;
      if (ppos[playerup]>39) ppos[playerup]-=40;
      a=ppos[playerup];
      if (DEBUGMODE) printf (" Moves to %s\n",names[a]);
      hits[a]++;
      if ((a==2) || (a==17) || (a==33)) {
        if (DEBUGMODE) printf (" Draws Community Chest Card");  
        cccard();  
      } else if ((a==7) || (a==22) || (a==36)) {
        if (DEBUGMODE) printf (" Draws Chance Card");    
        ccard();
      } else if (a==30) {
        gotojail();
      }
      if (dbl) {
        dieroll();
        if (DEBUGMODE && dbl) printf (" Rolls a %d - Another Double!\n",roll);
        if (DEBUGMODE && !dbl) printf (" Rolls a %d - No Double This Time\n",roll);
        if (dbl && (dbls==2)) gotojail();
      }
    }
    if (DEBUGMODE) printf (" End of Turn\n");    
    if (turns % MOD == 0) { finalresults(turns);
      if (DICEMODE) printdist();
    }
  }
  finalresults(turns);
}



-- Wei-Hwa Huang <whuang@ugcs.caltech.edu>