8.2. RG – klocki 1
Wskazówka
Każdy „klocek” można testować osobno, a później w połączeniu z innymi. Warto i trzeba zmieniać kolejność stosowanych reguł!
8.2.1. Idź do środka
To będzie nasza domyślna reguła. Umieszczamy ją w pliku robot01.py
zawierającym niezbędne minimum działającego bota:
1#! /usr/bin/env python
2# -*- coding: utf-8 -*-
3
4import rg
5
6
7class Robot:
8
9 def act(self, game):
10
11 # idź do środka planszy, ruch domyślny
12 return ['move', rg.toward(self.location, rg.CENTER_POINT)]
Metody i właściwości biblioteki rg:
rg.toward(poz_wyj, poz_cel)– zwraca następne położenie na drodze z bieżącego miejsca do podanego.self.location– pozycja robota, który podejmuje działanie (self).rg.CENTER_POINT– środek areny.
8.2.2. W środku broń się lub giń
Co powinien robić robot, kiedy dojdzie do środka? Może się bronić lub popełnić samobójstwo:
1# jeżeli jesteś w środku, broń się
2if self.location == rg.CENTER_POINT:
3 return ['guard']
4
5# LUB
6
7# jeżeli jesteś w środku, popełnij samobójstwo
8if self.location == rg.CENTER_POINT:
9 return ['suicide']
8.2.3. Atakuj wrogów obok
Wersja wykorzystująca pętlę.
1# jeżeli obok są przeciwnicy, atakuj
2# wersja z pętlą przeglądającą wszystkie pola zajęte przez roboty
3for poz, robot in game.robots.iteritems():
4 if robot.player_id != self.player_id:
5 if rg.dist(poz, self.location) <= 1:
6 return ['attack', poz]
Metody i właściwości biblioteki rg:
Słownik
game.robotszawiera dane wszystkich robotów na planszy. Metoda.iteritems()zwraca indekspoz, czyli położenie (x,y) robota, oraz słownikrobotopisujący jego właściwości, czyli:player_id – identyfikator gracza, do którego należy robot;
hp – ilość punktów HP robota;
location – tupla (x, y) oznaczająca położenie robota na planszy;
robot_id – identyfikator robota w Twojej drużynie.
rg.dist(poz1, poz1)– zwraca matematyczną odległość między dwoma położeniami.
8.2.4. Robot podstawowy
Łącząc omówione wyżej trzy podstawowe reguły, otrzymujemy robota podstawowego:
1#! /usr/bin/env python
2# -*- coding: utf-8 -*-
3
4import rg
5
6
7class Robot:
8
9 def act(self, game):
10 # jeżeli jesteś w środku, broń się
11 if self.location == rg.CENTER_POINT:
12 return ['guard']
13
14 # jeżeli wokół są przeciwnicy, atakuj
15 for poz, robot in game.robots.iteritems():
16 if robot.player_id != self.player_id:
17 if rg.dist(poz, self.location) <= 1:
18 return ['attack', poz]
19
20 # idź do środka planszy
21 return ['move', rg.toward(self.location, rg.CENTER_POINT)]
Wybrane działanie robota zwracamy za pomocą instrukcji return.
Zwróć uwagę, jak ważna jest w tej wersji kodu kolejność umieszczenia reguł,
pierwszy spełniony warunek powoduje wyjście z funkcji, więc pozostałe
możliwości nie są już sprawdzane!
Powyższy kod można przekształcić wykorzystując zmienną pomocniczą ruch,
inicjowaną działaniem domyślnym, które może zostać zmienione przez kolejne reguły.
Dopiero na końcu zwracamy ustaloną akcję:
1#! /usr/bin/env python
2# -*- coding: utf-8 -*-
3
4import rg
5
6
7class Robot:
8
9 def act(self, game):
10 # działanie domyślne:
11 ruch = ['move', rg.toward(self.location, rg.CENTER_POINT)]
12
13 if self.location == rg.CENTER_POINT:
14 ruch = ['guard']
15
16 for poz, robot in game.robots.iteritems():
17 if robot.player_id != self.player_id:
18 if rg.dist(poz, self.location) <= 1:
19 ruch = ['attack', poz]
20
21 return ruch
8.2.4.1. Ćwiczenie 1
Przetestuj działanie robota podstawowego wystawiając go do gry z samym sobą w symulatorze. Zaobserwuj zachowanie się robotów tworząc różne układy początkowe:
(env)~/robot$ python ./symuluj robot04a.py robot04b.py
8.2.5. Możliwe ulepszenia
Robota podstawowego można rozbudowywać na różne sposoby przy użyciu różnych technik kodowania. Proponujemy więc wersję **A** opartą na funkcjach i listach oraz wersję **B** opartą na zbiorach. Obie wersje implementują te same reguły, jednak efekt końcowy wcale nie musi być identyczny. Przetestuj i przekonaj się sam.
Wskazówka
Przydatną rzeczą byłaby możliwość dokładniejszego śledzenia decyzji podejmowanych
przez robota. Najprościej można to osiągnąć używając polecenia print
w kluczowych miejscach algorytmu. Podany niżej Kod nr 6 wyświetla w terminalu
pozycję aktualnego i atakowanego robota. Kod nr 7, który nadaje się zwłaszcza
do wersji robota wykorzystującej pomocniczą zmienną ruch, umieszczony przed
instrukcją return pozwoli zobaczyć w terminalu kolejne ruchy naszego robota.
1for poz, robot in game.robots.iteritems():
2 if robot.player_id != self.player_id:
3 if rg.dist(poz, self.location) <= 1:
4 print "Atak", self.location, "=>", poz
5 return ['attack', poz]
print ruch[0], self.location, "=>",
if (len(ruch) > 1):
print ruch[1]
else:
print
Materiały Python 101
udostępniane przez
Centrum Edukacji Obywatelskiej na licencji
Creative Commons Uznanie autorstwa-Na tych samych warunkach 4.0 Międzynarodowa.
- Utworzony:
2026-04-19 o 17:42 w Sphinx 7.3.7
- Autorzy: