IB111 Domácí úkol č. 5

Zadání: 28. 11. 2016

Odevzdání: do 07.12.2016 22:00

Poznámky k řešení domácích úkolů:

Představení úkolu: Faraónovo zlato

V tomto úkolu si za pomocí jednoduchých objektů naprogramujete jednoduchou textovou dobrodružnou hru (tzv. „textovku“). Hlavní hrdina této hry se vydává do egyptské pyramidy, aby zde čelil mnohým nástrahám a přinesl si odtamtud co nejvíce hodnotných předmětů. Protože v pyramidě se mohou vyskytovat nepřátelská stvoření, bude hrdina také vyzbrojen (a možná v pyramidě najde nějaké zbraně po předchozích pokusech svých méně úspěšných kolegů).

Pyramida bude reprezentována jako množství místností, mezi kterými se dá procházet (někdy jednosměrně). V místnostech se budou nacházet cenné předměty, zbraně a případně i nepřátelé. Všechny tyto věci budeme reprezentovat pomocí Pythonovských objektů. Pro pohyb a jiné akce hrdiny se budou používat textové příkazy zadávané na vstup.

Abyste si mohli své řešení vyzkoušet a otestovat, máte k dispozici předpřipravené předměty, zbraně, příšery a plán pyramidy v souboru IB111DU5template.py. Tento plán si samozřejmě můžete libovolně upravit.

Část 1: Předměty (3 body)

Vytvořte třídu Item pro reprezentaci cenných předmětů. Každý předmět má následující atributy:

Všechny tyto atributy nastaví metoda __init__(self, name, description, value, weight).

Dále pak ve třídě Item vytvořte metodu describe(self), která vypíše popis předmětu na výstup ve formátu uvedeném níže.

>>> it = Item("mince", "Stara petikoruna.", 5, 1)
>>> it.describe()
mince: Stara petikoruna. (cena: 5, vaha 1)

Část 2: Zbraně (3 body)

Vytvořte třídu Weapon pro reprezentaci zbraní. Každá zbraň má následující atributy:

Všechny tyto atributy nastaví metoda __init__(self, name, description, attack, defence).

Dále pak ve třídě Weapon vytvořte metodu describe(self), která vypíše popis zbraně na výstup ve formátu uvedeném níže.

>>> w = Weapon("dyka", "Stara rezava dyka. Dost tupa.", 5, 2)
>>> w.describe()
dyka: Stara rezava dyka. Dost tupa. (utok: 5, obrana: 2)

Část 3: Příšery (3 body)

Vytvořte třídu Monster pro reprezentaci nepřátelských příšer. Každá příšera má následující atributy:

Všechny tyto atributy nastaví metoda __init__(self, name, attack, defence, vigilance, health).

Dále pak ve třídě Monster vytvořte metodu react_to_noise(self). Tato metoda reprezentuje reakci příšery na hluk (při příchodu do místnosti apod.). V této metodě se hodí dvacetistěnnou kostkou (vygeneruje se číslo od 1 do 20) a pokud je toto číslo menší nebo rovno hodnotě ostražitosti dané příšery, pak se její stav sleeping nastaví na False.

>>> m = Monster("zla mumie", 10, 5, 10, 100)
>>> print m.sleeping
True
>>> m.react_to_noise()  # polovicni sance, ze se probudi
>>> print m.sleeping
False

Část 4: Hráč (3 body)

Vytvořte třídu Player pro reprezentaci hráče. Hráč má následující atributy:

Všechny tyto atributy nastaví metoda __init__(self, name).

Dále pak ve třídě Player vytvořte následující metody:

>>> p = Player("Indiana Jones")
>>> p.describe()
Jmeno hrace: Indiana Jones
Zdravi: 182/182
Zbyvajici kapacita batohu: 152
Prazdny batoh.
Zbran: dyka: Stara rezava dyka. Dost tupa. (utok: 5, obrana: 2)
>>> print p.add_to_bag(it)
True
>>> p.describe()
Jmeno hrace: Indiana Jones
Zdravi: 182/182
Zbyvajici kapacita batohu: 151
Obsah batohu:
- mince: Stara petikoruna. (cena: 5, vaha: 1)
Zbran: dyka: Stara rezava dyka. Dost tupa. (utok: 5, obrana: 2)
>>> print p.add_to_bag(Item("tuna", "Fakt tezka vec", 100, 200))
False
>>> x = p.take_from_bag("mince")
>>> x.describe()
mince: Stara petikoruna. (cena: 5, vaha: 1)
>>> lte = Weapon("lte", "Laserovy takticky eliminator.", 100, 0)
>>> y = p.take_weapon(lte)
>>> y.describe()
dyka: Stara rezava dyka. Dost tupa. (utok: 5, obrana: 2)
>>> p.describe()
Jmeno hrace: Indiana Jones
Zdravi: 182/182
Zbyvajici kapacita batohu: 152
Prazdny batoh.
Zbran: lte: Laserovy takticky eliminator. (utok: 100, obrana: 0)

Část 5: Souboj (3 body)

Když už máte hráče i nepřátele, je čas na implementaci souboje. Vytvořte funkci fight(player, monster), která odehraje souboj mezi hráčem a příšerou podle následujících pravidel:

V průběhu souboje by měla funkce fight vypisovat podrobné informace o jeho průběhu (včetně zdraví účastníků). Pro přehlednost nechte uživatele mezi jednotlivými koly stisknout Enter (nápověda: použijte raw_input). Na konci pak funkce fight vrátí True, pokud byl protivník poražen, nebo False, pokud byl poražen hráč.

>>> p = Player("Indiana Jones")
>>> m = Monster("mumie", 5, 2, 10, 100)
>>> result = fight(p, m)
Souboj s protivnikem: mumie (100 zdravi)
Tvoje zdravi: 173/173
Protivnik "mumie" na tebe utoci.
Tento utok ti zpusobil 3 zraneni.
Tvoje zdravi: 170/173
Stiskni enter:
Utocis na protivnika.
Tvuj utok zpusobil 2 zraneni.
Protivnikovo zdravi: 98
Stiskni enter:
Protivnik "mumie" na tebe utoci.
Tento utok ti zpusobil 2 zraneni.
Tvoje zdravi: 168/173
Stiskni enter:
Utocis na protivnika.
Tvuj utok zpusobil 3 zraneni.
Protivnikovo zdravi: 95
Stiskni enter:

# ... vynechano 248 radku ...

Protivnik "mumie" na tebe utoci.
Tento utok ti zpusobil 2 zraneni.
Tvoje zdravi: 73/173
Stiskni enter:
Utocis na protivnika.
Tvuj utok zpusobil 3 zraneni.
Protivnikovo zdravi: 4
Stiskni enter:
Protivnik "mumie" na tebe utoci.
Tento utok ti zpusobil 4 zraneni.
Tvoje zdravi: 69/173
Stiskni enter:
Utocis na protivnika.
Tvuj utok zpusobil 4 zraneni.
Protivnikovo zdravi: 0
Stiskni enter:
Protivnik je porazen!
>>> print result
True

Část 6: Místnosti (3 body)

Vytvořte třídu Room pro reprezentaci místností v pyramidě. Každá místnost má následující atributy:

Všechny tyto atributy nastaví metoda __init__(self, description, ending=None). Všimněte si, že parametr ending má implicitní hodnotu.

Dále pak ve třídě Room vytvořte následující metody:

Příklad toho, jak může vypadat popis místnosti:

Jsi uprostred chodby, ktera vede zapadovychodnim smerem.
V mistnosti se nachazeji nasledujici zbrane:
- sekera: Obrovska oborucni sekera. Uneses ji? (utok: 15, obrana: 1)
- kus: Samostril. Ucinny, ale obtizne se natahuje. (utok: 20, obrana: 0)
V mistnosti se nachazeji nasledujici cenne predmety:
- prsten1: Prsten s diamantem. (cena: 50, vaha: 1)
- prsten2: Prsten bez diamantu. (cena: 5, vaha: 1)
Z mistnosti se da odejit nasledujicimi smery:
- zapad
- vychod
V mistnosti je slaba mumie. Spi.

Část 7: Náhodné rozmístění (3 body)

Aby byla hra zajímavější, tak chceme většinu předmětů, zbraní a příšer rozmístit po pyramidě náhodně. K tomu účelu vytvořte funkci randomize(rooms, monsters, items, weapons), která dostane seznamy místností, příšer, předmětů a zbraní a provede náhodné rozmístění. Pamatujte na to, že v každé místnosti smí být jen jedna příšera.

Poznámka: Funkce randomize nemá předměty (zbraně, příšery) duplikovat, jen je má rozmístit po místnostech. To znamená, že ve výsledku nemůže být jeden předmět ve více místnostech zároveň.

Část 8: Samotná hra (4 body)

Máte-li už všechno připraveno, můžete se pustit do implementace samotné hry. Napište funkci play(start), která jako parametr dostane počáteční místnost. Funkce by se nejprve měla hráče zeptat na jméno, poté vypsat základní informace o hráči a o počáteční místnosti. Dále pak bude hra očekávat textové příkazy (popsané dále) a reagovat na ně. Hra končí v těchto případech:

Příkazy, které může hráč zadávat jsou následující:
(Pro jednoduchost zde ignorujeme správnou gramatiku, takže příkazy budou znít jdi sever a vezmi dyka, ale tím se zbytečně netrapte.)

Nemusíte nijak reagovat na špatně napsané příkazy. Bylo by ale lepší, pokud by se vaše hra při zadání špatného příkazu nezhroutila.

Ve chvíli, kdy se hráč nachází v místnosti s probuzenou příšerou, začne okamžitě probíhat souboj (bez možnosti útěku). Pokud souboj dopadne pro hráče vítězně, příšera je z místnosti odstraněna.

Příklad toho, jak může vypadat sehrání hry:

Zadej sve jmeno: Indiana Jones
Jmeno hrace: Indiana Jones
Zdravi: 170/170
Zbyvajici kapacita batohu: 168
Prazdny batoh.
Zbran: dyka: Stara rezava dyka. Dost tupa. (utok: 5, obrana: 2)

Jsi ve vchodu do pyramidy.
Z mistnosti se da odejit nasledujicimi smery:
- ven
- dovnitr

Zadej prikaz: jdi dovnitr

Jsi v pyramide, chodby vedou na sever, na jih a na vychod.
V mistnosti se nachazeji nasledujici zbrane:
- r_mec: Rezavy mec. (utok: 6, obrana: 4)
V mistnosti se nachazeji nasledujici cenne predmety:
- prsten3: Zlaty prsten. (cena: 20, vaha: 1)
Z mistnosti se da odejit nasledujicimi smery:
- jih
- sever
- vychod
V mistnosti je stir. Spi.

Zadej prikaz: vezmi r_mec

Beres zbran r_mec.

Jsi v pyramide, chodby vedou na sever, na jih a na vychod.
V mistnosti se nachazeji nasledujici zbrane:
- dyka: Stara rezava dyka. Dost tupa. (utok: 5, obrana: 2)
V mistnosti se nachazeji nasledujici cenne predmety:
- prsten3: Zlaty prsten. (cena: 20, vaha: 1)
Z mistnosti se da odejit nasledujicimi smery:
- jih
- sever
- vychod
V mistnosti je stir. Spi.

Zadej prikaz: vezmi prsten3

Beres predmet prsten3.

Jsi v pyramide, chodby vedou na sever, na jih a na vychod.
V mistnosti se nachazeji nasledujici zbrane:
- dyka: Stara rezava dyka. Dost tupa. (utok: 5, obrana: 2)
Z mistnosti se da odejit nasledujicimi smery:
- jih
- sever
- vychod
V mistnosti je stir. Spi.

Zadej prikaz: jdi jih

Jsi v klikate chodbe, ze ktere se da pokracovat na sever a na zapad.
U steny chodby jsou schody nahoru.
V mistnosti se nachazeji nasledujici zbrane:
- sekera: Obrovska oborucni sekera. Uneses ji? (utok: 15, obrana: 1)
V mistnosti se nachazeji nasledujici cenne predmety:
- miska: Zlata miska osazena drahokamy. (cena: 120, vaha: 5)
- prsten2: Prsten bez diamantu. (cena: 5, vaha: 1)
- vaza: Cenna anticka vaza. (cena: 75, vaha: 20)
Z mistnosti se da odejit nasledujicimi smery:
- nahoru
- zapad
- sever
V mistnosti je ostrazita mumie. Je vzhuru!

Souboj s protivnikem: ostrazita mumie (50 zdravi)
Tvoje zdravi: 170/170
Protivnik "ostrazita mumie" na tebe utoci.
Tento utok ti zpusobil 2 zraneni.
Tvoje zdravi: 168/170
Stiskni enter:

# ... vynechan souboj ...

Utocis na protivnika.
Tvuj utok zpusobil 7 zraneni.
Protivnikovo zdravi: -6
Stiskni enter:
Protivnik je porazen!

Jsi v klikate chodbe, ze ktere se da pokracovat na sever a na zapad.
U steny chodby jsou schody nahoru.
V mistnosti se nachazeji nasledujici zbrane:
- sekera: Obrovska oborucni sekera. Uneses ji? (utok: 15, obrana: 1)
V mistnosti se nachazeji nasledujici cenne predmety:
- miska: Zlata miska osazena drahokamy. (cena: 120, vaha: 5)
- prsten2: Prsten bez diamantu. (cena: 5, vaha: 1)
- vaza: Cenna anticka vaza. (cena: 75, vaha: 20)
Z mistnosti se da odejit nasledujicimi smery:
- nahoru
- zapad
- sever

Zadej prikaz: vezmi miska

Beres predmet miska.

Jsi v klikate chodbe, ze ktere se da pokracovat na sever a na zapad.
U steny chodby jsou schody nahoru.
V mistnosti se nachazeji nasledujici zbrane:
- sekera: Obrovska oborucni sekera. Uneses ji? (utok: 15, obrana: 1)
V mistnosti se nachazeji nasledujici cenne predmety:
- prsten2: Prsten bez diamantu. (cena: 5, vaha: 1)
- vaza: Cenna anticka vaza. (cena: 75, vaha: 20)
Z mistnosti se da odejit nasledujicimi smery:
- nahoru
- zapad
- sever

Zadej prikaz: info

Jmeno hrace: Indiana Jones
Zdravi: 145/170
Zbyvajici kapacita batohu: 162
Obsah batohu:
- prsten3: Zlaty prsten. (cena: 20, vaha: 1)
- miska: Zlata miska osazena drahokamy. (cena: 120, vaha: 5)
Zbran: r_mec: Rezavy mec. (utok: 6, obrana: 4)

Zadej prikaz: jdi zapad

Jsi v klikate chodbe, ze ktere se da pokracovat na sever a na vychod.
V mistnosti se nachazeji nasledujici cenne predmety:
- prsten4: Zelezny prsten. (cena: 1, vaha: 1)
Z mistnosti se da odejit nasledujicimi smery:
- vychod
- sever
V mistnosti je velky zly pavouk. Spi.

Zadej prikaz: jdi sever

Vchazis do mistnosti, kdyz tu slysis, jak pod tebou cvaklo propadlo.
Z mistnosti se da odejit nasledujicimi smery:
- dolu

Zadej prikaz: jdi dolu

Padas do mistnosti plne hadu. Tim to pro tebe konci.
--- neuspesny konec hry ---

Bonus

Můžete získat bonusové body, pokud svou hru proti tomuto základnímu zadání nějak rozšíříte. Do bonusových rozšíření se ale pouštějte až ve chvíli, kdy vám funguje základní varianta. Možných rozšíření je jistě celá řada, můžete se inspirovat následujícími náměty: ukládání skóre hráčů do souboru a výpis nejlepších hrdinů po skončení hry, rozšíření hry o jiné textové příkazy, rozšíření soubojového systému, počítání kroků, omezení odpočívání, apod. V komentářích popište, v čem vaše rozšíření spočívá.