diff --git a/src/apps/SnakeAI/BestSnakeDisplay.tsx b/src/apps/SnakeAI/BestSnakeDisplay.tsx index 0338837..dff539c 100644 --- a/src/apps/SnakeAI/BestSnakeDisplay.tsx +++ b/src/apps/SnakeAI/BestSnakeDisplay.tsx @@ -1,3 +1,4 @@ +import { useState } from 'react'; import SnakeCanvas from './SnakeCanvas'; import type { Network } from '../../lib/snakeAI/network'; @@ -8,6 +9,8 @@ interface BestSnakeDisplayProps { } export default function BestSnakeDisplay({ network, gridSize, fitness }: BestSnakeDisplayProps) { + const [playbackSpeed, setPlaybackSpeed] = useState(15); + if (!network) return null; return ( @@ -19,6 +22,22 @@ export default function BestSnakeDisplay({ network, gridSize, fitness }: BestSna {Math.round(fitness)} + +
+
+ Replay Speed: + setPlaybackSpeed(Number(e.target.value))} + style={{ flex: 1, accentColor: '#4ecdc4' }} + /> + {playbackSpeed}x +
+
+
diff --git a/src/apps/SnakeAI/SnakeCanvas.tsx b/src/apps/SnakeAI/SnakeCanvas.tsx index 0fabeec..f572ca7 100644 --- a/src/apps/SnakeAI/SnakeCanvas.tsx +++ b/src/apps/SnakeAI/SnakeCanvas.tsx @@ -9,6 +9,7 @@ interface SnakeCanvasProps { showGrid?: boolean; size?: 'small' | 'normal' | 'large'; showStats?: boolean; // Show score/length/steps even in small mode + playbackSpeed?: number; // Steps per second (default: 15) } const CELL_SIZES = { @@ -19,7 +20,7 @@ const CELL_SIZES = { const CANVAS_PADDING = 10; -export default function SnakeCanvas({ network, gridSize, showGrid = true, size = 'normal', showStats = false }: SnakeCanvasProps) { +export default function SnakeCanvas({ network, gridSize, showGrid = true, size = 'normal', showStats = false, playbackSpeed = 15 }: SnakeCanvasProps) { const canvasRef = useRef(null); const [currentGame, setCurrentGame] = useState(null); const animationFrameRef = useRef(); @@ -43,7 +44,7 @@ export default function SnakeCanvas({ network, gridSize, showGrid = true, size = useEffect(() => { if (!network || !currentGame) return; - const STEPS_PER_SECOND = 10; // Speed of game playback + const STEPS_PER_SECOND = playbackSpeed; // Use prop const UPDATE_INTERVAL = 1000 / STEPS_PER_SECOND; const animate = (timestamp: number) => { @@ -82,7 +83,7 @@ export default function SnakeCanvas({ network, gridSize, showGrid = true, size = cancelAnimationFrame(animationFrameRef.current); } }; - }, [network?.id, !!currentGame, gridSize]); // Use ID and boolean existence check to prevent loop restart on every frame + }, [network?.id, !!currentGame, gridSize, playbackSpeed]); // Added playbackSpeed dependency // Set canvas size once when props change (not on every render) useEffect(() => {