Skip to content

Instantly share code, notes, and snippets.

@celechii
Created November 13, 2020 00:01
Show Gist options
  • Save celechii/efa96fe7365f92ea9389df82f2f0ce3b to your computer and use it in GitHub Desktop.
Save celechii/efa96fe7365f92ea9389df82f2f0ce3b to your computer and use it in GitHub Desktop.
using UnityEngine;
public class Maze : MonoBehaviour {
public Vector2Int mazeSize = new Vector2Int(15, 15); // this should b odd dimensions
[SerializeField]
public bool drawGizmos = true;
private bool[, ] maze;
private Vector2Int prevSize; // delete this, the OnValidate() method, n the OnDrawGizmos() method if u dont wanna preview it in the editor
[ContextMenu("Generate Maze")]
public bool[, ] GenerateMaze() {
maze = new bool[mazeSize.x, mazeSize.y];
// random starting pos on an odd index position
Vector2Int startPos = new Vector2Int(Random.Range(0, (int)(mazeSize.x / 2f)), Random.Range(0, (int)(mazeSize.y / 2f)));
startPos *= 2;
startPos += Vector2Int.one;
maze[startPos.x, startPos.y] = true;
RecurseMaze(startPos.x, startPos.y);
return maze;
}
private void OnValidate() {
if (!drawGizmos)
return;
Vector2Int change = mazeSize - prevSize;
if (mazeSize.x <= 3)
mazeSize.x = 3;
if (mazeSize.y <= 3)
mazeSize.y = 3;
if (mazeSize.x % 2 == 0)
mazeSize.x += (int)Mathf.Sign(change.x);
if (mazeSize.y % 2 == 0)
mazeSize.y += (int)Mathf.Sign(change.y);
GenerateMaze();
prevSize = mazeSize;
}
private void RecurseMaze(int xPos, int yPos) {
// shuffle the order u check the directions in
int[] randomDirs = new int[] {-1, -1, -1, -1 };
for (int i = 0; i < randomDirs.Length; i++) {
int arrayPos;
do {
arrayPos = Random.Range(0, 4);
} while (randomDirs[arrayPos] != -1);
randomDirs[arrayPos] = i;
}
// go in each direction u can
for (int i = 0; i < randomDirs.Length; i++) {
// only run in this direction if its a valid one
if (IsValidDirection(randomDirs[i], xPos, yPos)) {
if (randomDirs[i] == 0) { // go up
maze[xPos, yPos + 1] = maze[xPos, yPos + 2] = true;
RecurseMaze(xPos, yPos + 2);
} else if (randomDirs[i] == 1) { // go down
maze[xPos, yPos - 1] = maze[xPos, yPos - 2] = true;
RecurseMaze(xPos, yPos - 2);
} else if (randomDirs[i] == 2) { // go left
maze[xPos - 1, yPos] = maze[xPos - 2, yPos] = true;
RecurseMaze(xPos - 2, yPos);
} else if (randomDirs[i] == 3) { // go right
maze[xPos + 1, yPos] = maze[xPos + 2, yPos] = true;
RecurseMaze(xPos + 2, yPos);
}
}
}
}
private bool IsValidDirection(int dir, int x, int y) {
if (dir == 0)
return IsValidPosition(x, y + 1) && IsValidPosition(x, y + 2); // up
if (dir == 1)
return IsValidPosition(x, y - 1) && IsValidPosition(x, y - 2); // down
if (dir == 2)
return IsValidPosition(x - 1, y) && IsValidPosition(x - 2, y); // left
if (dir == 3)
return IsValidPosition(x + 1, y) && IsValidPosition(x + 2, y); // right
return false;
bool IsValidPosition(int xPos, int yPos) {
return xPos >= 0 && xPos < mazeSize.x && yPos >= 0 && yPos < mazeSize.y && !maze[xPos, yPos];
}
}
private void OnDrawGizmos() {
if (!drawGizmos)
return;
if (maze == null)
GenerateMaze();
for (int x = 0; x < mazeSize.x; x++) {
for (int y = 0; y < mazeSize.y; y++) {
Vector2 offset = (Vector2)mazeSize / 2f;
if (x < 0 || x >= maze.GetLength(0) || y < 0 || y >= maze.GetLength(1))
Gizmos.color = Color.black;
else
Gizmos.color = maze[x, y] ? Color.white : Color.black;
Gizmos.DrawCube(new Vector2(x, y) - offset, Vector2.one);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment