괄호 앞 음수 분배 스테이지 추가

This commit is contained in:
2026-05-23 12:15:53 +09:00
parent 1ed0611b9d
commit 5ee33bf0d3
13 changed files with 1644 additions and 31 deletions
+109
View File
@@ -0,0 +1,109 @@
import { create } from "zustand";
import {
generateSession,
gradeAnswer,
} from "@/lib/engine/parenthesis-sign";
import type {
GradeResult,
ParenthesisSignProblem,
UserAnswer,
} from "@/lib/engine/types";
interface GameSession {
problems: ParenthesisSignProblem[];
currentIndex: number;
results: (GradeResult | null)[];
}
interface GameState {
session: GameSession | null;
initSession: (count?: number) => void;
submitAnswer: (answer: UserAnswer) => void;
nextProblem: () => void;
resetSession: () => void;
currentProblem: () => ParenthesisSignProblem | null;
currentResult: () => GradeResult | null;
isComplete: () => boolean;
score: () => { correct: number; total: number };
}
const DEFAULT_SESSION_COUNT = 10;
function createSession(count = DEFAULT_SESSION_COUNT): GameSession {
const problems = generateSession(count);
return {
problems,
currentIndex: 0,
results: problems.map(() => null),
};
}
export const useGameStore = create<GameState>((set, get) => ({
session: null,
initSession: (count = DEFAULT_SESSION_COUNT) => {
set({ session: createSession(count) });
},
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() });
},
currentProblem: () => {
const { session } = get();
if (!session) return null;
return session.problems[session.currentIndex] ?? null;
},
currentResult: () => {
const { session } = get();
if (!session) return null;
return session.results[session.currentIndex] ?? null;
},
isComplete: () => {
const { session } = get();
return Boolean(session && session.currentIndex >= session.problems.length);
},
score: () => {
const { session } = get();
if (!session) return { correct: 0, total: 0 };
return {
correct: session.results.filter((result) => result?.correct).length,
total: session.problems.length,
};
},
}));