6 struct result
{ unsigned long p1
; unsigned long p2
; };
7 struct player
{ uint8_t pos
; uint8_t score
; };
8 struct key
{ struct player p1
; struct player p2
; bool p1turn
; };
15 struct player
move (struct player p
, int steps
)
17 p
.pos
= (p
.pos
+steps
)%10;
24 struct cache
*cache
= NULL
;
26 struct result
playd (bool p1turn
, struct player p1
, struct player p2
);
27 struct result
play(bool p1turn
, struct player p1
, struct player p2
)
31 memset(&p
, 0, sizeof(p
));
32 p
= (struct key
){.p1turn
=p1turn
, .p1
=p1
, .p2
=p2
};
33 HASH_FIND(hh
, cache
, &p
, sizeof(struct key
), e
);
35 struct result r
= playd(p1turn
, p1
, p2
);
36 e
= calloc(1, sizeof(struct cache
));
37 *e
= (struct cache
){.key
=p
, .res
=r
};
38 HASH_ADD(hh
, cache
, key
, sizeof(struct key
), e
);
45 static inline void add_result(struct result
*l
, struct result r
)
51 #define FOR_THROWS(x) \
52 for (int i = 1; i<=3; i++)\
53 for (int j = 1; j<=3; j++)\
54 for (int k = 1; k<=3; k++)\
57 struct result
playd (bool p1turn
, struct player p1
, struct player p2
)
59 struct result r
= {.p1
=0, .p2
=0};
62 else if (p2
.score
>= 21)
65 FOR_THROWS(add_result(&r
, play(!p1turn
, move(p1
, i
+j
+k
), p2
)));
67 FOR_THROWS(add_result(&r
, play(!p1turn
, p1
, move(p2
, i
+j
+k
))));
73 struct player p1
= {.score
=0}, p2
= {.score
=0};
74 if (2 != scanf("Player 1 starting position: %" SCNu8
"\n"
75 "Player 2 starting position: %" SCNu8
"\n",
79 struct result r
= play(true, p1
, p2
);
80 printf("%lu\n", r
.p1
> r
.p2
? r
.p1
: r
.p2
);