Tic Tac Toe Game with Minimax Algorithm

Answered using OpenAI o1 mini by OpenAI o1

Question:

Generate code for a Tic Tac Toe game using HTML, CSS, and JavaScript. Use the MinMax algorithm. Include a restart button functionality. Include feedback messages, such as "Player's turn" or "AI thinking..." Finally, combine all the files into the HTML file.

Answer:

Certainly! Below is a complete implementation of a Tic Tac Toe game using HTML, CSS, and JavaScript, which includes the Minimax algorithm for AI moves, a restart button, and feedback messages.

You can copy and paste the following code into an HTML file and open it in your web browser to play the game.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tic Tac Toe</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100vh;
            background-color: #f0f0f0;
        }
        h1 {
            margin-bottom: 20px;
        }
        #board {
            display: grid;
            grid-template-columns: repeat(3, 100px);
            grid-template-rows: repeat(3, 100px);
            gap: 5px;
        }
        .cell {
            width: 100px;
            height: 100px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 2em;
            background-color: white;
            border: 2px solid #333;
            cursor: pointer;
        }
        .cell:hover {
            background-color: #e0e0e0;
        }
        #message {
            margin-top: 20px;
            font-size: 1.2em;
        }
        button {
            margin-top: 20px;
            padding: 10px 20px;
            font-size: 1em;
        }
    </style>
</head>
<body>

    <h1>Tic Tac Toe</h1>
    <div id="board"></div>
    <div id="message">Player's turn</div>
    <button id="restart">Restart</button>

    <script>
        const board = document.getElementById('board');
        const message = document.getElementById('message');
        const restartButton = document.getElementById('restart');
        let gameBoard = ['', '', '', '', '', '', '', '', ''];
        let currentPlayer = 'X';
        let isGameActive = true;

        const createBoard = () => {
            board.innerHTML = '';
            gameBoard.forEach((cell, index) => {
                const cellDiv = document.createElement('div');
                cellDiv.classList.add('cell');
                cellDiv.textContent = cell;
                cellDiv.addEventListener('click', () => handleCellClick(index));
                board.appendChild(cellDiv);
            });
        };

        const handleCellClick = (index) => {
            if (gameBoard[index] === '' && isGameActive) {
                gameBoard[index] = currentPlayer;
                createBoard();
                checkWinner();
                if (isGameActive) {
                    currentPlayer = 'O';
                    message.textContent = "AI thinking...";
                    setTimeout(aiMove, 500);
                }
            }
        };

        const aiMove = () => {
            const bestMove = minimax(gameBoard, 'O').index;
            gameBoard[bestMove] = currentPlayer;
            createBoard();
            checkWinner();
            if (isGameActive) {
                currentPlayer = 'X';
                message.textContent = "Player's turn";
            }
        };

        const checkWinner = () => {
            const winningCombinations = [
                [0, 1, 2], [3, 4, 5], [6, 7, 8],
                [0, 3, 6], [1, 4, 7], [2, 5, 8],
                [0, 4, 8], [2, 4, 6]
            ];

            for (const combination of winningCombinations) {
                const [a, b, c] = combination;
                if (gameBoard[a] && gameBoard[a] === gameBoard[b] && gameBoard[a] === gameBoard[c]) {
                    message.textContent = `${gameBoard[a]} wins!`;
                    isGameActive = false;
                    return;
                }
            }

            if (!gameBoard.includes('')) {
                message.textContent = "It's a draw!";
                isGameActive = false;
            }
        };

        const minimax = (board, player) => {
            const availableSpots = board.reduce((acc, val, index) => {
                if (val === '') acc.push(index);
                return acc;
            }, []);

            if (checkWinnerCondition(board, 'O')) return { score: 10 };
            if (checkWinnerCondition(board, 'X')) return { score: -10 };
            if (availableSpots.length === 0) return { score: 0 };

            const moves = [];
            for (const spot of availableSpots) {
                const newBoard = [...board];
                newBoard[spot] = player;
                const result = minimax(newBoard, player === 'O' ? 'X' : 'O');
                moves.push({ index: spot, score: result.score });
            }

            return player === 'O'
                ? moves.reduce((bestMove, move) => move.score > bestMove.score ? move : bestMove)
                : moves.reduce((bestMove, move) => move.score < bestMove.score ? move : bestMove);
        };

        const checkWinnerCondition = (board, player) => {
            const winningCombinations = [
                [0, 1, 2], [3, 4, 5], [6, 7, 8],
                [0, 3, 6], [1, 4, 7], [2, 5, 8],
                [0, 4, 8], [2, 4, 6]
            ];
            return winningCombinations.some(combination => {
                const [a, b, c] = combination;
                return board[a] === player && board[b] === player && board[c] === player;
            });
        };

        const restartGame = () => {
            gameBoard = ['', '', '', '', '', '', '', '', ''];
            currentPlayer = 'X';
            isGameActive = true;
            message.textContent = "Player's turn";
            createBoard();
        };

        restartButton.addEventListener('click', restartGame);
        createBoard();
    </script>

</body>
</html>

Explanation:

  • HTML Structure: The HTML consists of a title, a game board, a message area for feedback, and a restart button.
  • CSS Styles: Basic styles are applied to center the content, style the game board, and provide hover effects.
  • JavaScript Logic:
    • The game board is represented as an array.
    • The handleCellClick function updates the board and checks for a winner.
    • The AI's move is determined using the Minimax algorithm.
    • The checkWinner function checks for winning conditions or a draw.
    • The restartGame function resets the game state.

You can save this code in an HTML file (e.g., tic-tac-toe.html) and open it in a web browser to play the game. Enjoy!