diff --git a/example/src/App.tsx b/example/src/App.tsx index 735b57d..068cce8 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -1,15 +1,60 @@ import { useGame } from "../../src/useGame/useGame"; import { useKeyBindings } from './useKeyBindings'; +import { useMounted } from './useMounted'; +import { GameOverlay } from './GameOverlay'; import "../../src/sudoku.css"; +function formatTime(ms: number): string { + const seconds = Math.floor(ms / 1000); + const minutes = Math.floor(seconds / 60); + const remainingSeconds = seconds % 60; + return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`; +} + export default function App() { - const { containerRef, initGame, solveBoard } = useGame(useKeyBindings); + const mounted = useMounted(); + const { + containerRef, + initGame, + solveBoard, + scoreManager, + keyLog, + gameStatus, + } = useGame(useKeyBindings); + + const { timeValue, finalScore } = scoreManager; return (
Press i to play...
-h,j,k,l to move around
-try other vim motions
you're familiar with
- $,^,0,G,gg only valid if
- the edges are reachable
-
Press New Puzzle to start
+Navigation Mode (default):
+h,j,k,l to move around
+R or C to enter edit mode
+ +Edit Mode:
+Type 1-9 to fill cell
+Esc or Enter to exit edit mode
+ ++ Try vim motions: $, ^, 0, counted moves +
+Congratulations!
+🎉 Puzzle Solved!
Final Score:
{finalScore.toLocaleString()}
- min + max ( + 0 + , 100000 - , ( - optimalTime - / - actualTime - ) * - 100000 + - + timeInSeconds + * + 10 )
-Press i to play again
+Click New Puzzle to play again
Press here to play
-all the vim motions
available on desktop
Tap New Puzzle to start
+VIM motions available
via on-screen keyboard
Congratulations!
+🎉 Solved!
Final Score:
{finalScore.toLocaleString()}
- min + max ( + 0 + , 100000 - , ( - optimalTime - / - actualTime - ) * - 100000 + - + time + * + 10 )
-Press to play again
+Tap to play again
); }; diff --git a/src/sudoku.css b/src/sudoku.css index c7eb2c1..11131c0 100644 --- a/src/sudoku.css +++ b/src/sudoku.css @@ -8,6 +8,14 @@ --box-separator: 3px; } + +:root { + --cell-size: 96px; + --cell-font-size: 48px; + --grid-gap: 6px; + --box-separator: 9px; +} + /* ========================================================= Container & Grid Base ========================================================= */ diff --git a/src/useGame/useGame.ts b/src/useGame/useGame.ts index e962539..914be9e 100644 --- a/src/useGame/useGame.ts +++ b/src/useGame/useGame.ts @@ -16,10 +16,6 @@ export function useGame(platformHook?: unknown) { const boardManager = useBoardState(cursorManager); const { board, initialBoard, solution, setDigit, erase, reset, solveBoard } = boardManager; - const scoreManager = useScore({ - gameContext: { gameStatus, setGameStatus }, - }); - // --------------------------- // Keybindings // --------------------------- @@ -33,7 +29,15 @@ export function useGame(platformHook?: unknown) { initialBoard, }); - const { editMode } = keyBindings; + const { editMode, keyLog } = keyBindings; + + // --------------------------- + // Scoring (needs keyLog from keyBindings) + // --------------------------- + const scoreManager = useScore({ + gameContext: { gameStatus, setGameStatus }, + keystrokeCount: keyLog.length, + }); // --------------------------- // Rendering diff --git a/src/useScore/useScore.ts b/src/useScore/useScore.ts index f1917e8..2365d40 100644 --- a/src/useScore/useScore.ts +++ b/src/useScore/useScore.ts @@ -3,6 +3,9 @@ import { useTimer } from "./hooks/useTimer"; import { useScoreTime } from "./useScoreTime"; import type { GameStatus } from "../types"; +const TIME_LIMIT_MS = 60000; // 60 seconds +const KEYSTROKE_LIMIT = 100; + type GameScoreContext = { gameStatus: GameStatus; setGameStatus: (status: GameStatus) => void; @@ -10,17 +13,35 @@ type GameScoreContext = { type UseScoreParams = { gameContext: GameScoreContext; + keystrokeCount: number; }; -export function useScore({ gameContext }: UseScoreParams) { +export function useScore({ gameContext, keystrokeCount }: UseScoreParams) { const timer = useTimer(); - const { gameStatus } = gameContext; + const { gameStatus, setGameStatus } = gameContext; const { timeValue, startTimer, stopTimer, resetTimer } = timer; const [finalScore, setFinalScore] = useState