V lekci Funkce a želva jsi napsala program, který postupně načte od
uživatele dvě čísla a operaci ('+'
, '-'
, '*'
nebo '/'
)
a provede na číslech příslušnou operaci.
Program uprav tak, aby:
Nulou nelze dělit.
Použij na to ošetření příslušné chyby (tj. ne if delitel == 0:
).
Příklad použití:
První číslo: třistatřiatřicet
Zadávej jen čísla
První číslo: 333
Druhé číslo: 0
Operace: /
Nulou nelze dělit.
Dnešním úkolem je naprogramovat hru 1D Piškvorky. Nakonec bude fungovat následovně:
1-D piškvorky se hrají na řádku s dvaceti políčky. Hráči střídavě přidávají kolečka (`o`) a křížky (`x`), třeba:1. kolo: -------x------------ 2. kolo: -------x--o--------- 3. kolo: -------xx-o--------- 4. kolo: -------xxoo--------- 5. kolo: ------xxxoo---------Hráč, která dá tři své symboly vedle sebe, vyhrál.
Vymyslet, jak hezky napsat takový program, to není úplně jednoduché. Proto jsme to udělali za tebe a program jsme rozdělili do malých částí - funkcí a procedur. Z nich budeš hru postupně skládat. Napřed tedy musíš vytvořit ty malé části, pak je poskládáš dohromady.
V praxi to chodí podobně - seniorní kolegové ti řeknou, jaké funkce máš napsat, co mají ty funkce dělat, a jaké mají mít vstupy a výstupy. Na tobě je funkce napsat tak, aby splňovaly toto zadání. Jen tak je totiž bude možné do programu zapojit, aby celek fungoval.
Stejné je to i u našich piškvorek.
Úkoly dělej postupně.
Odevzdávej prosím celé soubory se všemi potřebnými importy a pomocnými funkcemi.
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 (tj. hra ještě neskončila)Například:
vyhodnot('--------------------')
vrátí '-'
vyhodnot('--o--xxx---o--o-----')
vrátí 'x'
vyhodnot('xoxoxoxoxoxoxoxoxoxo')
vrátí '!'
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 (tj. ř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 už máš napsanou?
Než začneš pracovat na tomto úkolu, počkej, až ti kouč schválí řešení toho předchozího.
Přepiš funkci tah
, aby skončila s chybou ValueError
v těchto případech:
tah('--------------------', -1, 'x')
tah('x-------------------', 0, 'o')
'x'
nebo 'o'
, např.
tah('--------------------', 0, 'řeřicha')
Odevzdané řešení předchozího úkolu můžeš nechat tak, jak je.
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áče,Pokud uživatel zadá špatný vstup (nečíslo, záporné číslo, obsazené políčko apod.), funkce mu vynadá a zeptá se znova. (Není potřeba použít pro každý případ jinou hlášku.)
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("Nový stav hry je:", 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
Nový stav hry je: o-x-----------------
Pozor: pravděpodobně budeš potřebovat ošetřit různé chyby na různých místech.
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---------
.
Napiš funkci piskvorky1d
, která:
'--------------------'
tah_hrace
a její výsledek uloží jako nové poletah_pocitace
a její výsledek uloží jako nové poleZatím neřeš konec hry.
Než začneš pracovat na tomto úkolu, počkej, až ti kouč schválí řešení toho předchozího.
Teď 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ávou.
Stav hry kontroluj po každém tahu.
Nezapomeň, že máš k dispozici funkci vyhodnot
!
Program rozděl do modulů a uprav importy tak, aby program stále fungoval. Moduly by neměly mít vedlejší efekty.
vyhodnot
, tah_hrace
a piskvorky1d
patří do modulu piskvorky
(tj. souboru piskvorky.py
).tah_pocitace
patří do modulu ai
(tj. souboru ai.py
).tah
zařaď podle materiálů o cyklických importech.Protože samotná hra – vypisování a ptaní na otázky – je vedlejší efekt,
tak teď nepůjde spustit. Aby to šlo, vytvoř ještě „spouštěcí“ modul hra
(tj. soubor hra.py
) s následujícím obsahem:
from piskvorky import piskvorky1d
piskvorky1d()
Odevzdávání a kontrola několika souborů je zatím složité, proto si tento úkol zkontroluj sama:
python hra.py
v příkazové řádce spustí funkční hru.import piskvorky
v Pythonu nespustí hru (a nemá ani další
vedlejší efekty).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í!
Odevzdej celý soubor ai.py
.