⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 maze.cs

📁 迷宫游戏源码
💻 CS
字号:
using System;
using System.Collections;
using System.Drawing;
using System.Threading;

/*
 * create a CellStack (LIFO) to hold a list of cell locations  
set TotalCells = number of cells in grid  
choose a cell at random and call it CurrentCell  
set VisitedCells = 1  
   
while VisitedCells < TotalCells  
find all neighbors of CurrentCell with all walls intact   
if one or more found  
choose one at random  
knock down the wall between it and CurrentCell  
push CurrentCell location on the CellStack  
make the new cell CurrentCell  
add 1 to VisitedCells 
else  
pop the most recent cell entry off the CellStack  
make it CurrentCell 
endIf 
endWhile  
*/

namespace MazeSolution
{
	/// <summary>
	/// Summary description for Maze.
	/// </summary>
	public class Maze
	{
		public static int kDimension = 100;
		Cell[][] Cells = null;
		Stack CellStack = new Stack();
		int VisitedCells = 1;
		int TotalCells = kDimension * kDimension;
		Cell CurrentCell = null;

		// A delegate type for hooking up completion notifications.
		public delegate void MazeEventHandler(object sender, EventArgs e);
		
		public event MazeEventHandler MazeSolutionComplete;

		public Maze()
		{
			Initialize();
		}

		private ArrayList GetNeighborsWithWalls(Cell aCell)
		{
			ArrayList Neighbors = new ArrayList();
			//int count = 0;
			for (int countRow = -1; countRow <= 1; countRow++)
				for (int countCol = -1; countCol <= 1; countCol++)
				{
					if ( (aCell.Row + countRow < kDimension) &&  
						 (aCell.Column+countCol < kDimension) &&
						 (aCell.Row+countRow >= 0) &&
						 (aCell.Column+countCol >= 0) &&
						 ((countCol == 0) || (countRow == 0)) &&
						 (countRow != countCol)
						)
					{
						if (Cells[aCell.Row+countRow][aCell.Column+countCol].HasAllWalls())
						{
							Neighbors.Add( Cells[aCell.Row+countRow][aCell.Column+countCol]);
						}
					}
				}

			return Neighbors;
		}

		public void Initialize()
		{
			Cells = new Cell[kDimension][];
			TotalCells = kDimension * kDimension;
			for (int i = 0; i < kDimension; i++)
			{
				Cells[i] = new Cell[kDimension];
				for (int j = 0; j < kDimension; j++)
				{
					Cells[i][j] =  new Cell();
					Cells[i][j].Row = i;
					Cells[i][j].Column = j;
				}
			}

			CurrentCell = Cells[0][0];
			VisitedCells = 1;
			CellStack.Clear();

		}

		public void  Generate()
		{
			while (VisitedCells < TotalCells)
			{
				// get a list of the neighboring cells with all walls intact
				ArrayList AdjacentCells = GetNeighborsWithWalls(CurrentCell);
				// test if a cell like this exists
				if (AdjacentCells.Count > 0)
				{
					// yes, choose one of them, and knock down the wall between it and the current cell
					int randomCell = Cell.TheRandom.Next(0, AdjacentCells.Count);
					Cell theCell = ((Cell)AdjacentCells[randomCell]);
					CurrentCell.KnockDownWall(theCell);
					CellStack.Push(CurrentCell); // push the current cell onto the stack
					CurrentCell = theCell; // make the random neighbor the new current cell
					VisitedCells++;
				}
				else
				{
					// No cells with walls intact, pop current cell from stack
					CurrentCell = (Cell)CellStack.Pop();
				}

			}

			// Show the entry and exit
			Cells[0][0].Walls[0] = 0;
			Cells[kDimension-1][kDimension-1].Walls[3] = 0;

		}

		public void SolveIt( Cell.CellState cellState )
		{
			bool steadyState = true;

			// Loop through the maze, with each pass blocking off more and more
			// dead ends until steadyState = true.
			do
			{
				steadyState = true;
				
				for( int i=0; i<kDimension; i++ )
				{
					for( int j=0; j<kDimension; j++ )
					{
						if( Cells[i][j].cellState == Cell.CellState.FREE )
						{
							if ( !IsFree(i,j) ) 
							{
								Cells[i][j].cellState = cellState;
								steadyState = false;
							}
						}
					}
					Thread.Sleep(0);
				}
			} while( !steadyState );
		}

		public void SolveItBackward( Cell.CellState cellState )
		{
			bool steadyState = true;

			// Loop backward through the maze, with each pass blocking off more and more
			// dead ends until steadyState = true.
			do
			{
				steadyState = true;
				
				for( int i=kDimension-1; i>=0; i-- )
				{
					for( int j=kDimension-1; j>=0; j-- )
					{
						if( Cells[i][j].cellState == Cell.CellState.FREE )
						{
							if ( !IsFree(i,j) ) 
							{
								Cells[i][j].cellState = cellState;
								steadyState = false;
							}
						}
					}
					Thread.Sleep(0);
				}
			} while( !steadyState );
		}

		// Each solution method just uses a different wall type
		// which is drawn in a different color so that we can
		// see each threads progress.  When complete, the event
		// MazeSolutionComplete is raised.
		public void SolveA()
		{
			SolveIt( Cell.CellState.WALLA );
			MazeSolutionComplete( this, EventArgs.Empty );
		}

		public void SolveB()
		{
			SolveItBackward( Cell.CellState.WALLB );
			MazeSolutionComplete( this, EventArgs.Empty );
		}

		public void SolveC()
		{
			SolveIt( Cell.CellState.WALLC );
			MazeSolutionComplete( this, EventArgs.Empty );
		}

		public void SolveD()
		{
			SolveItBackward( Cell.CellState.WALLD );
			MazeSolutionComplete( this, EventArgs.Empty );
		}

		public void SolveE()
		{
			SolveIt( Cell.CellState.WALLE );
			MazeSolutionComplete( this, EventArgs.Empty );
		}

		public void SolveF()
		{
			SolveItBackward( Cell.CellState.WALLF );
			MazeSolutionComplete( this, EventArgs.Empty );
		}

		public void SolveG()
		{
			SolveIt( Cell.CellState.WALLG );
			MazeSolutionComplete( this, EventArgs.Empty );
		}

		public void SolveH()
		{
			SolveItBackward( Cell.CellState.WALLH );
			MazeSolutionComplete( this, EventArgs.Empty );
		}

		public void SolveI()
		{
			SolveIt( Cell.CellState.WALLI );
			MazeSolutionComplete( this, EventArgs.Empty );
		}

		public void SolveJ()
		{
			SolveItBackward( Cell.CellState.WALLJ );
			MazeSolutionComplete( this, EventArgs.Empty );
		}

		public void SolveK()
		{
			SolveIt( Cell.CellState.WALLK );
			MazeSolutionComplete( this, EventArgs.Empty );
		}

		public void SolveL()
		{
			SolveItBackward( Cell.CellState.WALLL );
			MazeSolutionComplete( this, EventArgs.Empty );
		}

		public void SolveM()
		{
			SolveIt( Cell.CellState.WALLM );
			MazeSolutionComplete( this, EventArgs.Empty );
		}

		public void SolveN()
		{
			SolveItBackward( Cell.CellState.WALLN );
			MazeSolutionComplete( this, EventArgs.Empty );
		}

		public void SolveO()
		{
			SolveIt( Cell.CellState.WALLO );
			MazeSolutionComplete( this, EventArgs.Empty );
		}

		public void SolveP()
		{
			SolveItBackward( Cell.CellState.WALLP );
			MazeSolutionComplete( this, EventArgs.Empty );
		}

		/// <summary>
		/// This is the key to solving the maze.  If a cell isn't free, block it off.
		/// We determine whether it is free by examining its walls and the free state
		/// of all neighboring cells.
		/// </summary>
		/// <param name="x"></param>
		/// <param name="y"></param>
		/// <returns></returns>
		private bool IsFree( int x, int y )
		{
			int walls = 0;

			if( Cells[x][y].Walls[0] == 1 )
				walls ++;
			else if( y > 0 && ((int)Cells[x][y-1].cellState > (int)Cell.CellState.FREE ))
				walls++;

			if( Cells[x][y].Walls[1] == 1 )
				walls ++;
			else if( x > 0 && ((int)Cells[x-1][y].cellState > (int)Cell.CellState.FREE ))
				walls++;

			if( Cells[x][y].Walls[2] == 1 )
				walls ++;
			else if( y < kDimension-1 && ((int)Cells[x][y+1].cellState  > (int)Cell.CellState.FREE ))
				walls++;

			if( Cells[x][y].Walls[3] == 1 )
				walls ++;
			else if( x < kDimension-1 && ((int)Cells[x+1][y].cellState  > (int)Cell.CellState.FREE ))
				walls++;
			
			return (walls < 3);
		}

		public void Draw(Graphics g)
		{
			for (int i = 0; i < kDimension; i++)
				for (int j = 0; j < kDimension; j++)
				{
					Cells[i][j].Draw(g);
				}
		}

		public void Reset()
		{
			for (int i = 0; i < kDimension; i++)
				for (int j = 0; j < kDimension; j++)
				{
					Cells[i][j].cellState = Cell.CellState.FREE;
				}
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -