jemxx / autobot

Autobot for TSO
3 stars 2 forks source link

Решение проблем с зацикливанием набора армии #56

Closed ghost closed 3 years ago

ghost commented 3 years ago

Основное обсуждение проблемы можно найти по ссылке Originally posted by @Marsik-A in https://github.com/jemxx/autobot/issues/52#issuecomment-747972256

В этой задаче напишу ее решение во всех аспектах, как мне кажется.

Аспект первый, упомянутый Jemxx-ом - бесконечное зацикливание набора армии в основном юните autoit.au3 В трех командах работы с генералом из звезды Набрать, НабратьИАтаковать и НабратьИПеренести в трех местах для каждой команды ("П", "1" и "Э") заменить код

While applyarmy() <> 1 / apply_elitnoy_army() <> 1
    zmemsmennuyukartinku("media\closegena.bmp", 30, "media\closegena_.bmp", 30)
    openzvezdap()
    selecttabatzvezda("specialisti", 1)
    generali($gena, $parametr[2])
WEnd

на

$ii = 0
While applyarmy() <> 1 / apply_elitnoy_army() <> 1
    zmemsmennuyukartinku("media\closegena.bmp", 30, "media\closegena_.bmp", 30)
    openzvezdap()
    selecttabatzvezda("specialisti", 1)
    generali($gena, $parametr[2])
       $ii = $ii +1 
       if $ii > 5 Then Return 0
WEnd

В двух командах работы по координатам - НаборИАтакаПоКоординатам и НаборИПереносПоКоординатам тоже в трех местах для "Э", "П" и "1" заменить код

While applyarmy() <> 1 или apply_elitnoy_army() <> 1
    zmemsmennuyukartinku("media\closegena.bmp", 30, "media\closegena_.bmp", 30)
    stoitligena()
WEnd

на код

$ii  = 0 
While applyarmy() <> 1 или apply_elitnoy_army() <> 1
    zmemsmennuyukartinku("media\closegena.bmp", 30, "media\closegena_.bmp", 30)
    stoitligena()
       $ii = $ii +1 
       if $ii > 5 Then Return 0
WEnd

Аналогичные замены: добавление счетчика $ii, его наращивание и проверка внутри while-а - необходимо сделать и для других команд работы по координатам, предложенных LEKALA.

ghost commented 3 years ago

Аспект второй - связанный с ошибочной логикой при наборе армии и зависании на песочных часах при ускорении скорости работы бота при помощи переменной $tormoza.

В функциях okclosegena() и okclose_elitnoy_gena() юнита globalWAR.au3

в однотипных условиях была ошибка
While ($i < 6 * $tormoza) AND ($search = 0) умножение на $tormoza необходимо убрать в обеих функциях While ($i < 6) AND ($search = 0)

ghost commented 3 years ago

Аспект третий - связан с зацикливанием набора при нехватке необходимых юнитов или если игрок пытается загрузить в генерала больше его вместимости. Для решения этой проблемы изменения внесены в функции vvodzifr(), setarmy() и set_elitnoy_army() юнита globalWAR.au3

Будет добавлено позже - когда запустится игра и проверю работоспособность этого функционала.

Итак функция vvodzifr($skolko) выглядит теперь так

Func vvodzifr($skolko)
    If naborgenarea() = 0 Then Return 0
    If $skolko = "" Then
        MsgBox(0, "ОШИБКА", "Количество армии пустое")
        Return 0
    EndIf
    Local $i = 0, $error = 0, $symbol
    While $i < StringLen($skolko)
        $symbol = StringMid($skolko, $i + 1, 1)
        If StringInStr("0123456789", $symbol) <> 0 Then
            $error = $error + 1
        EndIf
        $i = $i + 1
    WEnd
    If $error <> StringLen($skolko) Then
        MsgBox(0, "ОШИБКА", "Недопустимые символы в количестве войск")
        Return 0
    EndIf
    $i = 0
    While ($i < 5)
        MouseMove($polezifrx, $polezifry, 10 * $tormoza)
        MouseClick("left", $polezifrx, $polezifry, 2)
        Sleep(300 * $tormoza)
        Send($skolko)
        Sleep(1000 * $tormoza)
        If haveimagearea($skolkokartinka, 20, $zifri_area[0], $zifri_area[1], $zifri_area[2], $zifri_area[3]) = 1 Then
            Return 1
        EndIf
        $i = $i + 1
    WEnd
;   TrayTip("", "Недостаточно юнитов для набора", 0)
    Return 2
EndFunc

Функции setarmy() и set_elitnoy_army() - заодно убрал лишний код, который обсуждали в исходном топике

Func setarmy($kogo, $skolko, $gena)
    Local $ty = 0, $tx = 0, $search = 0, $fullGenaImg = 0, $i = 0
    ;writelog("| SA " & $kogo & "," & $skolko & "," & $gena & " | ")
    If $skolko = 0 Then
        ;writelog("0" & @CRLF)
        Return 1
    EndIf
    $fullGenaImg = getFullGeneralImg($gena)
    If $skolko = 3000 Then ; добиваем до максимума
        viborarmii($kogo)
        $i = 0
        $search = 0
        While ($i < 10) AND ($search = 0)
            MouseMove($maxx, $maxy, 10 * $tormoza)
            MouseClick("left", $maxx, $maxy, 2)
            $search = _imagesearch($fullGenaImg, 1, $tx, $ty, 30)
            Sleep(500 * $tormoza)
            $i = $i + 1
        WEnd
        If $i < 9 Then
            Return 1
        Else
            TrayTip("", "Ошибка: Не набрали войска", 0)
            Return 0
        EndIf
    Else ; ввод обычных значений
        viborarmii($kogo)
        $skolkokartinka = "media\army_values\" & $diffarmy & ".bmp"
        $i = 0
        While vvodzifr($skolko) <> 1
            ;writelog("+" & $skolko)
            MouseMove($minx, $miny, 10 * $tormoza)
            MouseClick("left", $minx, $miny, 2)
            $i = $i + 1
            if vvodzifr($skolko) = 2 Then Return 2
            if $i > 5 Then Return 0
        WEnd
        Return 1
    EndIf
    ;writelog("Ошибка " & @CRLF)
;   Return 0
EndFunc

Func set_elitnoy_army($kogo, $skolko, $gena)
    Local $ty = 0, $tx = 0, $search = 0, $fullGenaImg = 0, $i = 0
    ;writelog("| SEA " & $kogo & "," & $skolko & "," & $gena & " | ")
    If $skolko = 0 Then
        ;writelog("0" & @CRLF)
        Return 1
    EndIf
    $fullGenaImg = getFullGeneralImg($gena)
    If $skolko = 3000 Then
        vibor_elitnoy_armii($kogo)
        $i = 0
        $search = 0
        While ($i < 10) AND ($search = 0)
            MouseMove($maxx, $maxy, 10 * $tormoza)
            MouseClick("left", $maxx, $maxy, 2)
            $search = _imagesearch($fullGenaImg, 1, $tx, $ty, 30)
            Sleep(500 * $tormoza)
            $i = $i + 1
        WEnd
        If $i < 9 Then
            Return 1
        Else
            ;writelog("Ошибка " & $i & @CRLF)
            TrayTip("", "Ошибка: Не набрали войска", 0)
            Return 0
        EndIf
    Else
        vibor_elitnoy_armii($kogo)
        $skolkokartinka = "media\army_values\" & $diffarmy & ".bmp"
        ;writelog("+" & $skolko)
        $i = 0
        While vvodzifr($skolko) <> 1
            ;writelog("+" & $skolko)
            MouseMove($minx, $miny, 10 * $tormoza)
            MouseClick("left", $minx, $miny, 2)
            $i = $i + 1
            if vvodzifr($skolko) = 2 Then Return 2
            if $i > 5 Then Return 0
        WEnd
        ;writelog(" Успех " & $diffarmy & @CRLF)
        Return 1
    EndIf
    ;writelog("Ошибка " & @CRLF)
    Return 0
EndFunc

В обеих этих функциях вот этот функционал теперь лишний - если юнитов нехватает, или гена вмещает меньше заданного числа, то каждый vvodzifr вызовется лишних 5 раз

        $i = 0
        While vvodzifr($skolko) <> 1
            ;writelog("+" & $skolko)
            MouseMove($minx, $miny, 10 * $tormoza)
            MouseClick("left", $minx, $miny, 2)
            $i = $i + 1
            if $i > 5 Then Return 0
        WEnd

и еще лишних 5 раз по 5 раз вызовутся те правки, которые я сделал в 1м аспекте. Чтобы этого избежать, нужно убирать while-ы и ставить if-ы, т.к. если юнитов нет, они с неба не прилетят, и в гену больше его вместимости тоже не запихнуть, но я пока не придумал как. Возможно еще покручу ,но пока не уверен. Максимум что сокращу, это не число выполнений не 5 5 5, а всего 5 * 5.

Поэтому нужно ли что-то добавлять в релиз - на усмотрение Jemxx-а. Ну кроме 2го аспекта - там однозначно все работает как надо.

UPD! Сократил число неудачных попыток при наборе - ввел еще один параметр при выходе из функций vvodzifr(), setarmy() и set_elitnoy_army() - Return 2. Выше уже поправленный код. Добавил проверку, если на выходе 2, то выходить из циклов. Но зацикливание в основном юните не трогал, т.к. причин, по которым арма не наберется бывает много, а не только нехватка юнитов. Поэтому теперь бот 5 раз попробует набрать нужно число юнитов, и еще 5 раз проверит успешность набора в основном юните, т.е. всего 5 * 5 повторов. По этому пути можно пойти и дальше, задавать и отслеживать 2, но пока делать этого не стал. Других вариантов пока нет.

ghost commented 3 years ago

Прошел три разных прикла (Юный, ТБ и ЧР), нормальное функционирование набора не сломал - что уже неплохо.

jemxx commented 3 years ago

Ну тогда добавляю) И на этом все. Завтра будет релиз перед ивентом.

ghost commented 3 years ago

да на этом пока все, дальше в планах разобраться с центровкой и сдвигом карты. Возможно чуть допилю этот функционал с ошибкой набора, чтобы было красиво, но не факт. В любом случае бот стопнется при неуспешном наборе, на 5 сек раньше или 5 сек позже, не суть( Иду Юного, под клиентом ЖдемПобеду работает как и работало в браузере.

ghost commented 3 years ago

Эту задачу можно тоже закрыть, все же добавлено. Если придумаю, как обойти лишний набор - открою и допишу.