Глупая ходилка с обходом.

Anything and all.

Moderators: Murderator+, Murderator

Post Reply
ZeroDX
Posts: 718
Joined: 2006-12-08 10:51:50
Location: Москва
Contact:

Глупая ходилка с обходом.

Post by ZeroDX »

В общем дело было вечером, делать было......
Решил я понять, как работает ходилка бьёндера. Посмотрел, ни чего не понял вообще, и решил написать свою (попроще), с таким же обходом. (туда 10 шагов, сюда 10 шагов). И спустя часок, в блокноте родилась вот такая вот ходячая беда. В общем тут несколько проблемм.

3) Закоментировов while в LegToIt и уперев в стену (которая было с противоположной от целевой точки стороны) добился обхода этой стены (вечного), но и тут меня ждал облом... При смене направления, он не делает шаг, а просто крутанется в сторону (но это решить можно дублированием UO.Press())
2) Runtime error
1) Определение направления. Вроде все правильно расставил, но зараза делает шаг в другую сторону.

Code: Select all

var Pause = 200, StepDelay = 500, MaximalBypassDistance = 10, Bypass = 0, Turn = 1

sub test()
  If LegToIt(1527, 1778, 1) then
    UO.Print('Success')
   else
    UO.Print('Fail')
  Endif
Endif

Sub LegToIt(x, y, prec)
  var BypassDistance =  MaximalBypassDistance, Direction
  While Absolute(UO.GetX() - x) >= prec or Absolute(UO.GetY() - y) >= prec
    Direction = FindDirection(x, y)
    If not AttemptDirection(Direction) then
      If Bypass(Direction) then
        Bypass = 0
        MaximalBypassDistance = BypassDistance
       else
        Turn = -Turn
        MaximalBypassDistance = MaximalBypassDistance * 2
        If Bypass(Direction) then
          Bypass = 0
          MaximalBypassDistance = BypassDistance
         else
          Return 0
        Endif
      Endif
    Endif
  Wend
  Return 1
Endsub

Sub Bypass(dir)
  var NewDirection, StepOver = 0
  Repeat
    If Bypass >= MaximalBypassDistance then
      Return 0
     else
      If AttemptDirection(dir) then
        StepOver = 1
        Bypass = Bypass + 1
       else
        NewDirection = ChangeRoute(dir)
        Bypass(NewDirection)
      Endif
    Endif
  Until StepOver == 1
  Return 1
Endsub

Sub AttemptDirection(dir)
  var StartX = UO.GetX(), StartY = UO.GetY(), Time
  Time = UO.Timer()
  Step(dir)
  Repeat
  Wait(50)
  Until StartX <> UO.GetX() or StartY <> UO.GetY() or Time + StepDelay / 100 <= UO.Timer()
  If StartX <> UO.GetX() or StartY <> UO.GetY() then
    Return 1
   else
    Return 0
  Endif
Endsub

Sub ChangeRoute(dir)
  var NewDirection
  NewDirection = dir + Turn
  If NewDirection > 8 then
    NewDirection = NewDirection - 8
  Endif
  If NewDirection < 1 then
    NewDirection = NewDirection + 8
  Endif
  Step(NewDirection)
  UO.Print('ChangeRoute ' + str(NewDirection))
  Return NewDirection
Endsub

Sub Step(dir)
  Dim Key[8]
   Key[1] = 36
   Key[2] = 38
   Key[3] = 33
   Key[4] = 39
   Key[5] = 34
   Key[6] = 40
   Key[7] = 35
   Key[8] = 37
  UO.Press(Key[dir])
  Wait(Pause)
Endsub

Sub FindDirection(x, y)
  var Direction
  If UO.GetX() < x and UO.GetY() < y then
    Direction = 6
  Endif
  If UO.GetX() < x and UO.GetY() == y then
    Direction = 5
  Endif
  If UO.GetX() < x and UO.GetY() > y then
    Direction = 4
  Endif
  If UO.GetX() > x and UO.GetY() < y then
    Direction = 8
  Endif
  If UO.GetX() > x and UO.GetY() == y then
    Direction = 1
  Endif
  If UO.GetX() > x and UO.GetY() > y then
    Direction = 2
  Endif
  If UO.GetX() == x and UO.GetY() < y then
    Direction = 7
  Endif
  If UO.GetX() == x and UO.GetY() > y then
    Direction = 3
  Endif
  UO.Print('FindDirection ' + str(Direction))
  Return Direction
Endsub

Sub Absolute(val)
  If val >= 0 then
    Return val
   else
    Return -val
  Endif
Endsub


В общем... Кто чем сможет :roll:
Last edited by ZeroDX on 2011-06-02 16:22:39, edited 6 times in total.
ZeroDX
Posts: 718
Joined: 2006-12-08 10:51:50
Location: Москва
Contact:

Re: Глупая ходилка с обходом.

Post by ZeroDX »

Такой вопрос

Code: Select all

Sub Bypass(dir)
  var NewDirection, StepOver = 0
  Repeat
    If Bypass >= MaximalBypassDistance then
      Return 0
    Endif
    If AttemptDirection(dir) then
      Return
      StepOver = 1
      Bypass = Bypass + 1
     else
      NewDirection = ChangeRoute(dir)
      Bypass(NewDirection)
    Endif
  Until StepOver == 1
Endsub


Не будут ли слетать переменные после рекурсии?
Mirage
Posts: 2802
Joined: 2009-05-28 09:58:28
Location: Иваново
Contact:

Re: Глупая ходилка с обходом.

Post by Mirage »

If AttemptDirection(dir) then
Return

в этом месте скрипт прекратит свое существование - все что ниже выполнятся не будет.

Bypass = Bypass + 1 - зачем это? У тебя же значение задается от переменной dir

Ps я ходилками как то не озадачивался :roll: Нужно будет оживлять память 400 граммами валерьянки.
ZeroDX
Posts: 718
Joined: 2006-12-08 10:51:50
Location: Москва
Contact:

Re: Глупая ходилка с обходом.

Post by ZeroDX »

Return провтыкал. Спасибо. Уже сам не помню для чего Bypass :roll: Видимо считать удачные шаги обхода
ZeroDX
Posts: 718
Joined: 2006-12-08 10:51:50
Location: Москва
Contact:

Re: Глупая ходилка с обходом.

Post by ZeroDX »

Обновил скрипт в первом посте.

Ходит, но куда не надо ходит, а если в 2-3 тайлах от пункта назначения запустить, то Runtime error line 12


Вот как я себе это представляю
Image

Code: Select all

Sub FindDirection(x, y)
  If UO.GetX() < x and UO.GetY() < y then
    Return 6
  Endif
  If UO.GetX() < x and UO.GetY() == y then
    Return 7
  Endif
  If UO.GetX() < x and UO.GetY() > y then
    Return 8
  Endif
  If UO.GetX() > x and UO.GetY() < y then
    Return 4
  Endif
  If UO.GetX() > x and UO.GetY() == y then
    Return 3
  Endif
  If UO.GetX() > x and UO.GetY() > y then
    Return 2
  Endif
  If UO.GetX() == x and UO.GetY() < y then
    Return 5
  Endif
  If UO.GetX() == x and UO.GetY() > y then
    Return 1
  Endif
Endsub


Вроде все правильно, но идёт не туда...
С Bypass'ом тоже весело получилось, во время обхода выше одного не поднимается, хотя было задумано сначала до 10, потом поднять до 20 (идти в обратную сторону)

Так же просто не лезет в голову, как после смены направления, сделать ещё и шаг в ту сторону. Ведб одноразовое клацкание просто повернёт персонажа.

PS. Все наоборот
PSS. А нет все верно :oops:
Last edited by ZeroDX on 2011-06-02 15:03:53, edited 1 time in total.
Mirage
Posts: 2802
Joined: 2009-05-28 09:58:28
Location: Иваново
Contact:

Re: Глупая ходилка с обходом.

Post by Mirage »

2 раза прескей ;)

Code: Select all

если направление <> направлению на север тогда
жмем на север
конец если
жмем на север.



какаято команда была для разворачивания - в helpe посмотри - мне сейчас некогда сори. :roll:
ZeroDX
Posts: 718
Joined: 2006-12-08 10:51:50
Location: Москва
Contact:

Re: Глупая ходилка с обходом.

Post by ZeroDX »

Проблемму с направлением решил. Остальные актуальны.
Решения проблеммы с поворотами - Просто делать шаг при смене направления в Sub ChangeRoute(dir). Но если есть более изящное решение, буду благодарен.

Скрипт обновлён в первом посте
ZeroDX
Posts: 718
Joined: 2006-12-08 10:51:50
Location: Москва
Contact:

Re: Глупая ходилка с обходом.

Post by ZeroDX »

Только после подхода к точке. prec игнорирует. Грешу на то, что Sub FindDirection() не знает, что нужно вернуть 0.
Line 13: Runtime error. Invalid operation for this type.

Code: Select all

While Absolute(UO.GetX() - x) >= prec or Absolute(UO.GetY() - y) >= prec


Попробую похимичить
ZeroDX
Posts: 718
Joined: 2006-12-08 10:51:50
Location: Москва
Contact:

Re: Глупая ходилка с обходом.

Post by ZeroDX »

Проект скорее жив, чем мёртв
Post Reply