Prim';s算法C#Unity
我目前正在使用prim的算法生成一个统一的随机迷宫 如果我运行游戏,迷宫就是这个样子 这就是我想要迷宫的样子 不同的是,第一个有一个角落的白色方块接触,而第二个有空间之间的白色方块在任何时候 这是控制迷宫视觉创建的代码:Prim';s算法C#Unity,c#,algorithm,unity3d,prims-algorithm,C#,Algorithm,Unity3d,Prims Algorithm,我目前正在使用prim的算法生成一个统一的随机迷宫 如果我运行游戏,迷宫就是这个样子 这就是我想要迷宫的样子 不同的是,第一个有一个角落的白色方块接触,而第二个有空间之间的白色方块在任何时候 这是控制迷宫视觉创建的代码: void FindNext(){ //We create an empty Transform variable // to store the next cell in. Transform next; //List for the cur
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);
}
void FindNext(){
//我们创建一个空的转换变量
//将下一个单元格存储在中。
下一步改造;
//当前单元格邻接的列表
列出策展人名单;
//元素邻接的列表
列出邻接元素;
//while循环的数字变量
int num=1;
//执行这个循环
//而:
//提议的下一个游戏对象的邻接点被打开
//小于或等于2。
//这是为了确保迷宫式结构。
做{
//我们首先假设AdjSet的每个子列表都是空的
//并试图在for循环中证明这个假设是错误的。
//此布尔值将保持跟踪。
bool empty=true;
//我们还将记录下哪个列表是最低的,
//并将其存储在这个变量中。
int lowestList=0;
对于(int i=0;i<10;i++){
//我们循环遍历AdjSet列表中的每个子列表
//列表,直到找到一个计数大于0的列表。
//如果子列表中的项目超过0项,
//它不是空的。
//然后使用break关键字停止循环;
//我们已经找到了最低的子列表,因此没有必要
//继续搜索。
最低级=i;
如果(调整集[i]。计数>0){
空=假;
打破
}
}
//AdjSet的子列表中可能没有一个会
//里面有什么东西吗。
//如果发生这种情况,那么我们就没有更多的细胞可以打开
//都是用迷宫制作的。
如果(空){
//如果我们完成,如上所述和确定,
//向调试控制台显示消息
//这包括完成所需的秒数。
Log(“我们完成了,”+Time.timesineclevelload+“花费的秒数”);
//然后,取消FindNext函数的递归调用,
//就像我们完成迷宫一样。
//如果我们允许调用继续进行,我们将收到一个错误。
取消调用(“FindNext”);
//Set.Count-1是集合中最后一个元素的索引,
//或者是我们打开的最后一间牢房。
//这将被标记为我们迷宫的结束,依此类推
//我们把它标成红色。
Set[Set.Count-1].renderer.material.color=color.red;
//网格中不在集合中的每个单元格
//将向上移动一个单位并变为黑色。
//(我先前将默认颜色从黑色更改为透明)。
//如果您现在在迷宫中实例化FirstPersonController,
//你可以试着穿过它。
//这真的很难。
foreach(网格中的变换单元){
如果(!Set.Contains(单元格)){
细胞翻译(向量3向上);
cell.renderer.material.color=color.black;
}
}
返回;
}
//如果我们没有完成,那么:
//1.使用AdjSet中最小的子列表
//如前所述,使用最下面的
//变数。
//2.对于最小的子列表,选择第一个
//元素,并将其用作“下一个”。
next=AdjSet[lowerist][0];
curAdjacents=next.GetComponent().Adjacents;
//因为我们不希望在AdjSet和Set中使用相同的单元格,
//从AdjSet中删除此“下一个”变量。
AdjSet[最下面的]。删除(下一步);
//这是我试图用来解决这个问题的代码
//当我运行它时,除了第一个和最后一个,
//方形白色。如果其中一个电流,
//单元格的邻接单元格有一个已,
//我不知道这个密码怎么了。
//foreach(策展人中的转换元素){
//eleAdjacents=element.GetComponent().Adjacents;
//foreach(元素邻接中的变换元素){
//if(集合包含(元素)){
//继续;
//}
//否则{
//Log(“BREAK!”);
//num=0;
//中断;
//}
//}
//}
}while(next.GetComponent().AdjacentsOpened>=2&&num==1);
//“下一个”变换的材质颜色变为白色。
next.renderer.material.color=color.white;
//我们将此“下一步”变换添加到函数集。
AddToSet(下一个);
//一旦调用此函数,就递归调用此函数
//完成。
调用(“FindNext”,0);
}
任何解决方案都是受欢迎的,无论是小改动还是对所有代码的完全修改。如果你不知道如何修复代码,但你知道如何使用prim的算法制作迷宫,请分享 事实上,我想你差不多做到了,你只需要在节点之间加入人工空间。我猜如果你在这样的图上操作
ooo
ooo
ooo
当o
表示节点时,迷宫中实际生成的路径应该如下所示
o-o-o
| | |
o-o-o
| | |
o-o-o
这意味着在实际的迷宫中需要更多的空间。好的,我将尝试用一堆ascii图片来解释这个逻辑,因为我对文字不感兴趣 假设你从一个迷宫开始,看起来像:
...X..
.X.X.X
X....X
X.X.X.
X.X...
...XXX
XXX
...
XXX
XXXXXXXXXXXXXXXXXX
X.......XXXXX.....
X.XXXXX.XXXXX.XXXX
XXXXXXX.XXXXX.XXXX
XXXX..........XXXX
XXXX.XXXXX.XXXXXXX
XXXX.XXXXX.XXXXXXX
XXXX.XXXXX.XXXXX.X
XXXX.XXXXX.XXXXX.X
XXXX.XXXXX.XXXXX.X
XXXX.XXXXX.......X
XXXX.XXXXXXXXXXXXX
XXXX.XXXXXXXXXXXXX
........XXXXXXXXXX
XXXXXXXXXXXXXXXXXX
旅行在哪里
XXXXXX[][][][][]
X.....[][][][][]
X.XXXX[][][][][]
[][][][][][][][]
[][][][][][][][]
XXXXXXXXXXXXXXXXXX
X.......XXXXX.....
X.XXXXX.XXXXX.XXXX
XXXXXXX.XXXXX.XXXX
XXXX..........XXXX
XXXX.XXXXX.XXXXXXX
XXXX.XXXXX.XXXXXXX
XXXX.XXXXX.XXXXX.X
XXXX.XXXXX.XXXXX.X
XXXX.XXXXX.XXXXX.X
XXXX.XXXXX.......X
XXXX.XXXXXXXXXXXXX
XXXX.XXXXXXXXXXXXX
........XXXXXXXXXX
XXXXXXXXXXXXXXXXXX