import { create } from "zustand"; import { generateSession, gradeAnswer, } from "@/lib/engine/parenthesis-sign"; import type { ParenthesisTermCount } from "@/lib/engine/parenthesis-sign"; import type { GradeResult, ParenthesisSignProblem, UserAnswer, } from "@/lib/engine/types"; export interface GameSession { problems: ParenthesisSignProblem[]; currentIndex: number; results: (GradeResult | null)[]; termCount: ParenthesisTermCount; } export type ProblemCount = 5 | 10; export type MaxTermCount = ParenthesisTermCount; interface GameState { session: GameSession | null; selectedProblemCount: ProblemCount; selectedMaxTermCount: MaxTermCount; setProblemCount: (count: ProblemCount) => void; setMaxTermCount: (count: MaxTermCount) => void; initSession: (count?: ProblemCount, maxTermCount?: MaxTermCount) => void; submitAnswer: (answer: UserAnswer) => void; nextProblem: () => void; resetSession: () => void; } const DEFAULT_SESSION_COUNT: ProblemCount = 10; const DEFAULT_MAX_TERM_COUNT: MaxTermCount = 2; function createSession( count: ProblemCount = DEFAULT_SESSION_COUNT, maxTermCount: MaxTermCount = DEFAULT_MAX_TERM_COUNT, ): GameSession { const problems = generateSession(count, maxTermCount); return { problems, currentIndex: 0, results: problems.map(() => null), termCount: maxTermCount, }; } export const useGameStore = create((set, get) => ({ session: null, selectedProblemCount: DEFAULT_SESSION_COUNT, selectedMaxTermCount: DEFAULT_MAX_TERM_COUNT, setProblemCount: (count) => { set({ selectedProblemCount: count }); }, setMaxTermCount: (count) => { set({ selectedMaxTermCount: count }); }, initSession: (count, maxTermCount) => { const selectedProblemCount = count ?? get().selectedProblemCount; const selectedMaxTermCount = maxTermCount ?? get().selectedMaxTermCount; set({ session: createSession(selectedProblemCount, selectedMaxTermCount) }); }, submitAnswer: (answer) => { const { session } = get(); if (!session || session.currentIndex >= session.problems.length) return; if (session.results[session.currentIndex] !== null) return; const problem = session.problems[session.currentIndex]; const result = gradeAnswer(problem, answer); const results = [...session.results]; results[session.currentIndex] = result; set({ session: { ...session, results, }, }); }, nextProblem: () => { const { session } = get(); if (!session || session.currentIndex >= session.problems.length) return; if (session.results[session.currentIndex] === null) return; set({ session: { ...session, currentIndex: session.currentIndex + 1, }, }); }, resetSession: () => { set({ session: createSession( get().selectedProblemCount, get().selectedMaxTermCount, ), }); }, }));