source code
source code
interface MainMenuProps {
onSelectGameMode: (mode: GameMode) => void;
}
<Button
onClick={() => onSelectGameMode('ai')}
size="lg"
className="w-full bg-orange-600 hover:bg-orange-700"
>
Play Against AI
</Button>
</div>
</div>
);
};
return (
<div className="min-h-screen flex flex-col items-center justify-center bg-
gradient-to-b from-gray-900 to-gray-800 p-4">
<h1 className="text-4xl font-bold mb-2 text-white">Tic Tac Toe</h1>
<p className="text-gray-300 mb-8">Classic game with a modern twist</p>
interface GameBoardProps {
gameMode: GameMode;
xScore: number;
oScore: number;
drawScore: number;
onScoreUpdate: (scores: GameStatus) => void;
}
return null;
};
// Update board
const newBoard = [...board];
newBoard[index] = isXNext ? 'X' : 'O';
setBoard(newBoard);
setIsXNext(!isXNext);
};
// Check if AI won
const result = checkWinner(newBoard);
if (result) {
handleGameResult(result);
return;
}
setIsXNext(true);
}, 600); // Small delay for better UX
const newScores = {
xScore: result === 'X' ? xScore + 1 : xScore,
oScore: result === 'O' ? oScore + 1 : oScore,
drawScore
};
onScoreUpdate(newScores);
// Reset game
const resetGame = (): void => {
setBoard(Array(9).fill(null));
setIsXNext(true);
setWinner(null);
setWinningCombination(null);
setGameOver(false);
};
// Reset scores
const resetScores = (): void => {
onScoreUpdate({
xScore: 0,
oScore: 0,
drawScore: 0
});
resetGame();
};
return (
<div
className={`flex items-center justify-center w-full h-full transition-
colors ${
value
? "cursor-default"
: "cursor-pointer hover:bg-game-cell-hover"
} ${isWinningCell ? "bg-opacity-80 animate-pulse-soft" : ""}`}
onClick={() => handleCellClick(index)}
>
{value === "X" && (
<X
className={`text-game-x animate-mark-cell w-12 h-12 sm:w-16 sm:h-16 ${
isWinningCell ? "drop-shadow-lg" : ""
}`}
strokeWidth={3}
/>
)}
{value === "O" && (
<Circle
className={`text-game-o animate-mark-cell w-12 h-12 sm:w-16 sm:h-16 ${
isWinningCell ? "drop-shadow-lg" : ""
}`}
strokeWidth={3}
/>
)}
</div>
);
};
return (
<div className="flex flex-col items-center gap-6">
{/* Game status */}
<div className="flex justify-between w-full max-w-xs sm:max-w-md">
<div className="text-game-x font-bold">
{gameMode === 'ai' ? 'You' : 'X'}: {xScore}
</div>
<div className="text-gray-500 font-bold">
Draws: {drawScore}
</div>
<div className="text-game-o font-bold">
{gameMode === 'ai' ? 'AI' : 'O'}: {oScore}
</div>
</div>