之前有人问寻路算法 把N年前的A*寻路算法重新编了一下
c4droid吧
全部回复
仅看楼主
level 1
tstxwwzj 楼主
一楼献给国家
2016年08月06日 05点08分 1
level 1
tstxwwzj 楼主
纯正C语言语法,没有使用各种花销的C++结构类神马的。最基本的A*算法,没有采用排序、二叉树之类的加速算法,因为地图不是很大并且地图节点都是拥有阻力加权可通过的。使用排序和二叉树加速不明显的同时还会导致程序复杂度呈几何级上升。这个算法和普通A*寻路算法的区别就是可以处理不同的阻力加权地图,也就意味着寻路计算时可对地图中可破坏障碍进行处理。不过原理都是大同小异,没神马本质区别……
运行结果图片:
2016年08月06日 05点08分 2
色块颜色越浅阻力越小(纯白阻力为0,纯黑阻力位255),固定起始终止点,红线就是最优路线。根据A*算法特点,一次计算,终止点可以任意指定新的坐标,只是不同的回溯路线而已。
2016年08月06日 05点08分
level 1
tstxwwzj 楼主
#include <SDL2/SDL.h>
#include <stdio.h>
/*使用rand()函数必须的申明,如果要使用时间来srand(),还需要申明time.h*/
#include <iostream>
/*最大值为屏幕宽度的分辨率除以20*/
#define X 48
/*最大值为屏幕除去任务栏和虚拟按键(如果设置有的话)的高度的分辨率除以20*/
#define Y 80
/*重复计算的次数*/
#define N 10
int main(int args,char *argv[])
{
SDL_Window *win=NULL;
SDL_Renderer *render=NULL;
SDL_Event event;
SDL_Init(SDL_INIT_VIDEO);
SDL_Rect rect;
Uint8 i,j,map[X][Y],lx,ly,tx,ty,sx,sy,from[X][Y][2],flag,tempx,tempy,n;
Uint64 edge[X][Y],sv;
float touchx,touchy;
win=SDL_CreateWindow("road",0,0,X*20,Y*20,0);
render=SDL_CreateRenderer(win,-1,SDL_RENDERER_ACCELERATED);
SDL_SetRenderDrawBlendMode(render,SDL_BLENDMODE_BLEND);
for(n=0;n<N;n++)
{
flag=1;
for(i=0;i<X;i++)
{
for(j=0;j<Y;j++)
{
map[i][j]=rand()%255;
edge[i][j]=0;
if(i==0||i==X-1)
{
map[i][j]=255;
edge[i][j]=0xffffffff;
}
if(j==0||j==Y-1)
{
map[i][j]=255;
edge[i][j]=0xffffffff;
}
}
}
lx=2;
ly=4;
tx=X-3;
ty=Y-6;
edge[lx][ly]=map[lx][ly];
from[lx][ly][0]=lx;
from[lx][ly][1]=ly;
SDL_RenderClear(render);
while(flag>0)
{
sv=0xffffffff;
for(i=0;i<X;i++)
{
for(j=0;j<Y;j++)
{
if(edge[i][j]>0&&edge[i][j]<0xffffffff)
{
if(edge[i+1][j]==0||edge[i-1][j]==0||edge[i][j+1]==0||edge[i][j-1]==0)
{
if(edge[i][j]<sv)
{
sv=edge[i][j];
sx=i;
sy=j;
}
}
}
}
}
if(edge[sx-1][sy]==0)
{
edge[sx-1][sy]=edge[sx][sy]+map[sx-1][sy];
from[sx-1][sy][0]=sx;
from[sx-1][sy][1]=sy;
}
if(edge[sx+1][sy]==0)
{
edge[sx+1][sy]=edge[sx][sy]+map[sx+1][sy];
from[sx+1][sy][0]=sx;
from[sx+1][sy][1]=sy;
}
if(edge[sx][sy-1]==0)
{
edge[sx][sy-1]=edge[sx][sy]+map[sx][sy-1];
from[sx][sy-1][0]=sx;
from[sx][sy-1][1]=sy;
}
if(edge[sx][sy+1]==0)
{
edge[sx][sy+1]=edge[sx][sy]+map[sx][sy+1];
from[sx][sy+1][0]=sx;
from[sx][sy+1][1]=sy;
}
if(((sx-1==tx)||(sx+1==tx))&&(sy==ty))
{
flag=0;
}
if((sx==tx)&&((sy-1==ty)||(sy+1==ty)))
{
flag=0;
}
}
for(i=0;i<X;i++)
{
for(j=0;j<Y;j++)
{
SDL_SetRenderDrawColor(render,255-map[i][j],255-map[i][j],255-map[i][j],0xff);
rect={i*20,j*20,20,20};
SDL_RenderFillRect(render,&rect);
}
}
i=tx;
j=ty;
flag=1;
SDL_SetRenderDrawColor(render,0xff,0,0,0xff);
while(flag>0)
{
tempx=from[i][j][0];
tempy=from[i][j][1];
SDL_RenderDrawLine(render,i*20+10,j*20+10,tempx*20+10,tempy*20+10);
i=tempx;
j=tempy;
if((i==lx)&&(j==ly))flag=0;
}
SDL_RenderPresent(render);
SDL_Delay(10000);
}
SDL_DestroyRenderer(render);
SDL_DestroyWindow(win);
SDL_Quit();
return 0;
}
2016年08月06日 05点08分 3
所有高级结构不见了……算了,就这样了……我也没法上传文本文件……
2016年08月06日 05点08分
对了,float的touchx和touchy可以不用申明,没有用到,那个本来是用来实时设置终止点和重新生成地图运算的,不过SDL_Event的tfinger好像在我的手机上调用结果十分不靠谱……所以简化程序时忘了删除它俩[滑稽]……
2016年08月06日 05点08分
level 1
tstxwwzj 楼主
另外不知道度娘是肿么了,一楼只能那样才能发帖,否则不让发帖,奇怪哉……
2016年08月06日 05点08分 4
level 11
支持[真棒]
2016年08月06日 06点08分 5
level 6
垃圾手机,编译成功,运行就闪退[泪]
2016年08月06日 12点08分 6
直接点运行试试……
2016年08月06日 13点08分
手机问题,不能运行sdl
2016年08月06日 13点08分
回复 守候你de微笑 :可能是字体原因?[疑问]吧里之前谈论过。
2016年08月06日 16点08分
回复 tgxx501 :我没用字体,就系统自带的没换
2016年08月06日 23点08分
level 13
生成个纯随机地图试下,就是存在无路径的情况!并把选路过程绘出来!
2016年08月06日 17点08分 7
看源代码……map数组就是rand随机函数赋的值……路径就是一根一像素宽的红线,注意看,如果你的手机PPI很高的话,确实看的有点困难……A*算法可以说是遍历了出发点到目标点的所有路径,最后从目标点向出发点追溯出最短路径,要看算法过程就类似于水流从高处向低处流动的过程,单看路径绘制无意义。
2016年08月07日 04点08分
@tstxwwzj 直通和无路径的效率怎么样?
2016年08月07日 09点08分
也就是在两个极端情况下的效率如何?
2016年08月07日 09点08分
@savage200 我设置的地图阻力就没有无法通过的情况,所以不可能无路径。如果改动地图块有无法通过的情况,则无法通过的块越多,寻路速度越快,这是A*算法的优势。直通的话,算法速度肯定弱于贪心算法。
2016年08月07日 11点08分
level 8
厉害!
2016年08月07日 05点08分 8
level 12
我刚开始改我的ai就看到这个qaq
2016年08月07日 09点08分 9
1