|
- #define DTY 20
- #define DTX 20
- struct point {
- int x, y;
- };
- struct A_node {
- // 路徑節(jié)點(diǎn)
- struct point pt; // 當(dāng)前節(jié)點(diǎn)坐標(biāo)
- int g, h, f; // 評(píng)估值
- struct point fpt; // 父節(jié)點(diǎn)坐標(biāo)
- struct A_node *next; // 鏈表下一個(gè)節(jié)點(diǎn)
- };
- struct bu_node {
- int fx; // 運(yùn)動(dòng)方向
- struct bu_node *next;
- };
- class Astar {
- public:
- struct A_node *openlist; // 開啟列表
- struct A_node *closelist; // 關(guān)閉列表
- struct bu_node *bulist; // 運(yùn)動(dòng)步序列表
- struct point spt; // 開始和目標(biāo)點(diǎn)坐標(biāo)
- struct point ept;
- int DT[DTY][DTX]; // 一張二維數(shù)組表示的地圖(根據(jù)實(shí)際需求設(shè)定大。
- Astar(); // 初始化
- void setspt(int y, int x); // 設(shè)置開始坐標(biāo)
- void setept(int y, int x); // 設(shè)置目標(biāo)坐標(biāo)
- void setdt(int dt[DTY][DTX]); // 設(shè)置地圖信息0為通路
- void addopennode(struct A_node *node); // 增加一個(gè)開啟節(jié)點(diǎn)
- void delopennode(struct A_node *node); // 刪除一個(gè)開啟節(jié)點(diǎn)
- void addclosenode(struct A_node *node); // 增加一個(gè)關(guān)閉節(jié)點(diǎn)
- int inopenlist(struct A_node *node); // 判斷節(jié)點(diǎn)是否已經(jīng)在開啟列表中
- int incloselist(struct A_node *node); // 判斷節(jié)點(diǎn)是否已經(jīng)在關(guān)閉列表中
- void pinggu(struct A_node *node, int G); // 對(duì)地圖上的一個(gè)節(jié)點(diǎn)進(jìn)行價(jià)值評(píng)估
- void axgo(); // 開始一步尋路
- int find(); // 是否找到路徑判定
- void gofind(); // 開始尋路
- void print();
- void addbu(int fx); // 往列表添加一步
- int delbu(); // 從列表刪除并返回一步
- };
- Astar::Astar() {
- openlist = NULL;
- closelist = NULL;
- bulist = NULL;
- }
- void Astar::setspt(int y, int x) {
- spt.y = y;
- spt.x = x;
- // 設(shè)置并把開始節(jié)點(diǎn)添加到開啟列表
- openlist = (A_node *) malloc(sizeof(A_node));
- if (openlist == NULL) {
- printf("開啟列表創(chuàng)建失敗!");
- }
- openlist->pt = spt;
- openlist->g = 1;
- openlist->next = NULL;
- }
- void Astar::setept(int y, int x) {
- ept.y = y;
- ept.x = x;
- }
- void Astar::setdt(int dt[DTY][DTX]) {
- for (int y = 0; y < 20; y++)
- for (int x = 0; x < 20; x++)
- DT[y][x] = dt[y][x];
- }
- void Astar::pinggu(struct A_node *node, int G) {
- if (inopenlist(node)) {
- node->f = 0;
- node->g = 0;
- node->h = 0;
- } else if (incloselist(node)) {
- node->f = 0;
- node->g = 0;
- node->h = 0;
- } else if (DT[node->pt.y][node->pt.x] == 8) {
- node->f = 0;
- node->g = 0; // 障礙標(biāo)記這里為貪吃蛇身標(biāo)記
- node->h = 0;
- } else {
- node->g = G + 10;
- int H, H1;
- H = node->pt.y - ept.y;
- if (H < 0)
- H = ept.y - node->pt.y;
- H1 = node->pt.x - ept.x;
- if (H1 < 0)
- H1 = ept.x - node->pt.x;
- node->h = (H + H1) * 10;
- node->f = node->h + node->g;
- }
- }
- void Astar::addopennode(struct A_node *node) {
- struct A_node *p;
- p = (A_node *) malloc(sizeof(A_node));
- *p = *node;
- p->next = openlist;
- openlist = p;
- }
- void Astar::delopennode(struct A_node *node) {
- struct A_node *p;
- p = openlist;
- if (openlist != NULL)
- openlist = openlist->next;
- if (p != NULL) {
- *node = *p;
- free(p);
- }
- }
- void Astar::addclosenode(struct A_node *node) {
- struct A_node *p;
- p = (A_node *) malloc(sizeof(A_node));
- *p = *node;
- p->next = closelist;
- closelist = p;
- }
- void Astar::addbu(int fx) {
- struct bu_node *p;
- p = (bu_node *) malloc(sizeof(bu_node));
- p->fx = fx;
- p->next = bulist;
- bulist = p;
- }
- int Astar::delbu() {
- struct bu_node *p;
- int fx = 0;
- p = bulist;
- if (bulist != NULL)
- bulist = bulist->next;
- if (p != NULL) {
- fx = p->fx;
- free(p);
- }
- return fx;
- }
- int Astar::inopenlist(struct A_node *node) {
- struct A_node *p;
- p = openlist;
- while (p != NULL) {
- if ((p->pt.y == node->pt.y) && (p->pt.x == node->pt.x))
- return 1;
- p = p->next;
- }
- return 0; // 在返回1不在返回0
- }
- int Astar::incloselist(struct A_node *node) {
- struct A_node *p;
- p = closelist;
- while (p != NULL) {
- if ((p->pt.y == node->pt.y) && (p->pt.x == node->pt.x))
- return 1;
- p = p->next;
- }
- return 0; // 在返回1不在返回0
- }
- int Astar::find() {
- struct A_node *p;
- p = closelist;
- while (p != NULL) {
- if ((p->pt.y == ept.y) && (p->pt.x == ept.x))
- return 1;
- p = p->next;
- }
- return 0; // 在返回1不在返回0
- }
- void Astar::axgo() {
- struct A_node p, p1, p2, p3, p4; // 不斜著走所以只對(duì)四個(gè)方向進(jìn)行評(píng)估
- delopennode(&p); // 從開啟列表取出最上層的節(jié)點(diǎn)
- addclosenode(&p); // 把這個(gè)節(jié)點(diǎn)加入到關(guān)閉列表
- p1.pt.y = p.pt.y + 1; // 上面的節(jié)點(diǎn)
- p1.pt.x = p.pt.x;
- p2.pt.y = p.pt.y - 1; // 下面的節(jié)點(diǎn)
- p2.pt.x = p.pt.x;
- p3.pt.y = p.pt.y; // 左面的節(jié)點(diǎn)
- p3.pt.x = p.pt.x - 1;
- p4.pt.y = p.pt.y; // 右面的節(jié)點(diǎn)
- p4.pt.x = p.pt.x + 1;
- p1.fpt = p.pt; // 設(shè)置父節(jié)點(diǎn)坐標(biāo)
- p2.fpt = p.pt;
- p3.fpt = p.pt;
- p4.fpt = p.pt;
- p1.g = p1.h = p1.f = 0;
- p2.g = p2.h = p2.f = 0;
- p3.g = p3.h = p3.f = 0;
- p4.g = p4.h = p4.f = 0;
- if ((p1.pt.y >= 0) && (p1.pt.y < DTY) && (p1.pt.x >= 0) && (p1.pt.x < DTX))
- pinggu(&p1, p.g); // 對(duì)當(dāng)前節(jié)點(diǎn)相鄰的節(jié)點(diǎn)進(jìn)行價(jià)值評(píng)估
- if ((p2.pt.y >= 0) && (p2.pt.y < DTY) && (p2.pt.x >= 0) && (p2.pt.x < DTX))
- pinggu(&p2, p.g);
- if ((p3.pt.y >= 0) && (p3.pt.y < DTY) && (p3.pt.x >= 0) && (p3.pt.x < DTX))
- pinggu(&p3, p.g);
- if ((p4.pt.y >= 0) && (p4.pt.y < DTY) && (p4.pt.x >= 0) && (p4.pt.x < DTX))
- pinggu(&p4, p.g);
- int bp1, bp2, bp3, bp4;
- bp1 = bp2 = bp3 = bp4 = 1; // 排序用入棧標(biāo)記
- // 4個(gè)待選節(jié)點(diǎn)排序后入棧
- for (int i = 0; i < 4; i++) {
- if ((p1.f >= p2.f * bp2) && (p1.f >= p3.f * bp3) && (p1.f >= p4.f * bp4)
- && (bp1 == 1)) {
- if ((p1.f + p1.g + p1.h) > 0)
- addopennode(&p1);
- bp1 = 0;
- }
- if ((p2.f >= p1.f * bp1) && (p2.f >= p3.f * bp3) && (p2.f >= p4.f * bp4)
- && (bp2 == 1)) {
- if ((p2.f + p2.g + p2.h) > 0)
- addopennode(&p2);
- bp2 = 0;
- }
- if ((p3.f >= p1.f * bp1) && (p3.f >= p2.f * bp2) && (p3.f >= p4.f * bp4)
- && (bp3 == 1)) {
- if ((p3.f + p3.g + p3.h) > 0)
- addopennode(&p3);
- bp3 = 0;
- }
- if ((p4.f >= p1.f * bp1) && (p4.f >= p2.f * bp2) && (p4.f >= p3.f * bp3)
- && (bp4 == 1)) {
- if ((p4.f + p4.g + p4.h) > 0)
- addopennode(&p4);
- bp4 = 0;
- }
- }
- }
- void Astar::gofind() {
- while ((openlist != NULL) && (!find()))
- axgo();
- if (openlist == NULL)
- printf("找不到可通行路徑!\n");
- if (find()) {
- // 生成運(yùn)動(dòng)方向列表
- struct A_node *p;
- int fx;
- p = closelist;
- while (p != NULL) {
- if (p->fpt.y > p->pt.y)
- fx = 1;
- else // 上
- if (p->fpt.y < p->pt.y)
- fx = 2;
- else // 下
- if (p->fpt.x > p->pt.x)
- fx = 3;
- else // 左
- if (p->fpt.x < p->pt.x)
- fx = 4; // 右
- addbu(fx);
- p = p->next;
- }
- }
- }
- void Astar::print() {
- printf("開始打印開啟列表:\n");
- struct A_node *p;
- p = openlist;
- while (p != NULL) {
- printf("節(jié)點(diǎn)坐標(biāo):%d %d\n", p->pt.y, p->pt.x);
- printf("父節(jié)點(diǎn)坐標(biāo):%d %d\n", p->fpt.y, p->fpt.x);
- printf("評(píng)估值:%d %d %d\n\n", p->g, p->h, p->f);
- p = p->next;
- }
- printf("\n開始打印關(guān)閉列表:\n");
- p = closelist;
- while (p != NULL) {
- printf("節(jié)點(diǎn)坐標(biāo):%d %d\n", p->pt.y, p->pt.x);
- printf("父節(jié)點(diǎn)坐標(biāo):%d %d\n", p->fpt.y, p->fpt.x);
- printf("評(píng)估值:%d %d %d\n\n", p->g, p->h, p->f);
- p = p->next;
- }
- }
- 用貪吃蛇測試:
- #include "ditu.h"
- #include "AX.h"
- #include "stdio.h"
- int main() {
- ditu T;
- while (1) {
- usleep(100000);
- clrscr();
- T.print();
- Astar A;
- // 初始化A星算法
- A.setspt(T.she_Y, T.she_X);
- A.setept(T.shiwu_Y, T.shiwu_X);
- A.setdt(T.dt);
- // 對(duì)蛇頭和食物開始尋路
- A.gofind();
- // A.print();//打印開啟和關(guān)閉列表信息
- A.delbu(); // 去掉起點(diǎn)信息
- int fx;
- do {
- fx = A.delbu(); // 輸出步序
- if (fx == 1)
- T.U();
- else if (fx == 2)
- T.D();
- else if (fx == 3)
- T.L();
- else if (fx == 4)
- T.R();
- usleep(100000);
- clrscr();
- T.print();
- } while (fx != 0);
- }
- return 0;
- }
復(fù)制代碼
|
|