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

如何用Vanilla JavaScript实现四子棋每列及全局落子点击次数限制

Connect 4 落子限制与棋盘数组写入方案

核心问题修正点

你当前代码出现无限堆叠、数组写入错误的核心原因有两个:

  • 落子位置硬编码为gameBoard[5][列索引],没有动态查找每列的可用空位,导致不管点多少次都只修改数组最后一行的固定位置,和实际渲染的堆叠棋子不匹配
  • 没有在落子前做全局、单列的落子数量校验,点击后会无限制创建DOM元素造成无限堆叠

实现规则

  • 全局总落子数达到42时,所有列点击直接终止逻辑,不响应落子
  • 单列落子数达到6时,当前列点击直接终止逻辑,不响应落子
  • 每次落子从列的最底部向上查找第一个空位,将对应玩家编号写入gameBoard数组对应位置

完整实现代码

// 初始化6行7列棋盘,行索引0为最顶部,行索引5为最底部
let gameBoard = Array(6).fill(null).map(() => Array(7).fill(null));
let currentPlayer = 1; // 1代表黑棋玩家,2代表红棋玩家
let discCount = 0;
const MAX_TOTAL_DISC = 42;
const MAX_COLUMN_DISC = 6;

/**
 * 列点击通用处理逻辑
 * @param {number} colIndex 点击的列索引 0-6
 */
function columnClickHandler(colIndex) {
  // 第一层校验:全局棋子已满,直接返回
  if (discCount >= MAX_TOTAL_DISC) return;

  // 从最底部向上查找当前列第一个空位
  let targetRow = -1;
  for (let row = 5; row >= 0; row--) {
    if (gameBoard[row][colIndex] === null) {
      targetRow = row;
      break;
    }
  }

  // 第二层校验:当前列棋子已满,直接返回
  if (targetRow === -1) return;

  // 将落子结果写入棋盘数组
  gameBoard[targetRow][colIndex] = currentPlayer;

  // 渲染对应颜色棋子
  const currentColumn = document.querySelector(`#column${colIndex}`);
  const disc = document.createElement("span");
  disc.className = currentPlayer === 1 ? "blackDisc" : "redDisc";
  currentColumn.append(disc);

  // 更新落子计数、切换玩家轮次
  discCount++;
  currentPlayer = currentPlayer === 1 ? 2 : 1;

  // 后续可在此处追加四子连珠的胜负判断逻辑
}

// 批量给7列绑定点击事件,替代重复的7份独立绑定代码
for (let i = 0; i < 7; i++) {
  const columnEl = document.querySelector(`#column${i}`);
  columnEl.addEventListener("click", () => columnClickHandler(i));
}

兼容原有代码的调整说明

如果你不想重构现有的7个独立列事件绑定,不需要修改现有DOM获取逻辑,只需要把columnClickHandler里的校验、空位查找、数组写入逻辑复制到每个列的事件函数中,将colIndex替换为对应列的索引值即可。例如column0的事件函数中固定传入0,column1传入1,以此类推。


内容的提问来源于stack exchange,提问作者PeteyP

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 06:15:36