본 미로 생성 알고리즘 아이디어는 http://www.jamisbuck.org/mazes/ 블로그에 있습니다.
미로를 만들기 전 준비단계
미로를 만들기 전에는 벽으로 둘러싸인 격자 Grid를 만들어야 합니다.
여기서 초록색은 갈 수 있는 부분 빨간색은 벽을 말합니다.
void InitBoard()
{
// 일단 길을 다 막아버림
for (int y = 0; y < _size; y++)
{
for (int x = 0; x < _size; x++)
{
if (x % 2 == 0 || y % 2 == 0)
_tile[y, x] = TileType.Wall;
else
_tile[y, x] = TileType.Empty;
}
}
}
1. Binary Tree Algorithm
해당 알고리즘은 미로 생성 알고리즘 중 가장 간단합니다.
이름에서 알 수 있듯이 각 스텝마다 가능한 2가지의 옵션(아래 혹은 오른쪽으로 길을 틈) 중 랜덤으로 선택합니다.
이 방법을 맨 끝줄까지 반복한다면 미로가 완성됩니다.
[ Binary Tree Algorithm ] 코드 구현
public enum Direction
{
DOWN = 0,
RIGHT,
}
void GeneratedByBinaryTree()
{
// 랜덤으로 우측 혹은 아래로 길을 뚫음
Random rand = new Random();
for (int y = 0; y < _size; y++)
{
for (int x = 0; x < _size; x++)
{
if (x % 2 == 0 || y % 2 == 0)
continue;
if (x == _size - 2 && y == _size - 2)
continue;
if (x == _size - 2)
{
_tile[y + 1, x] = TileType.Empty;
continue;
}
if (y == _size - 2)
{
_tile[y, x + 1] = TileType.Empty;
continue;
}
else
{
Direction dir = (Direction)rand.Next(0, 2);
switch (dir)
{
case Direction.DOWN: // 아래
_tile[y + 1, x] = TileType.Empty;
break;
case Direction.RIGHT: // 우측
_tile[y, x + 1] = TileType.Empty;
break;
}
}
}
}
}
2. Sidewinder Algorithm
해당 알고리즘도 미로 생성 알고리즘 중 가장 간단합니다.
이 알고리즘은 위에서 설명한 Binary Tree 알고리즘과 비슷합니다.
Binary Tree 알고리즘처럼 각 스텝마다 가능한 2가지의 옵션(아래 혹은 오른쪽으로 길을 틈) 중 랜덤으로 선택합니다.
오른쪽으로 연속 이동한 횟수를 Count하여 오른쪽 이동 중 아래로 이동하는 옵션이 선택되면 오른쪽 연속으로 이동한 Cell 중 랜덤으로 선택하여 그 Cell에서 아래로 길을 틉니다.
이 방법을 맨 끝줄까지 반복한다면 미로가 완성됩니다.
[ Sidewinder Algorithm ] 코드 구현
void CreatedBySideWinder()
{
// 랜덤으로 우측 혹은 아래로 길을 뚫음
// i) 연속으로 우측으로 길을 뚫다가 아래로 뚫을 경우,
// 연속으로 뚫은 길 중 한 곳을 골라서 아래로 뚫는다.
Random rand = new Random();
for (int y = 0; y < _size; y++)
{
int rightCount = 1;
for (int x = 0; x < _size; x++)
{
if (x % 2 == 0 || y % 2 == 0)
continue;
if (x == _size - 2 && y == _size - 2)
continue;
if (x == _size - 2)
{
_tile[y + 1, x] = TileType.Empty;
continue;
}
if (y == _size - 2)
{
_tile[y, x + 1] = TileType.Empty;
continue;
}
Direction dir = (Direction)rand.Next(0, 2);
switch (dir)
{
case Direction.DOWN: // 아래
int randomIndex = rand.Next(0, rightCount);
_tile[y + 1, x - randomIndex * 2] = TileType.Empty;
rightCount = 1;
break;
case Direction.RIGHT: // 우측
_tile[y, x + 1] = TileType.Empty;
rightCount += 1;
break;
}
}
}
}
오늘의 깨달음
간단한 알고리즘일수록 미로의 퀄리티가 낮아진다는 것을 명심해야 합니다!
'C# 공부 > 알고리즘' 카테고리의 다른 글
길찾기 알고리즘(DFS, BFS, Dijkstra) (0) | 2020.08.19 |
---|