Mój pierwszy bot

plusmanLTE
Można jeszcze bardzo wiele rzeczy poprawić i ulepszyć w poniższym kodzie – ale gdyby ktoś zastanawiał się od czego zacząć tworzenie bota do gry (np. zrobionej we Flashu, HTML5), może skorzystać z mojego podejścia i kodu.

 

1. Gra

Bot powstał „na szybko” do gry będącej częścią kampanii reklamowej LTE od Plusa w serwisie wykop.pl. Gra wzorowana na PacManie, w której rozgrywkę można było podzielić na dwa etapy. Pierwszy – zbieranie wykopów (najlepiej w trybie Super Plusmana), punktów LTE (zamieniających Plusmana w Super Plusmana), zjadanie „wolnych internetów” jako Super Plusman i unikanie ich jako zwykły Plusman oraz zbieranie pojawiających się co 30 sekund tabletów Lenovo Yoga – zabawa w sumie na jakieś 2 minuty jeśli chcemy zsynchronizować bycie Super Plusmanem z pojawianiem się tabletów (Super Plusman porusza się szybciej i przechodzi przez ściany, więc zwiększamy w ten sposób szansę zgarnięcia tabletu). Gra kończy się w chwili zgarnięcia ostatniego wykopu – ale jeśli gracz się z tym wstrzyma – to zaczynał się drugi etap – zbieranie tabletów co 30s (i unikanie „wolnych internetów”). Etap ten mógł trwać nawet kilka godzin (chyba po ok. 5h przestawały pojawiać się tablety), więc na nim się skupiłem.

Ekran z gry Plusman LTE

Ekran z gry Plusman LTE

Link do gry: http://www.wykop.pl/+/pluslte/ (link nieaktualny)

2. Narzędzia

Skorzystałem z programu AutoHotkey – w którym można tworzyć różne skrypty, makra automatyzujące czynności wykonywane na komputerze. Kiedyś stworzyłem przy jego pomocy łamacz haseł do jakiegoś programu księgowego. W skrócie program/skrypt wpisywał trzy hasła ze słownika (wygenerowanego wcześniej przez HashCata w oparciu o informacje nt. zapomnianego hasła), zamykał i uruchamiał program i sprawdzał kolejne hasła (na szczęście można było tak robić w nieskończoność).
Oprócz AHK w międzyczasie przydał się również GIMP, LibreOffice Calc oraz Notepad++.

3. Bot

a) Lokalizowanie elementów na ekranie
Ponieważ to mój pierwszy bot, to zacząłem od sprawdzenia, czy AHK jest w stanie znaleźć na ekranie Plusmana i tablet.

Plusman różnie wygląda w różnych pozycjach, jego peleryna ciągle faluje, tło pod nim się zmienia, to wybranie jednego obrazka nie było takie proste. Dopiero przy dużym zbliżeniu w GIMPie znalazłem fragment płaszcza (5×5 pikseli), który występował cały czas. Oto on: plusman
Z tabletem było podobnie – dopiero odpowiedni fragment 1×5 pikseli (yogab) pozwalał na zlokalizowanie obrazka. Obrazek między nawiasami w poprzednim zdaniu 🙂

W międzyczasie przydał się skrypt pokazujący aktualne współrzędne kursora myszy.

Skoro działa, to jedziemy dalej.

b) Labirynt
Rozważałem dwa podejścia – albo analizować na bieżąco obraz i w ten sposób nawigować po planszy, albo trzymać planszę jako tablicę w pamięci i z jej pomocą poruszać się po labiryncie.
Wybrałem drugie rozwiązanie. Wystarczył zrzut ekranu z grą (Print Screen) + naniesiona z pomocą GIMPa siatka (Filtry -> Renderowanie -> Deseń -> Siatka…) i całość wstawiona jako tło do arkusza kalkulacyjnego (może być Calc, może być Excel). Następnie szerokość i wysokość komórek dopasowana do grubości pojedynczej ścianki labiryntu, całość wypełniona najpierw zerami, a potem pozaznaczane komórki pokrywające się ze ścianami i wypełnione jedynkami – mniej więcej jak na poniższym obrazku:

Plansza gry Plusman w Calcu

Plansza gry Plusman w Calcu

Zewnętrzne ściany do pominięcia. Czerwone komórki – tam gdzie przeoczyłem wcześniej ściany i wstawiłem 0 zamiast 1, a żółty ślad to test nawigowania po labiryncie z dalszego etapu budowy bota.
Jeszcze tylko przeliczanie pozycji na ekranie na odpowiedni wiersz i kolumnę – przetestowane poniższym „skrypcikiem” (współczynniki wpisane na stałe, dostosowane do mojego ekranu, rozdzielczości i pozycji gry w zmaksymalizowanym oknie przeglądarki).

 

c) Wyznaczanie trasy
Pewnie większość programistów słyszała o algorytmie A* – słyszałem i ja 🙂
Miałem poprzerabiać gotowy kod JS na AHK, ale google podsunął gotową implementację A* dla AHK, która właściwie nie wymagała żadnych przeróbek – można było od razu odpalić tak:

PathFind(Grid, col_begin, row_begin, col_end, row_end)

gdzie Grid to odpowiednio sparsowana tablica Field (z danymi z arkusza kalkulacyjnego):

d) Poruszanie się
To w sumie tylko wysyłanie wirtualnych wciśnięć klawiszy strzałek i odczekanie chwilkę:
Ponieważ algorytm A* zwracał tablicę kolejnych pól, przez które trzeba przejść, to zrobiona na szybko implementacja poruszania wyglądała mniej więcej tak:

 

e) Podsumowanie
W sumie algorytm działa tak, że cały czas wyszukuje na ekranie pozycji Plusmana i tabletu. Gdy znajdzie tablet, to korzystając z alg. A* (oraz tablicy z zero-jedynkową mapą poziomu) wyznacza trasę i – jeśli tylko nie jest za daleko – to właściwie na ślepo realizuje tę trasę (wysyłając do gry wciśnięcia odpowiednich klawiszy). Następnie powraca do pozycji gdzieś po środku 10 kolumny i czeka na pojawienie się kolejnego tabletu. Poniżej cały skrypt, pełen jeszcze prowizorek, zakomentowanych fragmentów, testowych śmieci, warunków pod konkretną rozgrywkę itp., bo niestety ostatecznej wersji nie mam pod ręką (pozostała na innym komputerze – na którym skrypt działał sobie po klika godzin). Większość zajmuje skopiowana implementacja A* i zero-jedynkowa mapa poziomu.

A co do skuteczności samego bota – dzięki niemu znalazłem się w pierwszej 10 rankingu graczy…

 

f) Ulepszenia
Można by np. dodać omijanie „wolnych internetów” – ja skorzystałem z faktu, że przez większość gry poruszają się one w prawym górnym lub dolnym rogu, ewentualnie czasami utkną w którejś z bocznych zatoczek – i po prostu przy pomocy paru prostych warunków omijałem tamte miejsca. Można też dopracować poruszanie postacią, tak żeby lepiej adaptowało się do różnych sytuacji (np. w tej wersji, gdy obciążenie komputera nagle skoczyło, zdarzało się, że Plusman skręcał odrobinę za wcześnie, uderzał w ścianę i realizując (w ciemno) resztę wyznaczonej trasy nie docierał już do celu. Można usunąć jedno wywołanie funkcji PathFind(Grid,col,row,colY,rowY) korzystając z zapisanego wyniku pierwszego wywołania (w załączonym kodzie raz jest wywoływana dla ustalenia odległości Plusmana od tabletu (wyrażonej ilością kroków w wyniku działania alg. A*), a potem drugi raz przy ewentualnym realizowaniu trasy – bo miałem jakiś problem z zapisaniem wyniku do tablicy a nie chciałem tracić na to czasu).

4. Posłowie

Wiem, że dla tego skryptu jeszcze daleka droga do bycia porządnym botem – zamieszczam głównie dlatego, że jakoś tam działa i może komuś kiedyś się przyda. Zwłaszcza jeśli podobnie jak ja – nie tworzył nigdy bota i zaczyna od podstaw.

 

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *