迷宮導航時人工智慧領域一個常見的問題,迷宮中有走廊和牆壁,機器人可以通過走廊,但不能闖過牆壁。
輸入描述:
首先輸入兩個整數: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;
}
}