基于JS+HTML的人机对战井字棋开发问题求助
井字棋人机对战模式实现方案
核心变量定义
在全局作用域定义游戏状态相关变量,确保逻辑统一:
// 棋盘状态数组,存储每个格子的内容(X/O/null) let board = Array(9).fill(null); // 当前玩家,随机决定先手(X=玩家,O=电脑) let currentPlayer = Math.random() > 0.5 ? 'X' : 'O'; // 游戏是否处于活跃状态 let isGameActive = true;
玩家点击事件处理
每个棋盘格子通过onClick()绑定点击事件,传入对应格子的索引(0-8):
<div class="board"> <div class="cell" onClick="handleCellClick(0)"></div> <div class="cell" onClick="handleCellClick(1)"></div> <div class="cell" onClick="handleCellClick(2)"></div> <div class="cell" onClick="handleCellClick(3)"></div> <div class="cell" onClick="handleCellClick(4)"></div> <div class="cell" onClick="handleCellClick(5)"></div> <div class="cell" onClick="handleCellClick(6)"></div> <div class="cell" onClick="handleCellClick(7)"></div> <div class="cell" onClick="handleCellClick(8)"></div> </div>
编写点击事件处理函数,完成玩家落子、状态更新、胜负判断,并触发电脑回合:
function handleCellClick(index) { // 过滤无效操作:格子已被占用或游戏已结束 if (board[index] !== null || !isGameActive) return; // 更新棋盘数组与DOM显示 board[index] = 'X'; document.querySelectorAll('.cell')[index].textContent = 'X'; // 检查玩家是否获胜 if (checkWin('X')) { alert('玩家获胜!'); isGameActive = false; return; } // 检查是否平局 if (board.every(cell => cell !== null)) { alert('平局!'); isGameActive = false; return; } // 切换至电脑回合,延迟执行让玩家有视觉反馈 currentPlayer = 'O'; setTimeout(computerMove, 500); }
电脑随机落子逻辑
实现电脑自动选空位落子的函数,完成状态更新、胜负判断后切回玩家回合:
function computerMove() { if (!isGameActive) return; // 筛选所有空位的索引 const emptyCells = board .map((cell, idx) => cell === null ? idx : null) .filter(idx => idx !== null); // 随机选择一个空位 const randomIndex = emptyCells[Math.floor(Math.random() * emptyCells.length)]; // 更新棋盘数组与DOM显示 board[randomIndex] = 'O'; document.querySelectorAll('.cell')[randomIndex].textContent = 'O'; // 检查电脑是否获胜 if (checkWin('O')) { alert('电脑获胜!'); isGameActive = false; return; } // 检查是否平局 if (board.every(cell => cell !== null)) { alert('平局!'); isGameActive = false; return; } // 切换回玩家回合 currentPlayer = 'X'; }
胜负判断函数
复用(或补充)胜负逻辑,检查当前玩家是否达成获胜组合:
function checkWin(player) { // 所有可能的获胜组合 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] // 斜向 ]; // 判断是否有任意一组获胜组合被当前玩家填满 return winPatterns.some(pattern => { return pattern.every(index => board[index] === player); }); }
先手为电脑的初始化处理
页面加载时判断如果先手是电脑,自动触发电脑落子:
window.onload = function() { if (currentPlayer === 'O') { setTimeout(computerMove, 500); } };
关键注意点
- 每次落子必须同步更新
board数组和DOM,确保两者状态一致 - 所有操作前都要检查
isGameActive,避免游戏结束后继续操作 - 电脑落子使用
setTimeout延迟执行,提升交互体验
内容的提问来源于stack exchange,提问作者Labbayk
相关产品推荐
相关产品推荐

