You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 12:28:34