Dnešní úkoly budou asi povědomé. Vytvoříme totiž ... hru 1D piškvorky! Tentokrát ale s moduly a předpřipravenými testy.
Máš-li Piškvorky už hotové, doporučuji je udělat znovu. Ty původní můžeš mít vedle jako nápovědu.
Stáhni si soubor s testy, test_piskvorky.py
, a dej ho do adresáře, kde budeš tvořit
Piškvorky.
Na ulehčení testování si nainstaluj modul pytest-level
.
Ten umožňuje pouštět jen určité testy – podle toho, jak jsi daleko.
python -m pip install pytest-level
Zkus pustit všechny testy. Asi ti neprojdou:
python -m pytest -v
Pak zkus pustit testy pro úroveň 0:
python -m pytest -v --level 0
Teď se nepustí žádné testy – všechny se přeskočí. Výpis by měl končit nějak takto:
collected N items / N deselected
=== N deselected in 0.01 seconds ===
Zadáš-li v posledním příkazu --level 1
, aktivuje se první z testů.
Pravděpodobně neprojde – v dalším úkolu ho spravíš!
Tvůj postup vždycky bude:
V modulu piskvorky
(tj. v souboru piskvorky.py
)
napiš funkci vyhodnot
, která dostane řetězec
s herním polem 1-D piškvorek
a vrátí jednoznakový řetězec podle stavu hry:
"x"
– Vyhrál hráč s křížky (pole obsahuje "xxx"
)"o"
– Vyhrál hráč s kolečky (pole obsahuje "ooo"
)"!"
– Remíza (pole neobsahuje "-"
, a nikdo nevyhrál)"-"
– Ani jedna ze situací výše (t.j. hra ještě neskončila)Například:
vyhodnot('--------------------')
vrátí '-'
vyhodnot('--o--xxx---o--o-----')
vrátí 'x'
vyhodnot('xoxoxoxoxoxoxoxoxoxo')
vrátí '!'
Zatímco budeš psát tento úkol, průběžně ho kontroluj automatickými testy.
Pusť příkaz python -m pytest -v --level N
podle toho, jak jsi daleko:
--level 1
: V modulu piskvorky
je nějaká funkce vyhodnot
.--level 2
: V případě výhry dává funkce správný výsledek, 'x'
nebo 'o'
--level 3
: V případě remízy dává funkce správný výsledek, '!'
--level 4
: Když hra neskončila, funkce dává správný výsledek, '-'
Odevzdej celý soubor piskvorky.py
.
V modulu util
(tj. v souboru util.py
)
napiš funkci tah
, která dostane řetězec s herním polem,
číslo políčka (0-19), a symbol (x
nebo o
)
a vrátí herní pole (t.j. řetězec) s daným symbolem umístěným na danou pozici.
Hlavička funkce by tedy měla vypadat nějak takhle:
def tah(pole, pozice, symbol):
"""Vrátí herní pole s daným symbolem umístěným na danou pozici
`pole` je herní pole, na které se hraje.
`pozice` je číslo políčka. Čísluje se od nuly.
`symbol` může být 'x' nebo 'o', podle toho jestli je tah za křížky
nebo za kolečka.
"""
...
Například:
tah('--------------------', 0, 'x')
vrátí 'x-------------------'
tah('--------------------', 19, 'o')
vrátí '-------------------o'
tah('x-o-x-o-x-o-x-o-x-o-', 5, 'x')
vrátí 'x-o-xxo-x-o-x-o-x-o-'
Můžeš využít nějakou funkci, kterou jsme napsaly už na sraze?
Zatímco funkci budeš psát, průběžně ji kontroluj automatickými testy.
Pusť příkaz python -m pytest -v --level N
podle toho, jak jsi daleko:
--level 10
: V modulu util
je nějaká funkce tah
.
--level 11
: Funkce dává na prázdné pole x
nebo o
na dané místo
--level 20
: Hra na pozici, která není v poli, např.
tah('--------------------', -1, 'x')
--level 22
: Hra na obsazené políčko, např.
tah('x-------------------', 0, 'o')
--level 24
: Hra jiným symbolem než 'x'
nebo 'o'
, např.
tah('--------------------', 0, 'řeřicha')
Odevzdej celý soubor util.py
.
V modulu piskvorky
(tj. v souboru piskvorky.py
)
napiš funkci tah_hrace(pole, symbol)
, která dostane řetězec
s herním polem a symbol (x
nebo o
) a:
tah
zjistí, jak vypadá herní pole se zaznamenaným tahem
hráčePokud uživatel zadá špatný vstup (nečíslo, záporné číslo, obsazené políčko apod.), funkce mu vynadá a zeptá se znova.
Hlavička funkce by tedy měla vypadat nějak takhle:
def tah_hrace(pole, symbol):
"""Zeptá se hráče na tah a vrátí nové herní pole
`pole` je herní pole, na které se hraje.
`symbol` může být 'x' nebo 'o', podle toho jestli hráč hraje za křížky
nebo za kolečka.
"""
...
Například zavolání print(tah_hrace('o-------------------', 'x'))
by mohlo
dopadnout takto:
Kam chceš hrát? nevím
Zadávej čísla!
Kam chceš hrát? 0
Tam nejde hrát!
Kam chceš hrát? -1
Tam nejde hrát!
Kam chceš hrát? 151
Tam nejde hrát!
Kam chceš hrát? 2
o-x-----------------
Nezapomeň, že ve vedlejším modulu máš funkci tah
, kterou si můžeš
naimportovat.
Funkci piš podle automatických testů -- tentokrát nastavuj level na 30 až 34.
Odevzdej celý soubor piskvorky.py
(i s funkcí vyhodnot
).
V modulu ai
(tj. v souboru ai.py
)
napiš funkci tah_pocitace(pole, symbol)
, která dostane řetězec s herním
polem a symbol, vybere pozici, na kterou hrát, a vrátí herní pole
se zaznamenaným tahem počítače.
Použij jednoduchou náhodnou „strategii”:
Hlavička funkce by tedy měla vypadat nějak takhle:
def tah_pocitace(pole, symbol):
"""Vrátí herní pole se zaznamenaným tahem počítače
`pole` je herní pole, na které se hraje.
`symbol` může být 'x' nebo 'o', podle toho jestli hráč hraje za křížky
nebo za kolečka.
"""
...
Zavolání print(tah_pocitace('o-------------------', 'x'))
by
mohlo vypsat třeba o---------x---------
.
Testy jsou v levelech 40 až 44.
Odevzdej celý soubor ai.py
.
V modulu piskvorky
(tj. v souboru piskvorky.py
)
napiš funkci piskvorky1d
, která:
tah_hrace
, a výsledek uloží jako nové poletah_pocitace
, a výsledek uloží jako nové poleZatím neřeš konec hry.
V modulu hra
(tj. v souboru hra.py
) přidej import a volání funkce
piskvorky1d
.
Původní testy by měly stále procházet.
Automatické testy na celou hru ale nejsou – otestuj to ručně
pomocí python hra.py
!
Tady odevzdej pouze modul piskvorky.py
.
Tady odevzdej soubor hra.py
.
Pošéfuj konec hry. Když někdo vyhraje nebo dojde k remíze, cyklus se ukončí a vypíše se výsledek – třeba s gratulací nebo povzbuzující zpráva.
Stav hry kontroluj po každém tahu.
Nezapomeň, že máš k dispozici funkci vyhodnot
!
Automatické testy na celou hru nejsou – otestuj to ručně! Nezapomeň zkontrolovat remízu.
Odevzdej celý soubor piskvorky.py
.
Zvládneš pro počítač naprogramovat lepší strategii? Třeba aby se snažil hrát vedle svých existujících symbolů nebo aby bránil protihráčovi? Stačí jen docela malé vylepšení!
Testy by stále měly procházet.
Odevzdej celý soubor ai.py
.