Add core engine: tarot + astrology reading generator with CLI and i18n
Plain-C, dependency-free engine that produces a personalized daily Celtic Cross tarot spread and natal-chart/transit astrology reading, plus a standalone CLI (dist/deck-engine) and run.sh wrapper. Includes English/German output via a simple key=value translation format, and docs/diagrams describing the architecture and I/O.
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
#include "rng.h"
|
||||
|
||||
uint64_t rng_seed_from_string(const char *seed) {
|
||||
uint64_t hash = 0xcbf29ce484222325ULL; /* FNV offset basis */
|
||||
for (const unsigned char *p = (const unsigned char *)seed; *p; p++) {
|
||||
hash ^= (uint64_t)*p;
|
||||
hash *= 0x100000001b3ULL; /* FNV prime */
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
void rng_init(RngState *rng, uint64_t seed) {
|
||||
/* splitmix64 requires a nonzero-friendly state; any seed works, but
|
||||
* avoid the degenerate all-zero stream for the empty string. */
|
||||
rng->state = seed ? seed : 0x9e3779b97f4a7c15ULL;
|
||||
}
|
||||
|
||||
uint64_t rng_next_u64(RngState *rng) {
|
||||
uint64_t z = (rng->state += 0x9e3779b97f4a7c15ULL);
|
||||
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9ULL;
|
||||
z = (z ^ (z >> 27)) * 0x94d049bb133111ebULL;
|
||||
return z ^ (z >> 31);
|
||||
}
|
||||
|
||||
uint32_t rng_next_bounded(RngState *rng, uint32_t bound) {
|
||||
/* Rejection sampling against the largest multiple of `bound` that fits
|
||||
* in 32 bits, so every outcome in [0, bound) is equally likely. `limit`
|
||||
* must stay 64-bit: when `bound` evenly divides 2^32 (e.g. bound == 2,
|
||||
* used for every reversed-card coin flip), the true limit is 2^32
|
||||
* itself, which truncates to 0 in a uint32_t and turns the loop below
|
||||
* into an infinite one. */
|
||||
uint64_t limit = 0x100000000ULL - (0x100000000ULL % bound);
|
||||
uint64_t value;
|
||||
do {
|
||||
value = rng_next_u64(rng) & 0xffffffffULL;
|
||||
} while (value >= limit);
|
||||
return (uint32_t)(value % bound);
|
||||
}
|
||||
Reference in New Issue
Block a user