3.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ł!
3.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 2 3 4 5 6 7 8 9 10 11 12 | #! /usr/bin/env python
# -*- coding: utf-8 -*-
import rg
class Robot:
def act(self, game):
# idź do środka planszy, ruch domyślny
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.
3.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 2 3 4 5 6 7 8 9 | # jeżeli jesteś w środku, broń się
if self.location == rg.CENTER_POINT:
return ['guard']
# LUB
# jeżeli jesteś w środku, popełnij samobójstwo
if self.location == rg.CENTER_POINT:
return ['suicide']
|
3.2.3. Atakuj wrogów obok¶
Wersja wykorzystująca pętlę.
1 2 3 4 5 6 | # jeżeli obok są przeciwnicy, atakuj
# wersja z pętlą przeglądającą wszystkie pola zajęte przez roboty
for poz, robot in game.robots.iteritems():
if robot.player_id != self.player_id:
if rg.dist(poz, self.location) <= 1:
return ['attack', poz]
|
Metody i właściwości biblioteki rg:
Słownik
game.robots
zawiera dane wszystkich robotów na planszy. Metoda.iteritems()
zwraca indekspoz
, czyli położenie (x,y) robota, oraz słownikrobot
opisują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.
3.2.4. Robot podstawowy¶
Łącząc omówione wyżej trzy podstawowe reguły, otrzymujemy robota podstawowego:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #! /usr/bin/env python
# -*- coding: utf-8 -*-
import rg
class Robot:
def act(self, game):
# jeżeli jesteś w środku, broń się
if self.location == rg.CENTER_POINT:
return ['guard']
# jeżeli wokół są przeciwnicy, atakuj
for poz, robot in game.robots.iteritems():
if robot.player_id != self.player_id:
if rg.dist(poz, self.location) <= 1:
return ['attack', poz]
# idź do środka planszy
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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #! /usr/bin/env python
# -*- coding: utf-8 -*-
import rg
class Robot:
def act(self, game):
# działanie domyślne:
ruch = ['move', rg.toward(self.location, rg.CENTER_POINT)]
if self.location == rg.CENTER_POINT:
ruch = ['guard']
for poz, robot in game.robots.iteritems():
if robot.player_id != self.player_id:
if rg.dist(poz, self.location) <= 1:
ruch = ['attack', poz]
return ruch
|
3.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
3.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.
1 2 3 4 5 | for poz, robot in game.robots.iteritems():
if robot.player_id != self.player_id:
if rg.dist(poz, self.location) <= 1:
print "Atak", self.location, "=>", poz
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: | 2022-05-22 o 19:52 w Sphinx 1.5.3 |
---|---|
Autorzy: | Patrz plik “Autorzy” |