已解決

本帖最後由 jy02453563 於 2010-6-23 14:08 編輯

thx~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
附件: 您需要登錄才可以下載或查看附件。沒有帳號?註冊

nextstep函数是判断当前所处位置(x,y)是否可以向前(返回1)、向左(返回2)、向右(返回3)、向后(返回4)

TOP

原帖由 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也不行...想不出來...

TOP

原帖由 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, 再轉回主程式, 會回到上層, 然後不斷重復.... (好似係)

TOP

要搜索迷宫有没有出路, 就要遍历所有的路径, 直到有一条能够走出去, 可以通过递归来做。

ps:你的nextstep函数,只是判断从当前位置可以向哪里走, 因为你设定了run<3000, 所以不一定能够走出去的。

我要外出, 如有需要周六可以给你提供个例子。

TOP

求救.......................

TOP

  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 編輯 ]

TOP

周末出去玩了 :)
上面我刚写了个例子, 是利用递归寻找路径,例如上面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]

TOP

可以只修改
  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><~

TOP

这样实现比较困难, 需要保存尝试过的路径信息,不至于走重复的路线。nextstep里面有回退, 回退后又会走走过的路线, 这样就陷入了死循环。

TOP