Tic Tac Toe

Tic-Tac-Toe Game

Tic-Tac-Toe

const cells = document.querySelectorAll('.cell'); const result = document.getElementById('result'); const startBtn = document.getElementById('start-btn'); const humanVsHumanBtn = document.getElementById('human-vs-human'); const humanVsComputerBtn = document.getElementById('human-vs-computer'); const xBtn = document.getElementById('x'); const oBtn = document.getElementById('o'); let board; let currentPlayer; let humanPlayer; let computerPlayer; let isHumanVsHuman = true; let gameActive = false; // Winning combinations const winCombos = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6], ]; function startGame() { board = Array.from(Array(9).keys()); cells.forEach(cell => { cell.textContent = ''; cell.style.backgroundColor = ''; cell.addEventListener('click', turnClick, false); }); result.textContent = ''; gameActive = true; } function turnClick(event) { const cellIndex = event.target.dataset.index; if (typeof board[cellIndex] === 'number' && gameActive) { turn(cellIndex, currentPlayer); if (!checkWin(board, currentPlayer) && !checkTie()) { if (!isHumanVsHuman) { turn(bestSpot(), computerPlayer); } } } } function turn(cellIndex, player) { board[cellIndex] = player; document.querySelector(`[data-index="${cellIndex}"]`).textContent = player; const gameWon = checkWin(board, player); if (gameWon) { gameOver(gameWon); } currentPlayer = currentPlayer === 'X' ? 'O' : 'X'; } function checkWin(board, player) { let plays = board.reduce((a, e, i) => (e === player) ? a.concat(i) : a, []); let gameWon = null; for (let [index, win] of winCombos.entries()) { if (win.every(elem => plays.indexOf(elem) > -1)) { gameWon = {index: index, player: player}; break; } } return gameWon; } function gameOver(gameWon) { for (let index of winCombos[gameWon.index]) { document.querySelector(`[data-index="${index}"]`).style.backgroundColor = gameWon.player === humanPlayer ? "blue" : "red"; } cells.forEach(cell => cell.removeEventListener('click', turnClick, false)); declareWinner(gameWon.player === humanPlayer ? "You win!" : "You lose."); } function declareWinner(who) { result.textContent = who; gameActive = false; } function emptySquares() { return board.filter(s => typeof s === 'number'); } function bestSpot() { return minimax(board, computerPlayer).index; } function checkTie() { if (emptySquares().length === 0) { cells.forEach(cell => cell.style.backgroundColor = "green"); cells.forEach(cell => cell.removeEventListener('click', turnClick, false)); declareWinner("Tie Game!"); return true; } return false; } // Minimax algorithm to make the AI unbeatable function minimax(newBoard, player) { let availSpots = emptySquares(); if (checkWin(newBoard, humanPlayer)) { return {score: -10}; } else if (checkWin(newBoard, computerPlayer)) { return {score: 10}; } else if (availSpots.length === 0) { return {score: 0}; } let moves = []; for (let i = 0; i < availSpots.length; i++) { let move = {}; move.index = newBoard[availSpots[i]]; newBoard[availSpots[i]] = player; let result; if (player === computerPlayer) { result = minimax(newBoard, humanPlayer); move.score = result.score; } else { result = minimax(newBoard, computerPlayer); move.score = result.score; } newBoard[availSpots[i]] = move.index; moves.push(move); } let bestMove; if (player === computerPlayer) { let bestScore = -10000; for (let i = 0; i < moves.length; i++) { if (moves[i].score > bestScore) { bestScore = moves[i].score; bestMove = i; } } } else { let bestScore = 10000; for (let i = 0; i < moves.length; i++) { if (moves[i].score < bestScore) { bestScore = moves[i].score; bestMove = i; } } } return moves[bestMove]; } // Event Listeners humanVsHumanBtn.addEventListener('click', () => { isHumanVsHuman = true; }); humanVsComputerBtn.addEventListener('click', () => { isHumanVsHuman = false; }); xBtn.addEventListener('click', () => { humanPlayer = 'X'; computerPlayer = 'O'; currentPlayer = 'X'; }); oBtn.addEventListener('click', () => { humanPlayer = 'O'; computerPlayer = 'X'; currentPlayer = 'X'; }); startBtn.addEventListener('click', startGame);

Comments

Post a Comment

Popular posts from this blog