
本文详解如何在 8×8 跳棋板上,通过递归遍历左下/右下对角线方向,动态检测某枚棋子(如顶部金棋)是否可执行单步或多步连续捕获,并返回所有合法落点坐标。
本文详解如何在 8×8 跳棋板上,通过递归遍历左下/右下对角线方向,动态检测某枚棋子(如顶部金棋)是否可执行单步或多步连续捕获,并返回所有合法落点坐标。
在跳棋逻辑中,捕获(jump/capture)不是简单的邻格判断,而是一个链式路径探测问题:一枚棋子需满足“己方→敌方→空位”的三格模式才能完成一次跳跃;若落点之后仍存在相同模式,则可继续捕获——即所谓“强制连跳”(mandatory multiple capture)。JavaScript 中实现该逻辑的关键在于:将二维棋盘建模为数值数组、沿固定对角线偏移方向递归探测、并回溯收集所有终局空位坐标。
✅ 核心数据结构与约定
首先,统一棋盘表示法(与示例代码一致):
-
0表示空位 -
1表示己方棋子(如顶部金棋) -
-1表示敌方棋子(如底部红棋) - 坐标系:
board[y][x],原点(0,0)在左上角,y 向下递增(符合 HTML 表格行索引习惯)
const board = [ [ 0, 1, 0, 1, 0, 1, 0, 1], [ 1, 0, 1, 0, 1, 0, 1, 0], [ 0, 1, 0, 1, 0, 1, 0, 1], [-1, 0, -1, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0], [-1, 0, -1, 0, -1, 0, -1, 0], [ 0, 0, 0, -1, 0, 0, 0, -1], [-1, 0, -1, 0, -1, 0, -1, 0], ];
? 递归捕获检测函数(支持多重连跳)
getCaptures(board, y, x) 是核心算法:它检查从 (y,x) 出发,沿两个合法捕获方向(左下 ↓← 和右下 ↓→)能否形成“跳-吃-落”链条,并自动展开后续连跳可能:
function getCaptures(board, y, x) {
const captures = [];
// 仅考虑向下对角线:左下 (dy=1, dx=-1) 和右下 (dy=1, dx=1)
const directions = [[1, -1], [1, 1]];
for (const [dy, dx] of directions) {
const midY = y + dy;
const midX = x + dx;
const endY = y + 2 * dy;
const endX = x + 2 * dx;
// 检查中间格是否为敌方,终点格是否为空
if (
getCell(board, midY, midX) === -1 &&
getCell(board, endY, endX) === 0
) {
// 成功找到一次捕获 → 终点是合法落点
const nextCaptures = getCaptures(board, endY, endX);
if (nextCaptures.length === 0) {
// 无后续连跳:直接记录当前终点
captures.push([endY, endX]);
} else {
// 有后续连跳:合并所有终局坐标(非中间过程)
captures.push(...nextCaptures);
}
}
}
return captures;
}
// 安全获取格子值(越界返回 null)
function getCell(board, y, x) {
if (y < 0 || x < 0 || y >= board.length || x >= board[0].length) {
return null;
}
return board[y][x];
}? 关键设计点:
deep-java-review下载Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
立即学习“Java免费学习笔记(深入)”;
- 递归不返回路径,只返回所有可达的最终空位坐标(即用户点击后棋子应移动到的位置);
- 每次递归调用都以新落点为起点重新探测,自然覆盖任意长度连跳;
- 若某次跳跃后无进一步捕获,则该落点被加入结果 —— 这保证了“必须走最长捕获链”的规则(常见于国际跳棋变体)。
? 集成到你的棋盘交互中
在你已有的 canJumpOverOpponent() 函数中,可直接调用上述逻辑:
function canJumpOverOpponent(table, row, col) {
// 将 DOM 表格状态同步为 board 数组(需你实现)
const board = getBoardFromDOM(); // 示例伪函数,请按实际结构填充
// 仅当是己方棋子(如金棋)时检测
if (board[row][col] !== 1) return [];
const validMoves = getCaptures(board, row, col);
console.log(`Piece at [${row},${col}] can capture to:`, validMoves);
return validMoves; // 返回所有合法终局坐标,用于高亮或限制点击
}⚠️ 注意事项:
- 当前逻辑假设仅向前捕获(金棋只能向下跳),若需支持王棋(king)双向移动,需扩展
directions数组为[[±1, ±1]]四方向; - 实际项目中务必添加防无限递归保护(如深度限制
maxDepth=5); - DOM 同步需谨慎:避免每次点击都遍历整个表格,建议维护一个实时
boardState数组并在click事件中更新; - 用户体验上,检测到多重捕获后,应禁用其他操作,仅允许点击返回的
validMoves中的格子。
✅ 总结
通过将捕获建模为“位置+方向+递归验证”的纯函数式逻辑,你无需手动管理循环状态或临时路径栈。getCaptures() 以简洁递归封装了跳棋最复杂的连跳判定,既可独立测试(如 getCaptures(board, 2, 1)),也能无缝嵌入事件驱动流程。下一步可结合 CSS 动画实现跳跃视觉反馈,或扩展为带路径回溯的完整走法生成器。


















