使用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;
}
}
}