【问题标题】:Is there an algorithm to find all possible routes in a board game?有没有一种算法可以在棋盘游戏中找到所有可能的路线?
【发布时间】:2021-05-13 16:02:33
【问题描述】:

我正在尝试编写一个 javascript 函数,该函数在玩家无法沿对角线移动的棋盘(15x15 网格)上找到长度为 N 的所有可能路线。我能够想出一个非常简单的递归解决方案,但我怀疑它非常未优化。

代码如下:

search(n, u, v) {

    if (n == 0 || isWall(u, v))
        return;
        
    board[v][u] = 2;
    
    search(n - 1, u, v - 1);
    search(n - 1, u + 1, v);
    search(n - 1, u, v + 1);
    search(n - 1, u - 1, v);
    
    return;
}

board 是一个包含棋盘数据的二维数组。空闲空间、墙和可达空间分别用 0、1 和 2 表示。

Here's an example of what is looks like given N=6

编辑:如下所述,我试图在 N 或更少的移动中找到所有可到达的单元格。

【问题讨论】:

  • 从技术上讲,您在这里写的内容不是找到“所有可能的长度为 N 的路线”,而是“在 N 或更少的移动中所有可到达的单元格" 这要容易得多。你真正想要哪个?
  • 是的,可以找到所有路线,但通常迭代太多。可以计算路线或显示在 n 次移动中可以到达的位置。
  • 对于每个可到达的单元格,您可以使用 A* 搜索算法找到到该单元格的 最短 路线。这将为您提供通往每个单元格的路线,但不会是所有路线。够了吗?

标签: javascript algorithm path-finding


【解决方案1】:

就像其他人写的那样,您应该使用广度优先遍历而不是深度优先遍历。

其次,您不应该重新访问已标记为值 2 的单元格,因此您继续的条件应该是当前单元格的值为 0。

我建议使用两个数组来实现遍历:

function search(board, n, u, v) {
    let count = 0;
    let frontier = [[u, v]];
    
    while (n-- > 0 && frontier.length) {
        let newFrontier = [];
        for (let [u, v] of frontier) {
            if (board[v]?.[u] === 0) {
                board[v][u] = 2;
                count++;
                newFrontier.push([u, v - 1], [u + 1, v], [u, v + 1], [u - 1, v]);
            }
        }
        frontier = newFrontier;
    }
    
    return count;
}

let board = [
    "11111111111111",
    "10000000000001",
    "10000000000001",
    "10011100111001",
    "10010000001001",
    "10010000001001",
    "10000000000001",
    "10000000000001",
    "10000000000001",
    "10010000001001",
    "10010000001001",
    "10011100111001",
    "10000000000001",
    "10000000000001",
    "11111111111111"
].map(row => Array.from(row, Number));

let res = search(board, 6, 2, 2);

console.log("number of cells reached: ", res);

console.log(board.map(row => row.join(" ")).join("\n"));

【讨论】:

    【解决方案2】:

    您应该使用广度优先搜索来解决您的问题。您可以阅读有关 BFS here 的信息。以下是我在 Java 中未运行的代码。我建议不要使用它,因为我在 StackOverflow 编辑器中对其进行了编码,但基本思想就在那里。

    public class BFS {
        static final int MAX_N = 100;
        public static void main(String[] args) {
             int[][] board = new int[MAX_N][MAX_N];
             Queue<Point> q = new LinkedList<>();
             List<int[]> reachable = new ArrayList<>();
             boolean[][] vist = new boolean[MAX_N][MAX_N];
             q.add(new Point(0,0,0));
             vist[0][0] = true;
             while(!q.isEmpty()) {
                 Point curr = q.poll();
    
                 if(vist[curr.x][curr.y]) continue;
                 if(curr.move > N) continue;
     
                 reachable.add(new int[]{curr.x, curr.y});
    
                 // dx and dy array not shown
                 for(int i = 0; i < 4; i++) {
                     int nx = curr.x + dx[i];
                     int ny = curr.y + dy[i];
    
                     if(nx < 0 || nx >= MAX_N || ny < 0 || ny >= MAX_N) continue;
                     if(board[nx][ny] == 1) continue;
    
                     vist[nx][ny] = true;
                     q.add(new Point(nx, ny, curr.move+1));
                     
                 }
             }
    
             // You now have your reachable points.
        }
    }
    
    class Point {
        public int x, y, move;
        public Point(int x, int y, int move) {
            this.x = x;
            this.y = y;
            this.move = move;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-12-29
      • 2012-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-07
      • 1970-01-01
      • 2011-02-18
      相关资源
      最近更新 更多