如何用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
相关产品推荐
相关产品推荐

