我目前正在使用prim的算法生成一个统一的随机迷宫。
这就是我运行游戏时迷宫的样子。
这就是我想要迷宫的样子。
不同的是,第一个有白色正方形的角接触,而第二个有白色正方形之间的空间在任何时候。
这是控制迷宫视觉创建的代码:
void FindNext(){
//We create an empty Transform variable
// to store the next cell in.
Transform next;
//List for the current cell's adjacents
List<Transform> curAdjacents;
//List for an element's adjacents
List<Transform> eleAdjacents;
//Number variable for while loop
int num = 1;
//Perform this loop
// While:
// The proposed next gameObject's AdjacentsOpened
// is less than or equal to 2.
// This is to ensure the maze-like structure.
do{
//We'll initially assume that each sub-list of AdjSet is empty
// and try to prove that assumption false in the for loop.
// This boolean value will keep track.
bool empty = true;
//We'll also take a note of which list is the Lowest,
// and store it in this variable.
int lowestList = 0;
for(int i = 0; i < 10; i++){
//We loop through each sub-list in the AdjSet list of
// lists, until we find one with a count of more than 0.
// If there are more than 0 items in the sub-list,
// it is not empty.
//We then stop the loop by using the break keyword;
// We've found the lowest sub-list, so there is no need
// to continue searching.
lowestList = i;
if(AdjSet[i].Count > 0){
empty = false;
break;
}
}
//There is a chance that none of the sub-lists of AdjSet will
// have any items in them.
//If this happens, then we have no more cells to open, and
// are done with the maze production.
if(empty){
//If we finish, as stated and determined above,
// display a message to the DebugConsole
// that includes how many seconds it took to finish.
Debug.Log("We're Done, "+Time.timeSinceLevelLoad+" seconds taken");
//Then, cancel our recursive invokes of the FindNext function,
// as we're done with the maze.
//If we allowed the invokes to keep going, we will receive an error.
CancelInvoke("FindNext");
//Set.Count-1 is the index of the last element in Set,
// or the last cell we opened.
//This will be marked as the end of our maze, and so
// we mark it red.
Set[Set.Count-1].renderer.material.color = Color.red;
//Every cell in the grid that is not in the set
// will be moved one unit up and turned black.
// (I changed the default color from black to clear earlier).
// If you instantiate a FirstPersonController in the maze now,
// you can actually try walking through it.
// It's really hard.
foreach(Transform cell in Grid){
if(!Set.Contains(cell)){
cell.Translate(Vector3.up);
cell.renderer.material.color = Color.black;
}
}
return;
}
//If we did not finish, then:
// 1. Use the smallest sub-list in AdjSet
// as found earlier with the lowestList
// variable.
// 2. With that smallest sub-list, take the first
// element in that list, and use it as the 'next'.
next = AdjSet[lowestList][0];
curAdjacents = next.GetComponent<CellScript>().Adjacents;
//Since we do not want the same cell in both AdjSet and Set,
// remove this 'next' variable from AdjSet.
AdjSet[lowestList].Remove(next);
//This is code I'm trying to use to solve the issue
//When I run it though it makes all but the first and last,
//square white. It is supposed to NOT break if one of the current,
//cell's adjacents cells has an adjacent cell that has already,
//been made white. I don't know what's wrong with this code.
//foreach(Transform element in curAdjacents){
//eleAdjacents = element.GetComponent<CellScript>().Adjacents;
//foreach(Transform elem in eleAdjacents){
//if(Set.Contains(elem)){
//continue;
//}
//else{
//Debug.Log("BREAK!");
//num = 0;
//break;
//}
//}
//}
}while(next.GetComponent<CellScript>().AdjacentsOpened >= 2 && num == 1);
//The 'next' transform's material color becomes white.
next.renderer.material.color = Color.white;
//We add this 'next' transform to the Set our function.
AddToSet(next);
//Recursively call this function as soon as this function
// finishes.
Invoke("FindNext", 0);
}
任何解决方案都是受欢迎的,无论它们是小改动还是对所有代码的完全重写。如果你不知道如何修复代码,但你知道如何用prim的算法做一个迷宫,请分享。
最佳答案
事实上,我猜你就快到了,你只需要在节点之间加入人工空间。我想如果你在一个像
ooo
ooo
ooo
当
o
表示节点时,迷宫中实际生成的路径应该如下所示o-o-o
| | |
o-o-o
| | |
o-o-o
这意味着在真正的迷宫里必须有更多的空间。