zoukankan      html  css  js  c++  java
  • unity 使用 随机普里姆算法(Randomized Prim) 生成迷宫

     unity 使用 随机普里姆算法 随机生成迷宫

    下午闲着没事,继续上次的迷宫算法,鼓捣了一下Randomized Prim

    效果图如下

    Randomized_Prim

    参考如下文献:

    https://en.wikipedia.org/wiki/Maze_generation_algorithm

    话不多说,直接贴代码。

      1 using System.Collections;
      2 using System.Collections.Generic;
      3 using UnityEngine;
      4 using UnityEngine.UI;
      5 
      6 public class RandomizedPrimBehaviour : MonoBehaviour
      7 {
      8     public struct Cell
      9     {
     10         public int x;
     11         public int y;
     12         public int direction;
     13 
     14         public bool isVisited;
     15     }
     16 
     17     public int mapWidth;
     18     public int mapHeight;
     19     public Image imagePrefab;
     20     public Color bodyColor;
     21     public Color headColor;
     22 
     23     private Cell[,] cells;
     24     private Image[,] images;
     25 
     26     private List<Cell> cellList;
     27     private Queue<Cell> cellQueue;
     28 
     29     private Coroutine coroutine;
     30     // Use this for initialization
     31     void Start()
     32     {
     33         cellList = new List<Cell>();
     34         cellQueue = new Queue<Cell>();
     35 
     36         CreateAndInit();
     37         DoRandomizedPrim();
     38     }
     39     /// <summary>
     40     /// 创建和初始化
     41     /// </summary>
     42     private void CreateAndInit()
     43     {
     44         images = new Image[mapWidth, mapHeight];
     45         cells = new Cell[mapWidth, mapHeight];
     46 
     47         for (int i = 0; i < mapWidth; i++)
     48         {
     49             for (int j = 0; j < mapHeight; j++)
     50             {
     51                 images[i, j] = Instantiate(imagePrefab, transform);
     52                 images[i, j].rectTransform.anchoredPosition = new Vector2(i * imagePrefab.rectTransform.sizeDelta.x, j * imagePrefab.rectTransform.sizeDelta.y);
     53 
     54                 cells[i, j].x = i;
     55                 cells[i, j].y = j;
     56                 cells[i, j].direction = -1;
     57                 cells[i, j].isVisited = false;
     58             }
     59         }
     60     }
     61     /// <summary>
     62     /// Randomized Prim 
     63     /// </summary>
     64     private void DoRandomizedPrim()
     65     {
     66         int times = 0;
     67 
     68         int x = Random.Range(0, mapWidth);
     69         int y = Random.Range(0, mapHeight);
     70 
     71         cells[x, y].isVisited = true;
     72 
     73         AddNewCellsToList(x, y);
     74 
     75         cellQueue.Enqueue(cells[x, y]);
     76 
     77         while (cellList.Count > 0)
     78         {
     79             int listIndex = Random.Range(0, cellList.Count);
     80 
     81             int newX = -1, newY = -1;
     82             switch (cellList[listIndex].direction)
     83             {
     84                 case 0:
     85                     if (cellList[listIndex].y + 1 < mapHeight && !cells[cellList[listIndex].x, cellList[listIndex].y + 1].isVisited)
     86                     {
     87                         newX = cellList[listIndex].x;
     88                         newY = cellList[listIndex].y + 1;
     89                     }
     90                     break;
     91                 case 1:
     92                     if (cellList[listIndex].y - 1 >= 0 && !cells[cellList[listIndex].x, cellList[listIndex].y - 1].isVisited)
     93                     {
     94                         newX = cellList[listIndex].x;
     95                         newY = cellList[listIndex].y - 1;
     96                     }
     97                     break;
     98                 case 2:
     99                     if (cellList[listIndex].x - 1 >= 0 && !cells[cellList[listIndex].x - 1, cellList[listIndex].y].isVisited)
    100                     {
    101                         newX = cellList[listIndex].x - 1;
    102                         newY = cellList[listIndex].y;
    103                     }
    104                     break;
    105                 case 3:
    106                     if (cellList[listIndex].x + 1 < mapWidth && !cells[cellList[listIndex].x + 1, cellList[listIndex].y].isVisited)
    107                     {
    108                         newX = cellList[listIndex].x + 1;
    109                         newY = cellList[listIndex].y;
    110                     }
    111                     break;
    112                 default:
    113                     print(cellList[listIndex].x + "_" + cellList[listIndex].y + " Fail");
    114                     break;
    115             }
    116 
    117             if (newX != -1 && newY != -1)
    118             {
    119                 times++;
    120 
    121                 AddNewCellsToList(newX, newY);
    122 
    123                 cellQueue.Enqueue(cells[cellList[listIndex].x, cellList[listIndex].y]);
    124                 cellQueue.Enqueue(cells[newX, newY]);
    125 
    126                 cells[cellList[listIndex].x, cellList[listIndex].y].isVisited = true;
    127                 cells[newX, newY].isVisited = true;
    128             }
    129 
    130             cellList.RemoveAt(listIndex);
    131         }
    132         print("times:" + times);
    133         coroutine = StartCoroutine(SlowShow());
    134     }
    135     /// <summary>
    136     /// 增加新cell进列表
    137     /// </summary>
    138     /// <param name="x"></param>
    139     /// <param name="y"></param>
    140     private void AddNewCellsToList(int x, int y)
    141     {
    142         if (y + 1 < mapHeight && !cells[x, y + 1].isVisited)
    143         {
    144             cells[x, y + 1].direction = 0;
    145             cellList.Add(cells[x, y + 1]);
    146         }
    147 
    148         if (y - 1 >= 0 && !cells[x, y - 1].isVisited)
    149         {
    150             cells[x, y - 1].direction = 1;
    151             cellList.Add(cells[x, y - 1]);
    152         }
    153 
    154         if (x - 1 >= 0 && !cells[x - 1, y].isVisited)
    155         {
    156             cells[x - 1, y].direction = 2;
    157             cellList.Add(cells[x - 1, y]);
    158         }
    159 
    160         if (x + 1 < mapWidth && !cells[x + 1, y].isVisited)
    161         {
    162             cells[x + 1, y].direction = 3;
    163             cellList.Add(cells[x + 1, y]);
    164         }
    165     }
    166     /// <summary>
    167     /// 延时显示
    168     /// </summary>
    169     /// <returns></returns>
    170     private IEnumerator SlowShow()
    171     {
    172         print("cellQueue.Count:" + cellQueue.Count);
    173 
    174         int lastX = -1, lastY = -1;
    175 
    176         while (cellQueue.Count > 0)
    177         {
    178             yield return new WaitForSecondsRealtime(0.1f);
    179 
    180             if (lastX != -1 && lastY != -1)
    181             {
    182                 images[lastX, lastY].color = bodyColor;
    183             }
    184 
    185             Cell cell = cellQueue.Dequeue();
    186             images[cell.x, cell.y].color = headColor;
    187 
    188             lastX = cell.x;
    189             lastY = cell.y;
    190         }
    191 
    192         images[lastX, lastY].color = bodyColor;
    193 
    194         print("End");
    195         StopCoroutine(coroutine);
    196     }
    197 }

    工程文件如下: 

     https://files.cnblogs.com/files/JinT-Hwang/RandomizedPrim.7z

    欢迎交流指教。

  • 相关阅读:
    PHP数组(数组正则表达式、数组、预定义数组)
    面向对象。OOP三大特征:封装,继承,多态。 这个讲的是【封存】
    uvalive 3938 "Ray, Pass me the dishes!" 线段树 区间合并
    LA4329 Ping pong 树状数组
    HDU 1257 最少拦截系统
    HDU 1260 Tickets
    codeforce 621D
    codeforce 621C Wet Shark and Flowers
    codeforce 621B Wet Shark and Bishops
    codeforce 621A Wet Shark and Odd and Even
  • 原文地址:https://www.cnblogs.com/JinT-Hwang/p/9621395.html
Copyright © 2011-2022 走看看