main.c (3052B)
1 #include<stdio.h> 2 3 // pass the pigs strategy 4 // (not related to pass the pigs, all trademarks property of respective owners) 5 6 // related work (probably better): 7 // https://web.archive.org/web/20211206052308/http://daynebatten.com/2015/10/optimal-pass-the-pigs-strategy-two/ 8 9 // hack: approximate cochon nul as 1 point 10 // to avoid bothering with recursive markov chains 11 12 // cochons are assumed to be independent 13 // bon jambon and cochons a cheval are ignored 14 15 #define MAX 100 16 #define FACT 4 17 #define NRES 6 18 19 // saved score of current player, current score of current player, score of 20 // other player => winning probability 21 float S[FACT*MAX][FACT*MAX][FACT*MAX]; 22 // => best action 23 int A[FACT*MAX][FACT*MAX][FACT*MAX]; 24 25 // outcomes: DOT, NODOT, DOS, TROT, GROIN, BAJOUE 26 // probabilities from observed rolls 27 const float P[] = {27, 52, 45, 4, 1, 0}; 28 29 // scores of outcomes 30 const int V[] = {0, 0, 5, 5, 10, 15}; 31 32 int score(int p, int q) { 33 if (p == q) { 34 // bon flanc 35 if (p <= 1) 36 return 1; 37 // double ... 38 return (V[p] * 4); 39 } 40 if (p + q == 1) 41 return 0; // cochon nul 42 return V[p] + V[q]; 43 } 44 45 float play(int i, int j, int k) { 46 if (k >= FACT*MAX) 47 return 0; // other player won 48 if (i + j >= FACT*MAX) 49 return 1; // current player won 50 if (A[i][j][k]) 51 return (S[i][j][k]); 52 53 // probability when stopping now 54 // approximated: should be k 0 i+j 55 float pwin1; 56 if (j > 0) 57 pwin1 = 1 - play(k, 0, i+j); 58 else 59 pwin1 = 0; // never stop on first round 60 61 int tp = 0; 62 float pwin2 = 0; 63 for (int ii = 0; ii < NRES; ii++) 64 for (int jj = 0; jj < NRES; jj++) { 65 int p = P[ii] * P[jj]; 66 tp += p; 67 int s = FACT*score(ii, jj); 68 float ns; 69 if (!s) { 70 //approximated: should be k 0 i 71 ns = 1 - play(k, 0, i+1); 72 } else { 73 ns = play(i, j+s, k); 74 } 75 pwin2 += p * ns; 76 } 77 pwin2 /= tp; 78 A[i][j][k] = (pwin1 > pwin2) ? 1 : 2; 79 S[i][j][k] = (pwin1 > pwin2) ? pwin1 : pwin2; 80 81 return S[i][j][k]; 82 } 83 84 int main() { 85 play(0, 0, 0); 86 printf("ready\n"); 87 int i, k; 88 printf("input: your score, other player score\n"); 89 scanf("%d%d", &i, &k); 90 int j = 0; 91 while (i+j < MAX && k < MAX) { 92 j = 0; 93 int act = A[FACT*i][FACT*j][FACT*k]; 94 printf("@NOW: you cur / thm => \n"); 95 printf(" %3d %3d %3d: %d %f\n", i, j, k, act, S[FACT*i][FACT*j][FACT*k]); 96 while (act == 2) { 97 printf("ROLL: what did you roll?\n"); 98 int new = 0; 99 scanf("%d", &new); 100 j += new; 101 if (!new) 102 j = 0; 103 act = A[FACT*i][FACT*j][FACT*k]; 104 printf("@NOW: you cur / thm => \n"); 105 printf(" %3d %3d %3d: %d %f\n", i, j, k, act, S[FACT*i][FACT*j][FACT*k]); 106 if (!new) 107 break; 108 } 109 printf("PASS:"); 110 if (i + j >= MAX) 111 break; 112 printf("what is now the opponent score?\n"); 113 i += j; 114 scanf("%d", &k); 115 // because of hack 116 if (!k) 117 k = 1; 118 } 119 printf("finished: %d %d %d\n", i, j, k); 120 if (i+j >= MAX) 121 printf("YOU WIN!\n"); 122 else 123 printf("they win :(\n"); 124 } 125