[問題] 用 recursive 作闖迷宮的設定 求神支援

作者: lalawolala (太陽底下無新鮮事)   2014-05-01 07:33:43
開發平台(Platform): (Ex: VC++, GCC, Linux, ...)
VC2012
額外使用到的函數庫(Library Used): (Ex: OpenGL, ...)
問題(Question):
各位大大好 小弟剛學C++ 不久 實在是想不出來腦細胞死太多來請求神手支援了><
題目是要用 recursive 來解老鼠闖迷宮的問題 下面就是一開始的迷宮設定
是一個 data.txt 文件檔 首先把這個迷宮的文件檔 讀進我設定的 array 裡面
光這個就google好久才知道怎麼設定 dynamic 的二次陣列 這地圖上'e'代表出口
一開始的起始點是'm' 我式設定成 char 的二次陣列 另外設定了一個 class cell
裡面 private: int x, y; 是要代表座標軸位置用的 我總共宣告了三個 object cell
一個是 entry 起點 一個是 exit 出口 還有一個 current 目前位置 照我原本想的是
從起點開始檢察 current 的座標位置 相對應的 array maze[x][y] 如果剛好跟 exit
的座標未置一樣 就代表有通路連到出口(結束) 如果不同的話 就檢查東西南北四個方
位在迷宮裡是 1 還是 0 ,利用 current 裡的 x,y 坐標軸的加減來繞地圖找出通路 
可是實在不知道怎麼正確的設定好這個 recursive ..... 怎麼跑都會失敗 
應該說是根本就被強迫結束程式...超級灰心的 
我想了好幾天了也上網查了好久 但是一直沒有靈感 希望有大大能救救我><
!經過 K 大指點 目前已經可以把條件設定成 每經過一個座標就把它改成一個 '.'
然後可以順利開始繞迷宮 但是發生另一個問題 就是他明明有成功到達出口 卻沒有
回傳 true 跳出 function 反而繼續把剩下的迷宮全部走完然後回傳 false...
是我設定成功條件的位置有問題嗎 \_/ 剛好不容易開心一下馬上又自爆了...
我把現在的 code 更新上來 希望能有大大幫我檢查一下 無限感激!
餵入的資料(Input):
迷宮設定為
11
11111111111
10000010001
10100010101
e0100000101
10111110101
10101000101
10001010001
11111010001
101m1010001
10000010001
11111111111
'1' 代表牆壁不通行
'0' 代表可通過的路
'e' 代表出口
(迷宮最上面有一個 11 是迷宮的邊長 我預設為 11 X 11 的正方形
所以這個 11 只是讀入我的 int n 來設定給 dynamic array 用的
不影響迷宮本身)
預期的正確結果(Expected Output):
cout<< success !
錯誤結果(Wrong Output):
根本被強迫中斷....(跑成無窮迴圈?)
程式碼(Code):(請善用置底文網頁, 記得排版)
首先是 cell 我把它設定成 library... 不知道這樣好不好 
class cell
{
private:
int x;
int y;
public:
cell(){x = 0; y=0;}
void set_x(int a){x = a;}
void set_y(int b){y = b;}
int get_x(){return x;}
int get_y(){return y;}
~cell(){}
};
以下是我的 code
#include <iostream>
#include "Cell.h"
#include <fstream>
#include <ctime>
#include <iomanip >
using namespace std;
bool exitMaze(char **a, int n, int i, int j);
int main()
{
int n;
char **maze;
fstream f;
f.open("data.txt", ios::in);
f >> n;
maze = new char *[n];
for (int i= 0; i < n; ++i) maze[i] = new char[n];
for (int i= 0; i < n; ++i)
{
for(int j = 0; j < n; ++j)
{
f >> maze[i][j];
}
}
f.close();
cell current, entry;
entry.set_x(8);
entry.set_y(3);
current = entry;
int x = entry.get_x(), y = entry.get_y();
if(exitMaze(maze, n, x, y ))
{
cout << "Exit is found!" << endl;
}
else
{
cout << "No exit!" << endl;
}
system("pause");
return 0;
}
bool exitMaze(char** maze, int n, int a, int b)
{
cell exit;
exit.set_x(3);
exit.set_y(0);
if(a == exit.get_x() && b == exit.get_y())
{
return true;
}
else
{
if(maze[a][b+1] != '1' && maze[a][b+1] != '.')
{
maze[a][b+1] = '.';
exitMaze(maze, n, a, b+1);
}
if(maze[a][b-1] != '1' && maze[a][b-1] != '.')
{
maze[a][b-1] = '.';
exitMaze(maze, n, a, b-1);
}
if(maze[a+1][b] != '1' && maze[a+1][b] != '.')
{
maze[a+1][b] = '.';
exitMaze(maze, n, a+1, b);
}
if(maze[a-1][b] != '1' && maze[a-1][b] != '.')
{
maze[a-1][b] = '.';
exitMaze(maze, n, a-1, b);
}
}
return false;
}
補充說明(Supplement):
每次 run 都一定出問題 都快要恐懼症不敢 run 了 ... 真不好意思我知道我的
code 寫得不好 感謝各位大大指點迷津了! 希望能趕快變強 我每次都興高采烈
來寫程式解題目 然後都噴一堆問題出來 不過如果最後能解決問題成功跑過真的是
無比的爽快感! 再次感謝大家 
作者: kiedveian (極地之星光)   2014-05-01 08:50:00
第一步往下走,第二步往上走,第三步往下走……啊看錯了,不要理我看到問題了,你在走下一步前沒設成'.'然後就會變成1樓的來回走
作者: johnpage (johnpage)   2014-05-01 08:55:00
右手法則解題
作者: CaptainH (Cannon)   2014-05-01 09:04:00
先學會 DFS 或 BFS 演算法
作者: lalawolala (太陽底下無新鮮事)   2014-05-01 09:30:00
感謝大家 請問K大 我要在哪裡設定 '.' 才可以避免悲劇我只有在最後設定一個 maze[a][b]='.'; 可是沒成功recursive 真的是有夠難想像的 我快被我自己白癡氣死而且我每次執行 他一開始一定會說一句話讓我看不懂maze* 0x003a83d8<invalid charaters in string.>不知道是不是我 把 maze 放入 exitMaze 的地方有問題
作者: AndyLeo (打敗超越一切的人)   2014-05-01 19:16:00
a+-1跟b+-1 你要判斷有沒有超過邊界
作者: kiedveian (極地之星光)   2014-05-01 19:47:00
呼叫走下一步函式走到終點(回傳true)後,並沒有任何的處理,而是繼續試其他步,試完回傳false覺得難想像可以考慮玩玩看 light bot 或許有幫助
作者: lalawolala (太陽底下無新鮮事)   2014-05-02 12:46:00
感謝K大! 還真的沒有在往下一步走後的回傳判斷 ><Andy大是不是我要先設定a,b的最大值...不過我不會這種設定 @@ 我來 google 看看 感謝您!
作者: kiedveian (極地之星光)   2014-05-02 13:48:00
你的地圖包含牆,正常走不會出界andy大的情況是在沒牆的狀況才要判定
作者: a34021501 (CARD)   2014-05-03 22:37:00
紅的明顯,你在exit之後要把maze改回原值0如此DFS才會走回來,另外你要判斷是否出界Recursive Function: 1.改變狀態 2.call自己 3.恢復狀態最大值不就是11嗎? (0~10)

Links booklink

Contact Us: admin [ a t ] ucptt.com