Advertisement
Guest User

Maze.cs

a guest
Dec 1st, 2016
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.15 KB | None | 0 0
  1.  
  2. Maze.cs
  3. using System;
  4. using System.Collections;
  5. using System.Drawing;
  6. using System.Threading;
  7.  
  8. /*
  9. * create a CellStack (LIFO) to hold a list of cell locations
  10. set TotalCells = number of cells in grid
  11. choose a cell at random and call it CurrentCell
  12. set VisitedCells = 1
  13.  
  14. while VisitedCells < TotalCells
  15. find all neighbors of CurrentCell with all walls intact
  16. if one or more found
  17. choose one at random
  18. knock down the wall between it and CurrentCell
  19. push CurrentCell location on the CellStack
  20. make the new cell CurrentCell
  21. add 1 to VisitedCells
  22. else
  23. pop the most recent cell entry off the CellStack
  24. make it CurrentCell
  25. endIf
  26. endWhile
  27. */
  28.  
  29. namespace MazeSolution
  30. {
  31. /// <summary>
  32. /// Summary description for Maze.
  33. /// </summary>
  34. public class Maze
  35. {
  36. public static int kDimension = 20;
  37. Cell[][] Cells = null;
  38. Stack CellStack = new Stack();
  39. int VisitedCells = 1;
  40. int TotalCells = kDimension * kDimension;
  41. Cell CurrentCell = null;
  42.  
  43. // A delegate type for hooking up completion notifications.
  44. public delegate void MazeEventHandler(object sender, EventArgs e);
  45.  
  46. public event MazeEventHandler MazeSolutionComplete;
  47.  
  48. public Maze()
  49. {
  50. Initialize();
  51. }
  52.  
  53. private ArrayList GetNeighborsWithWalls(Cell aCell)
  54. {
  55. ArrayList Neighbors = new ArrayList();
  56. //int count = 0;
  57. for (int countRow = -1; countRow <= 1; countRow++)
  58. for (int countCol = -1; countCol <= 1; countCol++)
  59. {
  60. if ( (aCell.Row + countRow < kDimension) &&
  61. (aCell.Column+countCol < kDimension) &&
  62. (aCell.Row+countRow >= 0) &&
  63. (aCell.Column+countCol >= 0) &&
  64. ((countCol == 0) || (countRow == 0)) &&
  65. (countRow != countCol)
  66. )
  67. {
  68. if (Cells[aCell.Row+countRow][aCell.Column+countCol].HasAllWalls())
  69. {
  70. Neighbors.Add( Cells[aCell.Row+countRow][aCell.Column+countCol]);
  71. }
  72. }
  73. }
  74.  
  75. return Neighbors;
  76. }
  77.  
  78. public void Initialize()
  79. {
  80. Cells = new Cell[kDimension][];
  81. TotalCells = kDimension * kDimension;
  82. for (int i = 0; i < kDimension; i++)
  83. {
  84. Cells[i] = new Cell[kDimension];
  85. for (int j = 0; j < kDimension; j++)
  86. {
  87. Cells[i][j] = new Cell();
  88. Cells[i][j].Row = i;
  89. Cells[i][j].Column = j;
  90. }
  91. }
  92.  
  93. CurrentCell = Cells[0][0];
  94. VisitedCells = 1;
  95. CellStack.Clear();
  96.  
  97. }
  98.  
  99. public void Generate()
  100. {
  101. while (VisitedCells < TotalCells)
  102. {
  103. // get a list of the neighboring cells with all walls intact
  104. ArrayList AdjacentCells = GetNeighborsWithWalls(CurrentCell);
  105. // test if a cell like this exists
  106. if (AdjacentCells.Count > 0)
  107. {
  108. // yes, choose one of them, and knock down the wall between it and the current cell
  109. int randomCell = Cell.TheRandom.Next(0, AdjacentCells.Count);
  110. Cell theCell = ((Cell)AdjacentCells[randomCell]);
  111. CurrentCell.KnockDownWall(theCell);
  112. CellStack.Push(CurrentCell); // push the current cell onto the stack
  113. CurrentCell = theCell; // make the random neighbor the new current cell
  114. VisitedCells++;
  115. }
  116. else
  117. {
  118. // No cells with walls intact, pop current cell from stack
  119. CurrentCell = (Cell)CellStack.Pop();
  120. }
  121.  
  122. }
  123.  
  124. // Show the entry and exit
  125. Cells[0][0].Walls[0] = 0;
  126. Cells[kDimension-1][kDimension-1].Walls[3] = 0;
  127.  
  128. }
  129.  
  130. public void SolveIt( Cell.CellState cellState )
  131. {
  132. bool steadyState = true;
  133.  
  134. // Loop through the maze, with each pass blocking off more and more
  135. // dead ends until steadyState = true.
  136. do
  137. {
  138. steadyState = true;
  139.  
  140. for( int i=0; i<kDimension; i++ )
  141. {
  142. for( int j=0; j<kDimension; j++ )
  143. {
  144. if( Cells[i][j].cellState == Cell.CellState.FREE )
  145. {
  146. if ( !IsFree(i,j) )
  147. {
  148. Cells[i][j].cellState = cellState;
  149. steadyState = false;
  150. }
  151. }
  152. }
  153. Thread.Sleep(0);
  154. }
  155. } while( !steadyState );
  156. }
  157.  
  158. public void SolveItBackward( Cell.CellState cellState )
  159. {
  160. bool steadyState = true;
  161.  
  162. // Loop backward through the maze, with each pass blocking off more and more
  163. // dead ends until steadyState = true.
  164. do
  165. {
  166. steadyState = true;
  167.  
  168. for( int i=kDimension-1; i>=0; i-- )
  169. {
  170. for( int j=kDimension-1; j>=0; j-- )
  171. {
  172. if( Cells[i][j].cellState == Cell.CellState.FREE )
  173. {
  174. if ( !IsFree(i,j) )
  175. {
  176. Cells[i][j].cellState = cellState;
  177. steadyState = false;
  178. }
  179. }
  180. }
  181. Thread.Sleep(0);
  182. }
  183. } while( !steadyState );
  184. }
  185.  
  186. // Each solution method just uses a different wall type
  187. // which is drawn in a different color so that we can
  188. // see each threads progress. When complete, the event
  189. // MazeSolutionComplete is raised.
  190. public void SolveA()
  191. {
  192. SolveIt( Cell.CellState.WALLA );
  193. MazeSolutionComplete( this, EventArgs.Empty );
  194. }
  195.  
  196. public void SolveB()
  197. {
  198. SolveItBackward( Cell.CellState.WALLB );
  199. MazeSolutionComplete( this, EventArgs.Empty );
  200. }
  201.  
  202. public void SolveC()
  203. {
  204. SolveIt( Cell.CellState.WALLC );
  205. MazeSolutionComplete( this, EventArgs.Empty );
  206. }
  207.  
  208. public void SolveD()
  209. {
  210. SolveItBackward( Cell.CellState.WALLD );
  211. MazeSolutionComplete( this, EventArgs.Empty );
  212. }
  213.  
  214. public void SolveE()
  215. {
  216. SolveIt( Cell.CellState.WALLE );
  217. MazeSolutionComplete( this, EventArgs.Empty );
  218. }
  219.  
  220. public void SolveF()
  221. {
  222. SolveItBackward( Cell.CellState.WALLF );
  223. MazeSolutionComplete( this, EventArgs.Empty );
  224. }
  225.  
  226. public void SolveG()
  227. {
  228. SolveIt( Cell.CellState.WALLG );
  229. MazeSolutionComplete( this, EventArgs.Empty );
  230. }
  231.  
  232. public void SolveH()
  233. {
  234. SolveItBackward( Cell.CellState.WALLH );
  235. MazeSolutionComplete( this, EventArgs.Empty );
  236. }
  237.  
  238. public void SolveI()
  239. {
  240. SolveIt( Cell.CellState.WALLI );
  241. MazeSolutionComplete( this, EventArgs.Empty );
  242. }
  243.  
  244. public void SolveJ()
  245. {
  246. SolveItBackward( Cell.CellState.WALLJ );
  247. MazeSolutionComplete( this, EventArgs.Empty );
  248. }
  249.  
  250. public void SolveK()
  251. {
  252. SolveIt( Cell.CellState.WALLK );
  253. MazeSolutionComplete( this, EventArgs.Empty );
  254. }
  255.  
  256. public void SolveL()
  257. {
  258. SolveItBackward( Cell.CellState.WALLL );
  259. MazeSolutionComplete( this, EventArgs.Empty );
  260. }
  261.  
  262. public void SolveM()
  263. {
  264. SolveIt( Cell.CellState.WALLM );
  265. MazeSolutionComplete( this, EventArgs.Empty );
  266. }
  267.  
  268. public void SolveN()
  269. {
  270. SolveItBackward( Cell.CellState.WALLN );
  271. MazeSolutionComplete( this, EventArgs.Empty );
  272. }
  273.  
  274. public void SolveO()
  275. {
  276. SolveIt( Cell.CellState.WALLO );
  277. MazeSolutionComplete( this, EventArgs.Empty );
  278. }
  279.  
  280. public void SolveP()
  281. {
  282. SolveItBackward( Cell.CellState.WALLP );
  283. MazeSolutionComplete( this, EventArgs.Empty );
  284. }
  285.  
  286. /// <summary>
  287. /// This is the key to solving the maze. If a cell isn't free, block it off.
  288. /// We determine whether it is free by examining its walls and the free state
  289. /// of all neighboring cells.
  290. /// </summary>
  291. /// <param name="x"></param>
  292. /// <param name="y"></param>
  293. /// <returns></returns>
  294. private bool IsFree( int x, int y )
  295. {
  296. int walls = 0;
  297.  
  298. if( Cells[x][y].Walls[0] == 1 )
  299. walls ++;
  300. else if( y > 0 && ((int)Cells[x][y-1].cellState > (int)Cell.CellState.FREE ))
  301. walls++;
  302.  
  303. if( Cells[x][y].Walls[1] == 1 )
  304. walls ++;
  305. else if( x > 0 && ((int)Cells[x-1][y].cellState > (int)Cell.CellState.FREE ))
  306. walls++;
  307.  
  308. if( Cells[x][y].Walls[2] == 1 )
  309. walls ++;
  310. else if( y < kDimension-1 && ((int)Cells[x][y+1].cellState > (int)Cell.CellState.FREE ))
  311. walls++;
  312.  
  313. if( Cells[x][y].Walls[3] == 1 )
  314. walls ++;
  315. else if( x < kDimension-1 && ((int)Cells[x+1][y].cellState > (int)Cell.CellState.FREE ))
  316. walls++;
  317.  
  318. return (walls < 3);
  319. }
  320.  
  321. public void Draw(Graphics g)
  322. {
  323. for (int i = 0; i < kDimension; i++)
  324. for (int j = 0; j < kDimension; j++)
  325. {
  326. Cells[i][j].Draw(g);
  327. }
  328. }
  329.  
  330. public void Reset()
  331. {
  332. for (int i = 0; i < kDimension; i++)
  333. for (int j = 0; j < kDimension; j++)
  334. {
  335. Cells[i][j].cellState = Cell.CellState.FREE;
  336. }
  337. }
  338.  
  339.  
  340.  
  341. }
  342. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement