我正致力于迷宫生成算法。我的算法从预定义的图块中选择并创建一个迷宫。这是我的代码生成的示例。 ' **'是一堵墙,' __'是空的地板空间。
** ** ** ** ** ** ** ** ** ** **
** __ __ __ ** ** __ ** ** ** **
** ** __ __ __ __ __ ** ** ** **
** ** __ __ __ __ __ ** ** ** **
** __ __ __ ** __ ** ** ** ** **
** __ __ __ ** __ ** ** ** ** **
** __ __ ** ** __ ** ** ** ** **
** __ __ __ ** ** ** __ __ __ **
** __ ** __ ** ** ** __ __ ** **
** __ __ __ ** ** ** __ ** ** **
** ** ** ** ** ** ** ** ** ** **
我需要创建一个函数来测试是否所有楼层空间都已连接。即确保所有' __'可以从其他所有地方到达空间' __'空间。这意味着上述迷宫是非法的,但下面的内容是可以接受的。
** ** ** ** ** ** ** ** ** ** **
** ** __ ** __ __ __ __ __ __ **
** __ __ __ __ __ __ __ __ __ **
** ** __ ** __ __ ** ** __ ** **
** __ __ __ ** ** ** __ __ __ **
** __ __ ** ** ** ** __ __ __ **
** __ __ __ ** ** ** __ __ __ **
** ** ** __ ** ** ** ** ** ** **
** __ __ __ __ __ __ ** ** ** **
** __ __ __ ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** **
我不确定如何最好地解决这个问题。我想我应该使用BFS搜索,但我并不是100%肯定。欢迎提出所有建议,提前致谢!
答案 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
的教程