Programování pro hračičky/Opičky/Lekce 7
Tato stránka je součástí kurzu: | |
středoškolská | |
Příslušnost: skupinová |
Cykly
editovatPoté, co jsme se naučili řídit opičku v závislosti na splnění různých podmínek, nejspíše leckterého majitele opičky napadlo, jak by bylo pěkné, aby opička mohla nejenom rozpoznat, zda je podmínka splněna, nýbrž dokonce počkat, než bude nějaká podmínka splněna. Je sice pěkné, že si opička umí vzít sušenku a najíst se, pokud se na stole u Josefa nachází sušenka, ale nebylo by daleko lepší, aby v případě, že sušenka na stole není, dokázala v místnosti počkat, dokud se sušenka na stole neobjeví, a pak si ji vzít a sníst? Bystrý čtenář tuší, že když se takhle návodně ptáme, tak to opička skutečně dokáže:[1]
dokud nevidíš sušenku
tvař se jako opička čekající až někdo řekne nahlas slovo sušenka
potom
vem sušenku
jez sušenku
Když opička při vykonávání programu narazí na slovo dokud
, tak otestuje podmínku, a pokud je splněna, vykoná postupně všechny následující příkazy až do slova potom
(nebo do konce programu, pokud v němž už slovo potom
nenajde), a pak se opět vrátí ke slovu dokud
. To znamená, že skutečně pořád dokola koná příkazy umístěné mezi dokud
a potom
tak dlouho, dokud je splněna podmínka. Programátoři takovou konstrukci poměrně logicky nazývají cyklus, a toto označení budeme používat i my.
Takzvané tělo cyklu, tedy to, co se má konat stále dokola, dokud je podmínka splněna, tvoří v našem prvním příkladu jediný příkaz tvař se jako opička čekající až někdo řekne nahlas slovo sušenka
.[2] Tím opička nejen čeká, ale také napovídá případným hráčům, kteří do místnosti přijdou, jak by jí mohli pomoci — vyslovit klíčové slovo, po němž Josef vykouzlí na stůl nové sušenky, protože opička sama mluvit neumí. Jakmile se na stole objeví sušenka, přestane být pravda, že nevidíš sušenku
, a opička pokračuje ve vykonávání příkazů od slova potom
, tedy vezme si jednu sušenku a začne ji jíst.
Co když ale jedna sušenka nebude stačit na to, aby se opička nasytila? Josef vykouzlí vždy náhodné množství sušenek, možná jich je mnohem více a byla by škoda je nechat jen tak ležet. Opička tedy může poté, co se na stole objevily sušenky, zahájit další cyklus, jímž si postupně vezme a začne jíst všechny sušenky:
dokud nevidíš sušenku
tvař se jako opička čekající až někdo řekne nahlas slovo sušenka
potom
dokud vidíš sušenku
vem sušenku
jez sušenku
Co když ale opička vůbec nemá hlad? Nemůže pro ni být přejídání nebezpečné? Inu, můžeme přece použít podmínku máš hlad
, abychom zajistili, že opička se začne shánět po sušence jen v případě, že má hlad. A tuto podmínku můžeme také použít v cyklu (pak bude ovšem stačit vzít vždy jen jednu sušenku, protože opička následně opět od začátku prověří, zda nemá hlad, a v případě potřeby začne shánět další sušenku):
dokud máš hlad
dokud nevidíš sušenku
tvař se jako opička čekající až někdo řekne nahlas slovo sušenka
potom
vem sušenku
jez sušenku
potom
tvař se sytě
Na tomto příkladu vidíme, že jak cyklus s podmínkou máš hlad
, tak cyklus s podmínkou nevidíš sušenku
má své ukončovací slovo potom
. V našem přehledném zápisu rozpoznáme podle odsazení řádků, že potom
na řádku 4
patří k podmínce na řádku 2
, zatímco potom
na řádku 7
patří k podmínce na řádku 1
. Opičce ovšem nemůžeme zadat příkazy takto, ale zadáváme jí jednu dlouhou posloupnost příkazů, takže z jejího hlediska můžeme přesněji říci, že slovo potom
patří vždy k té nejbližší minulé podmínce, k níž zatím nepatří žádné slovo potom
. Když opička narazí na potom
, které vidíme na řádku 4
, přiřadí je k podmínce nevidíš sušenku
, a tím pro sebe ukončí tento malý cyklus, a když pak narazí na další potom
, přiřadí je k podmínce máš hlad
, a tím uzavře velký vnější cyklus.
Pokud jsme porozuměli těmto třem příkladům, pak jsme vybaveni k základnímu využití cyklů: umíme napsat cyklus trvající, dokud něco není, i cyklus trvající, dokud něco je, umíme zařadit dva cykly za sebe i vnořit dva cykly do sebe, a také umíme cyklus správně zakončit slovem potom
. Pokud máme dobrodružného ducha, vlastně ani nemusíme číst tuto lekci dál, protože všechno, co bychom se dočetli dále, si můžeme sami experimentujíce odhalit.
Cykly ve složitějších strukturách
editovatCykly můžeme samozřejmě kombinovat s podmíněnými příkazy. Můžeme například spustit cyklus jen v případě, že byla splněna nějaká jiná podmínka, tedy vnořit cyklus do podmíněného příkazu:
pokud vidíš vodu
dokud máš žízeň
pij vodu
potom
tvař se napitě
Anebo se můžeme uvnitř spuštěného cyklu ptát, zda byla splněna nějaká jiná podmínka, tedy vnořit podmíněný příkaz do cyklu:
dokud máš hlad
pokud máš jídlo
jez jídlo
jinak
pokud vidíš jídlo
vem jídlo
jez jídlo
potom
potom
potom
tvař se sytě
Každopádně ovšem, stejně jako když vnořujeme podmíněný příkaz do podmíněného příkazu nebo cyklus do cyklu, musíme dávat dobrý pozor, ke které podmínce se vztahuje ukončovací slovo potom
, případně přepínací slovo jinak
.
Stejně jako v případě složitějších konstrukcí z podmíněných příkazů, můžeme i složitější konstrukce s cykly rozložit do více podprogramů, které nám umožní přehledně a odděleně zapsat ucelené části složitého úkolu (potažmo usnadní hospodaření se vzájemně se pletoucími potom
):
hamham <1>:
jez <1>
dokud máš <1>
tvař se žravě
najezse:
dokud máš hlad
pokud máš jídlo
hamham jídlo
jinak pokud vidíš jídlo
vem jídlo
hamham jídlo
jinak
tvař se hladově
dosyta:
najezse
tvař se sytě
Cyklus můžeme také „zacyklit“ úplně, tedy udělat z něho nekonečný cyklus tím, že mu předepíšeme podmínku, která nepřestává být splněna. Můžeme například testovat nepřítomnost nějakého nesmyslu (dokud nevidíš škrblumpf
), můžeme testovat světlo, když se pohybujeme ve stále osvětlených prostorách (dokud je světlo
), nebo můžeme testovat přítomnost samotné opičky:[3]
dokud vidíš opičku
sever
východ
jih
západ
Takovýto program by nechal opičku běhat pořád dokolečka (nebo přesněji dočtverečku) a kdybychom jím nechtěli opičku zahubit, museli bychom jej po čase přerušit sami zvenčí příkazem konec
. Kdybychom ovšem tento příkaz využili uvnitř programu při splnění určité podmínky, dali bychom tím nekonečnému cyklu velmi praktický smysl:
dokud vidíš opičku
pokud nevidíš okno
pokud nevidíš dveře
konec
potom
potom
uteč
Tento program nechává opičku znovu a znovu utíkat náhodným směrem (příkaz uteč
si na sobě ostatně může vyzkoušet i hráč, viz pomoc uteč
), ovšem toto utíkání se zastaví, když se opička ocitne v místnosti bez oken a bez dveří. Pokud Vám takový program ještě nepřijde dost praktický, představte si, že opička místo místnosti bez oken a bez dveří hledá třeba zdroj vody, potravu nebo určitého hráče. (Pokud nám při takovém náhodném hledání náhoda nepřeje, můžeme opičku kdykoli zastavit tím, že jí zahřímáme konec
.)
Cykly jako spouštěče akcí
editovatPřipomeňme si první příklad z této lekce, jímž jsme nechali opičku čekat u Josefa a tím, jak se tváří, nabádat kolemjdoucí hráče k tomu, aby si řekli o sušenku. Představme si nyní, že z tohoto programu vyřadíme příkaz tvař se
, tedy vyprázdníme tělo cyklu:
dokud nevidíš sušenku
potom
vem sušenku
jez sušenku
Cyklus na řádku 1 neobsahuje žádné příkazy, a tak se nedá zvenčí nijak poznat, že probíhá. Po spuštění takového programu bude tedy opička tiše stát u Josefa a nedělat nic, ale ve chvíli, kdy se na stole objeví sušenky, si jednu vezme a pustí se do ní. Cyklus, který „nedělá nic“, totiž přece jen něco dělá — v taktu provádění příkazů, tedy přibližně jednou za dvě sekundy, znovu a znovu testuje podmínku. Jakmile podmínka přestane platit, cyklus skončí a opička provede příkazy, které následují po něm.
Dokud jsme neuměli používat cykly, mohli jsme opičku pohnout do akce jedině přímým vyslovením příkazu. Pomocí prázdného cyklu hlídajícího splnění určité podmínky můžeme opičku nechat automaticky reagovat na určitou změnu situace, tedy třeba objevení nebo zmizení nějakého předmětu, příchod nebo odchod nějakého hráče, setmění nebo rozednění, opiččino vyhládnutí atd.:
dokud nevidíš Šneka
potom
prohlédni si Šneka
vyplázni jazyk na Šneka
Co všechno se dá takto pomocí prázdného cyklu spustit (a jak se to dá případně využít v rámci rozsáhlejších programů), to budiž přenecháno fantazii a experimentům laskavého čtenáře.
Úkoly
editovat- Naprogramujte příkaz, kterým se opička pustí do nějaké potravy, jejíž snědení trvá delší dobu (může to být třeba i sušenka, jaká se najde u Josefa), a po jejím dojedení si hlasitě říhne.
- Naprogramujte příkaz, jímž opička jednotlivě přenosí všechny předměty určitého typu vyskytující se v jedné místnosti o jednu či několik místností dále a tam je nahromadí (například jednotlivě odnosí všechny sušenky, které jsou na stole u Josefa, do ledničky v kuchyni, nebo otrhá všechny plody z ostružiníku a udělá z nich hromádku ve vedlejší místnosti).
- Naprogramujte opičku tak, aby nečinně čekala v místnosti, ale jakmile se v místnosti objeví určitý předmět (třeba sekera, o které jste se rozhodli, že se jí opička bojí), tak si opička tento předmět prohlédne, načež začne zmateně pobíhat, než najde místnost, kde se takový předmět nenachází.
Pracovní odkazy
editovatPoznámky
editovat- ↑ Nová verze Josefa, spuštěná v květnu 2023, doplňuje sušenku i v případě, že někdo v jeho přítomnosti vyjádří sušenku i beze slov, tedy se například tváří jako čekající na sušenku. Opička si tedy může nyní vyžádat sušenku i zatvářením a nemusí čekat na nikoho, kdo umí mluvit. Příklad s cyklem však samozřejmě funguje i nadále.
- ↑ Opička tady porušuje pravidla českého pravopisu, ale jinak to bohužel nejde. Podle pravopisných pravidel by se měla před slovo „až“ napsat čárka, ale čárka by znamenala konec příkazu a začátek příkazu dalšího, a proto ji zde musíme vynechat. Stávající verze opičky (listopad 2020) neobsahuje žádnou možnost, jak zadat čárku uprostřed příkazu.
- ↑ Stejně jako hráč, může si i opička prohlížet sebe samu, tedy se vidí a je dostatečně „chytrá“ na to, aby to dokázala rozpoznat.