using System;
using System.Collections.Generic;
using System.Text;
namespace 队列应用迷宫
{
class Program
{
static void Main(string[] args)
{
new mg(20, 20);
}
}
class node
{
public int x;//第一维坐标
public int y;//第二维坐标
public int pre;//到达该结点的前导结点在队列的序号,可依靠它得到路径
public node(int vx, int vy, int vpre)
{
x = vx;
y = vy;
pre = vpre;
}
}
class mg
{
node[] query;// 走迷宫时回溯队列
int[,] mgjm;// 迷宫界面二维数组
// 结点周围8个方向
int[] zx ={ -1, -1, 0, 1, 1, 1, 0, -1 };
int[] zy ={ 0, 1, 1, 1, 0, -1, -1, -1 };
public mg(int width, int height)
{
// 队列初始化
query = new node[(height-2)*(width-2)];
int front, rear;
front = rear = -1;
// 迷宫界面初始化
mgjm = new int[height, width];
Random rand = new Random();
for (int k = 0; k < height; k++)
{
for (int l = 0; l < width; l++)
{
if (k == 0 || k == height - 1 || l == 0 || l == width - 1)
{// 周围的墙壁
mgjm[k, l] = 1;
}
else
{// 随即生成空挡或墙壁
mgjm[k, l] = rand.Next(100) % 2;
}
}
}
// 保证开始点、结束点为空挡
mgjm[1, 1] = 0;
mgjm[height - 2, width - 2] = 0;
// 开始点入队列
query[++rear] = new node(1, 1, -1);
mgjm[1, 1] = 2;// 进入队列的点就已经来过了,变成2
int i;
while (front < rear)
{// 队列非空时循环
node nodeTmp = query[++front];// 出队列
for (i = 0; i < 8; i++)
{// 8个方向循环
int tmpx = nodeTmp.x + zx[i];
int tmpy = nodeTmp.y + zy[i];
if (mgjm[tmpx, tmpy] == 0)
{// 如果是空挡
query[++rear] = new node(tmpx, tmpy, front);// 入队列
mgjm[tmpx, tmpy] = 2;// 置为已来过
if (tmpx == height - 2 && tmpy == width - 2)
{// 已到达结束点
break;
}
}
}
if (i < 8)
{// 已到达结束点
break;
}
}
StringBuilder strB = new StringBuilder();
if (mgjm[height - 2, width - 2] == 2)
{// 到达过结束点
Console.WriteLine("yes");
// 拼接路径
strB.Append("(" + query[rear].x.ToString() + "," + query[rear].y.ToString() + ")");
int preNode = query[rear].pre;
while(preNode>=0)
{
strB.Append("|(" + query[preNode].x.ToString() + "," + query[preNode].y.ToString() + ")");
preNode = query[preNode].pre;
}
}
else
{// 无法到达结束点
Console.WriteLine("no");
}
// 打印迷宫
for (int m = 0; m < height; m++)
{
for (int n = 0; n < width; n++)
{
if (strB.ToString().IndexOf("(" + m.ToString() + "," + n.ToString() + ")") != -1)
{// 路径
Console.Write("* ");
}
else
{
Console.Write(mgjm[m, n].ToString() + " ");
}
}
Console.Write("/r/n");
}
// 打印路径坐标
string[] arrTmp = strB.ToString().Split('|');
for (int k = arrTmp.Length - 1; k >= 0; k--)
{
Console.Write(arrTmp[k] + "->");
}
Console.Write("/b/b ");
}
}
}