Показать сообщение отдельно
Старый 17.03.2014, 22:17   #9
.:MaSe:.
Оператор ЭВМ
 
Регистрация: 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,speedinteger;//dir-direction,ta-time attack,wx-world x
selboolean;//isg-is going
  
end;

var
ftp: array[0..26of integer;// 
f,g,h,fwinteger;// 
soldier: array [0..10of SoldierType;
world_sold: array [0..52,0..57of integer;
world: array [0..52,0..57of 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,iinteger;);// 
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]]=-1then // если находится точка ближе чем предыдущая
begin 
h
:=ftp[f];// новое расстояние
g:=f;// запоминаем номер
end;//ftp<h
end;// for f:=1 .....

end;//proc

procedure findway(x,y,x1,y1,iinteger;);//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<56then
begin
for f:=(y-2to (y+2) do
for 
g:=(x-2to (x+2) do
begin
if (world[g,f]>2) and (world[g,f]<7then 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]]:=1across(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]]:=1across(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]]:=1across(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]]:=1across(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]]:=1across(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]]:=1across(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]]:=1across(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]]:=1across(x,y,x1,y1,i); end;//9

DrawText('Searching...',100,100);

end;//procedure 
(Offline)
 
Ответить с цитированием