From 2fcfd26429ab1cd2984e71b7e97880fb9a69142a Mon Sep 17 00:00:00 2001 From: Andre Padez Date: Fri, 31 Oct 2025 00:31:52 +0000 Subject: [PATCH] feat: add initialSnakeSize and initialFoodCount to GameOptions - New option: initialSnakeSize (defaults to 3) - New option: initialFoodCount (defaults to 1) - Snake spawns with configurable size - Initial food count is configurable - Example: useGame({ initialSnakeSize: 5, initialFoodCount: 2 }) --- src/types.ts | 2 ++ src/useCursor/useCursor.ts | 17 +++++++++++------ src/useGame/useGame.ts | 6 +++--- src/useGameStatus/useGameStatus.ts | 4 +++- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/types.ts b/src/types.ts index 88b39fe..5025042 100755 --- a/src/types.ts +++ b/src/types.ts @@ -35,6 +35,8 @@ export type GameOptions = { startingLevel?: number; foodsPerLevel?: number; maxLevel?: number; + initialSnakeSize?: number; + initialFoodCount?: number; }; // ============================================================================ diff --git a/src/useCursor/useCursor.ts b/src/useCursor/useCursor.ts index 7691ead..b478df4 100755 --- a/src/useCursor/useCursor.ts +++ b/src/useCursor/useCursor.ts @@ -2,11 +2,17 @@ import { useRef, useState } from "react"; import type { Direction, SnakeBody, Position } from "../types"; import type { UseBoardType } from "../useBoard"; +export type UseCursorParams = { + initialSnakeSize?: number; +}; + export function useCursor( cols: number, rows: number, - boardManager: UseBoardType + boardManager: UseBoardType, + params?: UseCursorParams ) { + const initialSnakeSize = params?.initialSnakeSize ?? 3; const { containerRef } = boardManager; const [snakeBody, setSnakeBody] = useState([]); const snakeBodyRef = useRef([]); @@ -19,11 +25,10 @@ export function useCursor( const centerR = Math.floor(rows / 2); const centerC = Math.floor(cols / 2); - const initialBody: SnakeBody = [ - { r: centerR, c: centerC }, - { r: centerR + 1, c: centerC }, - { r: centerR + 2, c: centerC }, - ]; + const initialBody: SnakeBody = []; + for (let i = 0; i < initialSnakeSize; i++) { + initialBody.push({ r: centerR + i, c: centerC }); + } setSnakeBody(initialBody); snakeBodyRef.current = initialBody; diff --git a/src/useGame/useGame.ts b/src/useGame/useGame.ts index 0d3fa16..7f8ae8c 100755 --- a/src/useGame/useGame.ts +++ b/src/useGame/useGame.ts @@ -8,17 +8,17 @@ import { useKeyBindings, type UseKeyBindingsType } from "./useKeyBindings"; import { useScore } from "../useScore"; export function useGame(options?: GameOptions, platformHook?: unknown): GameManager { - const { cols = 30, rows = 20, startingLevel, foodsPerLevel, maxLevel } = options ?? {}; + const { cols = 30, rows = 20, startingLevel, foodsPerLevel, maxLevel, initialSnakeSize, initialFoodCount } = options ?? {}; const boardManager = useBoard(); const { containerRef, renderBoard } = boardManager; - const snakeManager = useCursor(cols, rows, boardManager); + const snakeManager = useCursor(cols, rows, boardManager, { initialSnakeSize }); const { changeDirection } = snakeManager; const foodManager = useFood(cols, rows, boardManager); - const gameManager = useGameStatus(boardManager, snakeManager, foodManager, { startingLevel, foodsPerLevel, maxLevel }); + const gameManager = useGameStatus(boardManager, snakeManager, foodManager, { startingLevel, foodsPerLevel, maxLevel, initialFoodCount }); const { gameStatus, setGameStatus, startGame, quitGame, togglePause, score, level } = gameManager; useEffect(() => { diff --git a/src/useGameStatus/useGameStatus.ts b/src/useGameStatus/useGameStatus.ts index 5f848c1..8942a04 100755 --- a/src/useGameStatus/useGameStatus.ts +++ b/src/useGameStatus/useGameStatus.ts @@ -8,6 +8,7 @@ export type UseGameStatusParams = { startingLevel?: number; foodsPerLevel?: number; maxLevel?: number; + initialFoodCount?: number; }; export function useGameStatus( @@ -19,6 +20,7 @@ export function useGameStatus( const startingLevel = params?.startingLevel ?? 1; const foodsPerLevel = params?.foodsPerLevel ?? 10; const maxLevel = params?.maxLevel ?? 25; + const initialFoodCount = params?.initialFoodCount ?? 1; const { containerRef } = boardManager; const { initSnake, clearSnake, snakeBodyRef } = snakeManager; const { spawnFood, clearFood } = foodManager; @@ -38,7 +40,7 @@ export function useGameStatus( const startGame = () => { initSnake(); - spawnFood(snakeBodyRef.current, 3); + spawnFood(snakeBodyRef.current, initialFoodCount); setScore(0); setLevel(startingLevel); levelRef.current = startingLevel;