Page 1 of 1

Расстояние до цели

Posted: 14.01.2013 13:01
by shinma
Готовое решение внизу темы



Подскажите хотя бы на словах алгоритм
есть куча мобов разных типов
надо найти самого ближнего и дать мне его ID

вот моя тестовая наработка

и к да если использовать
NewMoveXY после этого и Цель находится в доме за дверями, то очень часто NewMoveXY просто не находит путь.
Бывает ситуация когда все таки зашел в дом, но выйти нельзя.

С дверями вопрос решил
добавить в
procedure Init;
moveOpenDoor := True;

но остается еще одна проблема
как мне получить массив ID монстров
т.к. FindType(monstro[ll],Ground); не дает никаких гарантий, что найдет дальнего моба или ближнего. она может сработать 20 раз и все 20 будут на дальнем мобе, и не разу не возьмет ближнего. я не знаю как это обойти.


FindType(monstro[ll],Ground);

Code: Select all

Program New;
var  
monstro:array of word;
dlinmass:array [0..3] of Cardinal; 
iskomoe:Cardinal;
l:integer;
procedure Init;
begin
monstro:=[$0032,$0099,$0038,$0003];
FindDistance:=15;
end;        
function sqr(a:LongInt):LongInt;
begin
 result:=a*a;
end;

function vector_length(c_1,c_2:TFoundTile):LongInt;
begin
 result:=Round(sqrt(sqr(c_1.X-c_2.X)+sqr(c_1.Y-c_2.Y)));
end;
function dlinna(massive:array of Cardinal):Cardinal;
var
i:integer;
vekorB,vektorA:LongInt;
t_c:TFoundTile;
t_c2:TFoundTile;
targetVektor:Cardinal;
begin
vektorA:=999;
t_c.x:=GetX(Self);
t_c.y:=GetY(Self);
for i:=0 to  (GetArrayLength(massive)-1) do
  if massive[i]<>0 then
  begin
  t_c2.x:=GetX(massive[i]);
  t_c2.y:=GetY(massive[i]);
  vekorB:=vector_length(t_c,t_c2); 
  if  vekorB < vektorA  then
  vektorA:=vekorB;
  targetVektor:=massive[i];
  end;
 result:=targetVektor; 
end;

function sozdmass(ll:integer):Cardinal;
var
massMobo:array [0..999] of Cardinal;
j,jj:integer;
begin
 FindType(monstro[ll],Ground);
 if FindCount>0 then  
 for j:=0 to 10 do
  begin 
  FindType(monstro[ll],Ground);
  for jj:=0 to 999  do 
      begin
        if finditem <> massMobo[j] then
        massMobo[j]:=finditem;
      end;
  end;
result:=dlinna (massMobo);
end;

begin
Init;  
 for l:=0 to  (GetArrayLength(monstro)-1) do 
 begin
 dlinmass[l]:=sozdmass(l); 
 AddToSystemJournal('l = '+inttostr(l));
 end; 
 iskomoe:=dlinna(dlinmass);
AddToSystemJournal('Самый ближний моб '+GetName(iskomoe)+', ИД ='+ inttohex(iskomoe,8));
end.

Re: Расстояние до цели

Posted: 14.01.2013 20:29
by nah nah

Code: Select all

bad_list = []

def find_mob():
    distance = 9999                       #ставим большую дистанцию для сравнения
    cur_mob = False                   #переменная для текущего моба
    for mob in mobs_array:             #перебираем массив
        while FyndType(mob, Ground()):           #перебираем всех мобов конкретного типа
            if GetDistance(FindItem()) < distance and not FindItem() in bad_list:                     #если дистанция моба меньше, чем последняя и моб не в списке bad_list
                distance = GetDistance(FindItem())              #ставим новую дистанцию
                cur_mob = FindItem()                      #запоминаем моба
                Ignore(FindItem())                         #игнорируем
    IgnoreReset()                               #сбрасываем игнор-лист после переборов
    return cur_mob                           #передаём последнего найденного моба

mob = find_mob()                    #получаем сериал ближнего моба
if mob and NewMoveXY(GetX(mob), GetY(mob), False, 1, True):                     #если моб найден и удалось к нему подойти
    pass                         #действия
else:
    print('error')         #либо моба нет, либо не удалось подойти
    bad_list.append(mob)

Re: Расстояние до цели

Posted: 15.01.2013 4:38
by shinma
спасибо щас попробую

Re: Расстояние до цели

Posted: 15.01.2013 10:32
by shinma
я постарался переделать на паскаль. получилось вот так, но есть баги

Code: Select all

function targetzertva:cardinal;
var
bad_list:array of cardinal;
distance,mob:integer;
cur_mob:cardinal;                 // #переменная для текущего моба 
begin
//def find_mob():
distance := 9999;//                       #ставим большую дистанцию для сравнения    
    for mob:=0 to (GetArrayLength(monstro)-1) do        //     #перебираем массив
        while FindType(monstro[mob], Ground) > 0 do       //    #перебираем всех мобов конкретного типа 
            if (GetDistance(FindItem) < distance) and (not FindItem in bad_list) then //#если дистанция моба меньше, чем последняя и моб не в списке bad_list       
                begin
                distance = GetDistance(FindItem) ;      //       #ставим новую дистанцию  
                cur_mob = FindItem;                 //    #запоминаем моба    
                Ignore(FindItem)                 //        #игнорируем  
                end;         
    IgnoreReset;                  //             #сбрасываем игнор-лист после переборов
result:= cur_mob;    //получаем сериал ближнего моба
end;
я не понял что имелось ввиду
тут
bad_list = []
и тут
FindItem() in bad_list

это какя-то встроенная функция в стелс или это имеллось ввиду что я должен свой массив забабахать и сделать еще и его обработку for to do.

потому что
if (GetDistance(FindItem) < distance) and (not FindItem in bad_list) then

выдает Type mismatch

Re: Расстояние до цели

Posted: 15.01.2013 10:37
by Vizit0r
наличие типа в бедлисте, что тут такого?
если тебе не надо - не пользуйся.

На ПС - это может быть что угодно - массив, TStringList, и т.д. - в него заносишь, а потом проверяешь тип - есть в бедлисте или нет.

тебе ненадо, как я понял.

Re: Расстояние до цели

Posted: 15.01.2013 11:12
by nah nah
Vizit0r wrote:наличие типа в бедлисте, что тут такого?
там серийник :roll:
shinma wrote:if (GetDistance(FindItem) < distance) and (not FindItem in bad_list) then
не знаю пс так хорошо... кстати думал, что оператор in отсутствует. и := вроде надо использовать. кстати что вернёт функция, если в локации не будет мобов?

Re: Расстояние до цели

Posted: 15.01.2013 11:52
by shinma
написал вот так. Но этот при запуске этого кода у меня на буке вентилятор начинает работать как бешеный)и результат функция не дает
все виснет после строки
while FindType(monstro[mob],Ground) <> 0 do
if GetDistance(FindItem) < distance then
дальше уже не проходит



Code: Select all

function targetzertva:cardinal;
var
bad_list:array [0..400] of cardinal;
distance,mob:integer;
cur_mob:cardinal;                 // #переменная для текущего моба 
begin

//def find_mob():
distance := 9999999;//                       #ставим большую дистанцию для сравнения
FindDistance:=50;
    
    for mob:=0 to (GetArrayLength(monstro)-1) do        //     #перебираем массив

        while FindType(monstro[mob],Ground) <> 0 do       //    #перебираем всех мобов конкретного типа 
           //AddToSystemJournal('444'+inttostr(GetDistance(FindItem) ));
            if GetDistance(FindItem) < distance  then //#если дистанция моба меньше, чем последняя и моб не в списке bad_list       
                begin
                distance := GetDistance(FindItem) ;      //       #ставим новую дистанцию  
                AddToSystemJournal('555');
                cur_mob := FindItem;                 //    #запоминаем моба    
                Ignore(FindItem);                 //        #игнорируем  
                end;
                
    IgnoreReset;                  //             #сбрасываем игнор-лист после переборов

                 
 AddToSystemJournal('Жертва: '+GetName(cur_mob)+'. координата Х: '+inttostr(GetX(cur_mob))+'. координата Y: '+inttostr(GetY(cur_mob))+'. дистанция: ' +inttostr(GetDistance(cur_mob)));
result:= cur_mob;    //получаем сериал ближнего моба
end;

Re: Расстояние до цели

Posted: 15.01.2013 11:59
by shinma
nah nah wrote:
Vizit0r wrote:наличие типа в бедлисте, что тут такого?
там серийник :roll:
shinma wrote:if (GetDistance(FindItem) < distance) and (not FindItem in bad_list) then
не знаю пс так хорошо... кстати думал, что оператор in отсутствует. и := вроде надо использовать. кстати что вернёт функция, если в локации не будет мобов?
насколько я понимаю , когда я использую Ignore то FindType не должен возвращать мне ID моба. в общем в этом и был косяк. она возвращает ID моба когда я его заигнорил.

Re: Расстояние до цели

Posted: 15.01.2013 12:20
by Vizit0r
не возвращает :)

Re: Расстояние до цели

Posted: 15.01.2013 12:32
by shinma
Всем спасибо особенно Vizit0r за функцию GetDistance. раньше её небыло. Вот готовый вариант кому надо.

Code: Select all

 function targetzertva:cardinal;
var
distance,mob:integer;            //обьявляем переменные
cur_mob:cardinal;                 // #переменная для текущего моба 
begin
distance := 9999999;//                       #ставим большую дистанцию для сравнения
FindDistance:=50;                //Расширяем квадрат поиска до 50 клеток
    for mob:=0 to (GetArrayLength(monstro)-1) do        //     #перебираем массив монстров объявленный в главном скрипте.
        while FindType(monstro[mob],Ground) <> 0 do       //    #перебираем всех мобов конкретного типа  
          begin
            if GetDistance(FindItem) < distance  then //#если дистанция моба меньше, чем последняя 
                begin
                distance := GetDistance(FindItem) ;      //       #ставим новую дистанцию  
                cur_mob := FindItem;                           //присваиваем переменной cur_mob  ID монстра 
            end;                   
                Ignore(FindItem);  //        #игнорируем   этого моба
          end;
                
    IgnoreReset;                  //             #сбрасываем игнор-лист после переборов
                   
 AddToSystemJournal('Жертва: '+GetName(cur_mob)+'. координата Х: '+inttostr(GetX(cur_mob))+'. координата Y: '+inttostr(GetY(cur_mob))+'. дистанция: ' +inttostr(GetDistance(cur_mob)));
result:= cur_mob;    //получаем сериал ближнего моба

end;

Re: Расстояние до цели

Posted: 15.01.2013 14:13
by Vizit0r
shinma wrote:Всем спасибо особенно Vizit0r за функцию GetDistance. раньше её небыло. Вот готовый вариант кому надо.
угу, появилась она недавно, всего лет 7-8 тому.