Last active
August 29, 2015 14:12
-
-
Save JonRurka/962b789113352a45a1e6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Maze | |
{ | |
public enum Direction | |
{ | |
N = 1, | |
W = 2 | |
} | |
Stack s_stack; | |
Random rand; | |
public int MSIZEX; | |
public int MSIZEY; | |
public int[] maze_base; | |
public byte[,] maze_data; | |
private int iSmooth; | |
#region Generating | |
public void GenerateMaze(int sizeX, int sizeY, int seed, int smoothness) | |
{ | |
iSmooth = smoothness; | |
MSIZEX = sizeX; | |
MSIZEY = sizeY; | |
maze_base = new int[MSIZEX * MSIZEY]; | |
maze_data = new Byte[MSIZEX, MSIZEY]; | |
s_stack = new Stack(); | |
rand = new Random(seed); | |
MazeInit(rand); | |
cMazeState state = new cMazeState(rand.Next() % MSIZEX, rand.Next() % MSIZEY, 0); | |
analyze_cell(state, rand); | |
} | |
void analyze_cell(cMazeState s, Random r) | |
{ | |
bool bEnd = false, found; | |
int indexSrc, indexDest, tDir = 0, prevDir = 0; | |
while (true) | |
{ | |
if (s.dir == 15) | |
{ | |
while (s.dir == 15) | |
{ | |
s = (cMazeState)s_stack.pop(); | |
if (s == null) | |
{ | |
bEnd = true; | |
break; | |
} | |
} | |
if (bEnd == true) break; | |
} | |
else | |
{ | |
do | |
{ | |
prevDir = tDir; | |
tDir = (int)System.Math.Pow(2, r.Next() % 4); | |
if ((r.Next() % 32) < iSmooth) | |
if ((s.dir & prevDir) == 0) | |
tDir = prevDir; | |
if ((s.dir & tDir) != 0) | |
found = true; | |
else | |
found = false; | |
} while (found == true && s.dir != 15); | |
s.dir |= tDir; | |
indexSrc = cell_index(s.x, s.y); | |
// direction W | |
if (tDir == 1 && s.x > 0) | |
{ | |
indexDest = cell_index(s.x - 1, s.y); | |
if (base_cell(indexSrc) != base_cell(indexDest)) | |
{ | |
merge(indexSrc, indexDest); | |
maze_data[s.x, s.y] |= (byte)Direction.W; | |
s_stack.push(new cMazeState(s)); | |
s.x -= 1; s.dir = 0; | |
} | |
} | |
// direction E | |
if (tDir == 2 && s.x < MSIZEX - 1) | |
{ | |
indexDest = cell_index(s.x + 1, s.y); | |
if (base_cell(indexSrc) != base_cell(indexDest)) | |
{ | |
merge(indexSrc, indexDest); | |
maze_data[s.x + 1, s.y] |= (byte)Direction.W; | |
s_stack.push(new cMazeState(s)); | |
s.x += 1; s.dir = 0; | |
} | |
} | |
// direction N | |
if (tDir == 4 && s.y > 0) | |
{ | |
indexDest = cell_index(s.x, s.y - 1); | |
if (base_cell(indexSrc) != base_cell(indexDest)) | |
{ | |
merge(indexSrc, indexDest); | |
maze_data[s.x, s.y] |= (byte)Direction.N; | |
s_stack.push(new cMazeState(s)); | |
s.y -= 1; s.dir = 0; | |
} | |
} | |
// direction S | |
if (tDir == 8 && s.y < MSIZEY - 1) | |
{ | |
indexDest = cell_index(s.x, s.y + 1); | |
if (base_cell(indexSrc) != base_cell(indexDest)) | |
{ | |
merge(indexSrc, indexDest); | |
maze_data[s.x, s.y + 1] |= (byte)Direction.N; | |
s_stack.push(new cMazeState(s)); | |
s.y += 1; s.dir = 0; | |
} | |
} | |
} // else | |
} // while | |
} // function | |
#endregion | |
#region Bitmap | |
public Bitmap GetBitmap(int xS, int yS) | |
{ | |
int i, j; | |
Bitmap tB = new Bitmap(xS + 1, yS + 1); | |
Graphics g = Graphics.FromImage((Image)tB); | |
Brush w = Brushes.White; | |
Brush b = Brushes.Black; | |
Pen bp = new Pen(b, 1); | |
// background | |
g.FillRectangle(w, 0, 0, tB.Width - 1, tB.Height - 1); | |
g.DrawRectangle(bp, 0, 0, tB.Width - 1, tB.Height - 1); | |
int xSize = xS / MSIZEX; | |
int ySize = yS / MSIZEY; | |
for (i = 0; i < MSIZEX; i++) | |
for (j = 0; j < MSIZEY; j++) | |
{ | |
// inspect the maze | |
if ((maze_data[i, j] & (byte)Direction.N) == 0) | |
g.DrawLine(bp, | |
new Point(xSize * i, ySize * j), | |
new Point(xSize * (i + 1), ySize * j)); | |
if ((maze_data[i, j] & (byte)Direction.W) == 0) | |
g.DrawLine(bp, | |
new Point(xSize * i, ySize * j), | |
new Point(xSize * i, ySize * (j + 1))); | |
} | |
// start & end | |
g.DrawLine(bp, 0, 0, xSize, 0); | |
g.DrawLine(bp, 0, 0, 0, xSize); | |
g.DrawLine(bp, xS, yS, xS - xSize, yS); | |
g.DrawLine(bp, xS, yS, xS, yS - ySize); | |
g.Dispose(); | |
return tB; | |
} | |
#endregion | |
#region Cell functions | |
int cell_index(int x, int y) | |
{ | |
return MSIZEX * y + x; | |
} | |
int base_cell(int tIndex) | |
{ | |
int index = tIndex; | |
while (maze_base[index] >= 0) | |
{ | |
index = maze_base[index]; | |
} | |
return index; | |
} | |
void merge(int index1, int index2) | |
{ | |
// merge both lists | |
int base1 = base_cell(index1); | |
int base2 = base_cell(index2); | |
maze_base[base2] = base1; | |
} | |
#endregion | |
#region MazeInit | |
void MazeInit(Random r) | |
{ | |
int i, j; | |
// maze data | |
for (i = 0; i < MSIZEX; i++) | |
for (j = 0; j < MSIZEY; j++) | |
{ | |
maze_base[cell_index(i, j)] = -1; | |
maze_data[i, j] = 0; | |
} | |
} | |
#endregion | |
} | |
ublic class cMazeState | |
{ | |
public int x, y, dir; | |
public cMazeState(int tx, int ty, int td) { x = tx; y = ty; dir = td; } | |
public cMazeState(cMazeState s) { x = s.x; y = s.y; dir = s.dir; } | |
} | |
public class cCellPosition | |
{ | |
public int x, y; | |
public cCellPosition() { } | |
public cCellPosition(int xp, int yp) { x = xp; y = yp; } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment