迷宫导航时人工智能领域一个常见的问题,迷宫中有走廊和墙壁,机器人可以通过走廊,但不能闯过墙壁。
输入描述:
首先输入两个整数:M,N,分别表示迷宫的行数和列数,都必须小于等于60;
接下来输入M行,每行有N个字符,其中空格表示走廊,*表示墙壁,迷宫没有出口;
接下来输入两个整数,表示机器人的初始位置,初始时,机器人是朝北的。
最后一行是机器人收到的指令,用字符表示,可能包含空格,有效的命令字符及其含义如下:
R:顺时针旋转90度
L:逆时针旋转90度
F:往前移动一步,如果前方位置为墙壁,则不移动
Q:退出程序,指令序列的最后一个字符必须是Q
输出描述:
输出机器人最终的位置和朝向(N,W,S,E)
*/
#include<iostream>
using namespace std;
void Output(char a[][80],int m,int n); //显示迷宫样式
int main()
{
int m,n; //机器人的行和列
int i,j;
char a[80][80]={0};
cout<<"请输入迷宫的行和列数(少于60):";
cin>>m;
cin>>n;
//判断输入是否符合要求
while (1)
{
if (m>60 || n>60)
{
cout<<"请输入少于60的数,请重新输入迷宫行和列:";
cin>>m;
cin>>n;
}
else
{
break;
}
}
//输入迷宫样式
//迷宫无出口
cout<<"请输入迷宫样式元素(星号代表墙壁,空格代表走廊):"<<endl;
getchar();
for (i=1; i<=m; i++)
{
for (j=1; j<=n; j++)
{
a[i][j] = getchar();
}
getchar();
}
Output(a,m,n); //显示迷宫
int row,col; //机器人的开始坐标
char point[4] = {'N','E','S','W'}; //机器人面朝的四个方向 :北,东,南,西
int p = 0; //初始机器人朝北,p代表方向数组的下标
cout<<"请输入机器人的起始位置:";
cin>>row;
cin>>col;
//判断机器人开始在那个位置,如开始就在墙壁,则提示
while (1)
{
if (a[row][col] == '*' )
{
cout<<"机器人起始位置不能在墙壁中,请重新给机器人定位:";
cin>>row;
cin>>col;
}
else if(row<1 || col<1 || row>m || col>n) //如果超出迷宫范围
{
cout<<"机器人起始位置超出迷宫范围,请重新给机器人定位:"<<endl;
cin>>row;
cin>>col;
}
else
{
break;
}
}
//输入指令 让机器人活动
cout<<"机器人已经准备就绪,请给字符命令指示:"<<endl;
char b[100] = {0}; //保存输入的指令
int ncount = 0; //记录指令条数,一个字符为一条
while (1) //输入指令
{
b[ncount]=getchar();
if (b[ncount] == 'q' || b[ncount] == 'Q' )
{
break;
}
ncount++;
}
//遍历指令 记录机器人活动 上面的p代表方向数组下标
int ki,kj; //记录机器的位置 初始化为机器人起始位置
ki = row;
kj = col;
for (i=0; i<ncount; i++)
{
if (b[i] == 'R' || b[i] == 'r')
{
p++; //方向顺时针旋转90度
//cout<<p<<endl;
}
else if (b[i] == 'L' || b[i] == 'l')
{
p--; //方向逆时针旋转90度
}
else if (b[i] == 'f' || b[i] == 'F') //向前进一步,首先判断其方向
{
if( (p+4)%4 == 0) //方向为北 取模的技巧使得p的值总会是(0,1,2,3)
{
if (a[--ki][kj] == '*' ) //如果向前一步为墙壁,则不移动 ,但此时ki已经减1了,所以else部分的ki就不要加了,后同
{
ki ++;
kj = kj;
}
else
{
ki = ki; //行纵坐标往上移1 上面if已经做了
kj = kj; //列坐标不变
}
}
else if( (p+4)%4 == 1) //方向为东
{
if (a[ki][++kj] == '*' ) //如果向前一步为墙壁,则不移动
{
ki = ki;
kj --;
}
else
{
ki = ki; //列坐标不变
kj = kj; //行纵坐标往右移1 上面if做了
}
}
else if( (p+4)%4 == 2) //方向为南
{
if (a[++ki][kj] == '*' ) //如果向前一步为墙壁,则不移动
{
ki --;
kj = kj;
}
else
{
ki = ki; //列坐标不变
kj =kj; //行纵坐标往下移1
}
}
else if( (p+4)%4 == 3) //方向为西
{
if (a[ki][--kj] == '*' ) //如果向前一步为墙壁,则不移动
{
ki = ki;
kj ++;
}
else
{
ki = ki; //行纵坐标不变
kj = kj; // 列坐标 左移1
}
}
}
else //其它无效字符不处理
{
continue;
}
}
p = (p+4)%4; //取模让p在 (0-3)之间
cout<<"当前机器人的坐标位置为:("<<ki<<","<<kj<<") 方向为:"<<point[p]<<endl;
system("pause");
return 0;
}
void Output(char a[][80],int m,int n) //显示迷宫样式
{
int i,j;
cout<<"迷宫模式如下:"<<endl<<endl;
for (i=1; i<=m; i++)
{
for (j=1; j<=n; j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}