[SAIL][AI] Skan terenu, ucieczka od przeciwnika.

Wszelkie pytania na temat SAIL'a i modowania OW.
Post Reply
User avatar
Xero Rozbójca
Soldier level 6
Soldier level 6
Posts: 391
Joined: Sun Mar 08, 2009 5:13 pm
Location: Szukaj w kioskach...

[SAIL][AI] Skan terenu, ucieczka od przeciwnika.

Post by Xero Rozbójca »

Witam wszystkich zgromadzonych:)
Po krótce: chciałbym by ktoś pomógł z napisaniem poprawnego kodu.
Założenia:
1) Pojazd 'RADIO' ma za zadanie wycofać się, gdy natrafi na jednostkę, która go zaatakuje, na bezpieczną odległość ( w tym wypadku 10 hexów ).
2) [jeszcze nieuwzględnione] 'RADIO' ma samemu znajdować drogę powrotną wśród drzew, budynków lub innych obiektów.

Code: Select all

var enemy;
var x,y,px,py,dir,dir2;
var d_c_unit, c_unit;
var dir_shot, dir_abs;

starting
begin


RandomizeAll;

prepare1;
ladowanie;

end;


Function prepare1;
begin
loop:=false;

enemy:=FilterAllUnits([f_side,3]);
SetAttitude(1,3,att_enemy,true);
ComHold(enemy[1]);
end;



function ladowanie;
begin
repeat
c_unit:=NearestUnitToUnit(FilterAllUnits([f_enemy, 1]),radio);
d_c_unit:=GetDistUnits(c_unit,radio);

SetSide(c_unit, rand(2,8));
wait(0$1);
until d_c_unit <1;
end;



every 0$2 trigger d_c_unit <=10 do
begin

repeat
skan;
wait(0$1);
until d_c_unit > 10;
enable;
end;

var loop;

Function skan;
var x2,y2;
begin

px:=GetX(radio);
py:=GetY(radio);
dir:=GetDir(radio);
wait(0$0.5);

dir_shot:=SideShoot(radio);
{ x:=ShiftX(px, dir, d_c_unit);
y:=ShiftY(py, dir, d_c_unit); }

If dir_shot>=0 then
   begin
   x:=ShiftX(px, ABS(dir_shot+dir), d_c_unit);
   y:=ShiftY(py, ABS(dir_shot+dir), d_c_unit);
 If ValidHex(x,y) then      {jesli hex jest poprawny}
   ComMoveXY(radio,x,y)    {to pojedzie na X,Y}
   else begin
      For dir2:=0 to 5 do   {Jesli nie, to zmieni kierunek}
       begin
    x:=ShiftX(px, dir2, d_c_unit);
     y:=ShiftY(py, dir2, d_c_unit);
         If ValidHex(x,y) then         {analogicznie}
           ComMoveXY(radio,x,y)       {wybrany nowy hex poprawny}
         else begin end;            {to odjezdza}
   end;
end;
end;

Function ABS(z);
begin
  If (z>=0) and (z<=5) then
    result:=z
    else if z<0 then
      result:=-z
      else if (z>5) then
        result:=z mod 5;
end;
"Osoby, stawiające więcej niż trzy znaki interpunkcyjne obok siebie, mają problemy ze zdrowiem psychicznym."

Image
User avatar
Serpent
Soldier level 10
Soldier level 10
Estonia
Posts: 4175
Joined: Tue Jul 07, 2009 9:13 pm
Location: Polska - EuroStan ZSRE
Contact:

Re: [SAIL][AI] Skan terenu, ucieczka od przeciwnika.

Post by Serpent »

Z tego co tam widziałem to McBeen w swoich skryptach w ar_camp miał podobny kod na ucieczkę, możesz sprawdzić. Jednak jak ci tak bardzo zależy to spróbuję coś wykminić ;D


EDIT:
Znalazłem coś takiego w MA:
http://forum.original-war.net/viewtopic.php?f=18&t=2253
Epickie teksty:
Marek1906: jak zrobic aby sail był zielony?
Kvantovy: Wszystko normalne, wszystko w koło było dziwne
Kvantovy:: To jest fajne, że to nie jest takie głupie
Kvantovy:: remove sos from kanapeczka
Kvantovy:: zdarzają się rzezy które sie filozofom nie śniły
Cenwen: problemem jest gejostwo
"Taki z niego fizyk jak ze mnie baletnica" - Profesor Scholtze o Kvantovym.
JAKBYŁ BYM CZECHEM TO BYM ROZŁOŻYŁ NAMIOT ~Kvanciak
User avatar
Xero Rozbójca
Soldier level 6
Soldier level 6
Posts: 391
Joined: Sun Mar 08, 2009 5:13 pm
Location: Szukaj w kioskach...

Re: [SAIL][AI] Skan terenu, ucieczka od przeciwnika.

Post by Xero Rozbójca »

@Serpent
Właśnie o coś takiego mi się rozchodziło :P

W każdym razie można do tego wątku w MA dodać mój kod. Przy wyjściu koordynatów poza mapę zmienia kierunek. Testowany.

Code: Select all

 If ValidHex(x,y) then      {jesli hex jest poprawny}
   ComMoveXY(radio,x,y)    {to pojedzie na X,Y}
   else begin
      For dir2:=0 to 5 do   {Jesli nie, to zmieni kierunek}
       begin
    x:=ShiftX(px, dir2, d_c_unit);
     y:=ShiftY(py, dir2, d_c_unit);
         If ValidHex(x,y) then         {analogicznie}
           ComMoveXY(radio,x,y)       {wybrany nowy hex poprawny}
         else begin end;            {to odjezdza}
   end;
end;

#EDIT:
Tak wygląda obecny kod w module AI_odwrot. Nadal się w niektórych miejscach wiesza, ale pikuś :P
Spoiler:

Code: Select all

Export Function odwrot(un, dist);

var d_c_unit, c_unit;
var x,y,px,py,dir,dir2;
var dir_shot, dir3;
var x2,y2;

begin

c_unit:=NearestUnitToUnit(FilterAllUnits([f_enemy, GetSide(un)]),un);
d_c_unit:=GetDistUnits(c_unit,un);

px:=GetX(un);
py:=GetY(un);
dir:=GetDir(un);

dir_shot:=SideShoot(un);
dir3:=dir_f(dir_shot);



 While true do
 begin
 odwrot_z:=true;
 Wait(0$1);  {okienko do wyjscia do edytora bez zawieszenia sie}
   x:=ShiftX(GetX(un), dir_f(dir_shot), d_c_unit);
   y:=ShiftY(GetY(un), dir_f(dir_shot), d_c_unit);
 If ValidHex(x, y) then      {jesli hex jest poprawny}
   ComMoveXY(un,x,y)        {to pojedzie na X,Y}
   else begin
      For dir2:=0 to 5 do   {Jesli nie, to zmieni kierunek}
       begin
    x:=ShiftX(GetX(un), dir2, d_c_unit);
    y:=ShiftY(GetY(un), dir2, d_c_unit);
         If ValidHex(x, y) then         {analogicznie}
            ComMoveXY(radio,x,y)       {wybrany nowy hex poprawny}
         else begin end;            {to odjezdza}
       end; {for dir2...}
    end; {if (1)ValidHex}

  if IsEnvironment(ShiftX(GetX(un),GetDir(un), 2),
                   ShiftY(GetY(un),GetDir(un), 2)) then
          begin
            repeat
             // d_c_unit := d_c_unit + 1;

              x := ShiftX(GetX(un), dir_f(dir_shot+1), d_c_unit);
              y := ShiftY(GetY(un), dir_f(dir_shot+1), d_c_unit);
            until not IsEnvironment(ShiftX(GetX(un),GetDir(un), 2),
                                    ShiftY(GetY(un),GetDir(un), 2));
          end;

  If IsAt(FilterAllUnits([f_or,
                                   [f_type, unit_vehicle],
                                   [f_type, unit_vehicle],
                                   [f_type, unit_building]]),
              ShiftX(GetX(un),GetDir(un), 2),
              ShiftY(GetY(un),GetDir(un), 2)) then
       begin
          dir3 :=dir3 + 1;

          x := ShiftX(GetX(un), dir3, d_c_unit);
          y := ShiftY(GetY(un), dir3, d_c_unit);
       end;

    if GetDistUnits(un, NearestUnitToUnit(FilterAllUnits([f_enemy, GetSide(un)]), un)) >= dist then
          begin
            AddComStop(un);
            odwrot_z:=false;
            break;
          end;
 end; {while}
end;
a tak sdasdasddssa:
Spoiler:

Code: Select all

var enemy;
var zad_radio;



Function prepare1;
begin

enemy:=FilterAllUnits([f_side,3]);
SetAttitude(1,3,att_enemy,true);
ComHold(enemy[1]);
end;



function ladowanie;
var d_c_unit, c_unit;
begin
  repeat
c_unit:=NearestUnitToUnit(FilterAllUnits([f_enemy, 1]),radio);
d_c_unit:=GetDistUnits(c_unit,radio);

SetSide(c_unit, rand(2,8));
wait(0$1);
  until d_c_unit <1;
end;


every 0$1 do
begin
ComMoveXY(radio, 29,4);
AddComMoveXY(radio, 35,46);
AddComMoveXY(radio, 47,64);
AddComMoveXY(radio, 50,49);
AddComMoveXY(radio, 68,63);
end;

///////////////////////////////////////////////////////
// AI odwrot /////
//////////////////
export odwrot_z;

every 0$2 trigger GetDistUnits(NearestUnitToUnit(FilterAllUnits([f_enemy, 1]),radio),radio) <=10 do
begin
If not odwrot_z then
 begin        
   zad_radio:=GetTaskList(radio);
   odwrot_z:=false;
 end;
If GetDistUnits(NearestUnitToUnit(FilterAllUnits([f_enemy, 1]),radio),radio) < 15 then
  begin
    
    odwrot(radio, 15);
    wait(0$3);
    SetTaskList(radio, zad_radio);
  end;
  enable;
end;

//////////////////////////////////////////////////////

starting
begin
RandomizeAll;

prepare1;
ladowanie;
end;

////////////////////////////////////////////
Export Function ABS(z);
begin
  If (z>=0) and (z<=5) then
    result:=z
    else if z<0 then
      result:=-z
      else if (z>5) then
        result:=z mod 5;
end;

Export function dir_f(t); {odwrócenie kierunku}
begin
t := t - 3;
    if t < 0 then
      t := t + 6;
result:= t;
end

#EDIT 2:

Jest jakiś sposób, by "sprzęgnąć" ze sobą dwie funkcje?
Chodzi mi o to, by rezultat funkcji obrot(un) zależał od reachable_m(un, dir, dist) i odwrotnie.
Spoiler:

Code: Select all

export function obrot(un);  // rezultat - kierunek d.
var t, d;
begin
d:=GetDir(un);
  For t:=0 to 5 do
  begin
     d:=d + 1;
     If d>5 then
        begin
         d:=0;
        end;
     If pomocnicza_zmienna=true then
        begin
        result:=d;
        break;
        end;
   end;
end;

export pomocnicza_zmienna;

Export function reachable_m(un, dir, dist);
var x,y;
begin
    pomocnicza_zmienna:=false;
    x:=ShiftX(GetX(un), obrot(un), dist);
    y:=ShiftY(GetY(un), obrot(un), dist);

      If ValidHex(x, y) then
        pomocnicza_zmienna:=true
        else
        pomocnicza_zmienna:=false;

end;
"Osoby, stawiające więcej niż trzy znaki interpunkcyjne obok siebie, mają problemy ze zdrowiem psychicznym."

Image
User avatar
Serpent
Soldier level 10
Soldier level 10
Estonia
Posts: 4175
Joined: Tue Jul 07, 2009 9:13 pm
Location: Polska - EuroStan ZSRE
Contact:

Re: [SAIL][AI] Skan terenu, ucieczka od przeciwnika.

Post by Serpent »

Dobra, wykminiłem taką oto funkcję, która bazuję na funkcji z linku który podałem wcześniej:

Funkcja uwzględnia wszelkie przeszkody terenowe, tereny niedostępne, koordynaty poza mapą, budynki i materiały (skrzynki, beczki).

Code: Select all

Export Function ComRetreat(un);
var coord_dist, dir, x, y;
begin

    ComTurnUnit(un, NearestUnitToUnit(FilterAllUnits([f_enemy, GetSide(un)]), un));
    dir := GetDir(un);

    dir := dir - 3;

    if dir < 0 then
       dir := dir + 6;

    While true do
    begin
        coord_dist := 3;

        x := ShiftX(GetX(un), dir, coord_dist);
        y := ShiftY(GetY(un), dir, coord_dist);

        if IsEnvironment(x, y) or ValidHex(x, y) = 0 or InArea(x, y, HexEmpty) = 0 or HexInfo <> 0 then
           begin

           Repeat
            begin
              coord_dist := coord_dist + 1;
              dir := dir + 1;

              if dir > 5 then
                 dir = 0;

              x := ShiftX(GetX(un), dir, coord_dist);
              y := ShiftY(GetY(un), dir, coord_dist);
            end
           Until not IsEnvironment(x, y) and ValidHex(x, y) and InArea(x, y, HexEmpty) and HexInfo = 0;

           end;

        AddComMoveXY(un, x, y);
        Wait(0$1);

        if GetDistUnits(un, NearestUnitToUnit(FilterAllUnits([f_enemy, GetSide(un)]), un)) >= 16 then
           begin
            ComStop(un);
            break;
           end;

      end;


End;

Wklejamy gdzieś kodzik i można używać. Jednak wcześniej wyznaczyć trzeba aree obszaru po którym można chodzić (earth, rock, road... itd.). Nazywamy ją HexEmpty.


Kod był testowany i działa.
Last edited by Serpent on Wed Nov 19, 2014 2:11 pm, edited 2 times in total.
Epickie teksty:
Marek1906: jak zrobic aby sail był zielony?
Kvantovy: Wszystko normalne, wszystko w koło było dziwne
Kvantovy:: To jest fajne, że to nie jest takie głupie
Kvantovy:: remove sos from kanapeczka
Kvantovy:: zdarzają się rzezy które sie filozofom nie śniły
Cenwen: problemem jest gejostwo
"Taki z niego fizyk jak ze mnie baletnica" - Profesor Scholtze o Kvantovym.
JAKBYŁ BYM CZECHEM TO BYM ROZŁOŻYŁ NAMIOT ~Kvanciak
User avatar
Xero Rozbójca
Soldier level 6
Soldier level 6
Posts: 391
Joined: Sun Mar 08, 2009 5:13 pm
Location: Szukaj w kioskach...

Re: [SAIL][AI] Skan terenu, ucieczka od przeciwnika.

Post by Xero Rozbójca »

Jesteś pewien, że uwzględnia to także budynki blokujące drogę? :P
"Osoby, stawiające więcej niż trzy znaki interpunkcyjne obok siebie, mają problemy ze zdrowiem psychicznym."

Image
User avatar
Serpent
Soldier level 10
Soldier level 10
Estonia
Posts: 4175
Joined: Tue Jul 07, 2009 9:13 pm
Location: Polska - EuroStan ZSRE
Contact:

Re: [SAIL][AI] Skan terenu, ucieczka od przeciwnika.

Post by Serpent »

Teraz już tak, zapomniałem o tym ;p
Epickie teksty:
Marek1906: jak zrobic aby sail był zielony?
Kvantovy: Wszystko normalne, wszystko w koło było dziwne
Kvantovy:: To jest fajne, że to nie jest takie głupie
Kvantovy:: remove sos from kanapeczka
Kvantovy:: zdarzają się rzezy które sie filozofom nie śniły
Cenwen: problemem jest gejostwo
"Taki z niego fizyk jak ze mnie baletnica" - Profesor Scholtze o Kvantovym.
JAKBYŁ BYM CZECHEM TO BYM ROZŁOŻYŁ NAMIOT ~Kvanciak
User avatar
Xero Rozbójca
Soldier level 6
Soldier level 6
Posts: 391
Joined: Sun Mar 08, 2009 5:13 pm
Location: Szukaj w kioskach...

Re: [SAIL][AI] Skan terenu, ucieczka od przeciwnika.

Post by Xero Rozbójca »

No oke, działa. A teraz możemy podyskutować o funkcjach poniżej. Co o nich sądzisz i dlaczego są zbugowane? :D

#1:
Spoiler:

Code: Select all

Export function RevertedDir(t); {odwrócenie kierunku}
var g;
begin
g := GetDir(t);
g := g - 3;
    if g < 0 then
      g := g + 6;
result:= g;
end;
#2:
Spoiler:

Code: Select all

export function ChangeDirection(un);  // rezultat - kierunek d.
var cx,cy,t, d, task;
begin
d:=GetDir(un);
  For t:=0 to 5 do
  begin
     d:=d + 1;
     wait(0$0.25); // zawor bezpieczenstwa
     If d>5 then
          d:=0;
     If isReachableBy(un, d, 2) and not isFrontBlocking(un) then
        begin
           ComMoveXY(un, ShiftX(GetX(un), d, 3), ShiftY(GetY(un), d, 3));
        exit;
       end;
   end;
end;
#3:
Spoiler:

Code: Select all

Export function isReachableBy(un, d, dist);
var x,y;
begin
    x:=ShiftX(GetX(un), d, dist);
    y:=ShiftY(GetY(un), d, dist);

      If not isEnvironment(x,y) and ValidHex(x, y) then
        result:=true
        else
        result:=false;

end;
#4:
Spoiler:

Code: Select all

Export function isFrontBlocking(un);
begin
If HexInfo(ShiftX(GetX(un),GetDir(un), 2),
              ShiftY(GetY(un),GetDir(un), 2))=-1 then
  result:=true;
end;
"Osoby, stawiające więcej niż trzy znaki interpunkcyjne obok siebie, mają problemy ze zdrowiem psychicznym."

Image
User avatar
Serpent
Soldier level 10
Soldier level 10
Estonia
Posts: 4175
Joined: Tue Jul 07, 2009 9:13 pm
Location: Polska - EuroStan ZSRE
Contact:

Re: [SAIL][AI] Skan terenu, ucieczka od przeciwnika.

Post by Serpent »

Od początku:

#1
Spoiler:

Code: Select all

Export function RevertedDir(t); {odwrócenie kierunku}
var g;
begin
g := GetDir(t);
g := g - 3;
    if g < 0 then
      g := g + 6;
result:= g;
end;
Założenia są dobre, tylko nie rozumiem po co eksportować kierunek skoro od razu można obrócić jednostkę.

Moja funkcja #1:
Spoiler:

Code: Select all

Export function SetCDir(un); {odwrócenie kierunku}
var dir, x, y;
begin
dir := GetDir(un);
dir := dir - 3;

    if dir < 0 then
       dir := dir + 6;

x := ShiftX(GetX(un), dir, 1);
y := ShiftY(GetY(un), dir, 1);

ComTurnXY(un, x, y);
end;

Druga funkcja jest pokręcona, nie rozumiem co ona ma robić?

Code: Select all

For t:=0 to 5 do
  begin
     d:=d + 1;
     wait(0$0.25); // zawor bezpieczenstwa
     If d>5 then
          d:=0;
     If isReachableBy(un, d, 2) and not isFrontBlocking(un) then
        begin
           ComMoveXY(un, ShiftX(GetX(un), d, 3), ShiftY(GetY(un), d, 3));
Jest pętla w której co chwile zmieniasz kierunek, postać więc nie będzie szła w linii prostej tylko będzie kręcić bączki. "exit" jest niepotrzebny, zamiast tego trzeba było dać break'a.

Dwie pozostałe funkcje wyglądają dobrze.
Epickie teksty:
Marek1906: jak zrobic aby sail był zielony?
Kvantovy: Wszystko normalne, wszystko w koło było dziwne
Kvantovy:: To jest fajne, że to nie jest takie głupie
Kvantovy:: remove sos from kanapeczka
Kvantovy:: zdarzają się rzezy które sie filozofom nie śniły
Cenwen: problemem jest gejostwo
"Taki z niego fizyk jak ze mnie baletnica" - Profesor Scholtze o Kvantovym.
JAKBYŁ BYM CZECHEM TO BYM ROZŁOŻYŁ NAMIOT ~Kvanciak
User avatar
Xero Rozbójca
Soldier level 6
Soldier level 6
Posts: 391
Joined: Sun Mar 08, 2009 5:13 pm
Location: Szukaj w kioskach...

Re: [SAIL][AI] Skan terenu, ucieczka od przeciwnika.

Post by Xero Rozbójca »

Wydaje mi się, że miała ona na celu zmianę kierunku jednostki, gdy na przeciwko niej jest jakaś przeszkoda, potem ruszenie się w dostępnym kierunku i wyjście z pętli for tak, by nie zmieniało kierunku bez przerwy.
"Osoby, stawiające więcej niż trzy znaki interpunkcyjne obok siebie, mają problemy ze zdrowiem psychicznym."

Image
Post Reply