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

骑士游历问题:如何在BFS实现中回溯返回最短路径数组

Knight Travails作业问题

作业背景与要求

我正在学习The Odin Project课程,遇到了Knight Travails作业,它类似LeetCode的“Minimum Knight Moves”但要求更多。作业要求:

  • 编写脚本创建棋盘和骑士;
  • 将骑士的所有合法移动视为树的子节点,不允许移出棋盘;
  • 选择合适的搜索算法(提示:某算法可能产生无限序列);
  • 用所选算法找到起点到终点的最短路径并输出完整路径,示例如下:
> knightMoves([3,3],[4,3])
=> You made it in 3 moves!  Here's your path:
  [3,3]
  [4,5]
  [2,4]
  [4,3]

当前实现代码

以下是我当前的解决方案,虽未完全符合要求但已接近:

'use strict'
class Traversal {
  constructor (x, y) {
    this.x = x
    this.y = y
    this.xDir = [-1, 1, -1, 1, -2, -2, 2, 2] // LEFT-RIGHT
    this.yDir = [2, 2, -2, -2, 1, -1, 1, -1] // UP-DOWN
  }

  calculateMoves (targetX = 0, targetY = 0) {
    const viableMoves = [] // coords of the locations the knight can reach from his current position
    let queue = [[this.x, this.y]]
    const visited = new Set()
    let steps = 0 // holds the minimal amount of moves to reach the target
    for (let i = 0; i < this.xDir.length && i < this.yDir.length; i++) {
      viableMoves.push([(this.x + this.xDir[i]), (this.y + this.yDir[i])]) // this will correctly calculate viable moves I think? sure seems to work in the console
    }
    queue = [...viableMoves] // populate the queue with moves the knight can make at this moment

    while (queue.length) {
      const next = []
      while (queue.length) {
        const current = queue.shift()
        const currentX = current[0] // extract current position from the queue
        const currentY = current[1] // extract current position from the queue
        if (currentX === targetX && currentY === targetY) { // we've found our goal if this is truthy
          return steps
        }
        for (const d of viableMoves) { 
          const nextX = currentX + d[0]
          const nextY = currentY + d[1]

          if (!visited.has(`${nextX},${nextY}`)) { // this entire part might have to be rewritten, I barely understand wtf this is
            visited.add(`${nextX},${nextY}`)
            next.push([nextX, nextY])
          }
        }
      }
      steps++
      queue = next
    }
  }
}

待解决问题

该代码可正常运行:实例化Traversal对象后调用calculateMoves方法传入目标位置,会返回到达目标所需的最少步数。但我仍需实现检测到目标的实际路径并将其以数组形式返回的功能,对此我有些困惑,仅能想到用另一个数组存储接近目标的坐标,但不确定具体该存储什么。另外,当前实现假设棋盘是无限的,坐标可为负值,不确定这是否会对可行解决方案产生重大影响,必要时我可以重写整个代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 08:17:33