
一個你打不贏的井字遊戲
繼之前的雙手互博版本的井字遊戲,這文章提供與電腦對戰版本
井字遊戲
原始碼:
<!DOCTYPE html> <html lang="zh-TW"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>井字棋遊戲</title> <style> body { font-family: Arial, sans-serif; text-align: center; } #board { display: grid; grid-template-columns: repeat(3, 100px); grid-template-rows: repeat(3, 100px); gap: 5px; margin: 20px auto; width: 320px; } .cell { width: 100px; height: 100px; font-size: 36px; font-weight: bold; display: flex; align-items: center; justify-content: center; border: 2px solid black; cursor: pointer; background-color: #f0f0f0; } .cell.x { color: blue; } .cell.o { color: red; } #reset { padding: 10px 20px; font-size: 16px; cursor: pointer; } </style> </head> <body> <h1>井字棋遊戲</h1> <p id="status">載入中...</p> <div id="board"> <div class="cell" data-index="0"></div> <div class="cell" data-index="1"></div> <div class="cell" data-index="2"></div> <div class="cell" data-index="3"></div> <div class="cell" data-index="4"></div> <div class="cell" data-index="5"></div> <div class="cell" data-index="6"></div> <div class="cell" data-index="7"></div> <div class="cell" data-index="8"></div> </div> <button id="reset">重新開始</button> <script> const board = document.getElementById("board"); const statusText = document.getElementById("status"); const resetButton = document.getElementById("reset"); const cells = document.querySelectorAll(".cell"); let playerSymbol, computerSymbol; let currentPlayer; let boardState = ["", "", "", "", "", "", "", "", ""]; let gameActive = true; let isPlayerTurn; const winPatterns = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], // 橫排 [0, 3, 6], [1, 4, 7], [2, 5, 8], // 直排 [0, 4, 8], [2, 4, 6] // 斜線 ]; // 監聽玩家點擊格子 cells.forEach(cell => { cell.addEventListener("click", handleCellClick); }); // 處理玩家點擊事件 function handleCellClick(event) { if (!isPlayerTurn || !gameActive) return; const index = event.target.dataset.index; if (boardState[index] !== "") return; placeMove(index, currentPlayer); if (!gameActive) return; isPlayerTurn = false; setTimeout(computerMove, 500); // 電腦稍作延遲再行動 } // 電腦行動(強化 AI) function computerMove() { if (!gameActive) return; let bestMove = getBestMove(); placeMove(bestMove, currentPlayer); isPlayerTurn = true; } // AI 最佳選擇 function getBestMove() { let emptyCells = boardState .map((value, index) => (value === "" ? index : null)) .filter(index => index !== null); // 1. **檢查是否能直接獲勝** for (let index of emptyCells) { boardState[index] = currentPlayer; if (checkWin(currentPlayer)) { boardState[index] = ""; return index; } boardState[index] = ""; } // 2. **阻止玩家獲勝** let opponent = currentPlayer === playerSymbol ? computerSymbol : playerSymbol; for (let index of emptyCells) { boardState[index] = opponent; if (checkWin(opponent)) { boardState[index] = ""; return index; } boardState[index] = ""; } // 3. **優先選擇中心** if (boardState[4] === "") return 4; // 4. **優先選擇角落** let corners = [0, 2, 6, 8].filter(i => boardState[i] === ""); if (corners.length > 0) return corners[Math.floor(Math.random() * corners.length)]; // 5. **選擇邊緣** let edges = [1, 3, 5, 7].filter(i => boardState[i] === ""); if (edges.length > 0) return edges[Math.floor(Math.random() * edges.length)]; // 6. **最後隨機選擇** return emptyCells[Math.floor(Math.random() * emptyCells.length)]; } // 放置棋子並檢查勝負 function placeMove(index, player) { boardState[index] = player; cells[index].textContent = player; cells[index].classList.add(player === "X" ? "x" : "o"); if (checkWin(player)) { statusText.textContent = `${player === playerSymbol ? "玩家" : "電腦"} (${player}) 獲勝!`; gameActive = false; return; } if (boardState.every(cell => cell !== "")) { statusText.textContent = "平局!"; gameActive = false; return; } currentPlayer = currentPlayer === "X" ? "O" : "X"; statusText.textContent = `${currentPlayer === playerSymbol ? "玩家" : "電腦"} (${currentPlayer}) 的回合`; } // 檢查是否勝利 function checkWin(player) { return winPatterns.some(pattern => pattern.every(index => boardState[index] === player) ); } // 重新開始遊戲 resetButton.addEventListener("click", startGame); function startGame() { boardState = ["", "", "", "", "", "", "", "", ""]; gameActive = true; cells.forEach(cell => { cell.textContent = ""; cell.classList.remove("x", "o"); }); // 隨機決定玩家與電腦的符號 if (Math.random() < 0.5) { playerSymbol = "X"; computerSymbol = "O"; } else { playerSymbol = "O"; computerSymbol = "X"; } currentPlayer = "X"; // 遊戲固定從 X 開始 isPlayerTurn = (currentPlayer === playerSymbol); statusText.textContent = `${isPlayerTurn ? "玩家" : "電腦"} (${currentPlayer}) 先手`; if (!isPlayerTurn) { setTimeout(computerMove, 500); } } // 初始化遊戲 startGame(); </script> </body> </html>
