作者: jy02453563 時間: 2008-11-7 14:22 標題: 已解決
本帖最後由 jy02453563 於 2010-6-23 14:08 編輯
thx~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
作者: freewave 時間: 2008-11-7 14:36
nextstep函数是判断当前所处位置(x,y)是否可以向前(返回1)、向左(返回2)、向右(返回3)、向后(返回4)
作者: jy02453563 時間: 2008-11-7 17:16
我知道~但是我不知道讓怎麼改
- if(input[x+1][y]=='.'){
- d=1;}
- if(input[x][y+1]=='.'){
- d=2;}
- if(input[x][y-1]=='.'){
- d=3;}
- if(input[x-1][y]=='.'){
- d=4;}
作者: Newbie 時間: 2008-11-7 17:39
原帖由 jy02453563 於 2008-11-7 17:16 發表
我知道~但是我不知道讓怎麼改 if(input[x+1][y]=='.'){
d=1;}
if(input[x][y+1]=='.'){
d=2;}
if(input[x][y-1]=='.'){
d=3;}
if(input[x-1][y]=='.'){
d=4;}是我自己加進去~但是跑不出來,不懂改>
第一步會行落第二層, 但第二步會上返去, 係nextstep內d先會等如2, 然後等如3, 最後等如4, 再轉回主程式, 會回到上層, 然後不斷重復.... (好似係)
作者: freewave 時間: 2008-11-7 17:50
要搜索迷宫有没有出路, 就要遍历所有的路径, 直到有一条能够走出去, 可以通过递归来做。
ps:你的nextstep函数,只是判断从当前位置可以向哪里走, 因为你设定了run<3000, 所以不一定能够走出去的。
我要外出, 如有需要周六可以给你提供个例子。
作者: jy02453563 時間: 2008-11-9 16:11
求救.......................
作者: freewave 時間: 2008-11-9 21:41
- #include "stdafx.h"
- #include <assert.h>
- #include <vector>
- #include<iostream.h>
- #include<fstream.h>
- #pragma warning(disable:4786)
- /*
- # 16 * 16 的迷宫, '.'表示可以行走, '*'不可以行走
- (0,0)
- |---------------------->(x direction)
- |*.**************
- |*........*******
- |*.******.*******
- |*...***..*******
- |****.**.*.....**
- |**...**.*.***.**
- |**.***....***.**
- |**..*..**.***.**
- |***.*.*...***.**
- |**..*.**.****.**
- |**....**......**
- |**.*.*****.*****
- |*..*.*...*.*****
- |*.**...*.*.*****
- |*.******.*.*****
- |********.*******
- |
- (y direction)
- */
- enum Direction
- {
- FORE = 0x00000001,
- BACK = 0x00000002,
- LEFT = 0x00000004,
- RIGHT = 0x00000008
- };
- typedef struct tagPoint
- {
- int row, column;
- tagPoint ()
- {
- row = 0;
- column = 0;
- }
- tagPoint(int row, int column)
- {
- this->row = row;
- this->column = column;
- }
- } Point;
- typedef struct tagMatrixPos : public tagPoint
- {
- int wayDirections, wayDirectionsMarked;
- tagMatrixPos()
- {
- wayDirections = 0;
- wayDirectionsMarked = 0;
- }
- } MatrixPos;
- //该类代表一个迷宫
- class Matrix
- {
- private:
- int rows, columns;
- int directions[4];
- MatrixPos *pEndPos;
- MatrixPos *pEntrance;
- std::vector< std::vector<MatrixPos *> > matrixArray;
- std::vector< std::vector<char> > matrixMaps;
- std::vector<Point> ways;
- protected:
- MatrixPos * GetFirstPos()
- {
- return pEntrance;
- }
- //判断currentPos节点某个方向是否存在邻居节点
- bool HasNextPos(Direction direction, MatrixPos *currentPos)
- {
- if (currentPos == NULL)
- return false;
-
- switch (direction)
- {
- case FORE:
- return currentPos->row < rows - 1;
- case LEFT:
- return currentPos->column < columns - 1;
- case RIGHT:
- return currentPos->column > 0;
- case BACK:
- return currentPos->row > 0;
- }
- }
-
- //获取currentPos某个方向的邻居节点
- MatrixPos *GetPos(Direction direction, MatrixPos *currentPos)
- {
- if (!HasNextPos(direction, currentPos))
- return NULL;
-
- switch (direction)
- {
- case FORE:
- return matrixArray[currentPos->row + 1][currentPos->column];
- case LEFT:
- return matrixArray[currentPos->row][currentPos->column + 1];
- case RIGHT:
- return matrixArray[currentPos->row][currentPos->column - 1];
- case BACK:
- return currentPos->row == 0 ? NULL : matrixArray[currentPos->row - 1][currentPos->column];
- }
- }
-
- void SetPosition(Direction direction, MatrixPos *pos)
- {
- pos->wayDirections = pos->wayDirections | (int)direction;
- }
- //标记节点的某个方向已经走过
- void MarkPosition(Direction direction, MatrixPos *pos)
- {
- pos->wayDirectionsMarked = pos->wayDirectionsMarked | (int)direction;
- }
-
- //测试节点的某个方向是否可以通过
- bool TestDirection(Direction direction, MatrixPos *pos)
- {
- if ((pos->wayDirections & direction) != direction)
- return false;
-
- return (pos->wayDirectionsMarked & direction) != direction;
- }
- //从某个节点开始寻径
- bool WalkFromPos(MatrixPos *pos)
- {
- bool hasWay = false;
- if (pos == NULL)
- return false;
- //到达y方向的边界则结束
- if (pos->row == rows - 1) {
- pEndPos = pos;
- return true;
- }
- //从当前点向前、左、右、后依次测试
- for (int i = 0; i < 4; i++) {
- if (TestDirection((Direction)directions[i], pos)) {
- MatrixPos *pNextPos = GetPos((Direction)directions[i], pos);
- MarkPosition((Direction)directions[i], pos);
- if (WalkFromPos(pNextPos)) {
- hasWay = true;
- ways.push_back(Point(pNextPos->row, pNextPos->column));
- }
- }
- }
- return hasWay;
- }
- public:
- Matrix()
- {
- pEntrance = NULL;
- pEndPos = NULL;
- rows = columns = 0;
- directions[0] = FORE;
- directions[1] = LEFT;
- directions[2] = RIGHT;
- directions[3] = BACK;
- }
- ~Matrix()
- {
- for (int i = 0; i < matrixArray.size(); i++) {
- for (int j = 0; j < matrixArray.size(); j++)
- delete matrixArray[i][j];
- }
- matrixArray.clear();
- }
- bool ReadMatrix(const char* pszFile, int rows, int columns)
- {
- char pos;
- MatrixPos *pCurrent = NULL;
- MatrixPos *pRight = NULL;
- MatrixPos *pPrev = NULL;
- ifstream fin(pszFile);
- if (!fin.is_open())
- return false;
- this->rows = rows;
- this->columns = columns;
- for (int i = 0; i < rows; i++) {
- matrixArray.push_back(std::vector<MatrixPos *>());
- matrixMaps.push_back(std::vector<char>());
- for (int j = 0; j < columns; j++) {
- fin >> pos;
- pCurrent = new MatrixPos();
- pCurrent->row = i;
- pCurrent->column = j;
- matrixArray[i].push_back(pCurrent);
- matrixMaps[i].push_back(pos);
- pRight = GetPos(RIGHT, pCurrent);
- pPrev = GetPos(BACK, pCurrent);
- //设置其左、后节点的路径
- if (pos == '.') {
- if (pRight != NULL)
- SetPosition(LEFT, pRight);
- if (pPrev != NULL)
- SetPosition(FORE, pPrev);
- if (i == 0)
- pEntrance = pCurrent;
- }
- if (pRight != NULL && matrixMaps[i][j-1] == '.')
- SetPosition(RIGHT, pCurrent);
- if (pPrev != NULL && matrixMaps[i-1][j] == '.')
- SetPosition(BACK, pCurrent);
- }
- }
-
- fin.close();
- return true;
- }
- //寻找路径
- bool Walk()
- {
- MatrixPos *pCurrentPos = GetFirstPos();
- return WalkFromPos(pCurrentPos);
- }
- //打印路径
- void PrintWay()
- {
- printf ("[%d,%d] - > ", pEntrance->row + 1, pEntrance->column + 1);
- for (int i = ways.size() - 1 ; i >= 0 ; i--) {
- printf ("[%d,%d] -> ", ways[i].row + 1, ways[i].column + 1);
- }
- printf ("[%d,%d]", pEndPos->row + 1, pEndPos->column + 1);
- }
- void PrintMatrix()
- {
- for (int i = 0; i < rows; i++) {
- cout << endl;
- for (int j = 0; j < columns; i++) {
- cout << matrixMaps[i][j] << endl;
- }
- }
- }
- };
- int main(int argc, char* argv[])
- {
- Matrix matrix;
- if (!matrix.ReadMatrix("c:\\mg.txt", 16, 16))
- printf("read matrix failed");
- if (matrix.Walk())
- {
- printf("Find a way :\n");
- matrix.PrintWay();
- }
- else
- printf("no way found");
- printf("\npress any key to exit");
- getchar();
- return 0;
- }
[ 本帖最後由 freewave 於 2008-11-11 21:26 編輯 ]
作者: freewave 時間: 2008-11-9 21:45
周末出去玩了 :)
上面我刚写了个例子, 是利用递归寻找路径,例如上面16*16的迷宫的路径输出如下(这个路径不是最短路径,需要再加以计算才能得到,抱歉我没有做...):
[row,column]->[row,column]->....->[row,column] 代表各个点之间的走动
[1,2] - > [2,2] -> [3,2] -> [4,2] -> [4,3] -> [4,4] -> [4,3] -> [4,2] -> [3,2] -
> [2,2] -> [2,3] -> [2,4] -> [2,5] -> [2,6] -> [2,7] -> [2,8] -> [2,9] -> [3,9]
-> [4,9] -> [4,8] -> [5,8] -> [6,8] -> [7,8] -> [7,9] -> [7,10] -> [8,10] -> [9,
10] -> [9,9] -> [10,9] -> [11,9] -> [11,10] -> [11,11] -> [12,11] -> [13,11] ->
[14,11] -> [15,11] -> [14,11] -> [13,11] -> [12,11] -> [11,11] -> [11,12] -> [11
,13] -> [11,14] -> [11,13] -> [11,12] -> [11,11] -> [11,10] -> [11,9] -> [10,9]
-> [9,9] -> [9,10] -> [8,10] -> [7,10] -> [7,9] -> [7,8] -> [7,7] -> [8,7] -> [8
,6] -> [9,6] -> [10,6] -> [11,6] -> [11,5] -> [12,5] -> [13,5] -> [14,5] -> [14,
6] -> [14,7] -> [13,7] -> [13,8] -> [13,9] -> [14,9] -> [15,9] -> [16,9]
作者: jy02453563 時間: 2008-11-10 01:28
可以只修改
- int nextstep(int x,int y)
- {
- char input[37][37];
- int d=0;
- ifstream fin("mg.txt");
- for(int i=0;i<37;i++){
- for(int j=0;j<37;j++){
- fin>>input[i][j];}
- }
- fin.close();
- if(input[x+1][y]=='.'){
- d=1;}
- if(input[x][y+1]=='.'){
- d=2;}
- if(input[x][y-1]=='.'){
- d=3;}
- if(input[x-1][y]=='.'){
- d=4;}
- return d;
- }
作者: freewave 時間: 2008-11-10 21:23
这样实现比较困难, 需要保存尝试过的路径信息,不至于走重复的路线。nextstep里面有回退, 回退后又会走走过的路线, 这样就陷入了死循环。
作者: thinkpanda 時間: 2008-11-11 01:18
我做tutor 教year 1 C++ 既時候, 有個assignment 同呢個幾乎一模一樣....
作者: Tony仔 時間: 2008-11-11 01:22
wiki下: DFS depth-first search la
作者: jy02453563 時間: 2008-11-11 14:33
只能說我也覺得限制太多...但一定只能改那個位置><~
作者: Newbie 時間: 2008-11-11 16:17
- if(input[x+1][y]=='.'){
- d=1; return d; }
- if(input[x][y-1]=='.'){
- d=3; return d; }
- if(input[x-1][y]=='.'){
- d=4; return d; }
- if(input[x][y+1]=='.'){
- d=2; return d; }
重有個問題, 你每次 call nextstep 就會開1次個txt file, 係咪唔係咁好呢?
[ 本帖最後由 Newbie 於 2008-11-11 17:26 編輯 ]
作者: jy02453563 時間: 2008-11-11 20:43
這個是被老師限制了只能改那個位置...課堂內容教超快,第六課而已~就跳到這裡~頭上都超多問號....
作者: $$$ 時間: 2008-11-11 23:25
個陣係UST 讀
都做過但係LAB 嚟
作者: Newbie 時間: 2008-11-12 14:32
- #include<iostream.h>
- #include<fstream.h>
- int nextstep(int,int, const char output[][37]);
- int main(void)
- {
- int cpx=0,cpy=18,dd,run=0;
- char input[37][37],trace[37][37];
- char ttt;
- cout<<"0123456789012345678901234567890123456\n";
- ifstream fin("mg.txt");
- for(int i=0;i<37;i++){
- for(int j=0;j<37;j++){
- fin>>input[i][j];
- trace[i][j]=input[i][j];
- cout<<input[i][j];}
- cout<<i<<"\n";}
- fin.close();
- trace[0][18]='o';
- while(cpx!=36 && run<3000)
- {
- dd=nextstep(cpx,cpy,input);
- if(dd==1 && input[cpx+1][cpy]=='.')
- {cpx++;run++;trace[cpx][cpy]='o';}
- else if(dd==2 && input[cpx][cpy+1]=='.')
- {cpy++;run++;trace[cpx][cpy]='o';}
- else if(dd==3 && input[cpx][cpy-1]=='.')
- {cpy--;run++;trace[cpx][cpy]='o';}
- else if(dd==4 && input[cpx-1][cpy]=='.')
- {cpx--;run++;trace[cpx][cpy]='o';}
- else
- {run=10000000;cout<<"cpx="<<cpx<<",cpy="<<cpy<<",dd="<<dd<<"\n";}
- // system("PAUSE");
- cout<<run<<" "<<"cpx="<<cpx<<",cpy="<<cpy<<",dd="<<dd<<"\n";
- }
- if(cpx==36) {cout<<"到達終點 cpx="<<cpx<<",cpy="<<cpy<<"\n"; }
- cout<<"0123456789012345678901234567890123456\n";
- for(int i=0;i<37;i++)
- { for(int j=0;j<37;j++)
- { cout<<trace[i][j];
- }
- cout<<i<<"\n";
- }
- system("PAUSE");
- }
- int nextstep(int x,int y, const char output[][37])
- {
- /*
- char input[37][37];
- int d=0;
- ifstream fin("mg.txt");
- for(int i=0;i<37;i++){
- for(int j=0;j<37;j++){
- fin>>input[i][j];}
- }
- fin.close();
- */
- static int d_Last = 0;
- int d=0;
- // cout<<"Last direction = "<<d_Last<<"\n";
- // 1, 先定上一步行既方向
- // 2, check 右邊有冇路行, 有就轉去右邊及更新 d_Last
- // 3, 如右邊冇路, check 前方有冇路行, 有就向前行, 更新 d_Last
- // 4, 如前路冇路行, check 左邊有冇路行, 有就向左邊行, 更新 d_Last
- // 5, 如左邊都冇路行(即係死巷), 就轉頭向後行及更新 d_Last
- //
- switch (d_Last)
- {
- case 0:
- case 1: //如果先前向下
- if (output[x][y-1]=='.') { d=3; }
- else if(output[x+1][y]=='.') { d=1; }
- else if(output[x][y+1]=='.') { d=2; }
- else if(output[x-1][y]=='.') { d=4; }
- //print error...if no match
- break;
- case 3: //如果先前向左
- if (output[x-1][y]=='.') { d=4; }
- else if(output[x][y-1]=='.') { d=3; }
- else if(output[x+1][y]=='.') { d=1; }
- else if(output[x][y+1]=='.') { d=2; }
- //print error...if no match
- break;
- case 4: //如果先前向上
- if (output[x][y+1]=='.') { d=2; }
- else if(output[x-1][y]=='.') { d=4; }
- else if(output[x][y-1]=='.') { d=3; }
- else if(output[x+1][y]=='.') { d=1; }
- //print error...if no match
- break;
- case 2: //如果先前向右
- if (output[x+1][y]=='.') { d=1; }
- else if(output[x][y+1]=='.') { d=2; }
- else if(output[x-1][y]=='.') { d=4; }
- else if(output[x][y-1]=='.') { d=3; }
- //print error...if no match
- break;
- default:
- //print error
- break;
- }
- d_Last=d; //更新 d_Last
- return d;
- }
- // if(output[x+1][y]=='.'){
- // d=1; return d; }
- // if(output[x][y-1]=='.'){
- // d=3; return d; }
- // if(output[x-1][y]=='.'){
- // d=4; return d; }
- // if(output[x][y+1]=='.'){
- // d=2; return d; }
- // return d;
- //}
[ 本帖最後由 Newbie 於 2008-11-12 14:44 編輯 ]
作者: Gundamdriver 時間: 2008-11-12 15:50
同今年IVE HDSE Year 2個Assignment好似... 不過我地用Java寫。

作者: jy02453563 時間: 2008-11-12 23:11
原帖由 Newbie 於 2008-11-12 14:32 發表
#include
#include
int nextstep(int,int, const char output[][37]);
int main(void)
{
int cpx=0,cpy=18,dd,run=0;
char input[37][37],trace[37][37];
char ttt;
cout
先謝謝你~因為我們功課不能修改主程式部份~只能改nextstep~所以不能用
不過我明白你寫的內容的意思~我再自己修改一下吧~thx


