Оператор ЭВМ
Регистрация: 14.08.2013
Сообщений: 27
Написано одно полезное сообщение
|
Ответ: Алгоритм обхода препятствий
Вот алгоритм:
1.Движемся к точке.
2.Если препятсвтие, то...
3.Сканиреуем мир в радиусе двух клеток от юнита на препятствия.
4.Затем, среди каждого проходимого блока ищем точку наимение удалённую от координат дома.(с этим проблем нет)
5. Координаты полученные в п.4 запоминаем и передвигаем юнита к этой точке
6. Продолжаемся двигаться к точке, указанной в п.1, если опять препятсвие повторяем.
Проблема в том, что могут возникнуть препятсвие даже между этой временной точкой. Я присваивал блоку в п.4 значения не проходимого блока и опять запускал процедуру уже не расматривая этот блок, но юнит то стоит на месте, то идет вообще непонятно куда.
type SoldierType = record x,y,wx,wy,ptx,pty,psx,psy,px,py,dir,r,anim,anim_timer,ta,speed: integer;//dir-direction,ta-time attack,wx-world x sel: boolean;//isg-is going end;
var ftp: array[0..26] of integer;// f,g,h,fw: integer;// soldier: array [0..10] of SoldierType; world_sold: array [0..52,0..57] of integer; world: array [0..52,0..57] of integer;
j:=-2; for i:=1 to 25 do begin k[i]:=j; j:=j+1; if j>2 then j:=-2;
if i<5 then l[i]:=-2;else if i<10 then l[i]:=-1;else if i<15 then l[i]:= 0;else if i<20 then l[i]:= 1;else if i<25 then l[i]:= 2; end;//
procedure across(x,y,x1,y1,i: integer;);// begin
for f:=1 to 25 do begin ftp[f]:=abs(x1-x+y1-y); end;
h:=52*57;// Растояние максимальное for f:=1 to 25 do begin if (ftp[f]<=h) and (world_sold[x+k[f],y+l[f]]=-1) then // если находится точка ближе чем предыдущая begin h:=ftp[f];// новое расстояние g:=f;// запоминаем номер end;//ftp<h end;// for f:=1 .....
end;//proc
procedure findway(x,y,x1,y1,i: integer;);//x1=put x, i=№ soldier begin
for f:=1 to 56 do for g:=1 to 51 do begin world_sold[g,f]:=-3;//чистим мир// Думаю это стоит вызывать через определённое время, а не каждый раз, иначе в этом нет смысла end;
if (x>2) and (x<51) and (y>2) and (y<56) then begin for f:=(y-2) to (y+2) do for g:=(x-2) to (x+2) do begin if (world[g,f]>2) and (world[g,f]<7) then world_sold[g,f]:=-2;else//-2 neprohodimuy block world_sold[g,f]:=-1;//-1 prohodimuy end;//for end;//if (x>2) and (x<51) and (y>2) and (y<56)
world_sold[x,y]:=i;// we was here world_sold[x1,y1]:=0;// target
across(x,y,x1,y1,i); // Далее если между выбранной временной точкой и юнитом нет препятсвия то назначаем её, иначе помечаем назначенный блок как непроходимый и запускаем процедуру ещё раз if ((x>x+k[g]) and (y>y+l[g]) and (world_sold[x+k[7], y+l[7]]=-1)) then begin soldier[i].ptx:=(x+k[g]); soldier[i].pty:=(y+l[g]);end;else begin world_sold[x+k[g],y+k[g]]:=1; across(x,y,x1,y1,i); end;//1 if ((x=x+k[g]) and (y>y+l[g]) and (world_sold[x+k[8], y+l[8]]=-1)) then begin soldier[i].ptx:=(x+k[g]); soldier[i].pty:=(y+l[g]);end;else begin world_sold[x+k[g],y+k[g]]:=1; across(x,y,x1,y1,i); end;//2 if ((x<x+k[g]) and (y>y+l[g]) and (world_sold[x+k[9], y+l[9]]=-1)) then begin soldier[i].ptx:=(x+k[g]); soldier[i].pty:=(y+l[g]);end;else begin world_sold[x+k[g],y+k[g]]:=1; across(x,y,x1,y1,i); end;//3 if ((x<x+k[g]) and (y=y+l[g]) and (world_sold[x+k[12],y+l[12]]=-1)) then begin soldier[i].ptx:=(x+k[g]); soldier[i].pty:=(y+l[g]);end;else begin world_sold[x+k[g],y+k[g]]:=1; across(x,y,x1,y1,i); end;//4 if ((x>x+k[g]) and (y=y+l[g]) and (world_sold[x+k[14],y+l[14]]=-1)) then begin soldier[i].ptx:=(x+k[g]); soldier[i].pty:=(y+l[g]);end;else begin world_sold[x+k[g],y+k[g]]:=1; across(x,y,x1,y1,i); end;//6 if ((x>x+k[g]) and (y<y+l[g]) and (world_sold[x+k[17],y+l[17]]=-1)) then begin soldier[i].ptx:=(x+k[g]); soldier[i].pty:=(y+l[g]);end;else begin world_sold[x+k[g],y+k[g]]:=1; across(x,y,x1,y1,i); end;//7 if ((x=x+k[g]) and (y<y+l[g]) and (world_sold[x+k[18],y+l[18]]=-1)) then begin soldier[i].ptx:=(x+k[g]); soldier[i].pty:=(y+l[g]);end;else begin world_sold[x+k[g],y+k[g]]:=1; across(x,y,x1,y1,i); end;//8 if ((x<x+k[g]) and (y<y+l[g]) and (world_sold[x+k[19],y+l[19]]=-1)) then begin soldier[i].ptx:=(x+k[g]); soldier[i].pty:=(y+l[g]);end;else begin world_sold[x+k[g],y+k[g]]:=1; across(x,y,x1,y1,i); end;//9
DrawText('Searching...',100,100);
end;//procedure
|