Board logo

標題: 已解決 [打印本頁]

作者: 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

原帖由 freewave 於 2008-11-7 14:36 發表
nextstep函数是判断当前所处位置(x,y)是否可以向前(返回1)、向左(返回2)、向右(返回3)、向后(返回4)

我知道~但是我不知道讓怎麼改
  1.     if(input[x+1][y]=='.'){
  2.     d=1;}
  3.     if(input[x][y+1]=='.'){
  4.     d=2;}
  5.     if(input[x][y-1]=='.'){
  6.     d=3;}
  7.     if(input[x-1][y]=='.'){
  8.     d=4;}
複製代碼
是我自己加進去~但是跑不出來,不懂改><~用else if也不行...想不出來...
作者: 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

  1. #include "stdafx.h"
  2. #include <assert.h>
  3. #include <vector>
  4. #include<iostream.h>
  5. #include<fstream.h>

  6. #pragma warning(disable:4786)
  7. /*
  8.   # 16 * 16 的迷宫, '.'表示可以行走, '*'不可以行走
  9.   (0,0)
  10.   |---------------------->(x direction)
  11.   |*.**************
  12.   |*........*******
  13.   |*.******.*******
  14.   |*...***..*******
  15.   |****.**.*.....**
  16.   |**...**.*.***.**
  17.   |**.***....***.**
  18.   |**..*..**.***.**
  19.   |***.*.*...***.**
  20.   |**..*.**.****.**
  21.   |**....**......**
  22.   |**.*.*****.*****
  23.   |*..*.*...*.*****
  24.   |*.**...*.*.*****
  25.   |*.******.*.*****
  26.   |********.*******
  27.   |
  28.   (y direction)
  29. */


  30. enum Direction
  31. {
  32.         FORE = 0x00000001,
  33.         BACK = 0x00000002,
  34.         LEFT = 0x00000004,
  35.         RIGHT = 0x00000008
  36. };

  37. typedef struct tagPoint
  38. {
  39.         int row, column;
  40.         tagPoint ()
  41.         {
  42.                 row = 0;
  43.                 column = 0;
  44.         }

  45.         tagPoint(int row, int column)
  46.         {
  47.                 this->row = row;
  48.                 this->column = column;
  49.         }
  50. } Point;

  51. typedef struct tagMatrixPos : public tagPoint
  52. {
  53.         int wayDirections, wayDirectionsMarked;

  54.         tagMatrixPos()
  55.         {
  56.                 wayDirections = 0;
  57.                 wayDirectionsMarked = 0;
  58.         }
  59. } MatrixPos;


  60. //该类代表一个迷宫
  61. class Matrix
  62. {
  63. private:
  64.         int rows, columns;
  65.         int directions[4];
  66.         MatrixPos *pEndPos;
  67.         MatrixPos *pEntrance;
  68.         std::vector< std::vector<MatrixPos *> > matrixArray;
  69.         std::vector< std::vector<char> > matrixMaps;
  70.         std::vector<Point> ways;
  71. protected:
  72.         MatrixPos * GetFirstPos()
  73.         {
  74.                 return pEntrance;
  75.         }

  76.         //判断currentPos节点某个方向是否存在邻居节点
  77.         bool HasNextPos(Direction direction, MatrixPos *currentPos)
  78.         {
  79.                 if (currentPos == NULL)        
  80.                         return false;
  81.                
  82.                 switch (direction)
  83.                 {
  84.                 case FORE:
  85.                         return currentPos->row < rows - 1;
  86.                 case LEFT:
  87.                         return currentPos->column < columns - 1;
  88.                 case RIGHT:
  89.                         return currentPos->column > 0;
  90.                 case BACK:
  91.                         return currentPos->row > 0;
  92.                 }
  93.         }
  94.         
  95.         //获取currentPos某个方向的邻居节点
  96.         MatrixPos *GetPos(Direction direction, MatrixPos *currentPos)
  97.         {
  98.                 if (!HasNextPos(direction, currentPos))
  99.                         return NULL;
  100.                
  101.                 switch (direction)
  102.                 {
  103.                 case FORE:
  104.                         return matrixArray[currentPos->row + 1][currentPos->column];
  105.                 case LEFT:
  106.                         return matrixArray[currentPos->row][currentPos->column + 1];
  107.                 case RIGHT:
  108.                         return matrixArray[currentPos->row][currentPos->column - 1];
  109.                 case BACK:
  110.                         return currentPos->row == 0 ? NULL : matrixArray[currentPos->row - 1][currentPos->column];
  111.                 }
  112.         }
  113.         
  114.         void SetPosition(Direction direction, MatrixPos *pos)
  115.         {
  116.                 pos->wayDirections = pos->wayDirections | (int)direction;
  117.         }

  118.         //标记节点的某个方向已经走过
  119.         void MarkPosition(Direction direction, MatrixPos *pos)
  120.         {
  121.                 pos->wayDirectionsMarked = pos->wayDirectionsMarked | (int)direction;
  122.         }
  123.         
  124.         //测试节点的某个方向是否可以通过
  125.         bool TestDirection(Direction direction, MatrixPos *pos)
  126.         {
  127.                 if ((pos->wayDirections & direction) != direction)
  128.                         return false;
  129.                
  130.                 return (pos->wayDirectionsMarked & direction) != direction;
  131.         }


  132.         //从某个节点开始寻径
  133.         bool WalkFromPos(MatrixPos *pos)
  134.         {
  135.                 bool hasWay = false;
  136.                 if (pos == NULL)
  137.                         return false;

  138.                 //到达y方向的边界则结束
  139.                 if (pos->row == rows - 1) {
  140.                         pEndPos = pos;
  141.                         return true;
  142.                 }

  143.                 //从当前点向前、左、右、后依次测试
  144.                 for (int i = 0; i < 4; i++) {
  145.                         if (TestDirection((Direction)directions[i], pos)) {
  146.                                 MatrixPos *pNextPos = GetPos((Direction)directions[i], pos);
  147.                                 MarkPosition((Direction)directions[i], pos);
  148.                                 if (WalkFromPos(pNextPos)) {
  149.                                         hasWay = true;
  150.                                         ways.push_back(Point(pNextPos->row, pNextPos->column));
  151.                                 }
  152.                         }
  153.                 }

  154.                 return hasWay;
  155.         }
  156. public:
  157.         Matrix()
  158.         {
  159.                 pEntrance = NULL;
  160.                 pEndPos = NULL;
  161.                 rows = columns = 0;

  162.                 directions[0] = FORE;
  163.                 directions[1] = LEFT;
  164.                 directions[2] = RIGHT;
  165.                 directions[3] = BACK;
  166.         }

  167.         ~Matrix()
  168.         {
  169.                 for (int i = 0; i < matrixArray.size(); i++) {
  170.                         for (int j = 0; j < matrixArray.size(); j++)
  171.                                 delete matrixArray[i][j];
  172.                 }

  173.                 matrixArray.clear();
  174.         }

  175.         bool ReadMatrix(const char* pszFile, int rows, int columns)
  176.         {
  177.                 char pos;
  178.                 MatrixPos *pCurrent = NULL;
  179.                 MatrixPos *pRight = NULL;
  180.                 MatrixPos *pPrev = NULL;

  181.                 ifstream fin(pszFile);
  182.                 if (!fin.is_open())
  183.                         return false;

  184.                 this->rows = rows;
  185.                 this->columns = columns;
  186.                 for (int i = 0; i < rows; i++) {
  187.                         matrixArray.push_back(std::vector<MatrixPos *>());
  188.                         matrixMaps.push_back(std::vector<char>());
  189.                         for (int j = 0; j < columns; j++) {
  190.                                 fin >> pos;

  191.                                 pCurrent = new MatrixPos();
  192.                                 pCurrent->row = i;
  193.                                 pCurrent->column = j;
  194.                                 matrixArray[i].push_back(pCurrent);
  195.                                 matrixMaps[i].push_back(pos);

  196.                                 pRight = GetPos(RIGHT, pCurrent);
  197.                                 pPrev = GetPos(BACK, pCurrent);
  198.                                 //设置其左、后节点的路径
  199.                                 if (pos == '.') {
  200.                                         if (pRight != NULL)
  201.                                                 SetPosition(LEFT, pRight);

  202.                                         if (pPrev != NULL)
  203.                                                 SetPosition(FORE, pPrev);

  204.                                         if (i == 0)
  205.                                                 pEntrance = pCurrent;
  206.                                 }

  207.                                 if (pRight != NULL && matrixMaps[i][j-1] == '.')
  208.                                         SetPosition(RIGHT, pCurrent);
  209.                                 if (pPrev != NULL && matrixMaps[i-1][j] == '.')
  210.                                         SetPosition(BACK, pCurrent);
  211.                         }
  212.                 }
  213.                
  214.                 fin.close();
  215.                 return true;
  216.         }



  217.         //寻找路径
  218.         bool Walk()
  219.         {
  220.                 MatrixPos *pCurrentPos = GetFirstPos();
  221.                 return WalkFromPos(pCurrentPos);
  222.         }

  223.         //打印路径
  224.         void PrintWay()
  225.         {
  226.                 printf ("[%d,%d] - > ", pEntrance->row + 1, pEntrance->column + 1);
  227.                 for (int i = ways.size() - 1 ; i >= 0 ; i--) {
  228.                         printf ("[%d,%d] -> ", ways[i].row + 1, ways[i].column + 1);
  229.                 }

  230.                 printf ("[%d,%d]", pEndPos->row + 1, pEndPos->column + 1);
  231.         }

  232.         void PrintMatrix()
  233.         {
  234.                 for (int i = 0; i < rows; i++) {
  235.                         cout << endl;
  236.                         for (int j = 0; j < columns; i++) {
  237.                                 cout << matrixMaps[i][j] << endl;
  238.                         }
  239.                 }
  240.         }
  241. };


  242. int main(int argc, char* argv[])
  243. {
  244.         Matrix matrix;
  245.         if (!matrix.ReadMatrix("c:\\mg.txt", 16, 16))
  246.                 printf("read matrix failed");

  247.         if (matrix.Walk())
  248.         {
  249.                 printf("Find a way :\n");
  250.                 matrix.PrintWay();
  251.         }
  252.         else
  253.                 printf("no way found");

  254.         printf("\npress any key to exit");
  255.         getchar();
  256.         return 0;
  257. }
複製代碼
不好意思, 刚发现论坛将[ i ] 转换成斜体了, 所以代码中[ i ] 都没有了。 先已更正

[ 本帖最後由 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

可以只修改
  1. int nextstep(int x,int y)
  2. {
  3.     char input[37][37];
  4.     int d=0;
  5.     ifstream fin("mg.txt");
  6.     for(int i=0;i<37;i++){
  7.             for(int j=0;j<37;j++){
  8.             fin>>input[i][j];}
  9.     }
  10.     fin.close();
  11.     if(input[x+1][y]=='.'){
  12.     d=1;}
  13.     if(input[x][y+1]=='.'){
  14.     d=2;}
  15.     if(input[x][y-1]=='.'){
  16.     d=3;}
  17.     if(input[x-1][y]=='.'){
  18.     d=4;}
  19.     return d;
  20. }
複製代碼
的內容就能完成嗎?thx><~
作者: 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

  1. if(input[x+1][y]=='.'){
  2.     d=1; return d; }
  3. if(input[x][y-1]=='.'){
  4.     d=3; return d; }
  5. if(input[x-1][y]=='.'){
  6.     d=4; return d; }
  7. if(input[x][y+1]=='.'){
  8.     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

  1. #include<iostream.h>
  2. #include<fstream.h>
  3. int nextstep(int,int, const char output[][37]);
  4. int main(void)
  5. {
  6. int cpx=0,cpy=18,dd,run=0;
  7. char input[37][37],trace[37][37];
  8. char ttt;
  9. cout<<"0123456789012345678901234567890123456\n";
  10. ifstream fin("mg.txt");
  11. for(int i=0;i<37;i++){
  12.          for(int j=0;j<37;j++){
  13.          fin>>input[i][j];
  14.          trace[i][j]=input[i][j];
  15.          cout<<input[i][j];}
  16. cout<<i<<"\n";}
  17. fin.close();

  18. trace[0][18]='o';
  19. while(cpx!=36 && run<3000)
  20. {
  21.   dd=nextstep(cpx,cpy,input);
  22.   if(dd==1 && input[cpx+1][cpy]=='.')
  23.       {cpx++;run++;trace[cpx][cpy]='o';}
  24.   else if(dd==2 && input[cpx][cpy+1]=='.')
  25.       {cpy++;run++;trace[cpx][cpy]='o';}
  26.   else if(dd==3 && input[cpx][cpy-1]=='.')
  27.       {cpy--;run++;trace[cpx][cpy]='o';}
  28.   else if(dd==4 && input[cpx-1][cpy]=='.')
  29.       {cpx--;run++;trace[cpx][cpy]='o';}
  30.   else
  31.       {run=10000000;cout<<"cpx="<<cpx<<",cpy="<<cpy<<",dd="<<dd<<"\n";}
  32. // system("PAUSE");

  33.   cout<<run<<"  "<<"cpx="<<cpx<<",cpy="<<cpy<<",dd="<<dd<<"\n";
  34. }

  35.   if(cpx==36)   {cout<<"到達終點 cpx="<<cpx<<",cpy="<<cpy<<"\n"; }

  36.   cout<<"0123456789012345678901234567890123456\n";
  37.   for(int i=0;i<37;i++)
  38.   {   for(int j=0;j<37;j++)
  39.       {  cout<<trace[i][j];
  40.         }
  41.       cout<<i<<"\n";
  42.   }
  43. system("PAUSE");
  44. }

  45. int nextstep(int x,int y, const char output[][37])
  46. {
  47. /*
  48.     char input[37][37];
  49.     int d=0;
  50.     ifstream fin("mg.txt");
  51.     for(int i=0;i<37;i++){
  52.             for(int j=0;j<37;j++){
  53.             fin>>input[i][j];}
  54.     }
  55.     fin.close();
  56. */
  57.     static int d_Last = 0;
  58.     int d=0;
  59. //    cout<<"Last direction = "<<d_Last<<"\n";
  60. //      1, 先定上一步行既方向
  61. //      2, check 右邊有冇路行, 有就轉去右邊及更新 d_Last
  62. //      3, 如右邊冇路, check 前方有冇路行, 有就向前行, 更新 d_Last
  63. //      4, 如前路冇路行, check 左邊有冇路行, 有就向左邊行, 更新 d_Last
  64. //      5, 如左邊都冇路行(即係死巷), 就轉頭向後行及更新 d_Last
  65. //
  66.     switch (d_Last)
  67.     {
  68.         case 0:
  69.         case 1:     //如果先前向下
  70.             if (output[x][y-1]=='.') { d=3; }
  71.             else if(output[x+1][y]=='.') { d=1; }
  72.             else if(output[x][y+1]=='.') { d=2; }
  73.             else if(output[x-1][y]=='.') { d=4; }
  74.             //print error...if no match
  75.             break;
  76.         case 3:     //如果先前向左
  77.             if (output[x-1][y]=='.') { d=4; }
  78.             else if(output[x][y-1]=='.') { d=3; }
  79.             else if(output[x+1][y]=='.') { d=1; }
  80.             else if(output[x][y+1]=='.') { d=2; }
  81.             //print error...if no match
  82.             break;
  83.         case 4:     //如果先前向上
  84.             if (output[x][y+1]=='.') { d=2; }
  85.             else if(output[x-1][y]=='.') { d=4; }
  86.             else if(output[x][y-1]=='.') { d=3; }
  87.             else if(output[x+1][y]=='.') { d=1; }
  88.             //print error...if no match
  89.             break;
  90.         case 2:     //如果先前向右
  91.             if (output[x+1][y]=='.') { d=1; }
  92.             else if(output[x][y+1]=='.') { d=2; }
  93.             else if(output[x-1][y]=='.') { d=4; }
  94.             else if(output[x][y-1]=='.') { d=3; }
  95.             //print error...if no match
  96.             break;
  97.         default:
  98.             //print error
  99.             break;
  100.         }
  101.         d_Last=d;       //更新 d_Last
  102.         return d;
  103. }

  104. //    if(output[x+1][y]=='.'){
  105. //    d=1; return d; }
  106. //    if(output[x][y-1]=='.'){
  107. //    d=3; return d; }
  108. //    if(output[x-1][y]=='.'){
  109. //    d=4; return d; }
  110. //    if(output[x][y+1]=='.'){
  111. //    d=2; return d; }
  112. //    return d;
  113. //}
複製代碼
雖然蠢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





歡迎光臨 電腦領域 HKEPC Hardware (https://www.hkepc.com/forum/) Powered by Discuz! 7.2