C#编写简单的迷宫游戏

使用DFS生成迷宫。

using System;
using System.Threading;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace GameApplication {
	class Map {
		private char shapeBegin = '*', shapeEnd = '!';
		private int size, unit;
		private (int x, int y)[] move = new (int x, int y)[] {(-1, 0), (1, 0), (0, -1), (0, 1)};
		private char[,] canvas;
		private bool[,] visited;
// public:
		public void DrawGameActor((int x, int y) position, char ch) {
			canvas[position.x, position.y] = ch;
			return;
		}

		public bool Passable((int x, int y) U) {
			return canvas[U.x, U.y] == ' ' || canvas[U.x, U.y] == shapeEnd;
		}

		public int Unit() {
			return unit;
		}

		public int Size() {
			return size;
		}

		public char ShapeEnd() {
			return shapeEnd;
		}

		public bool SetMapUnit(String str) {
			if (Regex.IsMatch(str, "\\A[0-9]+\\Z")) {
				unit = Convert.ToInt32(str);
				if (unit <= 1)
					return false;
				else
					return true;
			}
			else
				return false;
		}

		public void Generate() {
			InitMap();

			(int x, int y) U = (0, 0);
			visited[U.x, U.y] = true;
			canvas[1, 1] = ' ';

			DFS(U, 1);
			return;
		}

		public void Print() {
			for (int i = 0; i < size; i++) {
				for (int j = 0; j < size; j++)
					Console.Write("{0} ", canvas[i, j]);
				Console.Write('\n');
			}
			return;
		}
// private:
		private void InitMap() {
			size = 2*unit + 1;
			visited = new bool[unit, unit];

			for (int i = 0; i < unit; i++)
				for (int j = 0; j < unit; j++)
					visited[i, j] = false;

			canvas = new char[size, size];
			for (int i = 0; i < size; i++)
				for (int j = 0; j < size; j++)
					canvas[i, j] = shapeBegin;
			return;
		}

		private int ConvertUnit(int _unit) {
			return 2*_unit + 1;
		}

		private bool InMap(int _x, int _y) {
			return 0 <= _x && _x < unit && 0 <= _y && _y < unit;
		}

		private void Connect((int x, int y) U, (int x, int y) _U) {
			canvas[_U.x*2+1, _U.y*2+1] = canvas[(U.x+_U.x)+1, (U.y+_U.y)+1] = ' ';
			return;
		}

		private int CountNeighbourVisited((int x, int y)U) {
			int cnt = 0;
			for (int i = 0; i < 4; i++)
				if (InMap(U.x+move[i].x, U.y+move[i].y)) {
					if (visited[U.x+move[i].x, U.y+move[i].y])
						cnt++;
				}
				else
					cnt++;
			return cnt;
		}

		private void DFS((int x, int y)U, int cnt) {
			if (CountNeighbourVisited(U) == 4)
				return;

			int _cnt = 0;
			bool[] calculated = new bool[] {false, false, false, false};
			Random rand = new Random((int)DateTime.Now.Ticks);
			while (_cnt < 4) {
				int _i = -1;
				while (_i==-1 || calculated[_i]) {
					_i = rand.Next(0, 4);
					Thread.Sleep(2);
				}
				(int x, int y) _U = (U.x + move[_i].x, U.y + move[_i].y);	
				if (InMap(_U.x, _U.y)) {
					if (!visited[_U.x, _U.y]) {
						visited[_U.x, _U.y] = true;
						Connect(U, _U);
						DFS(_U, cnt+1);
						calculated[_i] = true;
						_cnt++;
						if (CountNeighbourVisited(U) == 4)
							return;
					}
				}
			}
			return;
		}
	}

	class GameActor {
		private (int x, int y) position, target;
		private (int x, int y)[] move;
// public:
		public GameActor() {
			position = (1, 1);
			target = (-1, -1);
			move = new (int x, int y)[] {(-1, 0), (1, 0), (0, -1), (0, 1)};
		}

		public void SetTarget(ref Map map) {
			target.x = target.y = map.Size() - 2;
			map.DrawGameActor(target, map.ShapeEnd());
			return;
		}

		public (int x, int y) Position() {
			return position;
		}

		public (int x, int y) Target() {
			return target;
		}

		public void SetGameActor(ref Map map, char ch) {
			map.DrawGameActor(position, ch);
			return;
		}

		public void Move(ref Map map, int direc) {
			if (direc == -1)
				return;
			(int x, int y) next = (position.x+move[direc].x, position.y+move[direc].y);
			if (InMap(ref map, next) && map.Passable(next)) {
				position.x += move[direc].x;
				position.y += move[direc].y;
			}
			return;
		}
// private:
		private bool InMap(ref Map map, (int x, int y) U) {
			return 0 <= U.x && U.x < map.Size() && 0 <= U.y && U.y < map.Size();
		}
	}

	class Game {
		public bool checkWin(ref GameActor gameActor) {
			return gameActor.Position().x == gameActor.Target().x && gameActor.Position().y == gameActor.Target().y;
		}

		public int GetDirection(ConsoleKeyInfo key) {
            if (key.Key == ConsoleKey.UpArrow || key.Key == ConsoleKey.W)
	            return 0;
	        else if (key.Key == ConsoleKey.DownArrow || key.Key == ConsoleKey.S)
	        	return 1;
	        else if (key.Key == ConsoleKey.LeftArrow || key.Key == ConsoleKey.A)
	        	return 2;
	        else if (key.Key == ConsoleKey.RightArrow || key.Key == ConsoleKey.D)
	        	return 3;
	        else
	        	return -1;
        }

        public void Run() {
        	Map map = new Map();
			GameActor gameActor = new GameActor();

			Console.WriteLine("请输入地图尺寸:");
			while (!map.SetMapUnit(Console.ReadLine())) {
				Console.Clear();
				Console.WriteLine("输入无效。\n请输入地图尺寸:");
			}
			Console.WriteLine("请稍等\n地图生成中...");
			map.Generate();
			gameActor.SetTarget(ref map);

			Console.Clear();
			gameActor.SetGameActor(ref map, '+');
			map.Print();
			gameActor.SetGameActor(ref map, ' ');

			while (!checkWin(ref gameActor)) {
				gameActor.Move(ref map, GetDirection(Console.ReadKey()));
				Console.Clear();
				gameActor.SetGameActor(ref map, '+');
				map.Print();
				gameActor.SetGameActor(ref map, ' ');
			}

			Console.WriteLine("\n通关!");
			return;
        }

	}

	class GameApplication {
		static public bool EndGame(ConsoleKeyInfo key) {
            return key.Key == ConsoleKey.N;
        }

		static void Main() {
			Game game = new Game();
			while (true) {
				Console.Clear();
				game.Run();

				Console.WriteLine("再来一次? (Y/N)");
				ConsoleKeyInfo key = Console.ReadKey();
				while (key.Key != ConsoleKey.Y && key.Key != ConsoleKey.N)
					key = Console.ReadKey();
				if (EndGame(key))
					break;
			}

			Console.WriteLine("\b请按任意键继续...");
			Console.ReadKey();
			return;
		}
	}
}

 

你可能感兴趣的:(Games,游戏,c#)