protected override void Generate() { IMazeCell random_start = GetRandomCell(); int visited = 1; while (visited < cells.Count) { EMazeDirection valid = random_start.GenRandomNeighbourDirection(); IMazeCell pending_next = random_start.GetNeighbour(valid); if (pending_next != null) { //言外之意,没被访问过 //means, not visited. if (pending_next.ConnectionCount == 0) { random_start.ConnectionTo(valid); random_start = pending_next; visited++; } else { random_start = pending_next; continue; } } } }
/// <summary> /// 注意:该算法对不规则图形非常不友好,如果一定要应用到不规则图形 /// 需要做很多修改,因此建议直接禁止本算法应用到不规则图形上去。 /// </summary> protected override void Generate() { List <IMazeCell> temp_cell_collection = new List <IMazeCell>(); List <EMazeDirection> filter_dir = new List <EMazeDirection>(); filter_dir.Add(EMazeDirection.North); filter_dir.Add(EMazeDirection.East); for (int iy = 0; iy < size_y; iy++) { for (int ix = 0; ix < size_x; ix++) { IMazeCell cell = GetAt(ix, iy); //尽管如此,还是可以利用fiter做一波优化,去掉重复代码! EMazeDirection move_dir = cell.GenRandomNeighbourDirection(ESelectCondition.None, filter_dir); if (move_dir == EMazeDirection.North) { temp_cell_collection.Add(cell); IMazeCell dig_cell = temp_cell_collection[Random.Range(0, temp_cell_collection.Count)]; dig_cell.ConnectionTo(EMazeDirection.North); temp_cell_collection.Clear(); } else if (move_dir == EMazeDirection.East) { temp_cell_collection.Add(cell); cell.ConnectionTo(EMazeDirection.East); } } } }
void Hunt(int visited) { IMazeCell hunt_result = null; for (int iy = size_y - 1; iy >= 0; iy--) //for (int iy = 0; iy < size_y;iy++ ) { for (int ix = 0; ix < size_x; ix++) //for (int ix = size_x-1; ix >=0; ix--) { hunt_result = GetAt(ix, iy); //hunt result 必须是一个未访问过的点,并且他要链接一个已经访问过的点(隐含一定不会连接) if (hunt_result.ConnectionCount == 0) { EMazeDirection dir = hunt_result.GenRandomNeighbourDirection(ESelectCondition.Visited); if (dir != EMazeDirection.Invalid) { hunt_result.ConnectionTo(dir); visited++; Kill(visited, hunt_result); break; } } } } }
void Kill(int visited, IMazeCell start_point) { if (visited <= cells.Count) { do { EMazeDirection move_dir = start_point.GenRandomNeighbourDirection(ESelectCondition.NoVisited); if (move_dir == EMazeDirection.Invalid) { break; } IMazeCell next = start_point.GetNeighbour(move_dir); start_point.ConnectionTo(move_dir); start_point = next; visited++; }while(true); //finish kill begin hunt. if (visited < cells.Count) { Hunt(visited); } } }
protected override void Generate() { Stack <IMazeCell> back_tracker = new Stack <IMazeCell>(); //把起点塞进去 back_tracker.Push(cells[0]); //如果栈空了,表示迷宫完成了。 while (back_tracker.Count > 0) { //寻找栈顶元素 IMazeCell start_node = back_tracker.Peek(); //直接选择出,没访问过,且不连通的点。注意,不连通,但是有可能是已经访问过的,没访问过,一定不连通! EMazeDirection move_dir = start_node.GenRandomNeighbourDirection(ESelectCondition.NoVisited); //如果这个点的周围都已经访问过来,开始回溯,每次遍历回溯一格。直到找到下一个,周围有没访问过的点的节点。 if (move_dir == EMazeDirection.Invalid) { back_tracker.Pop(); continue; } //点周围有没访问过,也没联通的点 start_node.ConnectionTo(move_dir); back_tracker.Push(start_node.GetNeighbour(move_dir)); } }
public override void PostProcess(MazeAlgorithm maze_algorithm) { int size_x = maze_algorithm.size_x; int size_y = maze_algorithm.size_y; for (int iy = 0; iy < size_y; iy++) { for (int ix = 0; ix < size_x; ix++) { IMazeCell cell = maze_algorithm.GetAt(ix, iy); //Dead Ends if (cell != null && cell.ConnectionCount == 1 && Random.Range(0.0f, 1.0f) < braidingrate) { bool processed = false; for (int i = 0; i < (int)EMazeDirection.DirectionCount; i++) { EMazeDirection dir = (EMazeDirection)i; //尚未联通的点 if (cell.IsConnectedTo(dir) == true) { //只做反向联通,确保不会出现孤点 EMazeDirection inverse_dir = MazeAlgorithm.InvertDirection(dir); IMazeCell invert_cell = cell.GetNeighbour(inverse_dir); if (invert_cell != null) { cell.ConnectionTo(inverse_dir); processed = true; } } //END OF IF Connected to } //END OF FOR Neighbours if (processed == false) { EMazeDirection connect_dir = cell.GenRandomNeighbourDirection(ESelectCondition.NoConnected); if (connect_dir != EMazeDirection.DirectionCount) { cell.ConnectionTo(connect_dir); } } } } } }
/// <summary> /// 这个算法同样不能胜任,不规则格子的迷宫。 /// 因为他会产生孤立点。 /// </summary> protected override void Generate() { List <EMazeDirection> dir_filter = new List <EMazeDirection>(); dir_filter.Add(EMazeDirection.North); dir_filter.Add(EMazeDirection.East); for (int iy = 0; iy < size_y; iy++) { for (int ix = 0; ix < size_x; ix++) { IMazeCell cell = GetAt(ix, iy); //算法优化,不能每次都判断是不是在墙角,那种判断对于不规则迷宫是无效的,且麻烦的。 //如果只希望沿着某两个方向扩展,更科学的方式是使用DirectionFilter 这样可以方便的产生更多的选择组合。 EMazeDirection move_to_dir = cell.GenRandomNeighbourDirection(ESelectCondition.None, dir_filter); if (move_to_dir != EMazeDirection.DirectionCount) { cell.ConnectionTo(move_to_dir); } } } }
protected override void Generate() { IMazeCell random_start = GetRandomCell(); List <IMazeCell> unvisited = new List <IMazeCell>(cells); unvisited.Remove(random_start); //前半段,用AldourBroder while (unvisited.Count > cells.Count / 2) { EMazeDirection valid = random_start.GenRandomNeighbourDirection(); IMazeCell pending_next = random_start.GetNeighbour(valid); if (pending_next != null) { //言外之意,没被访问过 //means, not visited. if (pending_next.ConnectionCount == 0) { random_start.ConnectionTo(valid); random_start = pending_next; unvisited.Remove(random_start); } else { random_start = pending_next; continue; } } } //后半段,用Wilson List <IMazeCell> temp_path = new List <IMazeCell>(); random_start = unvisited[Random.Range(0, unvisited.Count)]; while (unvisited.Count > 0) { temp_path.Clear(); temp_path.Add(random_start); while (true) { //如果有强烈需求,可以考虑增加接口,暂时先这样做。 EMazeDirection dir = temp_path[temp_path.Count - 1].GenRandomNeighbourDirection(); IMazeCell next = temp_path[temp_path.Count - 1].GetNeighbour(dir); //没有形成环路 if (unvisited.Contains(next) == false) { //开始联通了 temp_path.Add(next); for (int i = 0; i < temp_path.Count - 1; i++) { unvisited.Remove(temp_path[i]); temp_path[i].ConnectionTo(temp_path[i].LastRandomNeibourDirection); } if (unvisited.Count > 0) { random_start = unvisited[Random.Range(0, unvisited.Count)]; } break; } //形成了环路 else if (temp_path.Contains(next) == true) { break; } temp_path.Add(next); } } }