commit 47f0ca847b3fe3d12db4cbd71b9d4999b23705c3
Author: Antoine Amarilli <a3nm@a3nm.net>
Date: Sun, 25 Dec 2016 23:08:12 +0100
commit
Diffstat:
main.c | | | 112 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 112 insertions(+), 0 deletions(-)
diff --git a/main.c b/main.c
@@ -0,0 +1,112 @@
+#include<stdio.h>
+
+// pass the pigs strategy
+
+// hack: approximate cochon nul as 1 point
+// to avoid bothering with recursive markov chains
+
+// cochons are assumed to be independent
+// bon jambon and cochons a cheval are ignored
+
+#define MAX 100
+#define FACT 4
+#define NRES 6
+
+// saved score of current player, current score of current player, score of
+// other player => winning probability
+float S[FACT*MAX][FACT*MAX][FACT*MAX];
+// => best action
+int A[FACT*MAX][FACT*MAX][FACT*MAX];
+
+// outcomes: DOT, NODOT, DOS, TROT, GROIN, BAJOUE
+// probabilities from observed rolls
+const float P[] = {27, 52, 45, 4, 1, 0};
+
+// scores of outcomes
+const int V[] = {0, 0, 5, 5, 10, 15};
+
+int score(int p, int q) {
+ if (p == q) {
+ // bon flanc
+ if (p <= 1)
+ return 1;
+ // double ...
+ return (V[p] * 4);
+ }
+ if (p + q == 1)
+ return 0; // cochon nul
+ return V[p] + V[q];
+}
+
+float play(int i, int j, int k) {
+ if (k >= FACT*MAX)
+ return 0; // other player won
+ if (i + j >= FACT*MAX)
+ return 1; // current player won
+ if (A[i][j][k])
+ return (S[i][j][k]);
+
+ // probability when stopping now
+ // approximated: should be k 0 i+j
+ float pwin1 = 1 - play(k, 0, i+(j ? j : 1));
+
+ int tp = 0;
+ float pwin2 = 0;
+ for (int ii = 0; ii < NRES; ii++)
+ for (int jj = 0; jj < NRES; jj++) {
+ int p = P[ii] * P[jj];
+ tp += p;
+ int s = FACT*score(ii, jj);
+ float ns;
+ if (!s) {
+ //approximated: should be k 0 i
+ ns = 1 - play(k, 0, i+1);
+ } else {
+ ns = play(i, j+s, k);
+ }
+ pwin2 += p * ns;
+ }
+ pwin2 /= tp;
+ A[i][j][k] = (pwin1 > pwin2) ? 1 : 2;
+ S[i][j][k] = (pwin1 > pwin2) ? pwin1 : pwin2;
+
+ return S[i][j][k];
+}
+
+int main() {
+ play(0, 0, 0);
+ printf("ready\n");
+ int i, k;
+ printf("input: your score, other player score\n");
+ scanf("%d%d", &i, &k);
+ int j = 0;
+ while (i+j < MAX && k < MAX) {
+ j = 0;
+ int act = A[FACT*i][FACT*j][FACT*k];
+ printf("@NOW: you cur / thm => \n");
+ printf(" %3d %3d %3d: %d %f\n", i, j, k, act, S[FACT*i][FACT*j][FACT*k]);
+ while (act == 2) {
+ printf("ROLL: what did you roll?\n");
+ int new = 0;
+ scanf("%d", &new);
+ j += new;
+ act = A[FACT*i][FACT*j][FACT*k];
+ printf("@NOW: you cur / thm => \n");
+ printf(" %3d %3d %3d: %d %f\n", i, j, k, act, S[FACT*i][FACT*j][FACT*k]);
+ if (!new)
+ break;
+ }
+ printf("PASS:");
+ if (i + j >= MAX)
+ break;
+ printf("what is now the opponent score?\n");
+ i += j;
+ scanf("%d", &k);
+ }
+ printf("finished: %d %d %d\n", i, j, k);
+ if (i+j >= MAX)
+ printf("YOU WIN!\n");
+ else
+ printf("they win :(\n");
+}
+