Forum in READ ONLY mode! All questions and discussions on Discord official server, invite link: https://discord.gg/VxsGzJ7

Ходилка SomeBody.

Only working scripts
grundick
Developer
Developer
Posts: 272
Joined: 31.01.2008 21:16

Ходилка SomeBody.

Post by grundick »

Чутка поправил. Теперь правильно считается расстояние и ходит по прямой(Спасиб Beyonderu ).

Code: Select all

// написал Somebody. ICQ: 475728522 e-mail: [email protected]

// Реализация алгоритма "надёжной трассировки"
// http://pmg.org.ru/ai/stout.htm#robust_trace

const 
FMoveArrMax = 300; // ставь здесь больше, если твой чар ходит на дистанции больше 13 тайлов или вокруг чара очень много препятствий. Если препятствий на пути мало, то можно оставить как есть. 
var 
PrognosisX, PrognosisY, FMoveArrCount : integer; 
FMoveArr : array [1..FMoveArrMax] of array [1..2] of smallint; 


Function Abs(A: integer): integer;
Begin
If A>=0 then result:=A 
Else result:=0-A;
End;

function SetDirection(x, y : integer) : integer; 
var
   MyX,MyY,DiffX,DiffY,GoDir: integer;
Begin
MyX:=GetX(self);
MyY:=GetY(self);
DiffX:=Abs(MyX-x);
DiffY:=Abs(MyY-y);

if (DiffX/(DiffY+0.1))>=2 then 
   begin
   if (MyX>X) then 
      GoDir:=6 
   else 
      GoDir:=2; 
   end  
else 
   
   if (DiffY/(DiffX+0.1))>=2 then 
      begin
      if (MyY>Y) then 
         GoDir:=0 
      else 
         GoDir:=4;
      end  
   else 
        
      if (MyX>X) and (MyY>Y) then  GoDir:=7
      else 

        if (MyX>X) and (MyY<Y) then  GoDir:=5 
        else 

           if (MyX<X) and (MyY>Y) then  GoDir:=1 
           else 

             if (MyX<X) and (MyY<Y) then  GoDir:=3; 
             
result:=GoDir;
end;


procedure CalcPrognosis(Dir : integer); 
begin 
   if (Dir = 1) or (Dir = 2) or (Dir = 3) then PrognosisX := GetX(self) + 1; 
   if (Dir = 5) or (Dir = 6) or (Dir = 7) then PrognosisX := GetX(self) - 1; 
   if (Dir = 0) or (Dir = 4) then PrognosisX := GetX(self); 

   if (Dir = 3) or (Dir = 4) or (Dir = 5) then PrognosisY := GetY(self) + 1; 
   if (Dir = 7) or (Dir = 0) or (Dir = 1) then PrognosisY := GetY(self) - 1; 
   if (Dir = 2) or (Dir = 6) then PrognosisY := GetY(self); 
end; 

function TryToMove(Direction : integer; RunFlag : boolean) : boolean; 
begin 
   if GetDirection(self) <> Direction then Raw_Move(Direction, RunFlag); 
   result := Raw_Move(Direction, RunFlag); 
end; 

function WrongMove(x, y : integer) : boolean; 
var 
i : integer; 
begin 
   result := false; 
   if FMoveArrCount = 0 then exit; 
   for i := 1 to FMoveArrCount do 
      begin 
      if (x = FMoveArr[i][1]) and (y = FMoveArr[i][2]) then 
         begin 
         result := true; 
         exit; 
         end; 
      end; 
end; 


function Min(x,y: integer): integer;
begin
 if x>y then Result:=y else Result:=x;
end;

function HEst(x,y: integer): integer;
var dx,dy,Ddx : integer;
begin
  dx:= GetX(self)-x;
  dy:= GetY(self)-y;
  Ddx:= dx-dy;
  If dx<0 then dx:=0-dx;
  If dy<0 then dy:=0-dy;
  If Ddx<0 then Ddx:=0-Ddx;
  Result:= min(dx,dy)+Ddx;
end;

procedure SetWrongMove(x, y : integer); 
begin 
   FMoveArrCount := FMoveArrCount + 1; 
   FMoveArr[FMoveArrCount][1] := x; 
   FMoveArr[FMoveArrCount][2] := y; 
end; 

function RewindDir(Dir, c : integer) : integer; 
begin 
   result := Dir + c; 
   if result < 0 then result := result + 8; 
   if result > 7 then result := result - 8; 
end; 

function Move(x, y, tolerance : integer) : boolean; 
var 
Dir, Dist, lastX, lastY, t, i, timeout : integer; 
begin 
   FMoveArrCount := 0; 
   Dist := HEst(x, y); 
   timeout := Dist * 13000; // 13 секунд времени на шаг 
   t := timer; 
   while true do 
      begin 
      Dist := HEst(x, y); 
      if Dist <= tolerance then // пришёл 
         begin 
         result := true; 
         exit; 
      end; 
      if timer - t > timeout then // провал по таймауту 
      begin 
         AddToSystemJournal('Move: Time moved out!'); 
         result := false; 
         exit; 
      end; 
      Dir := SetDirection(x, y); 
      CalcPrognosis(Dir); 
      if WrongMove(PrognosisX, PrognosisY) then 
         begin 
         for i := 1 to 7 do 
            begin 
            Dir := RewindDir(Dir, 1); 
            CalcPrognosis(Dir); 
            if not WrongMove(PrognosisX, PrognosisY) then break; 
            end; 
      if i = 8 then 
         begin 
         AddToSystemJournal('Move: Cannot move'); 
         result := false; 
         exit; 
         end; 
      end; 
      timeout := timeout + CheckFlow; 
      lastX := GetX(self); lastY := GetY(self); 
      if TryToMove(Dir, false) then SetWrongMove(lastX, lastY) // отсюда чар пришёл 
      else SetWrongMove(PrognosisX, PrognosisY); 
      end; 
end; 

procedure _move(x, y, tolerance : integer); 
begin 
while not Move(x, y, tolerance) do wait(100); 
end;
Edred
Moderator
Moderator
Posts: 559
Joined: 28.03.2006 21:29

Post by Edred »

Неплохо было бы снабдить подобный пост комментариями и инструкциями. Для чайников. Типа: "Вставьте этот код в текст своего файла скрипта в раздел функций. Вызывать процедуру _move с такими-то параметрами".
grundick
Developer
Developer
Posts: 272
Joined: 31.01.2008 21:16

Post by grundick »

Дык чуть выше (Sticky: Ходилка с обходом препятствий) всё есть.Эхх, выложили б пока релиз с проверкой тайлов на проходимость... : :roll:
Edred
Moderator
Moderator
Posts: 559
Joined: 28.03.2006 21:29

Post by Edred »

Не, так не пойдет. Возьми из прилепленной темы все описание и внеси его в первый пост.

После этого я перенесу из прилепленной темы все обсуждение в этот топик. Прилепленную тему удалю, а эту - прилеплю.
RaTaMaHaTTa
Novice
Novice
Posts: 89
Joined: 16.06.2008 12:22
Location: <||TORCHKI||>
Contact:

Post by RaTaMaHaTTa »

Как юзать её :roll:
-=JoKeR=-
Novice
Novice
Posts: 153
Joined: 10.02.2008 11:19
Location: [Forest Wars] Ode$$a

Post by -=JoKeR=- »

RaTaMaHaTTa wrote:Как юзать её :roll:
Почитай =)
http://stealth.od.ua/forum/viewtopic.php?t=996
RaTaMaHaTTa
Novice
Novice
Posts: 89
Joined: 16.06.2008 12:22
Location: <||TORCHKI||>
Contact:

Post by RaTaMaHaTTa »

-=JoKeR=- wrote:
RaTaMaHaTTa wrote:Как юзать её :roll:
Почитай =)
http://stealth.od.ua/forum/viewtopic.php?t=996
Да я то почитал но там всё кусками так брр
понел токо из скрипта вызвать можно процедурой

Code: Select all

procedure _move(1234, 1234, 0); 
Но вот чёто у меня не получилось Ш (
-=JoKeR=-
Novice
Novice
Posts: 153
Joined: 10.02.2008 11:19
Location: [Forest Wars] Ode$$a

Post by -=JoKeR=- »

так не, зачем

Code: Select all

procedure _move(1234, 1234, 0);
нужно

Code: Select all

move(1234,1234,0)
или

Code: Select all

_move(1234,1234,0)
не знаю, не пользовался этой ходилой, вот сейчас пишу програмку себе и проверю заодно как она себя ведёт, эта ходилка

PS
кто-то юзал её? как она в действии?
v26RuS
Novice
Novice
Posts: 61
Joined: 18.05.2008 16:07
Location: DRW
Contact:

Post by v26RuS »

Я пользуюсь это ходилкой для лумбера нормально ходить обходит все препятствия и вообще норм ходилка меня во всем устраивает...
Невозможное возможнО!
-=JoKeR=-
Novice
Novice
Posts: 153
Joined: 10.02.2008 11:19
Location: [Forest Wars] Ode$$a

Post by -=JoKeR=- »

юзать так:

Code: Select all

_move(CoordX,CoordY,1/0)
классная ходилкО =)
Unholy
Novice
Novice
Posts: 119
Joined: 23.06.2008 2:26
Location: DRW

Post by Unholy »

_move(CoordX,CoordY,1/0)
За что отвечает этот переключатель?
-=JoKeR=-
Novice
Novice
Posts: 153
Joined: 10.02.2008 11:19
Location: [Forest Wars] Ode$$a

Post by -=JoKeR=- »

Извиняюсь, не 1\0, а вот как:
_move(x, y, tolerance);
tolerance - дистанция, на которую чар подойдёт к (x, y)
grundick
Developer
Developer
Posts: 272
Joined: 31.01.2008 21:16

Post by grundick »

не знаю как у вас ,но меня этот 13ти секукндный таймаут при столкновении с препятствием просто убивал :( зачастую в буквальном смысле слова!
-=JoKeR=-
Novice
Novice
Posts: 153
Joined: 10.02.2008 11:19
Location: [Forest Wars] Ode$$a

Post by -=JoKeR=- »

незнаю...
у меня нет препятствий =)
v26RuS
Novice
Novice
Posts: 61
Joined: 18.05.2008 16:07
Location: DRW
Contact:

Post by v26RuS »

Пользоваться ходилкой можно двумя способами
1-й
move(Кордината x, Кордината y, Количество погрешности тайла*);
В данном случаи может слететь по таймауту на переход

или 2-й вариант
_move(Кордината x, Кордината y, Количество погрешности тайла*);
Будет идти до цели не обращая внимание на таймаут


*Количество тайлов за которое остановиться не доходя до цели. Очень удобно для лумбера ставим 1 и берем из файла кориднаты именно дерева и он не будет лезть на дерево а остановиться перед ним.

Вроде доступно описал)) Если что-то не так написал извените)
Невозможное возможнО!
Post Reply