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 (
+
+
+
+ 연습 시작
+
+
+
+
+
+ );
+}
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) });
},
}));