迷宮算法——驗證迷宮的可通性

【Qboy原創】node

      記得在大學學習數據結構時就學過採用迭代方式能夠判斷一個迷宮是否有解無解甚至能夠查找出全部的可能的出口。目前公司開發一個遊戲須要玩家去搭建迷宮讓其餘玩家去闖迷宮的遊戲,遊戲其實很簡單。可是有一個重點就是要驗證玩家所搭建的迷宮是否可到達。好吧這就是咱們接下去算法的需求。寫下此文只是爲了Mark過程。git

  首先先建立必須的結構體算法

  (1)迷宮中全部的節點類型  數組

  typedef enum{
      EMPTY=0, //空白
      OBSTACLE, //障礙
      ENTER, //入口
      EXIT, //出口
    }MazeNodeType; //迷宮節點的類型數據結構

  根據不一樣的業務需求可能還涉及到其餘的節點類型,這是最基礎的類型。學習

  (2)迷宮節點:指針

  typedef struct
  {
    CCPoint location;//位置
    MazeNodeType nodeType;
  }MazeNode;遊戲

  (3)迷宮地圖開發

  typedef struct
  {
    MazeNode** pMazeNode;//地圖的節點
    int iMazeOrientation;//橫向多少個
    int iMazeLongitudinal;//縱向it

    MazeNode* pEnter;//入口

  }MazeMap;

  (4)定義走迷宮時的方向枚舉

   typedef enum{
    UP = 0,//上
    LEFT,//左
    DOWN,//下
    RIGHT,//右
    MaxDirection
   } MazeDirection;//方向

  爲了簡單方便,定義了一個靜態數組,描述每一個方向中每一個X、Y的變化值。

  static CCPoint pointDirection[]={ccp(0,1),ccp(-1,0),ccp(0,-1),ccp(1,0)};

  其次驗證迷宮

bool checkMazeRoad(MazeMap& map, MazeNodeType selectType)
{
  CCAssert(map.pMazeNode!=NULL,"Map is NULL");
  CCAssert(map.iMazeOrientation>0,"Orientation must larger than 0");
  CCAssert(map.iMazeLongitudinal>0,"Longitudinal must larger than 0");
  std::stack<MazeNode*> sMazeNode;//未驗證過的節點
  std::list<MazeNode*> lMazeNode;//已驗證過的節點
  sMazeNode.push(map.pEnter);//入口進棧
  lMazeNode.push_back(map.pEnter);
  bool rtn = false;
  do
  {
    MazeNode* pnode = sMazeNode.top();
    sMazeNode.pop();

    for(int i = 0;i<MaxDirection&&!rtn;i++)//四個方向依次判斷
    {
      int x = (int)(pnode->location.x+pointDirection[i].x);
      int y = (int)(pnode->location.y+pointDirection[i].y);

      if(x < 0 || x >= map.iMazeLongitudinal || y < 0 || y >= map.iMazeOrientation)
      {
        continue;//越界取下一個
      }

      MazeNode* newNode = &map.pMazeNode[x][y];
      std::list<MazeNode*>::iterator it = find(lMazeNode.begin(), lMazeNode.end(), newNode);
      if(it!=lMazeNode.end())//find 說明該點已經進行過判斷或者還在棧中未處理不入棧
      {

        continue;

      }else{
        if(newNode->nodeType== selectType)//出口
        {
          rtn = true;
        }else if(newNode->nodeType==EMPTY){//空白點進棧便於下次檢查
          lMazeNode.push_back(newNode);
          sMazeNode.push(newNode);
        }
      }
    }

  } while (sMazeNode.size()>0&&!rtn);//無出口或者已經找到出口
  return rtn;
}

因爲該功能只是爲了知足是否有出口無需判斷出口路線,若是須要有出口路線,則在迷宮節點添加一個指向前面節點的指針,而後用反向找到迷宮路徑。

該功能比較簡單,因此直接上代碼了,見諒。

相關文章
相關標籤/搜索