Написание макроса-бота для браузерной игры

    Введение


    Не так давно на Google+ появились игры. Прочитав топик об этом, я решил во что нибудь поиграть. Выбор пал на игру Diamond Dash. Через некоторое время игры программист во мне заговорил, что однотипные действия нужно автоматизировать. И вот что из этого вышло…

    *Примечание: «руками» даже опытному игроку сложно набрать больше 400к

    Раньше я никогда не сталкивался с задачами работы с экраном и мышкой. После непродолжительного гугления было решено для решения использовать язык макросов AutoIt.
    Под катом вы найдете краткое описание игры, мой способ распознавания поля, алгоритм определения точки нажатия, и некоторое количество оптимизаций. А так же ссылку на github-репозиторий скрипта.
    UPD Добавлено видео работы скрипта.

    Краткое описание игры


    Игра представляет из себя простую «кликни-на-область-больше-трех-квадратиков-одного-цвета» головоломку.

    Есть поле 9 на 10, заполненное квадратиками 5 цветов. У нас есть одна минута на то, чтобы набрать максимальное количество очков. При нажатии на область из 3 или более одноцветных клеток, она исчезает, то что над ней проваливается, а сверху падает недостающее. Количество начисленных очков зависит от размера области: чем она больше — тем больше очков.
    Кроме того, если делать клики быстро, и почти безошибочно, поле вокруг загорается, а каждое удаление(в данном случае взрыв), захватывает соседние с удаляемой областью клетки.

    И наконец последняя особенность: наверху есть шкала с алмазом в конце, которая заполняется по мере уничтожения клеток(и уменьшается при ошибочных кликах). Когда она заполняется, на поле в случайном месте появляется горящий алмаз. При клике на него время останавливается, а сверху поля падает огненный шар, уничтожая все клетки в строке и столбце, где находился камень.


    Определение координат окна


    Эта часть была добавлена в самую последнюю очередь, до этого координаты угла были жестко прописаны в коде. Используется функция из сторонней библиотеки ImageSearch для поиска сохраненного шаблона 10 на 10 пикселей. Судя по всему, фон слегка меняется от игры к игре, потому что не любой кусок подходил.
    На форумах повсеместно не рекомендуют использование ImageSearch из-за долгого времени работы. Но так как нам нужно определить координаты только один раз в начале игры, провисаний по времени можно не опасаться.

    Распознавание цветов и сохранение скриншотов


    Для определения цвета пикселя по его координатам в AutoIt есть функция PixelGetColor. Но как показала практика, измерение всего 90 пикселей занимает полторы секунды, что, конечно, не очень хорошо. Но справедливости ради надо сказать, что бот написанный с использованием этой функции набирал 400-600 тысяч очков, а это больше чем может набрать человек, даже при большой сноровке.
    На форумах был найден метод сохранения текущего состояния монитора в Bitmap, используя WinAPI. Кстати, этот битмап, при необходимости(например для дебага), можно сохранить в файл функцией _ScreenCapture. Далее смотрим цвета 90 пикселей, расположенных по решетке и по ним строим таблицу цветов квадратиков.
    1. Func _GetField(ByRef $aiField) ; получение массива цветов поля
    2. ; получение BitMap-снимка экрана с помощью WinAPI
    3. Local $hWnd = WinGetHandle("Игры Google+ - Google Chrome")
    4. Local $Size = WinGetClientSize($hWnd)
    5. Local $hDC = _WinAPI_GetDC($hWnd)
    6. Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC)
    7. Local $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $Size[0], $Size[1])
    8. Local $hSv = _WinAPI_SelectObject($hMemDC, $hBitmap)
    9. _WinAPI_BitBlt($hMemDC, 0, 0, $Size[0], $Size[1], $hDC, 0, 0, $SRCCOPY)
    10. _WinAPI_SelectObject($hMemDC, $hSv)
    11. _WinAPI_DeleteDC($hMemDC)
    12. _WinAPI_ReleaseDC($hWnd, $hDC)
    13. Local $L = $Size[0] * $Size[1]
    14. Local $tBits = DllStructCreate('dword[' & $L & ']')
    15. _WinAPI_GetBitmapBits($hBitmap, 4 * $L, DllStructGetPtr($tBits))
    16. ; определение цветов клеток
    17. For $iCol = 0 To $iNumCols - 1
    18. For $iRow = $iNumRows - 1 to 0 Step -1
    19. ; замер цвета квадратика
    20. $iX = $iCornerX + ($iCol * 40) + $iDeltaX
    21. $iY = $iCornerY + ($iRow * 40) + $iDeltaY
    22. $iPixelColor = Mod(DllStructGetData($tBits, 1, $iY * $Size[0] + $iX), 0x1000000)
    23. $aiField[$iRow][$iCol] = _GetCheckColor($iPixelColor)
    24. Next
    25. Next
    26. ; удаление данных для избежаня утечки памяти
    27. _WinAPI_DeleteObject($hBitmap)
    28. _WinAPI_DeleteObject($hMemDC)
    29. _WinAPI_DeleteObject($tBits)
    30. EndFunc


    Тут стоит оговориться, почему замер происходит всего по 1 точке. Этот метод был испробован мной в первую очередь, и остался в финальной версии. Между этими двумя моментами было испробовано довольно большое количество альтернативных способов, среди которых были: замер 64 точек на каждый квадратик(решетка 8 на 8) и различные усреднения полученных значений, случайный выбор координат для замера, хранение истории нескольких последних замеров для лучшей точности… Но все они оказались менее точными или удобными, чем самый первый способ.
    Возможно, что так как я весьма далек от темы распознавания изображений, я не знаю чего-то простого, способного помочь мне в этом вопросе. В таком случае буду рад любым предложениям. =)

    Определение одноцветной области по таблице цветов


    Ну, и, наконец, осталось найти подходящее место и кликнуть туда. Для этого обходим поле снизу вверх (потому что все падает вниз, а значит снизу менее пусто чем сверху), и проверяем одноцветные части. Я делал это с помощью алгоритма безрекурсивного поиска в глубину (DFS). Вкратце суть такова: кладем в стек стартовую клетку, а дальше, пока стек не пуст, достаем из него текущую клетку и обходим ее соседей, при совпадении цвета кладем в стек. Ну да что говорить, код понятней. =)
    1. Func _DfsAreaSize(ByRef $aiField, $iStartX, $iStartY) ; нерекурсивный алгоритм поиска размера одноцветной области
    2. ; методом поиска в глубину
    3. Local $aiResult[$iNumCols * $iNumRows][2] ; список клеток входящих в область
    4. Local $iResultSize = 0
    5. Local $afMap[$iNumRows][$iNumCols] ; флаги пройденности
    6. For $iRow = 0 to $iNumRows - 1
    7. For $iCol = 0 to $iNumCols - 1
    8. $afMap[$iRow][$iCol] = False
    9. Next
    10. Next
    11. $afMap[$iStartX][$iStartY] = True
    12. Local $aiStack[$iNumRows * $iNumCols][2] ; активный стек
    13. Local $iStackSize = 1
    14. $aiStack[0][0] = $iStartX
    15. $aiStack[0][1] = $iStartY
    16. While $iStackSize > 0
    17. $iStackSize -= 1
    18. $iX = $aiStack[$iStackSize][0]
    19. $iY = $aiStack[$iStackSize][1]
    20. $aiResult[$iResultSize][0] = $iX
    21. $aiResult[$iResultSize][1] = $iY
    22. $iResultSize += 1
    23. For $iDirection = 0 to 3 ; перебор 4 рядомстоящих клеток
    24. Local $iNewX = $iX
    25. Local $iNewY = $iY
    26. Switch $iDirection
    27. Case 0
    28. $iNewY += 1
    29. Case 1
    30. $iNewY -= 1
    31. Case 2
    32. $iNewX += 1
    33. Case 3
    34. $iNewX -= 1
    35. EndSwitch
    36. If ($iNewX >= 0 And $iNewX < $iNumRows And _
    37. $iNewY >= 0 And $iNewY < $iNumCols And _
    38. Not($afMap[$iNewX][$iNewY]) And $aiField[$iNewX][$iNewY] = $aiField[$iStartX][$iStartY]) Then
    39. $afMap[$iNewX][$iNewY] = True
    40. $aiStack[$iStackSize][0] = $iNewX
    41. $aiStack[$iStackSize][1] = $iNewY
    42. $iStackSize += 1
    43. EndIf
    44. Next
    45. WEnd
    46. Return $iResultSize
    47. EndFunc


    Оптимизации



    Оптимизация 1. Алмазики

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

    А между тем, алмазы — очень полезная вещь, потому что пока падает огненный шар, таймер останавливается, а квадратики падают. А значит пробелы заполняются, и ошибок будет меньше.
    Для определения алмазов для начала пришлось поиграть с координатами замеров, чтобы цветные клетки определялись корректно, а алмазы — не попадали ни под один из их цветов. После этого создаем массив $aiDiams размером 3 (будем проверять только нижние 3 строки, потому что все алмазы рано или поздно туда упадут) * ширину (в нашем случае — 10). При каждом замере просматриваем нижние 3 строки, и если ячейка определилась, то обнуляем соответствующее место в $aiDiams, иначе инкрементируем его. Таким образом для клеток с алмазиками значения будут велики. При накоплении некоего порога, кликаем.
    1. For $iRow = $iNumRows - 1 to $iNumRows - 3 Step -1
    2. For $iCol = 0 to $iNumCols - 1
    3. If $aiField[$iRow][$iCol] <> 0 Then
    4. $aiDiams[$iRow][$iCol] = 0
    5. Else
    6. $aiDiams[$iRow][$iCol] += 1
    7. If $aiDiams[$iRow][$iCol] > 15 Then
    8. MouseClick("Left", $iCornerX + 30 + ($iCol * 40), $iCornerY + 10 + ($iRow * 40), 1, $iMouseSpeed)
    9. $aiDiams[$iRow][$iCol] = 0
    10. Sleep(500)
    11. Return 0
    12. EndIf
    13. EndIf
    14. Next
    15. Next


    Оптимизация 2. Over Explosion

    Тут надо объяснить, почему очень важно уменьшить количество ошибок, и почему в моем скрипте между соседними снимками экрана стоит задержка в 1/10 секунды. Дело в том, что когда поле загорается и ячейки начинают взрываться, количество очков многократно возрастает. Но если слишком много ошибаться, поле перестает загораться. Поэтому минимизация ошибок не менее важная часть, чем оптимизация времени распознавания (а учитывая запас времени, вообще единственно важная).
    Несмотря на задержку в 1/10 секунды между соседними снимками экрана, некоторые ячейки все равно не успевают упасть, и определяются не на своих местах. Чтобы уменьшить их количество, была введена проверка на взрыв. При взрыве в квадратике появляется ореол почти чисто-белого цвета (#fffefc если быть точным), а это легко определить. Все клетки над взрывом, не мудрствуя лукаво, можно проставить как неопределенные.

    Оптимизация 3. Область последнего клика

    Защита от повторной ошибки, в эффективности которой я не уверен. Дело в том, что в самой игре при ошибке клетка становится серого цвета, а серый цвет алгоритмом определяется как неопределенный (тавтология получилась =) ). Но хуже эта проверка точно сделать не может, поэтому пусть живет.
    Суть в том, что при каждом клике сохраняем область, по которой кликаем, и при следующем клике не трогаем ее.

    Итог


    После всего вышеописанного, мой рекорд стал примерно таким:

    Очень хотелось 2 миллиона, но 4 дня попыток, пара тысяч строк экспериментального кода (с самописным логгированием и сохранением скринов), тщательное курение логов и сверки со скриншотами, результатов не дало. =(
    Ссылка на репозиторий github: github.com/EvilTosha/DiamondDash

    Вместо постскриптума. Пара слов об AutoIt


    Меня очень удивило, что этот язык почти не освещен на хабре. Собственно, желание исправить эту несправедливость и побудило написать этот топик.
    Язык при этом умеет довольно много, и обладает поражающей простотой изучения. Через пару часов после того, как я узнал о его существовании, я уже обладал всеми знаниями нужными для написания данного макроса.
    С помощью AutoIt можно автоматизировать почти любое рутинное действие: сохранение скриншота, установка программы(если надо поставить на много компов), многократный логин куда-либо… Можно скомпилировать в exe-шник, подключать DLL-ки.
    Но что-то я как евангелист заговорил. =)

    UPD Видео работы.


    Спасибо за внимание, буду рад любым комментариям.
    Поделиться публикацией

    Похожие публикации

    Комментарии 115

      –6
      Спасибо, топик очень интересный!

      А не проще было выловить запрос, который скорее всего шлет игра на сервер для записи рекордов, и подменить там значение? (Если есть сигнатура запроса, можно декомпилировать флешку и вытащить алгоритм подсчета.)

      Но конечно очень похвально и круто, что Вы выбрали подходящий язык для подобной цели!
        +8
        Всегда пожалуйста!
        Вопрос изначально был не в том, чтобы получить много-много очков (там даже рейтинга публичного нету, только среду друзей), а в том, чтобы переложить функции игрока на компьютер. А дальше уже азарт игрока заставлял пытаться набрать больше. =)
          +28
          Объявите игру для программистов — чей бот наберёт больше очков :)
            +1
            Ждём встречного поста.
              +8
              Вспоминаю старую добрую Ultima Online…
                +1
                То же самое! 8)
                Мне порой кажется что я состоялся как начинающий программист, написав макрос на ламберджекинг под УОИнжект.
                Занятная история, чпасибо!
                  0
                  черт, первая мысль была о нем. Ну что, кто первый напишет фармбота под D3?
            0
            Спасибо, крайне интересно.
              0
              «Использование ботов рассматривается большинством пользователей AutoIt как нечестная игра, и вам не следует ожидать значительной помощи от сообщества в их создании.» © Википедия
                +1
                Ах да, я в свое время мелких ботов на nnCron писал :)

                Но тут вроде все помощнее будет…
                  0
                  На форуме русского сообщества AutoIt есть целый раздел посвященный бототоводам, где всегда можно обменяться ценной информацией. Правда в основном там содержатся или запросы на написание бота, или самореклама, но иногда попадаются и очень полезные статьи.
                  +2
                  Огромное спасибо автору, я нашел чем занять себя в воскресенье… Сейчас буду писать на C#
                    +1
                    Посмотрел только 5 скрин и загорелся, алгоритмы не хочу смотреть… постараюсь сам сделать.
                      0
                      Жду вашего топика и побитого рекорда. =)
                      +2
                      >>Огромное спасибо автору, я нашел чем занять себя в воскресенье
                      Счастливый человек…
                        +19
                        За годы фриланса выработал правило «НЕ РАБОТАЙ В ВОСКРЕСЕНЬЕ!!!»
                          +2
                          это скорее хобби получается чем работа. как раз в воскресенье самое время.
                            0
                            Ну да, просто Klaster сказал так, как будто его работа придавила пару лет назад :)
                            > Счастливый человек…
                              0
                              Да, я протупил. :)
                            +1
                            и в субботу тоже не работай…
                              +2
                              Таки это уже не из фриланса.
                                +4
                                я вам больше скажу, это из другой религии
                        +7
                        Весьма полезно — для написания тестов приложений на флэше.
                          +3
                          Сто лет назад писал простешие скрипты, на заготовку дров/руды и первичную обработку в Ultima on-line.
                            0
                            Я как-то делал бота для кликомании с помощью java.awt.Robot.
                              +1
                              да, лучше начать изучать яву, чем этот autoit… не думаю, что ява сложнее, а возможностей намного больше)
                              –5
                              Браузерная игра
                              Почему AutoIt? Проще же взять Javascript и вызывать функции самой игры или эмулировать клики.
                                +1
                                Игра на Flash
                                  +2
                                    0
                                    Работает!
                                      0
                                      Читоры…
                                        0
                                        И даже так:
                                          +3
                                          Как вы теперь будете смотреть в глаза школьникам и домохозяйкам, угробившим полжизни на побитие этого рекорда?
                                  –1
                                  Где бы поиграть в эту игрушку, не регистрируясь в фейсбуках и гуглоплюсах?
                                    –1
                                    chrome.angrybirds.com :)
                                      +2
                                      черт, не та игрушка :(
                                    • НЛО прилетело и опубликовало эту надпись здесь
                                        +1
                                        очень просто. набираете в гугле, скачать бесплатно без регистрации…
                                        0
                                        Ругается, говорит, Api.Constants скрипта ему не хватает :)
                                          0
                                          А ещё WindowsConstants и Constants. Вот все необходимые файлы — zalil.ru/31585482
                                          После этого нужно прописать путь к template.bmp, в DD_Habr.
                                          Теперь следующая загвоздка, при запуске ошибка —

                                          C:\Users\LostSenSS\Desktop\DiamondDash\ImageSearch.au3 (40): ==> Subscript used with non-Array variable.:
                                          if $result[0]=«0» then return 0
                                          if $result^ ERROR

                                          Что с этим делать?
                                            0
                                            С этим я уже сам разобрался :) Вот сам на то же наткнулся, думаю.
                                              0
                                              Если найдете решение отпишитесь, пожалуйста.
                                              0
                                              Это ошибка DLL-ки ImageSearch. Возможно из за того что ее битность не совпадает с битностью системы. Сейчас выложу обе версии.
                                              Еще есть вариант, что ее надо класть не в папку со скриптом, а в Windows(или любую другую прописанную в path)
                                                0
                                                zalil.ru/31585625 — 32 бита
                                                zalil.ru/31585630 — 64 бита
                                                Разархивировать, и переименовать файл в ImageSearchDLL.dll
                                                  0
                                                  Нет, ошибка не исчезла :/
                                                  Пробовал класть и в папку со скриптом и в System32.
                                                    0
                                                    — попробуйте эту, мне помогло.
                                                    Кстати, у меня получилось набрать максимум ~ 400 000 очков, при большом числе эффектов картинка начинает тормозить, машина слабовата.
                                                      0
                                                      ImageSearchDLL.dll — парсер съел ссылку.
                                                        +1
                                                        Да, такая проблема есть. Попробуйте увеличить задержку между кликами ($IStepSleep).
                                                          0
                                                          При задержке 300 удалось заработать ~850 000 очков :)
                                                        0
                                                        Всё получилось.
                                                        Скачал с буржуйского форума отдельно ImageSearch.
                                                        Тут необходимые файлы и скомпилированный exe файл, если кому-то лень возиться :)
                                                        zalil.ru/upload/31585781
                                                          0
                                                          Не получается. Процесс в памяти висит, но ни чего не делает. Пробовал с разными dll.
                                                            0
                                                            Хоткеи пробовали нажимать? При открытом окне с запущенной игрой — F2 — старт, F3 — пауза, F4 — выход
                                                              0
                                                              Спасибо, заработало.
                                                                0
                                                                у меня данный архив как бы работает хоткеи пашут, но при нажатии на F2 вылетает «corner template wasn't found», хотя окно открыто, template.bmp рядом с файлами из архива.
                                                                  0
                                                                  Путь до template.bmp в DD_Habr правильно прописан?
                                                                    0
                                                                    Так у вас в архиве ведь экзешник
                                                                    0
                                                                    На самом деле это мой косяк. В последней версии путь до template.bmp остался абсолютным, хотя нужно было сделать просто «template.bmp». На гитхабе залил новую версию.
                                                        0
                                                        Открыл скирпт. Эдит — сэйв — и всё, заработало, очки набивает.
                                                      +2
                                                      Посмотрите Sikuli.
                                                      Я ей пользуюсь для таких вещей.
                                                      Программируется на jython. Использует OpenCV для обработки экрана, в результате все очень быстро…
                                                      Да и вообще, удобная весчь…
                                                        0
                                                        Посмотрел на демку на их сайте, где они автоматизируют ввод сетевых настроек в MacOS. Интересная штука, но не скажу, что финальный результат там быстро работал. Наоборот. Чё-то по целой секунде оно находит кнопки.
                                                          0
                                                          Вот сразу ссылка на «Showtime»: #5:09. До «it works» прошло около 25 сек :/ Это 4 клика и заполнение 3-ёх полей.
                                                            0
                                                            Кстати, обнаружил большой плюс Sikuli в том, что это как раз работает под Mac OS X.
                                                            0
                                                            Понравилась работа с контролами — находит нужное изображение на экране и и кликает.
                                                            +1
                                                            Читеры )
                                                              +1
                                                              А просты школьники будут месяцы жизни тратить чтобы дойти до такого результата… )))
                                                                0
                                                                К сожалению у них не получится. 500к — предел для человека.
                                                                  0
                                                                  У меня за десяток попыток получилось только 144к :)
                                                                    +2
                                                                    К тому же сожалению они об этом не догадываются…
                                                                  0
                                                                  Как насчёт бота играющего angry birds?
                                                                    0
                                                                    Думал об этом, но там все слишком сложно. Если бы хотя бы алгоритмы физики были известны… Да и то слишком много перебирать.
                                                                    +2
                                                                    Итак, я запустил-таки скрипт, с увлечением наблюдал за его работой, и теперь хочу задать несколько вопросов. Возможно, если подумать над ними — может и получится преодолеть рубеж в 2 кк очков.

                                                                    1 — периодически бот начинает затупливать в конце игры (последние секунд 20-15) и тыкать абы-как, куча ошибок, цепочки не составляет, рамочка не загорается. Хотя (при дальнейшем наблюдении выяснилось) в этом может быть виновата сама игра, т.к. после пяти раз за раунд загоревшейся рамочки — она попросту не активируется. Возможно — программное ограничение самой игрушки.

                                                                    2 — бриллианты — отдельная тема, самый высокий кпд у них — в последние 15 секунд (если избавиться от первой проблемы — тупняк в конце игры. Ну и как только доска сверху начинает пустеть — бриллианты могут помочь с её наполнением. Может, стоит учесть это в их использовании и выявлять их положение на доске каждый раз, как делаем скриншот, и знать, что у нас есть брюлик, если доска полупустая?

                                                                    3 — совсем брутальный вопрос по улучшению поведения бота: есть такая вещь, как тетрис-бот. Он анализирует следующие выпадающие блоки и выстраивает комбинации ещё до того, как блоки выпадут. Может имеет смысл снизить скорость скрипта, но заставить его делать клики, которые приведут к бОльшим комбинациям через 2-3 хода (т.е. заставить его при прочих равных делать ход, который приведёт к объединению цветового массива)? Хотя (учитывая поведение игрушки в конце партии (произвольная смена цвета кубиков на поле) — все усилия могут сойти на нет.

                                                                    Что скажете?
                                                                      +1
                                                                      Ну по порядку:
                                                                      1 — начало или конец партии — не должно иметь значения для работы скрипта. Возможно начинает тупить из за снижения FPS. Насчет загораний рамки — ограничений не замечал, единственное ограничение которое приходится учитывать — на количество ошибок (или на процент ошибок, не знаю). Если часто ошибаться, то звук кликов становится монотонным, а рамка перестает загораться. Именно для того, чтобы этого не происходило добавлена задержка между кликами.
                                                                      2 — алмазы вроде и сейчас неплохо определяются. У меня в конце минуты редко остается больше 1-2. Если у вас есть идея по эффективному выявлению алмазов при появлении — предлагайте, испробуем. =) Насчет того, чтобы кликать на них когда доска полупустая (а не когда только нашли)- пожалуй стоит попробовать, займусь этим.
                                                                      3 — в начальных версиях скрипта были различные алгоритмы просчета на несколько ходов вперед. Но есть два фактора сводящие их эффективность на нет. Первый — спецэффекты и ошибки. ВТорой куда более важен. Если внимательно присмотреться к полю, то можно заметить, что довольно часто квадратики меняют свой цвет, чтобы составить новую область. Сделано это видимо для того, чтобы всегда было куда можно кликнуть. И такие смены, понятное дело, не дают нормально просчитать все.
                                                                      Да и когда все взрывается мне кажется очков капает больше чем за большие комбинации с длинным просчетом.

                                                                      Спасибо за замечания!
                                                                        0
                                                                        да, у флеша то ли GC то ли общая криворукость разработчиков обычно просаживает фреймрейт после первых 3-5 минут, при этом степень просаживания может составлять порядки.
                                                                      0
                                                                      писал подобное на delphi для mail.ru
                                                                      1.5 секунды на сканирование цветов поля это сильно много.
                                                                      в игре Филлер на меилру в текстураз кубиков применяется дизеринг, в итоге пришлось измерять цвета соотношением составляющих
                                                                      например если R > G > B то это красный работало с дикой скоростью.
                                                                        0
                                                                        Пробовал, работает хуже.
                                                                        Со временем проблем нету, определение всех цветов занимает около 1/10 секунды, проблемы с неточностью определения…
                                                                          0
                                                                          а попробуйте брать цвет не из середины, а ближе к краю, насколько я вижу там он более опознаваемый, а в середине там мешают рисунки
                                                                            0
                                                                            А и так не из середины беру. =)
                                                                            по координатам 20 4 (размер клетки 40 на 40)
                                                                              0
                                                                              попробуйте 1, 22 или 35,5
                                                                            0
                                                                            PS: кстати у буржуев подобные браузерные игры идут на деньги ;) например king.com
                                                                              0
                                                                              Ну я думаю там стоит защита от таких умных. =)
                                                                                +1
                                                                                А как проверить, если скрипт отрабатывает клики мышкой, а не вмешательство в код?
                                                                            0
                                                                            а блюрить и пороги?
                                                                            0
                                                                            А почему в этом блоге?
                                                                              +1
                                                                              Мне не жалко, просто грустно, когда статьи по тематике блога набирают максимум +50, а читерный скрипт, не имеющий собственно к разработке игр никакого отношения, легко уходит за +100 :)

                                                                              P.S. если на это глаза закрыть, статья хорошая, я плюсик поставил :)
                                                                                0
                                                                                Этот вопрос меня тоже интересовал, я сомневался что тут ему место. Но ничего лучше я не нашел, и поиск показал, что подобные посты лежат здесь.
                                                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                                                    0
                                                                                    Я ведь и не говорил, что это не интересно, даже наоборот, подчеркнул, что поставил плюс :)

                                                                                    Просто посетовал на то, что статьи по разработке игр не набирают так легко своих ста плюсиков :)

                                                                                    P.S. признаю, возможно я слишком категорично сказал «не имеющего никакого отношения», конечно разработчику игр нужно знать как работают читы или как пишутся кряки
                                                                                      0
                                                                                      Я думаю, что большее количество людей способно оценить подобный скрипт, нежели обзор игрового движка или еще что-то такого рода.
                                                                                      Да и в принципе тема играния в игры ближе большему числу людей, чем тема разработки игр.
                                                                                      0
                                                                                      со временем они дозревают до того, что им интересно еще и тестирование.
                                                                                      • НЛО прилетело и опубликовало эту надпись здесь
                                                                                  +1
                                                                                  Автор не могли бы вы сравнить AutoIt и AutoHotKey, они очень сильно похожи, но хотелось бы узнать ваше мнение, я сколько ни пробовал AutoHotKey всегда прощще мне казался и удобнее AutoIt-а.
                                                                                  Может кто-то раскроет правду?
                                                                                    0
                                                                                    Посмотрю на досуге, возможно следующую задачу на нем напишу, если будет материал, постараюсь оформить в статью.
                                                                                      0
                                                                                      Спасибо ;) Кстати очень понравилась Sikula, правда не успел руками потрогать
                                                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                                                        0
                                                                                        На сколько я понял из краткого описания, для подобных задач AutoHotKey использует AutoIt старой версии. =)
                                                                                      0
                                                                                      Если вам не сложно, то немогли бы вы снять видео с экрана во время игры бота. Не хочется возиться сейчас с установкой AutoIt, но очень любопытно посмотреть как это когда набирают полтора ляма очков ))
                                                                                        0
                                                                                        Ну ставить ничего не надо, запустится по даблклику, но видео сниму. На самом деле собирался сделать видео еще перед публикацией, но в 5 утра лениво стало.
                                                                                          +1
                                                                                          Добавил видео в топик.
                                                                                            0
                                                                                            Кстати, автор мог выложить скомпилированный exe'шник. AutoIt вполне позволяет такие штуки.
                                                                                            0
                                                                                            В такого рода игрушках обычно дается гораздо больше очков, если уничтожается большое количество камней за раз.
                                                                                            Может есть смысл сделать алгоритм, который 90% времени будет собирать большие пятна правильно убирая мелкие, а в оставшееся время соберет с больших очки.
                                                                                              0
                                                                                              Чуть выше отвечал на подобный вопрос.
                                                                                              К сожалению так сделать не получится (по факту большие комбинации возможны только когда сразу падают сверху), кроме того в игре могут произвольно меняться цвета некоторых уже упавших кубиков, да и за взрывы дают очень немало очков. С нынешней скоростью бота почти всегда половина поля пустует.
                                                                                                +1
                                                                                                Видео добавлено в топик.
                                                                                                  0
                                                                                                  Комментарий веткой выше.
                                                                                                    0
                                                                                                    Да уж, человек так точно не сможет :)
                                                                                                  0
                                                                                                  Ух. Это будет интересно. Поздновато правда. Но лучше поздно чем никогда. Вечером проштудирую. Спасибо!
                                                                                                    0
                                                                                                    Я не пытаюсь что-то доказать автору, но всё же вместо «безрекурсивного поиска в глубину» было бы проще и правильнее написать поиск в ширину, который «безрекурсивный» сам по себе.
                                                                                                      0
                                                                                                      Ну была бы вместо стека очередь, и что?
                                                                                                      А для реализации ее на массиве нужно хранить 2 указателя (head и tail), вместо одного у стека. Кроме того места в памяти больше занимает. =) Мелочи это все конечно, но к вопросу о «проще».
                                                                                                        –1
                                                                                                        Просто это считается нехорошим тоном писать нерекурсивную реализацию рекурсивного алгоритма. Но ещё раз, без претензий.
                                                                                                          0
                                                                                                          Ну скажем так, для оптимизации часто разворачивают рекурсию в стек, а DFS со стеком (а не с рекурсией) наверное более правильный чем рекурсивный, просто во втором случае писать чуть меньше.
                                                                                                            0
                                                                                                            Ну, в конце концов, сама по себе рекурсия реализована стеком, так что в одном случае мы просто перекладываем работу со стеком на плечи языка.
                                                                                                              0
                                                                                                              И, разумеется, теряем в производительности. Несильно, по правде сказать.
                                                                                                      +1
                                                                                                      Интересно, спасибо. Я сам вот играю и написал бота для более известной игры — Травиан. Автопостройка, увод войска в лес, Фарм по расписанию и много чего ещё. Всё на C# и запросах к серверу (без gui, онли консоль). Если кому интересно, велком в профиль карму поднимать xDD
                                                                                                        0
                                                                                                        Хороший пример того, как из бессмысленного занятия типа игр для домохозяек и 12 летних детей может вырасти что-то весьма интересное и профессиональное. Спасибо вам.
                                                                                                          +3
                                                                                                          Написал свой вариант бота, на Java + JNA (про awt.Robot только сейчас узнал), стараясь не подглядывать в текст статьи. Во многом идеи совпали, но есть и отличия (например, в принципе задержек и в выборе места для клика). Сомневаюсь, впрочем, что это стоит отдельной статьи.

                                                                                                          Результат, полученный запуском скрипта время от времени спустя несколько дней:


                                                                                                          Пришел к выводу, что вряд ли удастся набрать значительно больше подобным методом — все упирается в длительность анимаций в самой игре.
                                                                                                            0
                                                                                                            Интереснее решать более алгоритмические задачки, например взять игру play with friends. Вот там более широкое поле для воображения, но только вот из-за пошаговости будет тяжело отлаживать бота.

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

                                                                                                            Самое читаемое