The demo bot draws from the seed, the round and the seat

This commit is contained in:
Eric Wagoner committed 2026-09-23 11:01:32 -04:00
1 parent f1c9b29e66
commit 457a536f58
2 files changed
+13 -6

No files matched your search

+5 -5
View File
@@ -33,12 +33,11 @@ export interface State {
export type Input = { pick: number };
/** Mulberry32: a small seeded generator, so a game replays to the same bot picks. */
function next(state: State): number {
let t = (state.rng += 0x6d2b79f5) >>> 0;
/** Mulberry32 on a seed: a small generator, so a game replays to the same bot picks. */
function random(seed: number): number {
let t = (seed + 0x6d2b79f5) >>> 0;
t = Math.imul(t ^ (t >>> 15), t | 1);
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
state.rng = state.rng >>> 0;
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
}
@@ -86,7 +85,8 @@ export const game: GameSpec<State, Input> = {
turn: (state) => state.rounds.length + 1,
// Every finished round is public; nothing is hidden, so the gallery sees what a seat sees.
view: (state, viewer) => (viewer === SPECTATOR ? structuredClone(state) : structuredClone(state)),
botInput: (state) => ({ pick: 1 + Math.floor(next(structuredClone(state)) * HIGHEST) }),
// A function of the state alone: the seed, the round and the seat, so a replay draws the same pick.
botInput: (state, seat) => ({ pick: 1 + Math.floor(random(state.rng + state.rounds.length * 7919 + state.seats.indexOf(seat)) * HIGHEST) }),
cleanInput: (raw) => {
const pick = Number((raw as { pick?: unknown })?.pick);
return { pick: Number.isInteger(pick) && pick >= 1 && pick <= HIGHEST ? pick : 1 };