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

    欢迎交流指教。

  • 相关阅读:
    QT QQuickView嵌入到QT MDI中
    地理入门-经纬度时区速成总结篇(转)
    Linux下系统时间函数、DST等相关问题总结(转)
    camera接口---MIPI CSI-2接口、DVP接口和FPD-Link III LVDS、GMSL等接口对比(转)
    基于spi FLASH的嵌入式文件系统 littlefs(转)
    PID 温控系统 解决方法(转)
    单相计量芯片RN8209D使用经验分享(转)
    【开源】EasyFlash 新年发布 V4.0 beta 版,完全重写(转)
    在uboot中加入cmd_run命令,运行环境变量(转)
    MPU6050开发 -- 数据分析(转)
  • 原文地址:https://www.cnblogs.com/JinT-Hwang/p/9621395.html
Copyright © 2011-2022 走看看