import { useState, useEffect, useCallback } from 'react'; import type { BoardManager } from '../useBoard/types'; import type { GameStatusManager } from '../useGameStatus/types'; import type { ScoreManager, UseScoreProps } from './types'; import { useTimer } from './useTimer'; export function useScore({ board, gameStatusManager, keystrokeCount }: UseScoreProps): ScoreManager { const timer = useTimer(); const [mistakes, setMistakes] = useState(0); const [hints, setHints] = useState(0); const addMistake = useCallback(() => { setMistakes(prev => prev + 1); }, []); const addHint = useCallback(() => { setHints(prev => prev + 1); }, []); const calculateEfficiency = useCallback((): number => { const boardString = board.boardRef.current.map(row => row.map(cell => cell.value || '.').join('') ).join(''); const filledCells = boardString.replace(/\./g, '').length; const totalCells = 81; const givenCells = board.initialBoardRef.current.replace(/\./g, '').length; const userFilledCells = filledCells - givenCells; if (userFilledCells === 0) return 100; const optimalMoves = userFilledCells; const actualMoves = keystrokeCount; const efficiency = Math.round((optimalMoves / actualMoves) * 100); return Math.max(0, Math.min(100, efficiency)); }, [board, keystrokeCount]); const calculateFinalScore = useCallback((): number | null => { const { gameStatus } = gameStatusManager; if (gameStatus !== 'game-won') return null; const efficiency = calculateEfficiency(); const timeInSeconds = timer.timeValue / 1000; const timeBonus = Math.max(0, 3600 - timeInSeconds) * 10; const mistakePenalty = mistakes * 100; const hintPenalty = hints * 200; const baseScore = 10000; const efficiencyBonus = efficiency * 50; const finalScore = baseScore + efficiencyBonus + timeBonus - mistakePenalty - hintPenalty; return Math.max(0, Math.round(finalScore)); }, [gameStatusManager, calculateEfficiency, timer.timeValue, mistakes, hints]); useEffect(() => { const { gameStatus } = gameStatusManager; if (gameStatus === 'started') { timer.startTimer(); } else if (gameStatus === 'paused' || gameStatus === 'game-over' || gameStatus === 'game-won') { timer.stopTimer(); } if (gameStatus === 'waiting') { timer.resetTimer(); setMistakes(0); setHints(0); } }, [gameStatusManager.gameStatus, timer]); useEffect(() => { const { gameStatus, setGameStatus } = gameStatusManager; if (gameStatus === 'started' && board.isComplete() && board.isFullyValid()) { setGameStatus('game-won'); } }, [board, gameStatusManager]); return { timeValue: timer.timeValue, keystrokes: keystrokeCount, mistakes, hints, efficiency: calculateEfficiency(), finalScore: calculateFinalScore(), startTimer: timer.startTimer, stopTimer: timer.stopTimer, resetTimer: timer.resetTimer, addMistake, addHint, calculateEfficiency, calculateFinalScore }; }