Triviaverse / src /hooks /useGameState.ts
Simeon Garratt
fix(spark): Batches 2 + 3 — atomic ELO, real DB IDs, polish
b5ee4ac
Raw
History Blame Contribute Delete
2.02 kB
"use client";
import { useReducer, useCallback, useMemo } from "react";
import { gameReducer, createInitialState } from "@/lib/game/engine";
import { calculateScore } from "@/lib/game/scoring";
import type { ShuffledQuestion, GameMode } from "@/lib/game/types";
export function useGameState(mode: GameMode, questions: ShuffledQuestion[]) {
const [state, dispatch] = useReducer(gameReducer, createInitialState(mode, questions));
const currentQuestion = useMemo(
() => state.questions[state.currentQuestionIndex] ?? null,
[state.questions, state.currentQuestionIndex],
);
const start = useCallback(() => dispatch({ type: "START" }), []);
const timeUp = useCallback(() => dispatch({ type: "TIME_UP" }), []);
const nextPhase = useCallback(() => dispatch({ type: "NEXT_PHASE" }), []);
const answer = useCallback(
(selectedAnswer: string, timeRemainingS: number, totalTimeS: number) => {
if (!currentQuestion) return;
const isCorrect = selectedAnswer === currentQuestion.correctAnswer;
if (isCorrect) {
// Pass the POST-increment streak so the 3rd consecutive correct
// answer earns the streak=3 multiplier (matches what the UI shows
// after this answer lands). state.streak is the value BEFORE this
// answer, so add 1.
const points = calculateScore(currentQuestion.difficulty, state.streak + 1, timeRemainingS, totalTimeS);
dispatch({ type: "ANSWER_CORRECT", points });
} else {
dispatch({ type: "ANSWER_WRONG" });
}
return isCorrect;
},
[currentQuestion, state.streak],
);
const addQuestions = useCallback(
(newQuestions: ShuffledQuestion[]) => dispatch({ type: "ADD_QUESTIONS", questions: newQuestions }),
[],
);
const setQuestions = useCallback(
(newQuestions: ShuffledQuestion[]) => dispatch({ type: "SET_QUESTIONS", questions: newQuestions }),
[],
);
return { state, currentQuestion, start, answer, timeUp, nextPhase, addQuestions, setQuestions };
}