青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

無我

讓內心永遠燃燒著偉大的光明的精神之火!
靈活的思考,嚴謹的實現
豪邁的氣魄、頑強的意志和周全的思考

A*算法實現

最近實現了一下A*算法,感覺蠻好的,尤其是修改地圖然后看電腦正確尋路后的那種成就感,有點像小時候蹲在地上,看著一堆螞蟻搬家,然后故意在他們的路上設置障礙物,然后看螞蟻不停的探索,然后重新找到新的路線的感覺,真是很有意思。
好!把代碼記錄在此,便于以后參考。

  1#include <iostream>
  2#include <string>
  3#include <vector>
  4#include <list>
  5#include <map>
  6#include <set>
  7
  8using namespace std;
  9
 10/************************************************************************/
 11/* A*算法實現,測試A*算法地圖      
 1240X10的地圖,B代表起始點,E代表終點;                                              
 13空格代表能通過;|代表是墻,不能通過;
 14xx0123456789012345678901234567890123456789xx
 15xx————————————————————xx
 160|                                        |0
 171|                                        |1
 182|                 |                      |2
 193|                   |                      |3
 204|                 |        E             |4
 215|    B            |                      |5
 226|                 |                      |6
 237|                                        |7
 248|                                        |8
 259|                                        |9
 26xx————————————————————xx
 27xx0123456789012345678901234567890123456789xx
 28/************************************************************************/

 29const static int X = 40;
 30const static int Y = 10;
 31//地圖上的情況
 32enum E_Map
 33{
 34    E_River=-2,            //有河流,無法通過,在地圖上用 ~ 標出
 35    E_Wall=-1,            //有墻,無法通過,在地圖上用 | 標出    
 36    E_Road = 0,            //沒有障礙物,能最快的順利通行,代價為0,在地圖上用空格標出    
 37    E_Sand=1,            //是沙地,能通過,但是相對難一些,代價為1,在地圖上用 * 標出
 38}
;
 39
 40struct Point
 41{
 42    int x;
 43    int y;
 44    Point(int i=0,int j=0):x(i),y(j){}
 45    bool operator==(const Point & r)
 46    {
 47        return (x==r.x)&&(y==r.y);
 48    }

 49}
;
 50bool operator==(const Point& l,const Point & r)
 51{
 52    return (l.x==r.x)&&(l.y==r.y);
 53}

 54bool operator<(const Point& l,const Point & r)
 55{
 56    if(l.y<r.y)    return true;
 57    else if(l.y>r.y)    return false;
 58    else    return (l.x < r.x);
 59}

 60
 61//const static int GameMap[Y][X] = {
 62//    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 63//    0,0,-2,-2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 64//    0,0,0,-2,-2,-2,0,0,0,0,0,0,0,0,0,0,0,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
 65//    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,-2,-2,-2,0,0,0,0,0,0,
 66//    0,0,0,0,0,0,0,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,-2,-2,0,0,0,0,0,
 67//    0,0,0,0,0,0,0,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,-2,0,0,0,0,0,
 68//    0,0,0,0,0,0,0,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,0,
 69//    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 70//    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 71//    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 72//};
 73
 74//const static int GameMap[Y][X] = {
 75//    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,0,0,0,0,0,0,0,0,
 76//    0,0,-2,-2,0,0,0,0,0,-1,-1,0,0,0,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,
 77//    0,0,0,-2,-2,-2,0,0,-1,0,-1,0,0,0,0,0,0,-1,-1,0,0,0,-1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
 78//    0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,-1,-1,0,0,0,0,0,-1,-1,0,0,0,0,0,-2,-2,-2,0,0,0,0,0,0,
 79//    0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-2,-2,0,0,0,0,0,
 80//    0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,-2,0,0,0,0,0,
 81//    0,0,0,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 82//    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,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,
 83//    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,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 84//    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,0,0,0,0,0,0,0,0
 85//};
 86
 87const static int GameMap[Y][X] = {
 88    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,0,0,0,0,0,0,0,0,0,
 89    0,0,-2,-2,0,0,0,0,-1,-1,0,0,0,0,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,
 90    0,0,0,-2,-2,-2,0,-1,-1,0,0,0,0,0,0,0,0,-1,-1,0,0,0,-1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
 91    0,0,0,0,0,0,0,0,-1,-1,0,0,0,0,0,0,0,-1,-1,0,0,0,0,0,-1,-1,0,0,0,0,0,-2,-2,-2,0,0,0,0,0,0,
 92    0,0,0,0,0,-1,0,0,-1,-1,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-2,-2,0,0,0,0,0,
 93    0,0,0,0,0,-1,0,0,-1,-1,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,-2,0,0,0,0,0,
 94    0,0,0,0,0,-1,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 95    0,0,0,0,0,-1,0,0,0,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,
 96    0,0,0,0,0,0,-1,0,0,-1,0,-1,0,0,0,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,
 97    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 98}
;
 99
100//打印地圖
101void PrintMap(const Point &B,const Point &E,const vector<Point>& path=vector<Point>());
102void PrintMap(const Point &B,const Point &E,const vector<Point>& path)
103{
104    int LastMap[Y][X] = {0};
105    for (int y=0;y<Y;++y)
106    {
107        for (int x=0;x<X;++x)
108        {
109            LastMap[y][x] = GameMap[y][x];
110        }

111    }

112    //路徑
113    vector<Point>::const_iterator itr = path.begin();
114    for (;itr != path.end();++itr)
115    {
116        LastMap[(*itr).y][(*itr).x] = '&';
117    }

118    //起始和目標
119    LastMap[B.y][B.x] = 'B';
120    LastMap[E.y][E.x] = 'E';
121
122    cout<<"A*尋路路徑為:"<<endl;
123    cout<<"xx0123456789012345678901234567890123456789xx"<<endl;
124    cout<<"xx————————————————————xx"<<endl;
125    for (int y=0;y<Y;++y)
126    {
127        cout<<y<<"[";
128        for (int x=0;x<X;++x)
129        {
130            if (LastMap[y][x] == E_Road)
131            {
132                cout<<" ";
133            }

134            else if (LastMap[y][x] == E_Wall)
135            {
136                cout<<"|";
137            }

138            else if (LastMap[y][x] == E_River)
139            {
140                cout<<"~";
141            }

142            else if (LastMap[y][x] == E_Sand)
143            {
144                cout<<"*";
145            }

146            else if (LastMap[y][x] == 'B')
147            {
148                cout<<"B";
149            }

150            else if (LastMap[y][x] == 'E')
151            {
152                cout<<"E";
153            }

154            else if (LastMap[y][x] == '&')
155            {
156                cout<<"&";
157            }

158        }

159        cout<<"]"<<y<<endl;
160    }

161    cout<<"xx————————————————————xx"<<endl;
162    cout<<"xx0123456789012345678901234567890123456789xx"<<endl;
163}

164
165//計算當前位置與終點位置的Hn
166double Hn(const Point & E,const Point&p)
167{
168    return abs(E.y-p.y) + abs(E.x-p.x);
169}

170
171//計算相鄰兩個位置(即包括對象線在內的周圍8個坐標)的相對Gn
172double Gg(const Point & p1,const Point& p2)
173{
174    double d = GameMap[p2.y][p2.x];
175    return ((p1.x-p2.x)!=0&&(p1.y-p2.y)!=0)?(1.5+d):(1.0+d);
176}

177
178//探測位置p的下一步(p.x + addx,p.y + addy)的Gn,Hn
179void testNext(const Point & E,const Point&p,const set<Point>& closeTbl,
180    map<Point,double> &mapGn,map<Point,double> &mapGnTemp,
181    multimap<double,Point> &HnPoint,int addx,int addy)
182{
183    int x = p.x + addx;
184    int y = p.y + addy;    
185    if (x>=0 && y>=0 && x<&& y<&& GameMap[y][x]>=0)
186    {
187        Point t = Point(x,y);
188        if (closeTbl.find(t) != closeTbl.end())
189        {
190            return;
191        }

192        //得到對應本次遍歷的Gn
193        double dgn = mapGn[p] + Gg(p,t);
194        mapGnTemp[t] = dgn;
195
196        map<Point,double>::iterator itr = mapGn.find(t);
197        if (itr == mapGn.end() || itr->second > dgn)
198        {
199            mapGn[t] = dgn;
200        }

201        HnPoint.insert(make_pair(Hn(E,t),t));
202    }

203}

204
205bool APath(const Point & B,const Point & E,vector<Point>&path)
206{    
207    //A*算法:Fn = Gn + Hn
208    path.clear();
209    vector<Point> openTbl;
210    openTbl.push_back(B);
211    set<Point>    closeTbl;
212    closeTbl.insert(B);
213    map<Point,double> mapGn;
214    mapGn[B] = 0;
215    while(!openTbl.empty())
216    {
217        Point p = openTbl.back();
218        openTbl.pop_back();
219        if (p == E)
220        {
221            path.push_back(E);
222            break;
223        }

224        //multimap<double,Point> FnPoint;
225        multimap<double,Point> HnPoint;    //當前位置周圍所有可選擇的位置到終點的Hn
226        map<Point,double> mapGnTemp;    //當前位置周圍所有可選擇的位置到起點的Gn
227
228        testNext(E,p,closeTbl,mapGn,mapGnTemp,HnPoint,-1,-1);        //左上位置
229        testNext(E,p,closeTbl,mapGn,mapGnTemp,HnPoint,-1,0);        //左邊位置
230        testNext(E,p,closeTbl,mapGn,mapGnTemp,HnPoint,-1,1);        //左下位置
231        testNext(E,p,closeTbl,mapGn,mapGnTemp,HnPoint,0,-1);        //上面位置
232        testNext(E,p,closeTbl,mapGn,mapGnTemp,HnPoint,0,1);            //下面位置
233        testNext(E,p,closeTbl,mapGn,mapGnTemp,HnPoint,1,-1);        //右上位置
234        testNext(E,p,closeTbl,mapGn,mapGnTemp,HnPoint,1,0);            //右邊位置
235        testNext(E,p,closeTbl,mapGn,mapGnTemp,HnPoint,1,1);            //右下位置
236        if (HnPoint.empty())
237        {
238            //無路可走了,只能一步一步回退。。。
239
240            //PrintMap(B,E,path);
241            //標記該點已經被探測,使得下次不再被選擇
242            closeTbl.insert(p);
243            //回退一步,重新探測之前走過的一個點
244            if (path.empty())
245            {
246                return false;
247            }

248            p = path.back();
249            path.pop_back();
250            closeTbl.erase(p);
251            openTbl.push_back(p);
252            continue;
253        }

254
255        //HnPoint的第一維就是從p點開始到達終點(Hn)最高效的周圍坐標點pt
256        multimap<double,Point>::iterator  itr = HnPoint.begin();
257        double hn = itr->first;
258        Point pt = itr->second;
259
260        map<Point,double>::iterator itrFind = mapGn.find(pt);
261        while (itrFind != mapGn.end() && (itrFind->second) < mapGnTemp[pt])
262        {
263            //如果這個不是最優,則優先試探其他的相同Hn的路徑
264            ++itr;
265            if (itr != HnPoint.end() )
266            {
267                if (hn < itr->first)
268                {
269                    break;
270                }

271                pt = itr->second;
272                itrFind = mapGn.find(pt);
273            }

274            else
275                break;
276        }

277        //判斷pt是否被探測過
278        if (itrFind != mapGn.end() && (itrFind->second) < mapGnTemp[pt])
279        {
280            /**************************************************************************************
281            pt已經被探測過,并且之前的Gn更小,說明可以用更小的代價到達pt。
282            所以說明我們之前選擇的p點不是最佳選擇,首先應該標記p無效,然后回退到之前的坐標重新選擇!
283            ****************************************************************************************/

284            //PrintMap(B,E,path);
285            //標記該點已經被探測,使得下次不再被選擇
286             closeTbl.insert(p);
287            //回退一步,重新探測之前走過的一個點
288            p = path.back();
289            path.pop_back();
290            closeTbl.erase(p);
291            openTbl.push_back(p);
292            continue;
293        }
    
294
295        //pt沒有被探測過,或者是最優選項,所以將p加入路徑,然后下一步探測pt 
296        openTbl.push_back(pt);
297
298        closeTbl.insert(p);
299        path.push_back(p);
300    }
    
301    return !path.empty();
302}

303
304int main(int argc, char * argv[])
305{
306    const Point B(4,5),E(36,4);
307    vector<Point> path;
308    bool bFind = APath(B,E,path);
309    
310    PrintMap(B,E,path);
311    if (!bFind)
312    {
313        cout<<"++++++找不到可達路徑!+++++++++"<<endl;
314    }

315
316    return 0;
317}

 


最上面注釋里面畫的地圖是為了簡單演示地圖最終的顯示效果,其實代碼二維數組給出的地圖有趣多了。

posted on 2012-11-05 09:04 Tim 閱讀(1850) 評論(0)  編輯 收藏 引用 所屬分類: 游戲編程C/C++語言

<2012年11月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

導航

統計

公告

本博客原創文章,歡迎轉載和交流。不過請注明以下信息:
作者:TimWu
郵箱:timfly@yeah.net
來源:www.shnenglu.com/Tim
感謝您對我的支持!

留言簿(9)

隨筆分類(173)

IT

Life

搜索

積分與排名

最新隨筆

最新評論

閱讀排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美影视一区| 欧美日韩直播| 国内精品久久久| 久久爱www久久做| 欧美一区2区三区4区公司二百 | 久久影院午夜论| 欧美一区二区视频网站| 国产在线成人| 亚洲国产精品成人| 欧美日韩 国产精品| 亚洲一区二区三区在线视频| 亚洲视频精选| 激情综合网址| 亚洲精品美女91| 国产精品视频网| 久久一区二区三区超碰国产精品| 免费观看成人网| 中文一区二区| 久久精品国产欧美激情| 亚洲国产视频一区二区| 亚洲视频在线二区| 悠悠资源网亚洲青| 一本色道久久99精品综合| 国产欧美精品久久| 亚洲福利视频免费观看| 欧美小视频在线观看| 狂野欧美激情性xxxx欧美| 欧美紧缚bdsm在线视频| 久久九九99| 欧美日韩国产限制| 老鸭窝91久久精品色噜噜导演| 女人香蕉久久**毛片精品| 亚洲永久在线| 免费久久99精品国产自在现线| 亚洲一区二区三区涩| 久久久水蜜桃av免费网站| 亚洲网友自拍| 免费美女久久99| 久久久久久久国产| 欧美性理论片在线观看片免费| 美腿丝袜亚洲色图| 国产欧美一区二区三区视频| 亚洲国产美国国产综合一区二区| 国产在线观看精品一区二区三区| 日韩天天综合| 亚洲三级毛片| 久久久久一区二区| 欧美影院久久久| 欧美日韩综合视频网址| 亚洲国产高清高潮精品美女| 韩日欧美一区二区三区| 亚洲一区在线免费| 在线亚洲美日韩| 欧美精品免费在线| 欧美黄色免费| 亚洲国产精品一区二区第一页| 欧美一区日韩一区| 久久国产乱子精品免费女| 欧美视频在线免费| 99国产精品| 亚洲一区二区三区成人在线视频精品 | 一区二区三区免费观看| 欧美激情视频给我| 亚洲国内高清视频| 亚洲精品日韩在线观看| 欧美sm极限捆绑bd| 亚洲国产黄色片| 亚洲日韩欧美一区二区在线| 老司机aⅴ在线精品导航| 欧美/亚洲一区| 亚洲国产精品黑人久久久| 久久琪琪电影院| 欧美黄色一级视频| 亚洲美女av网站| 欧美破处大片在线视频| 亚洲精品人人| 亚洲一区二区三区影院| 国产精品视频精品视频| 午夜精品福利一区二区蜜股av| 久久av一区| 在线日韩精品视频| 欧美激情a∨在线视频播放| 亚洲三级毛片| 亚洲免费小视频| 国产一区深夜福利| 蜜桃av一区二区三区| 亚洲国产婷婷| 午夜视频久久久| 红杏aⅴ成人免费视频| 欧美大尺度在线| 中文欧美字幕免费| 久久网站免费| 一区二区久久久久久| 国产精品视频福利| 久久综合国产精品| 99精品欧美一区二区三区综合在线| 亚洲综合日韩中文字幕v在线| 国产一区二区视频在线观看| 美国成人直播| 亚洲午夜精品久久久久久浪潮| 久久久精品国产免费观看同学| 最新成人av在线| 国产精品乱看| 免费视频亚洲| 亚洲欧美精品伊人久久| 欧美激情乱人伦| 久久xxxx精品视频| 999在线观看精品免费不卡网站| 国产精品一区二区a| 蜜桃久久av| 亚洲免费中文| 亚洲精品免费电影| 美女国内精品自产拍在线播放| 一区二区三区国产精华| 在线观看精品| 国产精品一级在线| 欧美日本三级| 免费成人高清视频| 久久er精品视频| 一区二区三区回区在观看免费视频| 免费观看成人网| 久久国产精品毛片| 亚洲欧美福利一区二区| 亚洲国产婷婷综合在线精品 | 欧美激情四色| 久久久综合免费视频| 亚洲永久免费视频| 日韩视频专区| 亚洲成人在线视频播放 | 亚洲日本中文| 免费av成人在线| 久久久久久一区| 欧美在线观看网站| 午夜激情一区| 午夜精品久久久久久久久久久久| 亚洲精品一区在线| 亚洲日韩成人| 亚洲美女区一区| 亚洲欧洲日本国产| 亚洲国产一区在线| 亚洲国产精品123| 亚洲高清在线精品| 亚洲第一福利视频| 亚洲国产精品成人久久综合一区| 国产原创一区二区| 一区在线观看视频| 亚洲成人在线视频播放| 在线观看亚洲精品| 亚洲国产婷婷香蕉久久久久久| 在线欧美日韩国产| 亚洲激情黄色| 日韩视频一区二区三区在线播放| 亚洲精品免费在线| 99re热这里只有精品免费视频| 99re这里只有精品6| 亚洲一区二区精品| 欧美有码视频| 蜜桃av一区二区| 欧美电影电视剧在线观看| 亚洲国产成人av| 日韩一级黄色片| 亚洲欧美日韩国产| 久久久久国产精品一区| 毛片基地黄久久久久久天堂| 欧美刺激性大交免费视频| 欧美日韩精品久久久| 国产精品美女在线| 国产一区二区三区久久久| 尤物九九久久国产精品的特点 | 国产精品一卡二卡| 黑人一区二区三区四区五区| 亚洲国产精品电影| 一个人看的www久久| 性欧美大战久久久久久久免费观看| 欧美一区二区久久久| 免费欧美在线视频| 一区二区三区日韩欧美| 欧美亚洲免费| 欧美激情精品久久久久久蜜臀 | 国产精品久久久久久av下载红粉| 国产美女搞久久| 亚洲精品中文字幕女同| 午夜一区二区三区不卡视频| 另类激情亚洲| 亚洲天堂av在线免费| 久久欧美肥婆一二区| 欧美午夜免费| 亚洲国产一区在线观看| 欧美一区二区三区四区在线| 欧美ed2k| 午夜精品久久久久久99热软件| 免费不卡在线视频| 国产日韩亚洲欧美综合| 日韩系列在线| 麻豆freexxxx性91精品| 亚洲欧美www| 欧美三日本三级三级在线播放| 激情av一区| 久久精品国产第一区二区三区| 亚洲日本激情|