Регистрация Главная Пользователи Все разделы прочитаны
Сообщения за день Справка Регистрация
Старый 21.06.2012, 13:27   #1
 Старший сержант
Аватар для Chosen by god
 
Chosen by god скоро будет известенChosen by god скоро будет известенChosen by god скоро будет известен
Регистрация: 17.12.2011
Сообщений: 172
Популярность: 261
Сказал(а) спасибо: 34
Поблагодарили 89 раз(а) в 34 сообщениях
Отправить сообщение для Chosen by god с помощью Skype™
 
Arrow AutoIt пишем бота сами!

[Ссылки могут видеть только зарегистрированные пользователи. ]
[Ссылки могут видеть только зарегистрированные пользователи. ]

Не так давно на 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),
23. 0x1000000)
24. $aiField[$iRow][$iCol] = _GetCheckColor($iPixelColor)
25. Next
26. Next
27. ; удаление данных для избежаня утечки памяти
28._WinAPI_DeleteObject($hBitmap)
29._WinAPI_DeleteObject($hMemDC)
30._WinAPI_DeleteObject($tBits)
31. EndFunc

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

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

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

А между тем, алмазы — очень полезная вещь, потому что пока падает огненный шар, таймер останавливается, а квадратики падают. А значит пробелы заполняются, и ошибок будет меньше.
Для определения алмазов для начала пришлось поиграть с координатами замеров, чтобы цветные клетки определялись корректно, а алмазы — не попадали ни под один из их цветов. После этого создаем массив $aiDiams размером 3 (будем проверять только нижние 3 строки, потому что все алмазы рано или поздно туда упадут) * ширину (в нашем случае — 10). При каждом замере просматриваем нижние 3 строки, и если ячейка определилась, то обнуляем соответствующее место в $aiDiams, иначе инкрементируем его. Таким образом для клеток с алмазиками значения будут велики. При накоплении некоего порога, кликаем.
Оптимизация 2. Over Explosion
Тут надо объяснить, почему очень важно уменьшить количество ошибок, и почему в моем скрипте между соседними снимками экрана стоит задержка в 1/10 секунды. Дело в том, что когда поле загорается и ячейки начинают взрываться, количество очков многократно возрастает. Но если слишком много ошибаться, поле перестает загораться. Поэтому минимизация ошибок не менее важная часть, чем оптимизация времени распознавания (а учитывая запас времени, вообще единственно важная).
Несмотря на задержку в 1/10 секунды между соседними снимками экрана, некоторые ячейки все равно не успевают упасть, и определяются не на своих местах. Чтобы уменьшить их количество, была введена проверка на взрыв. При взрыве в квадратике появляется ореол почти чисто-белого цвета (#fffefc если быть точным), а это легко определить. Все клетки над взрывом, не мудрствуя лукаво, можно проставить как неопределенные.
Оптимизация 3. Область последнего клика
Защита от повторной ошибки, в эффективности которой я не уверен. Дело в том, что в самой игре при ошибке клетка становится серого цвета, а серый цвет алгоритмом определяется как неопределенный (тавтология получилась =) ). Но хуже эта проверка точно сделать не может, поэтому пусть живет.
Суть в том, что при каждом клике сохраняем область, по которой кликаем, и при следующем клике не трогаем ее.
Итог
После всего вышеописанного, мой рекорд стал примерно таким:
________________
Мои темы:
1. БАЗЫ ПАРОЛЕЙ ДЛЯ БРУТА
2. MBot 7.5

Последний раз редактировалось Chosen by god; 21.06.2012 в 13:46.
  Ответить с цитированием
5 пользователя(ей) сказали cпасибо:
►Super Ann◄ (26.05.2018), Devsik1209 (14.08.2012), DonQuatro (04.08.2012), warl0ck (02.01.2013), _•*RÀNDOM*●_ (30.07.2012)
Старый 01.07.2012, 02:57   #2
 Разведчик
Аватар для leproroot
 
leproroot никому не известный тип
Регистрация: 28.02.2011
Сообщений: 1
Популярность: 16
Сказал(а) спасибо: 0
Поблагодарили 7 раз(а) в 7 сообщениях
 
По умолчанию Re: AutoIt пишем бота сами!

[Ссылки могут видеть только зарегистрированные пользователи. ]
________________
[Ссылки могут видеть только зарегистрированные пользователи. ]
  Ответить с цитированием
Пользователь сказал cпасибо:
Chosen by god (04.07.2012)
Ответ

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
[Руководство] Создание бота в AutoIt Часть 1 KlouS Школа Читера 4 09.09.2014 18:57
[Скрипт] Скрипт на AutoIT(пишем бота) Melak Боты, скрипты и прочий софт для Lineage 2 8 04.04.2012 22:06
[Информация] ..::Пишем свой читы для CF::.. NeGaTiV™ Общение и обсуждение CrossFire 2 28.12.2011 19:05
Создание бота в AutoIt Часть 2 KlouS Школа Читера 4 20.11.2011 01:53

Заявление об ответственности / Список мошенников

Часовой пояс GMT +4, время: 14:49.

Пишите нам: [email protected]
Copyright © 2024 vBulletin Solutions, Inc.
Translate: zCarot. Webdesign by DevArt (Fox)
G-gaMe! Team production | Since 2008
Hosted by GShost.net