Something went wrong. Try again.
A daily game
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178import { atom } from "jotai";import { atomWithRefresh, atomWithReset, RESET, selectAtom } from "jotai/utils";import { arrayOfSize, groupIntoRows } from "./game";
export const defaultWidth = 6;export const defaultHeight = 6;export const defaultVariants = ["🍒", "🍍"];
export const widthAtom = atomWithReset(defaultWidth);export const heightAtom = atomWithReset(defaultHeight);export const variantsAtom = atomWithReset(defaultVariants);
export const entropyAtom = atom((get) => get(variantsAtom).length);export const sizeAtom = atom((get) => get(widthAtom) * get(heightAtom));
export const _boardAtom = atom( generateBoard(defaultWidth * defaultHeight, defaultVariants.length),);
export const boardAtom = atom( (get) => get(_boardAtom), (get, set, _value?: typeof RESET) => { set(sessionAtom, RESET); set(_boardAtom, generateBoard(get(sizeAtom), get(entropyAtom))); },);
export const boardMatrixAtom = atom((get) => groupIntoRows(get(_boardAtom), get(widthAtom)),);
const newCell = () => { const cellAtom = atomWithReset(-1); return atom( (get) => get(cellAtom), (get, set, reset?: typeof RESET) => { if (reset === RESET) { return set(cellAtom, RESET); }
if (get(gameResultAtom)) { return; }
const options = get(variantsAtom); const currentValue = get(cellAtom);
let newValue: number = currentValue + 1; if (newValue === options.length) { newValue = -1; }
set(cellAtom, newValue); }, );};
const _sessionAtom = atomWithRefresh((get) => arrayOfSize(get(sizeAtom)).map(() => newCell()),);
export const sessionAtom = atom( (get) => get(_sessionAtom), (get, set, _value?: typeof RESET) => get(_sessionAtom).forEach((cell) => { if (get(cell) < 0) { return; } set(cell, RESET); }),);
export const sessionMatrixAtom = atom((get) => groupIntoRows(get(_sessionAtom).map(get), get(widthAtom)),);
export const gameResultAtom = atom( (get) => get(boardMatrixAtom).toString() === get(sessionMatrixAtom).toString(),);
export const preferencesAtom = atom( (get) => { return { width: get(widthAtom), height: get(heightAtom), variants: get(variantsAtom), }; }, ( _get, set, { width, height, variants, }: { width: number; height: number; variants: string[] }, ) => { set(widthAtom, width); set(heightAtom, height); set(variantsAtom, variants); set(boardAtom); },);
export const selectBoardSubset = (dir: "row" | "col", index: number) => selectAtom( boardMatrixAtom, (board) => { if (dir === "row") { const row = board[index]; if (typeof row === "undefined") { throw new Error(`No board ${dir} at index ${index}`); } return row; } else { return board.map((row) => { const col = row[index]; if (typeof col === "undefined") { throw new Error(`No board ${dir} at index ${index}`); } return col; }); } }, arraysAreEqual, );
export const selectSessionSubset = (dir: "row" | "col", index: number) => selectAtom( sessionMatrixAtom, (session) => { if (dir === "row") { const row = session[index]; if (typeof row === "undefined") { throw new Error(`No session ${dir} at index ${index}`); } return row; } else { return session.map((row) => { const col = row[index]; if (typeof col === "undefined") { throw new Error(`No session ${dir} at index ${index}`); } return col; }); } }, arraysAreEqual, );
export const selectGuessAt = (index: number) => selectAtom(sessionAtom, (cells) => { const cellAtom = cells[index]; if (typeof cellAtom === "undefined") { throw new Error(`Cell "${index}" not found.`); } return cellAtom; });
export function selectVariantAt(index: number) { return selectAtom(variantsAtom, (variants) => { const variant = variants[index]; if (typeof variant === "undefined") { throw new Error(`Variant at ${index} does not exist.`); } return variant; });}
function generateBoard(size: number, entropy: number) { return arrayOfSize(size).map(() => Math.floor(Math.random() * entropy));}
function arraysAreEqual(a: number[], b: number[]) { return a.toString() === b.toString();}