2차원 배열 형태의 미로를 생성하는 알고리즘이다. 오른쪽 혹은 위쪽으로 랜덤하게 길을 만들어 미로를 생성한다. 가지치기 형태로 사용되는 일반적인 이진 트리 알고리즘과 미로 생성시 사용되는 이진 트리 알고리즘은 조금 차이가 있다.
1번째 과정 | 2번째 과정 | 3번째 과정 | 최종 형태 |
---|---|---|---|
using UnityEngine;
using UnityEngine.Tilemaps;
public class MazeGeneratorByBinaryTree : MonoBehaviour
{
[SerializeField] private int width;
[SerializeField] private int height;
private int[,] map;
private const int ROAD = 0;
private const int WALL = 1;
[SerializeField] private Tilemap tilemap;
[SerializeField] private Tile tile;
[SerializeField] private Color[] colors;
private void Update()
{
Debug.Assert(!(width % 2 == 0 || height % 2 == 0), "홀수로 입력하십시오.");
if (Input.GetMouseButtonDown(0)) Generate();
}
private void Generate()
{
map = new int[width, height];
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
OnDrawTile(x, y); //맵 크기에 맞춰 타일맵 배치
}
}
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
if (x == 1 && y == 0) map[x, y] = ROAD; //시작 위치
else if (x == width - 2 && y == height - 1) map[x, y] = ROAD; //출구 위치
else if (x == 0 || x == width - 1 || y == 0 || y == height - 1) map[x, y] = WALL; //가장자리 벽으로 채움
else if (x % 2 == 0 || y % 2 == 0) map[x, y] = WALL; //짝수 칸 벽으로 채움
else map[x, y] = ROAD; //나머지 칸에는 길 배치
}
}
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
Vector2Int pos;
if (x % 2 == 0 || y % 2 == 0) continue; //짝수 칸은 건너 뜀
if (x == width - 2 && y == height - 2) continue; //우측 상단 모서리에 닿으면 길을 생성하지 않음
if (x == width - 2) pos = new Vector2Int(x, y + 1); //오른쪽 끝에 닿으면 길 생성 방향을 위로 설정
else if (y == height - 2) pos = new Vector2Int(x + 1, y); //위쪽 끝에 닿으면 길 생성 방향을 오른쪽으로 설정
else if (Random.Range(0, 2) == 0) pos = new Vector2Int(x + 1, y); //랜덤으로 방향 지정 (위쪽, 오른쪽)
else pos = new Vector2Int(x, y + 1);
map[pos.x, pos.y] = ROAD; //맵 데이터에 값 저장
SetTileColor(pos.x, pos.y); //타일맵 색상 변경
}
}
}
private void SetTileColor(int x, int y)
{
Vector3Int pos = new Vector3Int(-width / 2 + x, -height / 2 + y, 0); //생성 위치를 화면 중앙으로 설정
tilemap.SetTileFlags(pos, TileFlags.None); //타일맵의 색상을 변경하기 위해 TileFlags값을 None으로 변경
switch (map[x, y])
{
case ROAD: tilemap.SetColor(pos, colors[0]); break;
case WALL: tilemap.SetColor(pos, colors[1]); break;
}
}
private void OnDrawTile(int x, int y)
{
Vector3Int pos = new Vector3Int(-width / 2 + x, -height / 2 + y, 0);
tilemap.SetTile(pos, tile);
}
}
https://errorcode1001.tistory.com/9
https://develop-dream.tistory.com/83