JavaScript井字棋开发:满足获胜条件时阻止电脑回合函数调用
井字棋获胜后阻止电脑落子修复方案
问题核心原因
- 原有胜负判断逻辑存在漏洞:在遍历获胜组合的
forEach循环中动态修改nextTurn标记,只要某一个获胜组合不满足获胜条件,就会把nextTurn设为true,哪怕已经检测到用户获胜,后续遍历其他组合时仍会覆盖标记,导致错误触发电脑回合。 - 缺少全局游戏状态锁,游戏分出胜负后没有阻断后续逻辑执行,不仅可能误触发电脑落子,用户还能继续点击棋盘操作。
- 平局判断逻辑放在循环内重复执行,容易出现状态冲突。
修复步骤
- 新增全局游戏状态标记,用于锁定结束后的游戏
// 放在所有函数外层的全局作用域 let gameOver = false;
- 修正用户落子函数,增加状态拦截,游戏结束/格子已占时不允许落子
function leaveMark(){ // 游戏结束直接拦截操作 if(gameOver) return; let toes = document.querySelectorAll('img'); let toesId = this.getAttribute('data-id'); // 已被占用的格子不允许重复落子 if(takenId.includes(toesId)) return; chosenToeId.push(toesId); takenId.push(toesId); userChoices.push(toesId); let chosenToe = chosenToeId[0]; toes[chosenToe].setAttribute('src','img/tic-tac-toe/hammer.png'); chosenToeId = []; userValidation(); }
- 重写用户胜负校验逻辑,优先判断获胜、平局状态,满足结束条件时直接阻断电脑回合触发
function userValidation() { let numberUser = userChoices.map(i=>Number(i)); let isUserWin = false; // 遍历所有获胜组合,检测用户是否获胜 for (const combo of winningCombos) { const [a,b,c] = combo; if (numberUser.includes(a) && numberUser.includes(b) && numberUser.includes(c)) { isUserWin = true; break; } } if (isUserWin) { console.log('user wins'); gameOver = true; return; } // 检测是否平局 if (takenId.length === imgId.length) { console.log('This is a tie. Not bad, try again.'); gameOver = true; return; } // 未获胜也未平局,才触发电脑回合 setTimeout(computerTurn, 1000); }
- 修正电脑回合与电脑胜负校验逻辑,增加状态拦截
function computerTurn(){ // 游戏结束时不执行落子 if(gameOver) return; let randomId = Math.floor((Math.random()*imgId.length)); let randomIdString = randomId.toString(); let toes = document.querySelectorAll('img'); if (!takenId.includes(randomIdString)){ toes[randomId].setAttribute('src','img/tic-tac-toe/boots.png'); takenId.push(randomIdString); computerChoices.push(randomId); computerValidation(); } else{ // 抽到已占格子就重新随机 computerTurn(); } } function computerValidation() { let numberComputer = computerChoices.map(i=>Number(i)); let isComputerWin = false; for (const combo of winningCombos) { const [a,b,c] = combo; if (numberComputer.includes(a) && numberComputer.includes(b) && numberComputer.includes(c)) { isComputerWin = true; break; } } if (isComputerWin) { console.log('Sorry, you lost. Try again!'); gameOver = true; return; } if (takenId.length === imgId.length){ console.log('This is a tie. Not bad, try again.'); gameOver = true; return; } messages.textContent = 'Your turn, user.' }
补充说明
新增重开游戏功能时,需要同步重置状态:
- 将
gameOver设回false - 清空
takenId、userChoices、computerChoices数组 - 恢复所有棋盘格子的初始图片
内容的提问来源于stack exchange,提问作者Yoyes
相关产品推荐
相关产品推荐

