aboutsummaryrefslogtreecommitdiff
path: root/ytz.c
diff options
context:
space:
mode:
Diffstat (limited to 'ytz.c')
-rw-r--r--ytz.c175
1 files changed, 0 insertions, 175 deletions
diff --git a/ytz.c b/ytz.c
deleted file mode 100644
index 6b8968b..0000000
--- a/ytz.c
+++ /dev/null
@@ -1,175 +0,0 @@
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-
-/*
- 0000 0000 0000 0000 0000 0000 0000 0000
- rc topscore botflag. botscore.
- topflag x x
-
- 0000 0000 0000 0000 0000 0000 0000 0000
- xd4. d3.d 2.d1 .d0. prng state.... ....
-*/
-
-typedef struct {
- uint8_t topflag_w_roll;
- uint8_t topscore;
- uint8_t botflag;
- uint8_t botscore;
- uint16_t dice;
- uint16_t seed;
-} ytz_state;
-
-/* ROLLS */
-#define GET_ROLL(s) ((uint8_t)((s & 0xC0) >> 6)) /* top 2 bits */
-#define SET_ROLL(s, x) (s & 0x3F | ((uint8_t)x << 6))
-
-/* TOP NUMBERS */
-#define GET_NUM(s, x) ((uint8_t)((s & (1 << x)) >> x))
-#define GET_ACE(s) (GET_NUM(s, 0))
-#define GET_TWO(s) (GET_NUM(s, 1))
-#define GET_THREE(s) (GET_NUM(s, 2))
-#define GET_FOUR(s) (GET_NUM(s, 3))
-#define GET_FIVE(s) (GET_NUM(s, 4))
-#define GET_SIX(s) (GET_NUM(s, 5))
-
-#define SET_NUM(s, x) (s | (1 << x))
-#define SET_ACE(s) (SET_NUM(s, 0))
-#define SET_TWO(s) (SET_NUM(s, 1))
-#define SET_THREE(s) (SET_NUM(s, 2))
-#define SET_FOUR(s) (SET_NUM(s, 3))
-#define SET_FIVE(s) (SET_NUM(s, 4))
-#define SET_SIX(s) (SET_NUM(s, 5))
-
-/* DICE */
-#define GET_D(s, x) ((uint8_t)((s & (0x07 << (3 * x))) >> (3 * x)))
-#define GET_D0(s) (GET_D(s, 0))
-#define GET_D1(s) (GET_D(s, 1))
-#define GET_D2(s) (GET_D(s, 2))
-#define GET_D3(s) (GET_D(s, 3))
-#define GET_D4(s) (GET_D(s, 4))
-
-#define SET_D(s, x, y) (s & (0xFFFF ^ (0x0007 << (3 * x))) | (y << (3 * x)))
-#define SET_D0(s, y) (SET_D(s, 0, y))
-#define SET_D1(s, y) (SET_D(s, 1, y))
-#define SET_D2(s, y) (SET_D(s, 2, y))
-#define SET_D3(s, y) (SET_D(s, 3, y))
-#define SET_D4(s, y) (SET_D(s, 4, y))
-
-/* 16-bit prng, with thanks/apologies to Dr. Lemire (https://lemire.me/blog/2019/07/03/a-fast-16-bit-random-number-generator/) */
-uint32_t hash16(uint32_t input, uint32_t key) {
- uint32_t hash = input * key;
- return ((hash >> 16) ^ hash) & 0xFFFF;
-}
-
-uint16_t wyhash16(uint16_t* seed) {
- *seed += 0xfc15;
- 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 print_dice(ytz_state* state) {
- char* label = "die %d ";
- char* top = ",---,";
- char* mid = "| %d | ";
- char* bot = "'---'";
-
- for (int i = 0; i < 5; i++)
- printf(label, i);
- printf("\n%s %s %s %s %s\n", top, top, top, top, top);
- for (int i = 0; i < 5; i++)
- printf(mid, GET_D(state->dice, i));
- printf("\n%s %s %s %s %s\n", bot, bot, bot, bot, bot);
-}
-
-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 = 0;
- state->topscore = 0;
- state->botflag = 0;
- state->botscore = 0;
- state->dice = 0;
- state->seed = 13; /* TODO this isn't random */
-}
-
-void main() {
- ytz_state y;
- init_ytz_state(&y);
-
- /*
- * until the win condition is met
- * - roll all dice
- * - up to 2 times, ask user which dice to reroll
- * - ask user which category to mark it in
- * - validate and update state
- *
- *
- */
-
- 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));
-
- print_dice(&y);
-
- 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));
-}