feat: display optimalSteps and efficiency metrics on scoreboard

- Show optimal steps required for the maze
- Display player efficiency percentage (100% = perfect play)
- Metrics appear after maze loads (when optimalSteps > 0)
- Separated from final score with visual divider
- Helps players understand their navigation performance
This commit is contained in:
2025-11-02 16:55:46 +00:00
parent 9db77779b8
commit 156c6db9d2
+36 -23
View File
@@ -10,7 +10,7 @@ function App() {
const gameManager = useGame({ cols, rows }, useKeyBindings); const gameManager = useGame({ cols, rows }, useKeyBindings);
const { containerRef, gameStatus, scoreManager } = gameManager; const { containerRef, gameStatus, scoreManager } = gameManager;
const { timeValue, keystrokes, finalScore } = scoreManager; const { timeValue, keystrokes, optimalSteps, efficiency, finalScore } = scoreManager;
const formatTime = (ms: number) => { const formatTime = (ms: number) => {
const seconds = Math.floor(ms / 1000); const seconds = Math.floor(ms / 1000);
@@ -23,28 +23,41 @@ function App() {
<div className="flex flex-col items-center justify-around min-h-[100vh]"> <div className="flex flex-col items-center justify-around min-h-[100vh]">
<h1 className="text-6xl">VIMazing vim-maze <small>v{version}</small> example</h1> <h1 className="text-6xl">VIMazing vim-maze <small>v{version}</small> example</h1>
<div className="mx-auto my-4 w-fit bg-muted rounded-lg p-4"> <div className="mx-auto my-4 w-fit bg-muted rounded-lg p-4">
{(gameStatus === "started" || gameStatus === "has-key" || gameStatus === "game-won") && ( {(gameStatus === "started" || gameStatus === "has-key" || gameStatus === "game-won") && (
<div className="flex gap-8 text-sm font-mono items-center"> <div className="flex gap-8 text-sm font-mono items-center">
<div> <div>
<div className="text-muted-foreground">Time</div> <div className="text-muted-foreground">Time</div>
<div className="text-lg font-bold">{formatTime(timeValue)}</div> <div className="text-lg font-bold">{formatTime(timeValue)}</div>
</div> </div>
<div> <div>
<div className="text-muted-foreground">Keystrokes</div> <div className="text-muted-foreground">Keystrokes</div>
<div className="text-lg font-bold">{keystrokes}</div> <div className="text-lg font-bold">{keystrokes}</div>
</div> </div>
{gameStatus === "game-won" && finalScore && ( {optimalSteps > 0 && (
<> <>
<div className="w-px h-12 bg-muted-foreground/20" /> <div className="w-px h-12 bg-muted-foreground/20" />
<div className="text-center"> <div>
<div className="text-muted-foreground">Final Score</div> <div className="text-muted-foreground">Optimal Steps</div>
<div className="text-3xl font-bold bg-gradient-to-r from-green-400 to-emerald-500 bg-clip-text text-transparent">{finalScore}</div> <div className="text-lg font-bold">{optimalSteps}</div>
</div> </div>
</> <div>
)} <div className="text-muted-foreground">Efficiency</div>
</div> <div className="text-lg font-bold">{efficiency}%</div>
)} </div>
</div> </>
)}
{gameStatus === "game-won" && finalScore && (
<>
<div className="w-px h-12 bg-muted-foreground/20" />
<div className="text-center">
<div className="text-muted-foreground">Final Score</div>
<div className="text-3xl font-bold bg-gradient-to-r from-green-400 to-emerald-500 bg-clip-text text-transparent">{finalScore}</div>
</div>
</>
)}
</div>
)}
</div>
<div className="relative mx-auto my-4 w-fit" id="maze_container"> <div className="relative mx-auto my-4 w-fit" id="maze_container">
<div ref={containerRef} className="relative" /> <div ref={containerRef} className="relative" />
</div> </div>