#include <stdio.h>
enum color {RD, PU, YL, BL, OR, GR, PI};
char *names[] = {"RD", "PU", "YL", "BL", "OR", "GR", "PI"};
color sq[135] = {
PI, RD, PU, YL, BL, OR, GR, RD, PU, PI, YL, BL, OR, GR, RD, PU, YL, BL, PI, OR, GR, RD, PU, YL, BL, OR, GR, RD, PU, YL, BL, OR, GR, RD, PU, YL, BL, OR, GR, RD, PU, YL, BL, PI, OR, GR, RD, PU, YL, BL, OR, GR, RD, PU, YL, BL, OR, GR, RD, PU, YL, BL, OR, GR, RD, PU, YL, BL, OR, GR, RD, PU, YL, BL, OR, PI, GR, RD, PU, YL, BL, OR, GR, RD, PU, YL, BL, OR, GR, RD, PU, YL, BL, OR, GR, RD, PI, PU, YL, BL, OR, GR, RD, PU, PI, YL, BL, OR, GR, RD, PU, YL, BL, OR, GR, RD, PU, YL, BL, OR, GR, RD, PU, YL, BL, OR, GR, RD, PU, YL, BL, OR, GR, RD, PU};
int tr[135][18];

// a one character description for each square
char *sn = "S    P   L        C               P        G   ts          t               g          s         p       Q                s            F";
int main(int argc, char **argv)
{
int exact = 0;
if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'e') { // avoid strcmp
    exact = 1;
    printf("Version that requires landing exactly on last purple square\n");
    }
else
    printf("Official version - you can advance past end purple square\n");
int i,j,k,l;
// set the matrix to all 0
for(i=0; i<135; i++)
    for(j=0; j<18; j++)
        tr[i][j] = 0;

// first rules - picking a single color moves to next square of same color
// a doouble moves you to second square of that color
for(i=0; i<135; i++) {  // if you are on square i
   for(j=0; j<6; j++) { // and you get color j
       for (k=i+1; k<135 && sq[k] != color(j); k++)
           ;
       if (!exact)
            tr[i][j] = k < 135 ? k : 134;  // if too far, go to last square
	else
            tr[i][j] = k < 135 ? k : i;    // if too far, stay put
    // now find the second square of the same color
       for (l=k+1; l<135 && sq[l] != color(j); l++)
           ;
	if (!exact)
            tr[i][6+j] = l < 135 ? l : 134;  // if too far, go to last
	else  // just go as far as you can.
            tr[i][6+j] = l < 135 ? l : (k < 135 ? k : i);
       }
    }
// picture cards move you right to that square
for(i=0; i<135; i++) {
    tr[i][12] = 9;     // Lord Licorice
    tr[i][13] = 18;    // Candy cane
    tr[i][14] = 43;    // Gumdrop mountain
    tr[i][15] = 75;    // Grandma Nut
    tr[i][16] = 96;    // Princess Lolly
    tr[i][17] = 104;   // Queen Frostine
    }
// Now the passes.  5->59, 34->47
for(i=0; i<135; i++) {  
   for(j=0; j<12; j++) { 
       if (tr[i][j] == 5)
           tr[i][j] = 59;
       if (tr[i][j] == 34)
           tr[i][j] = 47;
       }
    }
// The stuck squares
for(j=0;j<18; j++) {
    if (j != int(YL) && j-6 != int(YL))  // on square 48, only YL or DYL will work
        tr[48][j] = 48;
    if (j != int(BL) && j-6 != int(BL))  // square 86 sticks till BL or DBL
        tr[86][j] = 86;
    if (j != int(RD) && j-6 != int(RD))  //square 121 sticks until red
        tr[121][j] = 121;
    tr[134][j] = 134;                    // stay in the last square forever.
    }
// print the transition matrix
printf("Matrix describing the result of each card starting from each square:\n");
printf(" SQ CLR  RD  PU  YL  BL  OR  GR DRD DPU DYL DBL DOR DGR LoL CyC GuM GrN PrL QnF\n");
for(i=0; i<135; i++) {
    printf("%3d %2s:", i, names[int(sq[i])]);
    for(j=0; j<18; j++)
        printf("%4d", tr[i][j]);
    printf("\n");
    }
printf("\n");

// now the prob of getting each card.  Assume 66 cards total;   8 each single colors
// 2 each double colors, 1 each picture
double prc[18];
for(j=0; j<6; j++) {
    prc[j] = 8.0/66.0;
    prc[6+j] = 2.0/66.0;
    prc[12+j] = 1.0/66.0;
    }
// initial probability
double pr[135];
for(i=0; i<135; i++)
    pr[i] = 0.0;
pr[0] = 1.0;

double winft = 0.0;  // total odds of winning if you go first
double winst = 0.0;  // total odds if you go second.
double avg[4] = {0.0,0.0,0.0,0.0}; // average game length
for(k=0; pr[134] < 0.9999; k++) {  // take turns until 99.9 chance of finishing
    printf("after turn %d: P=path, L=Lord Licorice, G=Gumdrop, t=target of path,\n",k);
    printf(" s=stuck, g=grandma, p=Princess Lolly, Q=Queen Frostine, F=finished\n");
    for(i=0; i<135; i++) {
	char num[10];
	sprintf(num, "%8.5f", pr[i]);
	if (i != 0)       // skip labelling first since it can be 1.00000
	    num[1] = sn[i];
        printf("%s", num);
	if ((i % 9) == 8)
	    printf("\n");
	}
    printf("\n");
    double newpr[135];
    for(i=0; i<135; i++)
	newpr[i] = 0.0;
    for(i=0; i<135; i++) {
        for(j=0; j<18; j++) {
	    int ta = tr[i][j];  // target square
	    newpr[ta] += pr[i]*prc[j];  // odds we land there
	    }
	}
    // Do some specific calculatioms for the two person case
    double thist = newpr[134] - pr[134];
    // odds of winning on this turn, if you go first = you win AND opponent takes at least as long
    double winf = thist*(1.0-pr[134]);
    winft += winf;
    // odds of winning if you go second (just double checking)
    double wins = thist*(1.0-newpr[134]);
    winst += wins;
    printf("odds that you win on this turn going first %7.5f, going second %7.5f\n", winf, wins);
    // Now do the calculations for the 1-4 player case
    double a = 1.0 - newpr[134];  // odds a single player not finished
    double p = 1.0 - pr[134];     // odds a single player not finished last turn
    double tt[4];  // odds of ending this turn
    tt[0] = p - a;
    tt[1] = p*p - a*a;
    tt[2] = p*p*p - a*a*a;
    tt[3] = p*p*p*p - a*a*a*a;
    printf("Odds finishing this turn with 1,2,3,4 players %7.5f %7.5f %7.5f %7.5f\n",
     tt[0], tt[1], tt[2], tt[3]);
    for(i=0; i<4; i++)
        avg[i] +=  tt[i]*(k+1);
    printf("Odds game is finished with 1,2,3,4 players %7.5f %7.5f %7.5f %7.5f\n",
     1.0-a, 1.0-a*a, 1.0-a*a*a, 1.0-a*a*a*a);
    for(i=0; i<135; i++)
	pr[i] = newpr[i];
    }
printf("\nAverage game length with 1,2,3,4 players %7.5f %7.5f %7.5f %7.5f\n",
avg[0], avg[1], avg[2], avg[3]);
printf("Total odds first=%7.5f, second = %7.5f, ratio %f\n", winft, winst, winft/winst);
return 0;
}
