JS:给定二维数组中的一个点和一个距离,哪些坐标是可移动的?

发布于 2024-10-06 05:12:43 字数 820 浏览 1 评论 0原文

给定一个任意大小的二维数组,如下所示:

var board = [
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0]
];

...以及该数组中给定的 [y][x] 点,例如:

board[3][4]

...以及它可以移动的给定数量的空间(上/下/左/右) ,不是对角线),例如:

var distance = 3;

...函数如何循环遍历 2D 数组并创建仅包含可能经过的那些坐标的列表?

(这是数组中给定坐标 (*) 以及周围可行驶坐标的直观示例。)

0 0 0 0 0 0 0 0
0 0 0 3 0 0 0 0
0 0 3 2 3 0 0 0
0 3 2 1 2 3 0 0
3 2 1 * 1 2 3 0
0 3 2 1 2 3 0 0
0 0 3 2 3 0 0 0
0 0 0 3 0 0 0 0

参考:JS:如何通过算法突出显示x/y坐标的菱形选择? (我之前问过这个问题,但我不明白如何输入坐标并接收坐标列表)

Given a 2D array of any size like so:

var board = [
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0]
];

...and a given [y][x] point in that array, such as:

board[3][4]

...and a given number of spaces it can travel (up/down/left/right, not diagonally), like:

var distance = 3;

...how would a function loop through the 2D array and create a list of only those coordinates that may be traveled?

(Here's a visual example of the given coordinate (*) in the array, and the surrounding travelable coordinates.)

0 0 0 0 0 0 0 0
0 0 0 3 0 0 0 0
0 0 3 2 3 0 0 0
0 3 2 1 2 3 0 0
3 2 1 * 1 2 3 0
0 3 2 1 2 3 0 0
0 0 3 2 3 0 0 0
0 0 0 3 0 0 0 0

Reference: JS: how to algorithmically highlight a diamond-shaped selection of x/y coordinates?
(I asked this question before, but I can't understand how to input a coordinate and receive a list of coordinates)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

微暖i 2024-10-13 05:12:43

迭代所有坐标(如果面积很大,则迭代子集 xd,yd ... x+d,y+d)。

对于其中的每个字段,计算距离 - 在您的情况下为 dx - dy - 每当您找到距离 > 的点时0,用它做任何你想做的事。否则,忽略它。就是这样!

与洪水填充方法相比,您可以获得简单的代码,并且没有额外的查找表的开销。

Iterate over all coordinates (or a subset x-d,y-d ... x+d,y+d if the area is big).

For each field of those, calculate the distance - in your case as dx - dy - and whenever you find a point with the distance > 0, do anything you want with it. Otherwise, ignore it. That's it!

Compared to a flood-fill approach, you get simple code and no overhead of additinal lookup tables.

梓梦 2024-10-13 05:12:43

这是我能想到的最简单的解决方案,它涉及从上到下、从左到右的工作,仅迭代允许移动的坐标,所以它应该非常快:

function getPossibleMoves(x, y) {
    var r, c, cMax, 
        distance = 3,
        rows = board.length,
        cols = board[0].length, 
        rMax = Math.min(y + distance + 1, rows),
        ret  = [],
        yOff;

    // Start at the first row with a permissible move
    for (r = Math.max(y - distance, 0); r < rMax; r++) {
        yOff = Math.abs(r - y);

        // Work out where we should stop looping for this row
        cMax = Math.min(x + distance - yOff + 1, cols);

        // Start at the first column with a permissible move
        for (c = Math.max(x - distance + yOff, 0); c < cMax; c++) {
            // If it's not the current position, add it to the result
            if (x != c || y != r)
                ret.push([c, r]);
        }
    }
    return ret;
}

给你一个更好的主意,我整理了一个演示,允许您调整所有不同的变量,例如板尺寸、距离等。

工作演示:http://jsfiddle.net/AndyE/fWDHy/2/

This is the simplest solution I could think of, it involves working from top to bottom and left to right, iterating over only the co-ordinates that are permissible moves so it should be pretty fast:

function getPossibleMoves(x, y) {
    var r, c, cMax, 
        distance = 3,
        rows = board.length,
        cols = board[0].length, 
        rMax = Math.min(y + distance + 1, rows),
        ret  = [],
        yOff;

    // Start at the first row with a permissible move
    for (r = Math.max(y - distance, 0); r < rMax; r++) {
        yOff = Math.abs(r - y);

        // Work out where we should stop looping for this row
        cMax = Math.min(x + distance - yOff + 1, cols);

        // Start at the first column with a permissible move
        for (c = Math.max(x - distance + yOff, 0); c < cMax; c++) {
            // If it's not the current position, add it to the result
            if (x != c || y != r)
                ret.push([c, r]);
        }
    }
    return ret;
}

To give you a better idea, I threw together a demo that allows you to adjust all the different variables, e.g. board size, distance, etc.

Working demo: http://jsfiddle.net/AndyE/fWDHy/2/

心奴独伤 2024-10-13 05:12:43

使用递归以及访问过的链接的列表/散列。迈出一步,将你旅行的能力降低一级,并传递你所看到的清​​单。将您当前的位置添加到访问过的地点列表中。向每个方向走一步(使用递归),传递一个比给定的值少 1 的“左步”值。

这是一个几乎有效的答案;唯一的问题是,即使经过很长的路才到达某个单元,它也永远不会重新访问该单元。您可以通过 广度优先搜索 或检测访问的单元格是否是通过比您将要采取的步骤更多的步骤来达到目标​​。

Use recursion along with a list/hash of visited links. Take a step, reduce your ability to travel by one and pass along the list of what you've seen. Add your current location to the list of visited spots. Go in each direction one step (using recursion), passing along a 'steps left' value that is one less than you were given.

Here's an answer that almost works; the only problem is that it never re-visits a cell even if the long way was used to get there. You could overcome this either via a breadth-first search or by detecting if the visited cell was reached via more steps than you are about to take to get there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文