A 尋路演算法

2021-07-05 17:21:14 字數 4325 閱讀 2577

問題

由於遊戲中尋路出了個小問題–玩家尋路到乙個死角後在那邊不停的來回跑,就是無法越過障礙物, 就研究了下a*尋路演算法以解決這個問題;

研究了幾天,自己寫了個demo這裡給出總結;

原理

*****:

a*演算法給出的是權值最優的路徑而不是最短路徑;

權值有f = g + h來表示;

啟發式函式如下:

f(p) = g(p) + h(p)

h值估算方法

這裡的估算方法類似距離*單位消耗, 計算過程優先使用整數, 浮點數的運算速度慢;

//曼哈頓估價法

private

function

manhattan

(node:node)

:number

//幾何估價法

private

function

euclidian

(node:node)

:number

//對角線估價法

private

function

diagonal

(node:node)

:number

g值估算方法
從起點到當前節點的消耗, 可以用疊加過程來得到, 即g(p)=g(p-1)+g_p; g_p為從p-1走到p的消耗, 上下左右為1則對角線為1.4 (sqrt(2)得到). 實際計算用整數,所以會使用10, 14來計算.

openlist與closelist
設計

節點設計

class point

; bool operator==(const

point& pos)

};struct node

; bool operator==(const

node& node)

};

所有的parent都是指向closelist裡的成員,而closelist裡的值是不會變的,closelist做成一維陣列表示二維,利用(x,y)定位,openlist也同樣處理,這樣當openlist裡的isvisited為true則表明被訪問過了,就可以對比g值並更新parent;list中的所有沒有訪問過的或刪除的記憶體全部清零(isvisited=0表示沒有訪問過);

標頭檔案.h
#ifndef strategyfactory_h

#define strategyfactory_h

/***************

a* searching road

***************/

#include

#include

using

namespace

std;

class point

; bool

operator==(const point& pos)

};struct node

; bool

operator==(const node& node)

};// 全域性變數的定義

static

const

int max_search_num = 1024;

static

const point up(0,0);

static

const

int max_grid_num = 15;

static

const point down(max_grid_num,max_grid_num);

static

const

char map_block = 'x';

static

const

char map_nonblock = '.';

static

const

char map_load = 'o';

char map[max_grid_num][max_grid_num];

enum searchdir // 8個搜尋方向

;// a*搜尋類

class astar

void getminfnode(node& cur);

bool getnextstepnode(node& cur,node& nextnode, int dir);

bool isincloselist(node& cur);

bool isinopenlist(node& cur);

void calhval(node& nextnode);

void calnodeval(node& nextnode, int dir);

void updategh(node& cur);

public:

astar():opencount(0)

void setstartpos(point spos)

void setendpos(point epos)

bool assearch(point spt, point ept); // 尋路核心函式

bool calload(); // 尋路完後通過父節點從終點查詢到起點

};#endif // strategyfactory_h

原始檔.cpp
#include 

#include "test.h"

#include "cmath"

#include

#include

bool astar::assearch(point spt, point ept)

// 將相鄰節點計算gh後壓入

for(int i = dir_left; i <= dir_up_left; ++i)}}

return

false;

}void astar::calhval(node& nextnode)

bool astar::getnextstepnode(node& cur,node& nextnode, int dir)

if(nxt.x=down.x||nxt.y>=down.y)

return

false;

if(map[nxt.x][nxt.y] == map_block)

return

false;

nextnode.pos = nxt;

nextnode.parent= &closelist[getindex(cur.pos)]; //指向closelist中的對應位置

return

true;

}bool astar::isincloselist(node& cur)

bool astar::isinopenlist(node& cur)

void astar::getminfnode(node& cur)

}return;

}void astar::updategh(node& cur)

void astar::calnodeval(node& nextnode, int dir)

bool astar::calload()

while(endnode->parent!=null)

map[mstart.x][mstart.y] = map_load;

map[mend.x][mend.y] = map_load;

return

true;

}void initmap()

}// 列印地圖情況

void showmap()

}void getendpos(point& e)

}int main (void)

{ initmap();

showmap();

astar astr;

point s,e;

getstartpos(s);

getendpos(e);

if(astr.assearch(s,e) && astr.calload())

showmap();

else

cout

<

演示

迷宮尋路(A星尋路演算法)

題目 假設我們有乙個7 5大小的迷宮,如下圖所示,綠色格仔表示起點,紅色的格仔表示終點,中間的3個深灰色格仔表示障礙物。請找到一條從起點到終點最短的路徑。解題思路 需要引入兩個集合和乙個公式,如下 具體步驟 把起點放入openlist 檢查openlist中是否有值,如果沒有則無法到達終點,結束尋路...

A 尋路演算法

a 演算法是靜態環境下求最短路徑的不二之選,由於是啟發式搜尋,比dijkstra 深搜廣搜要快的多啦。a 也算是我第一次接觸的移動機械人演算法,csdn上的科普文章也不少,但我作為乙個機械的小白,實現出來還是小有成就感滴。今天抽空和大家分享一下原始碼,開發環境win7 64 opengl vs201...

A 尋路演算法

很多遊戲特別是rts,rpg類遊戲,都需要用到尋路。尋路演算法有深度優先搜尋 dfs 廣度優先搜尋 bfs a星演算法等,而a星演算法是一種具備啟發性策略的演算法,效率是幾種演算法中最高的,因此也成為遊戲中最常用的尋路演算法。直入正題 在遊戲設計中,地圖可以劃分為若干大小相同的方塊區域 方格 這些方...