diff options
Diffstat (limited to 'ytz.c')
| -rw-r--r-- | ytz.c | 125 |
1 files changed, 125 insertions, 0 deletions
@@ -0,0 +1,125 @@ +#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); +} + +void init_ytz_state(ytz_state* state) { + state->topflag_w_roll = 0x70; /* roll 1, no flags */ + 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 + * + * + */ + + 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("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); +} |
