连接迷宫/网格的墙壁,使所有都相互连接

时间:2013-02-26 18:01:39

标签: java algorithm game-physics

我有一个2d网格,我正试图在所有墙之间建立链接。

网格的构造如下:

    grid = new State[8][8];
    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++) {
            grid[i][j] = State.blank;
        }
    }

我有一个机器人应该能够穿过墙壁到达对面,就像在蛇的游戏中一样。

因此,例如,如果机器人面向NORTH并且位于x [0] y [1]位置,那么它应该连接到x [7] y [1]。

机器人还应该能够读到前面三个街区中的一个,一个在左边,一个在右边,一个在正面前面。

# x = empty space
# R = robot
# S = spaces robots sensors pick up

如果它朝北,这就是机器人会选择的东西:

[S][S][S][x][x][x][x][x]
[x][R][x][x][x][x][x][x]
[x][x][x][x][x][x][x][x]
[x][x][x][x][x][x][x][x]
[x][x][x][x][x][x][x][x]
[x][x][x][x][x][x][x][x]
[x][x][x][x][x][x][x][x]
[x][x][x][x][x][x][x][x]

如果机器人面向东方,那么它就是这样的:

[x][x][S][x][x][x][x][x]
[x][R][S][x][x][x][x][x]
[x][x][S][x][x][x][x][x]
[x][x][x][x][x][x][x][x]
[x][x][x][x][x][x][x][x]
[x][x][x][x][x][x][x][x]
[x][x][x][x][x][x][x][x]
[x][x][x][x][x][x][x][x]

我遇到的问题是找到正确的算法,以确保机器人不仅可以通过墙壁,还可以通过墙壁读取传感器。

如果机器人位于左上角并朝向北方,那么它会像这样读取墙壁:

[R][x][x][x][x][x][x][x]
[x][x][x][x][x][x][x][x]
[x][x][x][x][x][x][x][x]
[x][x][x][x][x][x][x][x]
[x][x][x][x][x][x][x][x]
[x][x][x][x][x][x][x][x]
[x][x][x][x][x][x][x][x]
[S][S][x][x][x][x][x][S]

正如你可以想象的那样,我已经尝试过做一长串的IF语句,但是有太多的可能性来掩盖它们而不会疯狂!

我还写下了对X&amp; amp;在某些情况下放置在纸上,但我无法看到任何暗示算法的模式。

任何帮助将不胜感激!

4 个答案:

答案 0 :(得分:1)

使用像x = (x + 1) % array.length

这样的迭代器

(或x = (x - 1) % array.length

答案 1 :(得分:1)

我会尝试将其分解成不同的部分,希望这会对你有所帮助。 所以,你有一个8x8网格,由X和Y坐标表示,其中(0,0)是左上角,(7,7)是右下角。 您的算法将如下所示:

walking through walls:
N -> x = x, y = (y==0)?7:y-1
S -> x = x, y = (y==7)?0:y+1
E -> x = (x==7)?0:x+1, y = y
W -> x = (x==0)?7:x-1, y = y

Look ahead
N -> LH1 = x=x, y=y-1
     LH2 = x=x-1, y=y-1
     LH3 = x=x+1, y=y-1
S -> LH1 = x=x, y=y+1
     LH2 = x=x-1, y=y+1
     LH3 = x=x+1, y=y+1
E -> LH1 = x=x+1, y=y
     LH2 = x=x+1, y=y-1
     LH3 = x=x+1, y=y+1
W -> LH1 = x=x-1, y=y
     LH2 = x=x-1, y=y-1
     LH3 = x=x-1, y=y+1

现在,如果我将此算法转换为java方法,它们将如下所示:

public int getNextX (int currentX, String direction)
{
    if ("N".equals (direction) || "S".equals (direction))
    {
        return currentX;
    }
    else if ("E".equals (direction))
    {
        return ((currentX==7) ? 0 : currentX + 1);
    }
    else if ("W".equals (direction))
    {
        return ((currentX==0) ? 7 : currentX - 1);
    }
}

public int getNextY (int currentY, String direction)
{
    if ("E".equals (direction) || "W".equals (direction))
    {
        return currentY;
    }
    else if ("S".equals (direction))
    {
        return ((currentY==7) ? 0 : currentY + 1);
    }
    else if ("N".equals (direction))
    {
        return ((currentY==0) ? 7 : currentY - 1);
    }
}


public ArrayList getLookAheads (int currentX, int currentY, String direction)
{
    ArrayList lookAheads = new ArrayList ();
    int x[3];
    int y[3];
    if ("N".equals (direction))
    {
        // LH1
        x[0] = currentX;
        y[0] = currentY - 1;

        // LH2
        x[1] = currentX - 1;
        y[1] = currentY - 1;

        // LH3
        x[2] = currentX + 1;
        y[2] = currentY - 1;
    } 
    else if ("S".equals (direction))
    {
        // LH1
        x[0] = currentX;
        y[0] = currentY + 1;

        // LH2
        x[1] = currentX - 1;
        y[1] = currentY + 1;

        // LH3
        x[2] = currentX + 1;
        y[2] = currentY + 1;
    } 
    else if ("E".equals (direction))
    {
        // LH1
        x[0] = currentX + 1;
        y[0] = currentY;

        // LH2
        x[1] = currentX + 1;
        y[1] = currentY - 1;

        // LH3
        x[2] = currentX + 1;
        y[2] = currentY + 1;
    } 
    else if ("E".equals (direction))
    {
        // LH1
        x[0] = currentX - 1;
        y[0] = currentY;

        // LH2
        x[1] = currentX - 1;
        y[1] = currentY - 1;

        // LH3
        x[2] = currentX - 1;
        y[2] = currentY + 1;
    }

    for (int i=0;i < 3;i++)
    {
        HashMap h = new HashMap ();
        h.put ("X", new Integer (getNextX (x[i], direction)));
        h.put ("Y", new Integer (getNextY (y[i], direction)));

        lookAheads.add (h);
    }

    return lookAheads;
}

我没有测试方法的语法(我只是在记事本中编写它们),所以请原谅我是否存在编译错误,但你应该能够解决这个问题。

希望有所帮助。

答案 2 :(得分:1)

public class Robot {
    public int x;
    public int y;
    public Robot(int x,int y) {
        this.x = x;
        this.y = y;
    }
    public void move(int direction, int steps) {
        switch(direction) {
            case 1: //north
                int temp1 = (x-steps)%8;
                x = temp1<0?(temp1+8):temp1;
                break;
            case 2: //south
                x = (x+steps)%8;
                break;
            case 3: //west
                int temp3 = (y-steps)%8;
                y = temp3<0?(temp3+8):temp3;
                break;
            case 4: //east
                y = (y+steps)%8;
                break;
            default:
                System.out.println("I'm not smart enough to handle the direciton provided!");
        }
    }

    public static void main(String[] args) {
        int[][] grid = new int[8][8];
        Robot robot = new Robot(0,0);
        System.out.println("I'm starting at (0,0).");
        robot.move(3, 9);
        System.out.println("I'm moving west by 9 steps.");
        System.out.println("I've arrived at ("+robot.x+","+robot.y+").");
    }
}

希望上面的代码能给出一个想法。我测试了它。随意尝试一下。机器人前面的三个块的计算是类似的。你可以自己搞清楚。

答案 3 :(得分:0)

通过使用模数运算符(%)可以非常简单地解决这个问题。 Modulo在某个上限周围循环值。因此,如果机器人的x值超过最大边界,它只会跳回到0.这样机器人可以通过右边的一个墙移动,x坐标重置回0,它们将出现在左边舞台的一面。