From 2779bf1b0edbb376bc59fa6a1ea81a302b2ebe6c Mon Sep 17 00:00:00 2001 From: jisangs Date: Tue, 26 May 2026 15:23:21 +0900 Subject: [PATCH] =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=EC=88=98=20=EC=84=A0?= =?UTF-8?q?=ED=83=9D=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80=20-=205?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20/=2010=EB=AC=B8=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/(game)/play/PlayClient.tsx | 32 ++++++++++++++--- app/(game)/play/page.tsx | 15 ++++++-- app/StartControls.tsx | 66 ++++++++++++++++++++++++++++++++++ app/page.tsx | 11 ++---- store/gameStore.ts | 22 ++++++++---- 5 files changed, 124 insertions(+), 22 deletions(-) create mode 100644 app/StartControls.tsx diff --git a/app/(game)/play/PlayClient.tsx b/app/(game)/play/PlayClient.tsx index ca3db0c..05e9736 100644 --- a/app/(game)/play/PlayClient.tsx +++ b/app/(game)/play/PlayClient.tsx @@ -9,6 +9,7 @@ import ScoreSummary from "@/components/game/ScoreSummary"; import StageIndicator from "@/components/game/StageIndicator"; import KatexRenderer from "@/components/math/KatexRenderer"; import { useGameStore } from "@/store/gameStore"; +import type { ProblemCount } from "@/store/gameStore"; function parseAnswer(value: string) { const trimmed = value.trim(); @@ -18,8 +19,16 @@ function parseAnswer(value: string) { return Number(trimmed); } -export default function PlayClient() { +interface PlayClientProps { + problemCount: ProblemCount; +} + +export default function PlayClient({ problemCount }: PlayClientProps) { const session = useGameStore((state) => state.session); + const selectedProblemCount = useGameStore( + (state) => state.selectedProblemCount, + ); + const setProblemCount = useGameStore((state) => state.setProblemCount); const initSession = useGameStore((state) => state.initSession); const submitAnswer = useGameStore((state) => state.submitAnswer); const nextProblem = useGameStore((state) => state.nextProblem); @@ -34,15 +43,28 @@ export default function PlayClient() { const isComplete = Boolean( session && session.currentIndex >= session.problems.length, ); + const sessionNeedsInit = + session === null || session.problems.length !== problemCount; const correctCount = session?.results.filter((result) => result?.correct).length ?? 0; const totalCount = session?.problems.length ?? 0; useEffect(() => { - if (session === null) { - initSession(); + if (selectedProblemCount !== problemCount) { + setProblemCount(problemCount); } - }, [initSession, session]); + + if (sessionNeedsInit) { + initSession(problemCount); + } + }, [ + initSession, + problemCount, + selectedProblemCount, + session, + sessionNeedsInit, + setProblemCount, + ]); useEffect(() => { setAnswerA(""); @@ -67,7 +89,7 @@ export default function PlayClient() { submitAnswer({ a: parsedA, b: parsedB }); } - if (!session) { + if (sessionNeedsInit) { return (
diff --git a/app/(game)/play/page.tsx b/app/(game)/play/page.tsx index eed65b4..c1becd5 100644 --- a/app/(game)/play/page.tsx +++ b/app/(game)/play/page.tsx @@ -1,5 +1,16 @@ import PlayClient from "./PlayClient"; +import type { ProblemCount } from "@/store/gameStore"; -export default function PlayPage() { - return ; +interface PlayPageProps { + searchParams?: { + count?: string; + }; +} + +function parseProblemCount(count?: string): ProblemCount { + return count === "5" ? 5 : 10; +} + +export default function PlayPage({ searchParams }: PlayPageProps) { + return ; } diff --git a/app/StartControls.tsx b/app/StartControls.tsx new file mode 100644 index 0000000..8df34e1 --- /dev/null +++ b/app/StartControls.tsx @@ -0,0 +1,66 @@ +"use client"; + +import Link from "next/link"; +import { useEffect, useRef } from "react"; + +import { useGameStore } from "@/store/gameStore"; +import type { ProblemCount } from "@/store/gameStore"; + +const problemCounts: ProblemCount[] = [5, 10]; + +export default function StartControls() { + const startLinkRef = useRef(null); + const selectedProblemCount = useGameStore( + (state) => state.selectedProblemCount, + ); + const setProblemCount = useGameStore((state) => state.setProblemCount); + + useEffect(() => { + startLinkRef.current?.focus(); + }, []); + + return ( +
+
+ + 연습 시작 + +
+ +
+ + 문제 수 + +
+ {problemCounts.map((count) => { + const selected = selectedProblemCount === count; + + return ( + + ); + })} +
+
+
+ ); +} diff --git a/app/page.tsx b/app/page.tsx index d4e5206..836d737 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,4 +1,4 @@ -import Link from "next/link"; +import StartControls from "./StartControls"; export default function Home() { return ( @@ -17,14 +17,7 @@ export default function Home() {

-
- - 연습 시작 - -
+

이번 단계에서는 화면 이동만 확인합니다.

diff --git a/store/gameStore.ts b/store/gameStore.ts index 344bf36..abbfe88 100644 --- a/store/gameStore.ts +++ b/store/gameStore.ts @@ -16,17 +16,21 @@ export interface GameSession { results: (GradeResult | null)[]; } +export type ProblemCount = 5 | 10; + interface GameState { session: GameSession | null; - initSession: (count?: number) => void; + selectedProblemCount: ProblemCount; + setProblemCount: (count: ProblemCount) => void; + initSession: (count?: ProblemCount) => void; submitAnswer: (answer: UserAnswer) => void; nextProblem: () => void; resetSession: () => void; } -const DEFAULT_SESSION_COUNT = 10; +const DEFAULT_SESSION_COUNT: ProblemCount = 10; -function createSession(count = DEFAULT_SESSION_COUNT): GameSession { +function createSession(count: ProblemCount = DEFAULT_SESSION_COUNT): GameSession { const problems = generateSession(count); return { @@ -38,8 +42,14 @@ function createSession(count = DEFAULT_SESSION_COUNT): GameSession { export const useGameStore = create((set, get) => ({ session: null, - initSession: (count = DEFAULT_SESSION_COUNT) => { - set({ session: createSession(count) }); + selectedProblemCount: DEFAULT_SESSION_COUNT, + setProblemCount: (count) => { + set({ selectedProblemCount: count }); + }, + initSession: (count) => { + const selectedProblemCount = count ?? get().selectedProblemCount; + + set({ session: createSession(selectedProblemCount) }); }, submitAnswer: (answer) => { const { session } = get(); @@ -73,6 +83,6 @@ export const useGameStore = create((set, get) => ({ }); }, resetSession: () => { - set({ session: createSession() }); + set({ session: createSession(get().selectedProblemCount) }); }, }));