在Java中检查2D数组中的楼层同余

时间:2017-05-18 00:23:11

标签: java algorithm

我正致力于迷宫生成算法。我的算法从预定义的图块中选择并创建一个迷宫。这是我的代码生成的示例。 ' **'是一堵墙,' __'是空的地板空间。

** ** ** ** ** ** ** ** ** ** ** 
** __ __ __ ** ** __ ** ** ** ** 
** ** __ __ __ __ __ ** ** ** ** 
** ** __ __ __ __ __ ** ** ** ** 
** __ __ __ ** __ ** ** ** ** ** 
** __ __ __ ** __ ** ** ** ** ** 
** __ __ ** ** __ ** ** ** ** ** 
** __ __ __ ** ** ** __ __ __ ** 
** __ ** __ ** ** ** __ __ ** ** 
** __ __ __ ** ** ** __ ** ** ** 
** ** ** ** ** ** ** ** ** ** ** 

我需要创建一个函数来测试是否所有楼层空间都已连接。即确保所有' __'可以从其他所有地方到达空间' __'空间。这意味着上述迷宫是非法的,但下面的内容是可以接受的。

** ** ** ** ** ** ** ** ** ** ** 
** ** __ ** __ __ __ __ __ __ ** 
** __ __ __ __ __ __ __ __ __ ** 
** ** __ ** __ __ ** ** __ ** ** 
** __ __ __ ** ** ** __ __ __ ** 
** __ __ ** ** ** ** __ __ __ ** 
** __ __ __ ** ** ** __ __ __ ** 
** ** ** __ ** ** ** ** ** ** ** 
** __ __ __ __ __ __ ** ** ** ** 
** __ __ __ ** ** ** ** ** ** ** 
** ** ** ** ** ** ** ** ** ** ** 

我不确定如何最好地解决这个问题。我想我应该使用BFS搜索,但我并不是100%肯定。欢迎提出所有建议,提前致谢!

3 个答案:

答案 0 :(得分:1)

Flood-fill来自一些起始楼层的楼层。你可以通过另一个2D数组来做到这一点。您可以使用BFS(基于队列)或DFS(基于堆栈)。关键在于进行详尽的搜索。

再次穿过迷宫。如果您发现在上述步骤中没有填写任何楼层,我们知道它与其他楼层没有连接。

答案 1 :(得分:1)

我有太多的空闲时间,代码按预期工作,但有些方法可能会做得更好。

主要

package maze;

public class Tile
{
    public static final String FLOOR = "__";
    public static final String WALL = "**";

    private int x;
    private int y;

    public Tile(int x, int y)
    {
        this.setX(x);
        this.setY(y);
    }

    /** ---------------------------------------- **/
    /** --- GETTERS & SETTERS                --- **/
    /** ---------------------------------------- **/

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}

<强>瓷砖

package maze;

import java.util.ArrayList;
import java.util.List;

public class Maze
{
    //Maze dimensions.
    private int mazeDimX = 11;
    private int mazeDimY = 11;
    private String[][] array;

    //Last found floor tile coordinates.
    public int x = -1;
    public int y = -1;

    public Maze(int mazeDimX, int mazeDimY)
    {
        this.mazeDimX = mazeDimX;
        this.mazeDimY = mazeDimY;
        array = new String[mazeDimX][mazeDimY];
    }

    /** ---------------------------------------- **/
    /** --- METHODS                          --- **/
    /** ---------------------------------------- **/

    public void populate()
    {
        //Insert code to populate maze here.
    }

    public int getTotalFloorCount()
    {
        int count = 0;
        for (int i=0; i<mazeDimX; i++)
        {
            for (int j=0; j<mazeDimY; j++)
            {
                if (array[i][j].equals(Tile.FLOOR))
                {
                    //Increase the total count of floor tiles.
                    count++;

                    //Stores the last found floor tile.
                    x = i;
                    y = j;
                }
            }
        }
        return count;
    }

    public int getSectionFloorCount(int x, int y)
    {
        int tileCount = 0;

        List<Tile> tiles = new ArrayList<Tile>();
        List<Tile> removedTiles = new ArrayList<Tile>();
        if (x != -1 && y != -1)
        {
            tiles.add(new Tile(x, y));
        }

        while (!tiles.isEmpty())
        {
            //Increase current tile count.
            tileCount++;

            //Get next tile.
            Tile tile = tiles.get(0);

            //Get x and y of tile.
            int tileX = tile.getX();
            int tileY = tile.getY();

            //Get up, down, left and right tiles.
            Tile up =       getAdjacentTile(tileX, tileY - 1);
            Tile down =     getAdjacentTile(tileX, tileY + 1);
            Tile left =     getAdjacentTile(tileX - 1, tileY);
            Tile right =    getAdjacentTile(tileX + 1, tileY);

            //Add tile if required.
            addTile(tiles, removedTiles, up);
            addTile(tiles, removedTiles, down);
            addTile(tiles, removedTiles, left);
            addTile(tiles, removedTiles, right);

            //Move the tile from the checked list to the removed list.
            tiles.remove(tile);
            removedTiles.add(tile);
        }
        return tileCount;
    }

    private Tile getAdjacentTile(int x, int y)
    {
        //Check if the tile is in bounds.
        if (x >= 0 && x < mazeDimX && y >= 0 && y < mazeDimY)
        {
            //Check if the tile is a floor.
            if (array[x][y].equals(Tile.FLOOR))
            {
                return new Tile(x, y);
            }
        }
        return null;
    }

    private void addTile(List<Tile> tiles, List<Tile> removedTiles, Tile tile)
    {
        boolean isRemoved = false;
        if (tile != null)
        {
            //Check if the tile has already been removed.
            for (int i=0; i<removedTiles.size(); i++)
            {
                Tile removed = removedTiles.get(i);
                if (tile.getX() == removed.getX() && tile.getY() == removed.getY())
                {
                    isRemoved = true;
                    break;
                }
            }
            if (!isRemoved)
            {
                boolean isInList = false;
                //Check if the tile already is in the list to be checked.
                for (int i=0; i<tiles.size(); i++)
                {
                    Tile item = tiles.get(i);
                    if (tile.getX() == item.getX() && tile.getY() == item.getY())
                    {
                        isInList = true;
                    }
                }
                //Add the tile if it hasn't been checked or removed already.
                if (!isInList)
                {
                    tiles.add(tile);
                }
            }
        }
    }
}

<强>迷宫

05-18 11:01:52.756 710-722/? E/DatabaseUtils: Writing exception to parcel
                                          java.lang.SecurityException: Permission Denial: get/set setting for user asks to run as user -2 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL
                                              at com.android.server.am.ActivityManagerService.handleIncomingUser(ActivityManagerService.java:15401)
                                              at android.app.ActivityManager.handleIncomingUser(ActivityManager.java:2512)
                                              at com.android.providers.settings.SettingsProvider.call(SettingsProvider.java:685)
                                              at android.content.ContentProvider$Transport.call(ContentProvider.java:325)
                                              at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:275)
                                              at android.os.Binder.execTransact(Binder.java:404)
                                              at dalvik.system.NativeStart.run(Native Method)

答案 2 :(得分:0)

简单的A *搜索可以很好地用于此目的,虽然取决于你的迷宫的大小,它可能有点慢。在伪代码中:

for(t=0; t<arrayOfAllTiles.length; t++) {
    for(i=t; i<arrayOfAllTiles.length; i++) {
        if(doAStarTest(i, t) == false) {
            //oh no, not congruent
        }
    }
}

Red Blob Games有一些精彩的教程,包括一个关于A *:http://www.redblobgames.com/pathfinding/a-star/introduction.html

的教程