const boardDiv = document.getElementById('board'); const statusDiv = document.getElementById('status'); const restartBtn = document.getElementById('restart-btn'); let board, gameOver; function initGame() { board = Array(9).fill(''); gameOver = false; statusDiv.textContent = "Tu turno (X)"; renderBoard(); } function renderBoard() { boardDiv.innerHTML = ''; board.forEach((cell, idx) => { const cellDiv = document.createElement('div'); cellDiv.className = 'cell'; cellDiv.textContent = cell; cellDiv.onclick = () => handlePlayerMove(idx); boardDiv.appendChild(cellDiv); }); } function handlePlayerMove(idx) { if (gameOver || board[idx] !== '') return; board[idx] = 'X'; renderBoard(); if (checkWinner('X')) { statusDiv.textContent = `¡Tú ganas! 🎉`; gameOver = true; return; } if (isDraw()) { statusDiv.textContent = "¡Empate!"; gameOver = true; return; } statusDiv.textContent = "Turno de la máquina (O)"; setTimeout(machineMove, 400); } function machineMove() { if (gameOver) return; let bestScore = -Infinity; let move = null; for (let i = 0; i < 9; i++) { if (board[i] === '') { board[i] = 'O'; let score = minimax(board, 0, false); board[i] = ''; if (score > bestScore) { bestScore = score; move = i; } } } if (move !== null) board[move] = 'O'; renderBoard(); if (checkWinner('O')) { statusDiv.textContent = `¡La máquina gana! 🤖`; gameOver = true; return; } if (isDraw()) { statusDiv.textContent = "¡Empate!"; gameOver = true; return; } statusDiv.textContent = "Tu turno (X)"; } // Algoritmo Minimax function minimax(newBoard, depth, isMaximizing) { if (checkWinnerOnBoard(newBoard, 'O')) return 10 - depth; if (checkWinnerOnBoard(newBoard, 'X')) return depth - 10; if (newBoard.every(cell => cell !== '')) return 0; if (isMaximizing) { let bestScore = -Infinity; for (let i = 0; i < 9; i++) { if (newBoard[i] === '') { newBoard[i] = 'O'; let score = minimax(newBoard, depth + 1, false); newBoard[i] = ''; bestScore = Math.max(score, bestScore); } } return bestScore; } else { let bestScore = Infinity; for (let i = 0; i < 9; i++) { if (newBoard[i] === '') { newBoard[i] = 'X'; let score = minimax(newBoard, depth + 1, true); newBoard[i] = ''; bestScore = Math.min(score, bestScore); } } return bestScore; } } function checkWinner(player) { return checkWinnerOnBoard(board, player); } function checkWinnerOnBoard(b, player) { const wins = [ [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 wins.some(combo => combo.every(i => b[i] === player)); } function isDraw() { return board.every(cell => cell !== '') && !checkWinner('X') && !checkWinner('O'); } restartBtn.onclick = initGame; initGame();