A星演算法(遊戲尋路演算法)的C++實現
先吐槽一句:CODE功能太不給力了,怎麼弄怎麼崩潰,難道是CSDN也被掃黃打非了???
---------------------------------------------
A星演算法的實現原理看這裡:http://www.cnblogs.com/technology/archive/2011/05/26/2058842.html
實現部分:
標頭檔案:
/* A star 演算法的基礎處理 */ #ifndef _A_STAR_BASE_H_ #define _A_STAR_BASE_H_ #include "windows.h" typedef struct _APoint{ int x; // x 座標 int y; // y 座標 int type; // 型別 int f; // f = g + h int g; int h; } APoint,*PAPoint; enum APointType{ APT_UNKNOWN, // 未知狀態 APT_OPENED, // 開放列表中 APT_CLOSED, // 關閉列表中 APT_STARTPOINT, // 起始點 APT_ENDPOINT // 結束點 }; class CAStarBase{ public: CAStarBase(); ~CAStarBase(); private: PAPoint m_pAPointArr; int m_nAPointArrWidth; int m_nAPointArrHeight; PAPoint m_pStartPoint,m_pEndPoint,m_pCurPoint; char* m_pOldArr; public: BOOL Create(char* pDateArr,int nWidth,int nHeight); void SetStartPoint(int x,int y); void SetEndPoint(int x,int y); void SetOpened(int x,int y); void SetClosed(int x,int y); void SetCurrent( int x,int y ); void PrintCharArr(); PAPoint CalcNextPoint(PAPoint ptCalc); // 應用迭代的辦法進行查詢 }; #endif
實現cpp檔案:
#include "stdafx.h" #include "AStarBase.h" CAStarBase::CAStarBase() { m_pAPointArr = NULL; m_nAPointArrWidth = 0; m_nAPointArrHeight = 0; m_pStartPoint = NULL; m_pEndPoint = NULL; m_pCurPoint = NULL; } CAStarBase::~CAStarBase() { } BOOL CAStarBase::Create( char* pDateArr,int nWidth,int nHeight ) { if(!pDateArr) return FALSE; if(nWidth<1 || nHeight<1) return FALSE; m_pAPointArr = new APoint[nWidth*nHeight]; if(!m_pAPointArr) return FALSE; m_pOldArr = pDateArr; m_nAPointArrWidth = nWidth; m_nAPointArrHeight = nHeight; // 初始化陣列內容 for ( int y = 0;y<m_nAPointArrHeight;y++) { for ( int x=0;x<m_nAPointArrWidth;x++) { m_pAPointArr[y*m_nAPointArrWidth+x].x = x; m_pAPointArr[y*m_nAPointArrWidth+x].y = y; m_pAPointArr[y*m_nAPointArrWidth+x].g = 0; m_pAPointArr[y*m_nAPointArrWidth+x].f = 0; m_pAPointArr[y*m_nAPointArrWidth+x].h = 0; if ( pDateArr[y*m_nAPointArrWidth+x] == '0') { m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_OPENED; }else if ( pDateArr[y*m_nAPointArrWidth+x] == '1') { m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_CLOSED; }else if ( pDateArr[y*m_nAPointArrWidth+x] == 'S') { m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_STARTPOINT; m_pStartPoint = m_pAPointArr + y*m_nAPointArrWidth+x; m_pCurPoint = m_pStartPoint; }else if ( pDateArr[y*m_nAPointArrWidth+x] == 'E') { m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_ENDPOINT; m_pEndPoint = m_pAPointArr + y*m_nAPointArrWidth+x; }else{ m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_UNKNOWN; } } } return TRUE; } void CAStarBase::SetStartPoint( int x,int y ) { if ( m_pStartPoint && m_pAPointArr[y*m_nAPointArrWidth+x].type!=APT_CLOSED ) { m_pStartPoint->type = APT_OPENED; // 設定新的值 m_pStartPoint = m_pAPointArr + y*m_nAPointArrWidth+x; m_pStartPoint->type = APT_STARTPOINT; m_pCurPoint = m_pStartPoint; } } void CAStarBase::SetEndPoint( int x,int y ) { if ( m_pStartPoint && m_pAPointArr[y*m_nAPointArrWidth+x].type!=APT_CLOSED ) { m_pStartPoint->type = APT_OPENED; // 設定新的值 m_pStartPoint = m_pAPointArr + y*m_nAPointArrWidth+x; m_pStartPoint->type = APT_ENDPOINT; } } void CAStarBase::SetCurrent( int x,int y ) { // if ( m_pAPointArr[y*m_nAPointArrWidth+x].type==APT_OPENED ) { m_pCurPoint = m_pAPointArr+y*m_nAPointArrWidth+x; } } void CAStarBase::SetOpened( int x,int y ) { if ( m_pAPointArr[y*m_nAPointArrWidth+x].type!=APT_OPENED ) { m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_OPENED; } } void CAStarBase::SetClosed( int x,int y ) { if ( m_pAPointArr[y*m_nAPointArrWidth+x].type!=APT_CLOSED ) { m_pAPointArr[y*m_nAPointArrWidth+x].type = APT_CLOSED; } } void CAStarBase::PrintCharArr() { if ( m_pOldArr ) { for ( int y=0; y<m_nAPointArrHeight;y++) { for ( int x=0;x<m_nAPointArrWidth;x++) { printf("%c ",m_pOldArr[x+m_nAPointArrWidth*y]); } printf("\r\n"); } printf("\r\n"); } } PAPoint CAStarBase::CalcNextPoint( PAPoint ptCalc ) { if ( ptCalc == NULL ) { ptCalc = m_pStartPoint; } int x = ptCalc->x; int y = ptCalc->y; int dx = m_pEndPoint->x; int dy = m_pEndPoint->y; int xmin = x,ymin = y,vmin = 0; // 最優步驟的座標和值 // 判斷是否已經到了最終的位置 if ( (x==dx && abs(y-dy)==1) || (y==dy && abs(x-dx)==1) ) { return m_pEndPoint; } // 上 if ( m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].type == APT_OPENED && y>0) { m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].g = 10; m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].h = 10*(abs(x - dx) + abs(y-1 - dy)); m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].f = m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].g + m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].h; if ( vmin==0 ) { xmin = x; ymin = y-1; vmin = m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].f; }else{ if ( vmin > m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].f ) { xmin = x; ymin = y-1; vmin = m_pAPointArr[(x+0)+m_nAPointArrWidth*(y-1)].f; } } } // 下 if ( m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].type == APT_OPENED && y<m_nAPointArrHeight) { m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].g = 10; m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].h = 10*(abs(x - dx) + abs(y+1 - dy)); m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].f = m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].g + m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].h; if ( vmin==0 ) { xmin = x; ymin = y+1; vmin = m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].f; }else{ if ( vmin > m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].f ) { xmin = x; ymin = y+1; vmin = m_pAPointArr[(x+0)+m_nAPointArrWidth*(y+1)].f; } } } // 左 if ( m_pAPointArr[(x-1)+m_nAPointArrWidth*y].type == APT_OPENED && x>0) { m_pAPointArr[(x-1)+m_nAPointArrWidth*y].g = 10; m_pAPointArr[(x-1)+m_nAPointArrWidth*y].h = 10*(abs(x-1 - dx) + abs(y - dy)); m_pAPointArr[(x-1)+m_nAPointArrWidth*y].f = m_pAPointArr[(x-1)+m_nAPointArrWidth*y].g + m_pAPointArr[(x-1)+m_nAPointArrWidth*y].h; if ( vmin==0 ) { xmin = x-1; ymin = y; vmin = m_pAPointArr[(x-1)+m_nAPointArrWidth*y].f; }else{ if ( vmin > m_pAPointArr[(x-1)+m_nAPointArrWidth*y].f ) { xmin = x-1; ymin = y; vmin = m_pAPointArr[(x-1)+m_nAPointArrWidth*y].f; } } } // 右 if ( m_pAPointArr[(x+1)+m_nAPointArrWidth*y].type == APT_OPENED && x<m_nAPointArrWidth) { m_pAPointArr[(x+1)+m_nAPointArrWidth*y].g = 10; m_pAPointArr[(x+1)+m_nAPointArrWidth*y].h = 10*(abs(x+1 - dx) + abs(y - dy)); m_pAPointArr[(x+1)+m_nAPointArrWidth*y].f = m_pAPointArr[(x+1)+m_nAPointArrWidth*y].g + m_pAPointArr[(x+1)+m_nAPointArrWidth*y].h; if ( vmin==0 ) { xmin = x+1; ymin = y; vmin = m_pAPointArr[(x+1)+m_nAPointArrWidth*y].f; }else{ if ( vmin > m_pAPointArr[(x+1)+m_nAPointArrWidth*y].f ) { xmin = x+1; ymin = y; vmin = m_pAPointArr[(x+1)+m_nAPointArrWidth*y].f; } } } // 如果有最優點則迭代,則否就返回NULL if ( vmin ) { SetCurrent(xmin,ymin); SetClosed(xmin,ymin); *(m_pOldArr+xmin+m_nAPointArrWidth*ymin) = '-'; PrintCharArr(); PAPoint pApoint = CalcNextPoint(m_pCurPoint); if ( pApoint == NULL ) { SetCurrent(x,y); SetClosed(xmin,ymin); *(m_pOldArr+xmin+m_nAPointArrWidth*ymin) = '0'; return CalcNextPoint(m_pCurPoint); } return pApoint; }else{ return NULL; } }
測試檔案:
// AStarMath.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include "AStarBase.h" CAStarBase Astarbase; int _tmain(int argc, _TCHAR* argv[]) { char pBuff[5][7] = { '0','0','0','1','0','0','0', '0','1','1','0','0','1','1', '0','S','1','0','1','E','0', '0','1','0','0','0','1','0', '0','0','0','1','0','0','0' }; Astarbase.Create(&pBuff[0][0],7,5); Astarbase.PrintCharArr(); PAPoint pPoint = Astarbase.CalcNextPoint(NULL); if ( pPoint == NULL ) { printf("no path can arrive!\r\n"); }else{ printf("success arrived!\r\n"); } getchar(); return 0; }
結果:
相關推薦
A星演算法(遊戲尋路演算法)的C++實現
先吐槽一句:CODE功能太不給力了,怎麼弄怎麼崩潰,難道是CSDN也被掃黃打非了??? --------------------------------------------- A星演算法的實現原理看這裡:http://www.cnblogs.com
對於DFS,BFS,A*與IDA*等尋路演算法的總結跟感悟
本人大一,今年2017最後一天,準備做點這學期學的演算法一點總結,當做複習吧。 一週前看見了貪吃蛇AI演算法,受到震撼於是就把以前的win32貪吃蛇加了個AI實現,讓我這個渣渣寫了好幾天才完工,終於能吃完全屏了,雖然離自己看的那個貪吃蛇AI的gif還有些距離emmmm,貪吃蛇
A星演算法-自動尋路-c++
一共分三個檔案,一個頭檔案兩個CPP檔案 A星原理可以去網上搜。 那我就直接上程式碼啦! A星的標頭檔案 [cpp] view plaincopy /******************************************************
淺談遊戲中的A*尋路演算法
本文為銳亞教育原創文章,轉載請註明轉載自銳亞教育 A*尋路 A*演算法基本原理 A*(唸作A星)演算法對初學者來說的確有些難度。本文並不試圖對這個話題作權威性的陳述,取而代之的是描述演算法的原理,使你可以在進一步的閱讀中理解其他相關的資
如何實現A星尋路演算法 Cocos2d-x 3 0 beta2
bool pathFound = false;_spOpenSteps.clear();_spClosedSteps.clear();// 首先,新增貓的方塊座標到open列表this->insertInOpenSteps(ShortestPathStep::createWithPosition(fro
c++實現的A* 靜態尋路演算法 程式碼
在此僅提供程式碼,不對原理進行解釋。 如果想知道原理請自行百度,已經有很多前輩寫過了。 這裡用到了簡單的圖形庫 easyX #include<iostream> #include<math.h> #include<graphics.h> using n
A* (A-star A星)尋路演算法
A*在遊戲尋路演算法裡使用很廣,可是感覺很多介紹它的文章故意讓人看不懂。 仔細看了看gamedev.net的一片文章(A* Pathfinding for Beginners ),對A*更瞭解了一點,寫點東西記錄一下。 A*是一種啟發式的演算法,所謂的"啟發式",就是對每一個搜尋的位置進行評估,也就是把找的位
RPG遊戲製作-03-人物行走及A*尋路演算法
在遊戲中,可以控制人物的方法一般有:1.鍵盤 2.虛擬搖桿 3.滑鼠 4.手機觸碰。鍵盤一般是在PC端較為常用,如果在遊戲中使用wasd等操作人物的話,那麼在移植到安卓端時,就需要使用虛擬搖桿或虛擬按鈕來模擬鍵盤,以實現處理的統一性。滑鼠類似於手機的單點觸碰,而手機觸碰一般分
A*尋路演算法基於C#實現
玩過即時戰略,RPG等型別的遊戲的朋友一定會知道,當我們用滑鼠選取某些單位並命令其到達地圖上確定的位置時,這些單位總是可以自動的選擇最短的路徑到達。這個時候我們就會聯想到大名鼎鼎的A*尋路演算法,下文簡略介紹演算法實現原理,並附上C#實現方法。using System; u
A*尋路演算法的C++簡單實現
2007/8/13 17:26:59 #include <iostream> #include <ctime> #include <list> #include <algorithm> #include <cassert&
A星尋路演算法流程詳解
using System.Collections; using System.Collections.Generic; using UnityEngine; public class AStar : MonoBehaviour { private const int mapWith = 15;
天神降臨,大家過來膜拜吧! FLASH AS 3.0 A星(A*, A star) 尋路演算法--史上最快,極限優化挑戰!
天神降臨,大家過來膜拜吧! oh yeah! 轉載請宣告出處,例子程式碼可以免費隨意使用,但請保留或註明作者資訊. 這裡的演算法說是終極優化, 我挑戰了一下, 最終結果比較他快三倍, 我站在高高處,藐視了 一下作者. 優化思路:
記錄一個下午擼的A星尋路演算法
大致思路主要圍繞open表和close表 可能的路徑點先放到open列表裡面(如果該點已經存在於close則跳過,如果改點已經存在與open中,則判斷和值是否更小,如果是則更新) open列表裡面和值最小的轉移到close裡面去,直到最終到達終點,再遍歷前寄得到
A星尋路演算法的Lua實現
A*搜尋演算法俗稱A星演算法。這是一種在圖形平面上,有多個節點的路徑,求出最低通過成本的演算法。 對A星演算法的理解還是要從公式 F = G + H開始:在節點化的地圖上,每一步的操作,使得已走距離 + 距離終點距離最小。具體的實現上是維護一個open表和
A*尋路演算法C++簡單實現
參考文章: A*尋路演算法是遊戲中常用的AI演算法,這裡用C++簡單實現了一下演算法,便於理解。 搜尋區域 如圖所示簡易地圖, 其中綠色方塊的是起點 (用 A 表示), 中間藍色的是障礙物, 紅色的方塊 (用 B 表示) 是目的地. 為了可以用一個二
A星尋路演算法最簡單理解
對於a星尋路演算法最直白的理解: 從a點走到b點,首先把地圖畫成網格,讓障礙物在網格內 如圖,從s點要走到e點,把障礙物設成黑色,還要建立2個佇列,一個是尋找新的節點佇列(開啟佇列),一個是儲存已走過的節點佇列(關閉佇列)。在尋找新的節點時,要判斷該節點距
理解A*尋路演算法過程
這兩天研究了下 A* 尋路演算法, 主要學習了這篇文章, 但這篇翻譯得不是很好, 我花了很久才看明白文章中的各種指代. 特寫此篇部落格用來總結, 並寫了尋路演算法的程式碼, 覺得有用的同學可以看看. 另外因為圖片製作起來比較麻煩, 所以我用的是原文裡的圖片. &n
C語言-老鼠走迷宮(廣度尋路演算法)
老鼠走迷宮-c語言(基於廣度優先的尋路演算法) 深讀優先尋路演算法原文:https://blog.csdn.net/qq_42476927/article/details/81868068 本文是基於之前的深度優先尋路演算法改進而來,參考了許多廣度遍歷的程式碼結合自己程
C語言-老鼠走迷宮(深度尋路演算法)
老鼠走迷宮-c語言(基於深度優先的尋路演算法) 這個是學校的課設,剛開始有點頭疼,但是感覺越做越有意思了,於是就有如下程式碼,可能相較於大佬還有差距,但是這是我目前所能做的最優的程式了吧! 話不多說,說一下程式碼的核心內容吧! &nb
C#中的尋路演算法
目錄 介紹 問題 Dijkstra演算法 A *演算法 結果 結論 挑戰 Dijkstra和Astar的比較 Download source - 571.3 KB 在Visual Studio 2017中解壓縮並開啟解決方案 介紹 你有沒