求助:井字棋(Tic Tac Toe)获胜逻辑与棋盘数组更新实现
井字棋项目:棋盘状态存储与获胜判断解决方案
一、修复棋盘状态数组更新问题
直接用长度为9的空数组存储每个格子状态(索引0-8对应9个棋盘格子),给每个格子绑定索引属性,点击时通过索引更新数组:
- 初始化状态数组:
let myGameBoard = Array(9).fill("");
- 修改格子创建逻辑,添加索引绑定:
const gameBoardElements = function (index) { const getBoard = document.getElementById("board"); const createBoard = document.createElement("div"); getBoard.appendChild(createBoard); createBoard.className = "game-board"; createBoard.dataset.index = index; // 给格子绑定对应索引 }; const createGameBoard = function () { for (let i = 0; i < 9; i++) { gameBoardElements(i); // 传入索引 } };
- 在落子函数中更新数组:
function selectBoard(e) { const index = parseInt(e.target.dataset.index); const currentSymbol = turn % 2 === 0 ? Player1.symbol : Player2.symbol; // 更新DOM显示 e.target.appendChild(createPElement(currentSymbol)); turn++; e.target.className = "complete-board"; e.target.removeEventListener("click", selectBoard); // 更新状态数组 myGameBoard[index] = currentSymbol; // 落子后立即检查胜负 checkWin(currentSymbol); }
二、实现获胜判断逻辑
定义所有可能的获胜组合,每次落子后遍历组合检查是否满足获胜条件:
- 定义获胜组合数组:
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 checkWin(symbol) { // 检查是否有获胜组合 const isWinner = winCombos.some(combo => { return combo.every(index => myGameBoard[index] === symbol); }); if (isWinner) { const winner = symbol === Player1.symbol ? Player1.name : Player2.name; currentTurn.textContent = `${winner} 获胜!`; // 禁用所有格子点击 board.forEach(el => el.removeEventListener("click", selectBoard)); return; } // 检查平局(数组填满且无获胜) if (!myGameBoard.includes("")) { currentTurn.textContent = "平局!"; } }
- 添加重置函数,重置游戏状态:
function reset() { // 重置状态数组与回合数 myGameBoard = Array(9).fill(""); turn = 0; // 重置棋盘DOM const boardContainer = document.getElementById("board"); boardContainer.innerHTML = ""; createGameBoard(); // 重新绑定点击事件 const newBoard = document.querySelectorAll(".game-board"); newBoard.forEach(el => el.addEventListener("click", selectBoard)); newBoard.forEach(el => el.addEventListener("click", updateBoard)); // 重置回合提示 currentTurn.textContent = `${Player1.name} turn`; }
三、完整修改后的代码
JavaScript
const currentTurn = document.getElementById("current-turn"); const getGameBoard = document.getElementById("board"); const btn = document.getElementById("btn"); let turn = 0; let myGameBoard = Array(9).fill(""); // 所有获胜组合 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] ]; // 玩家构造函数 const player = (name, symbol) => { return { name, symbol }; }; const Player1 = player("Player X", "X"); const Player2 = player("Player O", "O"); // 创建单个棋盘格子,绑定索引 const gameBoardElements = function (index) { const getBoard = document.getElementById("board"); const createBoard = document.createElement("div"); getBoard.appendChild(createBoard); createBoard.className = "game-board"; createBoard.dataset.index = index; }; // 创建9个棋盘格子 const createGameBoard = function () { for (let i = 0; i < 9; i++) { gameBoardElements(i); } }; createGameBoard(); // 创建X/O文本元素 function createPElement(symbol) { let p = document.createElement("p"); p.textContent = symbol; p.className = "text"; return p; } // 绑定点击事件 const board = document.querySelectorAll(".game-board"); board.forEach((el) => el.addEventListener("click", selectBoard)); board.forEach((el) => el.addEventListener("click", updateBoard)); // 落子逻辑 function selectBoard(e) { const index = parseInt(e.target.dataset.index); const currentSymbol = turn % 2 === 0 ? Player1.symbol : Player2.symbol; e.target.appendChild(createPElement(currentSymbol)); turn++; e.target.className = "complete-board"; e.target.removeEventListener("click", selectBoard); // 更新状态数组 myGameBoard[index] = currentSymbol; // 检查胜负 checkWin(currentSymbol); } // 更新回合提示 function updateBoard() { if (currentTurn.textContent.includes("获胜") || currentTurn.textContent.includes("平局")) return; currentTurn.textContent = `${ turn % 2 === 0 ? `${Player1.name} turn` : `${Player2.name} turn` }`; } // 胜负检查函数 function checkWin(symbol) { const isWinner = winCombos.some(combo => { return combo.every(index => myGameBoard[index] === symbol); }); if (isWinner) { const winner = symbol === Player1.symbol ? Player1.name : Player2.name; currentTurn.textContent = `${winner} 获胜!`; board.forEach(el => el.removeEventListener("click", selectBoard)); return; } if (!myGameBoard.includes("")) { currentTurn.textContent = "平局!"; } } // 重置函数 function reset() { myGameBoard = Array(9).fill(""); turn = 0; const boardContainer = document.getElementById("board"); boardContainer.innerHTML = ""; createGameBoard(); const newBoard = document.querySelectorAll(".game-board"); newBoard.forEach(el => el.addEventListener("click", selectBoard)); newBoard.forEach(el => el.addEventListener("click", updateBoard)); currentTurn.textContent = `${Player1.name} turn`; } // 重置按钮交互 btn.addEventListener("mouseover", function () { this.querySelector(".skew-fix").textContent = "Reset >>"; }); btn.addEventListener("mouseout", function () { this.querySelector(".skew-fix").textContent = "Reset >"; });
CSS
body { background-color: #fffdfa; } .title { font-size: 42px; font-family: "Dancing Script", cursive; } .current-turn { font-size: 24px; } .content { background-color: #fffdfa; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 700px; width: 800px; margin: 0 auto; border-radius: 8px; } .board { display: flex; flex-flow: row wrap; align-content: center; justify-content: space-evenly; gap: 10px; background-color: #fff; height: 500px; width: 600px; } .board div, .complete-board { display: flex; justify-content: center; align-items: center; border: 2px solid #000; background-color: #3c4048; width: 175px; height: 150px; } .board div:hover { background-color: #f4e06d; transform: scale(1.1); transition: 0.8s; box-shadow: 5px 5px 0 rgba(0, 0, 0, 0.5); } .complete-board { background-color: #f4e06d !important; } .text { font-size: 64px; } .btn { display: inline-block; background-color: #4649ff; padding: 0.5em 2em; margin-top: 20px; cursor: pointer; font-family: "Poor Story", cursive; font-size: 2rem; letter-spacing: 0.4rem; transition: all 0.3s; text-decoration: none; } .btn:hover { box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.5); } .parallelogram { transform: skew(-20deg); } .skew-fix { display: inline-block; transform: skew(20deg); }
HTML
<div class="content"> <p class="title">Tic Tac Toe</p> <p class="current-turn" id="current-turn">Player X Turn</p> <div id="board" class="board"></div> <a id="btn" class="btn parallelogram" onclick="reset()"> <span class="skew-fix">Reset ></span> </a> </div>
内容的提问来源于stack exchange,提问作者Dagger
相关产品推荐
相关产品推荐

