a星自动寻路算法
A star
a星自動尋路算法的實現
規則可以自己去找
根本原理就是建立一個樹,遍歷所有可以走的節點,最終找出f值最小的那一個
在bilibili上https://www.bilibili.com/video/BV1Cv411x76X?from=search&seid=8246083468330961939,學習這門課,后自己敲的,
手敲不易,點個贊唄
#include<stdio.h> #include<stdlib.h> #include<iostream> #include<vector> #include<string.h> using namespace std;//#include<pch.h> //豎著y軸的行數 #define ROWS 9 //橫 x 列數 #define COLS 11 //輸出 #define ZXDJ 10 //直線代價 #define XXDJ 14 //斜線代價 struct MyPoint{int row;//行 int col;//列 int f;//總代價 int g;//移動代價,int h; //估算成本。void setF(){f=g+h;} }; //樹的節點類型 struct TreeNode{ MyPoint pos; //當前點坐標 vector<TreeNode*> childs;//存儲當前點的子節點指針的 數組 動態數組容器 裝下很多個指針 TreeNode* pParent; //存儲當前點的父節點指針的 變量 };enum direct{p_up,p_down,p_left,p_right,p_lup,p_ldown,p_rup,p_rdown};//枚舉類型 //輔助地圖節點類型 //struct PathNode{ // // bool //}; //輸出地圖 void printMap(int map[ROWS][COLS]);int getH(MyPoint endPos,MyPoint pos)//計算h值 {int x=(endPos.col>pos.col)?(endPos.col-pos.col):(pos.col-endPos.col);//取絕對值 int y=(endPos.row>pos.row)?(endPos.row-pos.row):(pos.row-endPos.row);return (x+y)*ZXDJ;} //判斷是否需要統計 bool needAdd(MyPoint pos,int map[ROWS][COLS], bool pathMap[ROWS][COLS]) {if(pos.row>=ROWS||pos.row<0||pos.col>=COLS||pos.col<0)//范圍限制 return false;if(map[pos.row][pos.col])//不是墻 return false;if(pathMap[pos.row][pos.col])//是否走過 return false;return true;} int main() {//地圖int map[ROWS][COLS] = {{0,0,0,0,0,1,0,0,0,0,0},{0,0,0,0,0,1,0,0,0,0,0},{0,0,0,0,0,1,0,0,0,0,0},{0,0,0,0,0,1,0,0,0,0,0},{0,0,0,0,0,1,0,0,0,0,0},{0,0,0,0,0,1,0,0,0,0,0},{0,0,0,0,0,1,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,1,0,0,0,0,0}};//2 輔助地圖 false 0;沒有走過 true 1:走過bool pathMap[ROWS][COLS]={0};//3 起點 終點MyPoint begpos={2,2}; MyPoint endpos={4,8}; //4 標記起點走過pathMap[begpos.row][begpos.col]=true;//5 創建一棵樹 起點是樹的根節點//創建一個新的節點 TreeNode* pNew=new TreeNode;memset(pNew,0,sizeof (TreeNode)); //注意頭文件 //新節點成為樹根 // pRoot一直指向樹的根節點 TreeNode* pRoot=pNew;//新節點是記錄起點 pRoot->pos =begpos; //6 需要一個動態數組 存儲用來比較的 節點 vector<TreeNode*>buff;//buff是數組名字 //7 尋路TreeNode* pCurrent=pRoot;//MyPoint currentPos=begPos;TreeNode* pChild=NULL;//迭代器 vector<TreeNode*>::iterator it;vector<TreeNode*>::iterator itMin;//最小的f值 bool isFindEnd=false;//用于儲存是否找到的結果 while(1){//7.1找到當前點周圍能走的點for(int i=0;i<8;i++){pChild=new TreeNode;memset(pChild,0,sizeof (TreeNode)); pChild->pos=pCurrent->pos; //pos是坐標 switch(i){case p_up:pChild->pos.row--;pChild->pos.g+=ZXDJ; break;case p_down:pChild->pos.row++;pChild->pos.g+=ZXDJ; break; case p_left:pChild->pos.col--;pChild->pos.g+=ZXDJ; break; case p_right:pChild->pos.col++;pChild->pos.g+=ZXDJ; break;case p_lup:pChild->pos.row--;pChild->pos.col--;pChild->pos.g+=XXDJ; break;case p_rup:pChild->pos.row--;pChild->pos.col++;pChild->pos.g+=XXDJ; break; case p_ldown:pChild->pos.row++;pChild->pos.col--;pChild->pos.g+=XXDJ; break; case p_rdown:pChild->pos.row++;pChild->pos.col++;pChild->pos.g+=XXDJ; break; default:break; }//printf("(%d,%d):%d\n",pChild->pos.row,pChild->pos.col,pChild->pos.g);//7.2計算ghf 值pChild->pos.h=getH(endpos, pChild->pos);pChild->pos.setF();//7.3 入樹 ,入 buff數組if(needAdd(pChild->pos,map,pathMap)){//入樹 pCurrent->childs.push_back(pChild);pChild->pParent=pCurrent; //入buff數組 buff.push_back(pChild);pathMap[pChild->pos.row][pChild->pos.col]=true;//標記走過 }else{delete pChild;}} //7.4 從buff數組中找到f最小的一個itMin=buff.begin();for(it=buff.begin();it!=buff.end();it++){itMin=(((*itMin)->pos.f>(*it)->pos.f)?it:itMin);} //7.5刪掉,變化成當前點pCurrent=*itMin;buff.erase(itMin);//7.6判斷是否尋路結束 if(pCurrent->pos.row==endpos.row&&pCurrent->pos.col==endpos.col){isFindEnd=true;break;}if(buff.empty())break; } if(isFindEnd){printf("找到終點了\n");while(pCurrent){printf("(%d,%d)",pCurrent->pos.row,pCurrent->pos.col);pCurrent=pCurrent->pParent;}printf("\n");}printMap(map);while (1);return 0; }void printMap(int map[ROWS][COLS]) {for (int i = 0; i < ROWS; i++){for (int j = 0; j < COLS;j++){if (map[i][j] == 0)printf("--");else if (map[i][j] == 1)printf("墻");}printf("\n");}}總結
- 上一篇: 保护腰带一些方法
- 下一篇: 我的第一篇博客——开篇