在js中使用多维数组查找路径

时间:2014-01-27 17:22:57

标签: javascript math multidimensional-array logic coordinates

我有一个存储在多维数组中的x-y网格。 x-y网格中的每个点都有一个值。

示例:

var xy = [
    [0,3,1,1,0],
    [0,0,2,2,1],
    [0,0,1,1,0]
];

假设var xy的布局类似于x-y网格(例如x 1和y 2将为3。

这是一个更大的“打印输出”这样的变量,具有更大的高度和宽度:

   (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13)
(1) 0   0   0   1   1   1   2   2   1    1    0    0    0
(2) 0   0   1   1   1   2   2   3   2    2    1    0    0
(3) 0   0   0   1   2   2   3   3   2    1    0    0    0
(4) 0   4   0   1   1   1   2   2   1    0    0    0    8
(5) 0   0   0   0   0   0   1   1   0    0    0    0    4
(6) 0   0   0   0   9   9   9   0   0    0    0    0    0 
(7) 0   0   0   0   9   9   0   0   0    0    0    0    0

现在,为了举例,假设上面的布局是一张地图,就像棋盘一样。对于初学者来说,不要注意网格上每个点的值,假设我们想要知道“游戏块”可以从哪个方块中获取,例如,x4 y8 ....我们可以在js中做这样的事情:

 var n = ,//total # of items in grid
    a = ,//a certain point on the grid
    r = 5; //range of movement
 for(var i = 0; i < n; i++){ //this would be a double for or something similar to go through the grid properly, but let's pretend i is a given point on the grid.
    Math.abs(((a.xLocation + a.yLocation) - (i.xLocation + i.yLocation)) <= r) //if the positive difference between the current point in the loop and the location of the certain point is less than or equal to the range....true!
 }

所以在上面的粗略例子中,A点的东西可以移动5个步骤,对角线,垂直,水平,等等。我们不知道方向,只知道运动的可能性。

这很容易理解。我仍然试图解决这个问题的部分是:你怎么知道a点的东西是否可以根据网格的值来达到点i。 0意味着没有增强,但是1或2需要1或2或任何额外的运动才能到达.....你如何在地图上找出每个点?同样,不知道哪个方向或路径 - 是否最佳。

澄清:想象一下棋盘。每个方形棋盘都有一个值,表示到达目的地所需的EXTRA移动点数。一个给定的棋子,根本不使用国际象棋规则,可以说,任何方向都可以移动5个'移动点'。许多正方形的值为0,因此不需要进一步花费运动点。但是1的平方将需要2个总运动点,2个需要总共3个,等等。真的,你可以轻松地在下面的所有正方形中加1,以找出相邻正方形中的一块是否可以移动到那里。但是你喜欢。我只是在寻找可以得出答案的某种论点或建议。在这里,看看这个更简单的例子。

    (1) (2) (3)
(1)  0   1   3
(2)  1   X   2
(3)  2   0   1

把它想象成一个游戏,每个方块代表某种地形劣势。有些路径比其他路径容易,但其他路径更直接。您可以采取任何路径到达某个方格,但在移动之前,哪个方块是合法的,哪些不是?所以我们的作品是X2 Y2,对吗?他有5个运动点。他想知道他可以搬到哪些人。好吧,他可以转移到他们中的任何一个。但是X1Y1将花费1个运动点,X1Y2将花费2个,X1Y3将花费4个等等。易于弄清楚。但是如果棋盘比较大,并且每个潜在的(未知)运动都需要点数,那么他可以移动到哪个方格,哪个不可以?这有意义吗?

编辑2:稍微复杂的例子:

    (1) (2) (3) (4) (5)
(1)  0   1   3   0   0
(2)  1   X   2   1   0
(3)  2   0   1   0   0
(4)  1   0   0   1   3
(5)  0   0   0   0   4

所以我们在这个例子中的作品再次出现在X2Y2中,但他想知道,对于每个方格,他是否可以在那里 - 布尔,是或否。只有九个方块很容易,但随着网格的增长,复杂性也随之增加。我当然可以手动完成 - 他可以达到X4Y4吗?是。但是以编程方式,我该如何获得这个?

编辑3:网格的大小毫无意义,我才刚刚意识到。这真的是范围的大小。例如,如果移动范围是5,我只需要计算每个方向上五个方格的正方形的可行性。所以这简化了一点。

EDIT4:我想我的想法有点好。看看最外面的戒指5。它大于0吗?那就不要。下一个最外圈(4出)。大于1?没有。下一个最外圈。大于2?那就不要。是否会起作用或导致不正确的结果?

在js或jQuery首选的答案(或者甚至只是正确的方向),但即使你可以通过逻辑工作,我也可以将其翻译成js或jquery。

1 个答案:

答案 0 :(得分:1)

我认为你想要做的是一种基本的搜索,在每次迭代中你都会检查周围的方块。我想出了一个模型示例with this jsfiddle。打开控制台,单击“运行”,它应打印出示例地图及其可以从(2,2)开始的3个步骤中获取的位置。

其中有一些额外的代码用于设置,但主要代码是search_rec函数:

function search_rec(
      map, // The input 'difficulty' map
      output, // The output map (puts '1's in spots that can be reached)
              // Should be the same size as the input map
      x, y, // The current/starting position
      limit) { // The number of spaces you are allowed to move

    // If the number of spaces allowed to move is negative, then we can't
    // reach this position, so we stop
    if (limit < 0) {
        return;
    }

    // Otherwise, if the limit is >= 0, then we can make it here and we
    // store that in the output
    output[y][x] = 1;

    // Now, for each of the four directions
    // Check if we're at a map boundary
    if (x > 0) {
        // If we're not, then we recurse, moving our starting point in
        // the given direction, and lowering our limit by 1 (for the
        // base movement) as well as the 'difficulty' of the terrain of
        // the space we're moving into

        search_rec(map, output, x - 1, y,
        //                      ^ change position
                      limit           - 1          - map[y][x - 1]);
        //   lower limit ^ by the base ^ and the difficulty ^
    }
    if (x < map[0].length - 1) {
        search_rec(map, output, x + 1, y, limit - map[y][x + 1] - 1);
    }
    if (y > 0) {
        search_rec(map, output, x, y - 1, limit - map[y - 1][x] - 1);
    }
    if (y < map.length - 1) {
        search_rec(map, output, x, y + 1, limit - map[y + 1][x] - 1);
    }
}

希望这种逻辑是有道理的,它实际上解决了你想解决的问题。