不是A*,WQX上恐怕用不起消耗这么大的方法。
所以想过了一个。
以下是用LAVA写的代码。- char map[16][16]={
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,
- 1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,5,2,4,1,1,1,1,1,1,1,
- 1,1,1,1,1,2,1,1,1,1,3,1,1,1,1,1,
- 1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,
- 1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 };
- // 地图数组
- char out[16][16];
- char Step[10][2];
- char fx;
- char fy; /*初始坐标 (7,11) */
- char tx;
- char ty; /*目标坐标 (4,8) */
- char mp; /* 拥有的移动力 */
- char Y_Max;
- char Y_Min; /* 供查询边界使用 */
- char V_Path;
- char lx;
- char ly;
- void WriteOut(char x,char y,char Left_mp)
- {
-
- if(y<Y_Min)Y_Min=y;
- else
- if(y>Y_Max)Y_Max=y;
-
- /* 向左搜索*/
- if(x-1)
- {
- if(Left_mp>=map[y][x-1])
- {
- if(Left_mp-map[y][x-1]>out[y][x-1])
- {
- out[y][x-1]=Left_mp-map[y][x-1];
- if((abs(x-tx)+abs(y-ty))<=V_Path)
- {V_Path=abs(x-tx)+abs(y-ty);lx=x;ly=y;}
- WriteOut(x-1,y,Left_mp-map[y][x-1]);
- }
- }
- else
- {
- if((abs(x-tx)+abs(y-ty))<=V_Path)
- {V_Path=abs(x-tx)+abs(y-ty);lx=x;ly=y;}
- }
- }
- /* 向右搜索*/
- if((x+1)<16)
- {
- if(Left_mp>=map[y][x+1])
- {
- if(Left_mp-map[y][x+1]>out[y][x+1])
- {
- out[y][x+1]=Left_mp-map[y][x+1];
- if((abs(x-tx)+abs(y-ty))<=V_Path)
- {V_Path=abs(x-tx)+abs(y-ty);lx=x;ly=y;}
- WriteOut(x+1,y,Left_mp-map[y][x+1]);
- }
- }
- else
- {
- if((abs(x-tx)+abs(y-ty))<=V_Path)
- {V_Path=abs(x-tx)+abs(y-ty);lx=x;ly=y;}
- }
- }
- /* 向上搜索*/
- if(y-1)
- {
- if(Left_mp>=map[y-1][x])
- {
- if(Left_mp-map[y-1][x]>out[y-1][x])
- {
- out[y-1][x]=Left_mp-map[y-1][x];
- if((abs(x-tx)+abs(y-ty))<=V_Path)
- {V_Path=abs(x-tx)+abs(y-ty);lx=x;ly=y;}
- WriteOut(x,y-1,Left_mp-map[y-1][x]);
- }
- }
- else
- {
- if((abs(x-tx)+abs(y-ty))<=V_Path)
- {V_Path=abs(x-tx)+abs(y-ty);lx=x;ly=y;}
- }
- }
- /*向下搜索*/
- if((y+1)<16)
- {
- if(Left_mp>=map[y+1][x])
- {
- if(Left_mp-map[y+1][x]>out[y+1][x])
- {
- out[y+1][x]=Left_mp-map[y+1][x];
- if((abs(x-tx)+abs(y-ty))<=V_Path)
- {V_Path=abs(x-tx)+abs(y-ty);lx=x;ly=y;}
- WriteOut(x,y+1,Left_mp-map[y+1][x]);
- }
- }
- else
- {
- if((abs(x-tx)+abs(y-ty))<=V_Path)
- {V_Path=abs(x-tx)+abs(y-ty);lx=x;ly=y;}
- }
- }
-
- }
- void main()
- {
- char fp;
- char wx;
- char wy;
- char px;
- char py;
- char ii;
- char pv;
- char s[20];
- mp=6;
- fx=7;
- fy=11;
- tx=12;
- ty=4;
- Y_Max=fy;
- Y_Min=fy;
- V_Path=abs(tx-fx)+abs(ty-fy); /* 初试估价权值 */
-
- /* 加1是为了不致减到最后变为0而不好判断范围*/
-
- out[fy][fx]=mp+1;
- WriteOut(fx,fy,mp+1);
- printf("Write Out Ok!\n");
- printf("%d,%d\n",Y_Min,Y_Max);
- printf("%d,%d",lx,ly);
- /* 将行进坐标输出 */
- ii=0;
- px=lx;
- py=ly;
- pv=out[py][px];
- Step[ii][0]=px;
- Step[ii][1]=py;
- i++;
- while(out[py][px]!=mp+1)
- {
- if(out[py][px-1]>pv){pv=out[py][px-1];Step[ii][0]=px-1;Step[ii][1]=py;ii++;px--;}
- else
- if(out[py][px+1]>pv){pv=out[py][px+1];Step[ii][0]=px+1;Step[ii][1]=py;ii++;px++;}
- else
- if(out[py-1][px]>pv){pv=out[py-1][px];Step[ii][0]=px;Step[ii][1]=py-1;ii++;py--;}
- else
- if(out[py+1][px]>pv){pv=out[py+1][px];Step[ii][0]=px;Step[ii][1]=py+1;ii++;py++;}
- }
- /* 输出以打印的寻路暂存图*/
-
- if ((fp=fopen("/LavaData/Out.txt","w"))==0)
- printf("创建文件失败!");
- else {
- for(wy=0;wy<16;wy++)
- {
- for(wx=0;wx<16;wx++)
- {
- out[wy][wx]=out[wy][wx]+48;
- putc(out[wy][wx],fp);
- putc(',',fp);
- }
- putc(13,fp);
- putc(10,fp);
- }
- ii--;
- ii--;
- for(ii;ii>0;ii--)
- {
- sprintf(s,"(%d,%d)\r\n",Step[ii][0],Step[ii][1]);
- fwrite(s,1,strlen(s)+1,fp);
- }
- sprintf(s,"(%d,%d)\r\n",Step[0][0],Step[0][1]);
- fwrite(s,1,strlen(s)+1,fp);
- fclose(fp);
- }
- }
-
复制代码
可输出OUT 文件:
- 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,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,
- 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,0,0,0,0,0,0,0,0,
- 0,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,
- 0,0,0,1,2,2,4,3,3,2,0,0,0,0,0,0,
- 0,0,1,2,3,4,5,4,4,3,2,1,0,0,0,0,
- 0,1,2,3,4,5,6,7,5,4,3,2,1,0,0,0,
- 0,0,1,2,3,3,5,6,5,4,3,2,1,0,0,0,
- 0,0,0,1,2,3,4,5,4,3,2,1,0,0,0,0,
- 0,0,0,0,1,2,3,4,3,2,1,0,0,0,0,0,
- 0,0,0,0,0,1,2,3,2,1,0,0,0,0,0,0,
- (8,11)
- (8,10)
- (8,9)
- (9,9)
- (9,8)
-
复制代码
括号内的为路径坐标,文件中的矩阵是辅助矩阵。
这个方法是可以节约遍历的点数,缺点是不能寻太长的路,4-6步内最佳。
附上原理:
从出发点(FX,FY)开始递归遍历其周围的点,通过遍历生成一个辅助表,其实就是可以移动到的范围,然后估价范围内点到目标点(TX,TY)的最短距离,找到点(LX,LY),然后通过辅助表,从(LX,LY)开始找路,即找点周围比该点MP(out数组里的值)值大的点。
---------------------------------------------------------------------
以此法可以以最少的移动力消耗到达离目标最近的点。
[此贴子已经被作者于2006-6-26 21:33:19编辑过] |