aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ytz.c97
1 files changed, 69 insertions, 28 deletions
diff --git a/ytz.c b/ytz.c
index acfdfde..3ca9b76 100644
--- a/ytz.c
+++ b/ytz.c
@@ -1,3 +1,4 @@
+#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
@@ -66,8 +67,57 @@ uint16_t wyhash16(uint16_t* seed) {
return hash16(*seed, 0x2ab);
}
+uint16_t roll_die(uint16_t* seed) {
+ const uint16_t s = 6; /* generating in the range of [0,6) */
+ uint16_t x = wyhash16(seed);
+ uint32_t m = (uint32_t)x * (uint32_t)s;
+ uint32_t l = (uint16_t)m;
+ if (l < s) {
+ uint16_t t = -s % s;
+ while (l < t) {
+ x = wyhash16(seed);
+ m = (uint32_t)x * (uint32_t)s;
+ l = (uint16_t)m;
+ }
+ }
+ return (m >> 16) + 1; /* we ultimately want [1,7) */
+}
+
+void ask_for_rerolls(ytz_state* state) {
+ char buf[10];
+ printf("which dice should be re-rolled? ");
+ fgets(buf, sizeof(buf), stdin);
+
+ int dice[6] = { -1, -1, -1, -1, -1, -1 }; /* we only ever look for 5 dice, so should always hit -1 at some point */
+ sscanf(buf, "%d %d %d %d %d", &dice[0], &dice[1], &dice[2], &dice[3], &dice[4]);
+
+ for (int i = 0; i < 5; i++) {
+ if (dice[i] == -1)
+ break;
+ state->dice = SET_D(state->dice, dice[i], 0);
+ }
+}
+
+void do_turn(ytz_state* state) {
+ int roll = GET_ROLL(state->topflag_w_roll);
+ bool reset = false;
+
+ // if we're out of rolls, reset
+ if (roll == 3) {
+ reset = true;
+ roll = 0;
+ }
+
+ for (int i = 0; i < 5; i++) {
+ if (reset || (GET_D(state->dice, i) == 0)) {
+ state->dice = SET_D(state->dice, i, roll_die(&(state->seed)));
+ }
+ }
+ state->topflag_w_roll = SET_ROLL(state->topflag_w_roll, ++roll);
+}
+
void init_ytz_state(ytz_state* state) {
- state->topflag_w_roll = 0x70; /* roll 1, no flags */
+ state->topflag_w_roll = 0;
state->topscore = 0;
state->botflag = 0;
state->botscore = 0;
@@ -89,37 +139,28 @@ void main() {
*
*/
- y.dice = SET_D0(y.dice, 1);
- y.dice = SET_D1(y.dice, 6);
- y.dice = SET_D2(y.dice, 4);
- y.dice = SET_D3(y.dice, 3);
- y.dice = SET_D4(y.dice, 2);
-
+ printf("roll: %d\n", GET_ROLL(y.topflag_w_roll));
printf("d1: %d\n", GET_D0(y.dice));
printf("d2: %d\n", GET_D1(y.dice));
printf("d3: %d\n", GET_D2(y.dice));
printf("d4: %d\n", GET_D3(y.dice));
printf("d5: %d\n", GET_D4(y.dice));
- printf("size: %d\n", sizeof(y));
-
- printf("roll: %d\n", GET_ROLL(y.topflag_w_roll));
-
- y.topflag_w_roll = SET_ROLL(y.topflag_w_roll, 2);
- printf("roll: %d\n", GET_ROLL(y.topflag_w_roll));
-
- printf("ace: %d\n", GET_ACE(y.topflag_w_roll));
- y.topflag_w_roll = SET_ACE(y.topflag_w_roll);
- printf("ace: %d\n", GET_ACE(y.topflag_w_roll));
-
- printf("seed: %d\n", y.seed);
- uint16_t hash;
- for (int i = 0; i < 10; i++) {
- hash = wyhash16(&(y.seed));
- printf("hash: %d\n", hash);
- printf("new seed: %d\n", y.seed);
- }
- hash = wyhash16(&(y.seed));
- printf("hash: %d\n", hash);
- printf("new seed: %d\n", y.seed);
+ do_turn(&y);
+
+ printf("new roll: %d\n", GET_ROLL(y.topflag_w_roll));
+ printf("new d1: %d\n", GET_D0(y.dice));
+ printf("new d2: %d\n", GET_D1(y.dice));
+ printf("new d3: %d\n", GET_D2(y.dice));
+ printf("new d4: %d\n", GET_D3(y.dice));
+ printf("new d5: %d\n", GET_D4(y.dice));
+
+ ask_for_rerolls(&y);
+ do_turn(&y);
+ printf("newer roll: %d\n", GET_ROLL(y.topflag_w_roll));
+ printf("newer d1: %d\n", GET_D0(y.dice));
+ printf("newer d2: %d\n", GET_D1(y.dice));
+ printf("newer d3: %d\n", GET_D2(y.dice));
+ printf("newer d4: %d\n", GET_D3(y.dice));
+ printf("newer d5: %d\n", GET_D4(y.dice));
}