Programování pro hračičky/Měniči/Lekce 11

Jak používat klasifikační nálepkuTato stránka je součástí kurzu:
středoškolská
Příslušnost: skupinová

Měničské mistrovství editovat

Tovaryš, který nasbíral dostatek měničské zkušenosti, se může dát povýšit na mistra (pokud nevíte, jak na to, zkuste prostě v přítomnosti mistra Ezechiela prohlásit, že se chcete stát mistrem). Jako mistrovi se mu otevře nevyčerpatelná zásoba možností, jak zasahovat do hry, ovšem k jejich využívání potřebuje mnohem více studovat, než potřeboval jako učeň pro užívání příkazu změň nebo jako tovaryš pro užívání příkazu přeonač. Mistr totiž může vytvářet přímo části programů v LPC (tedy v programovacím jazyce, v němž jsou napsány celé Prahy) a připojovat je k programům jednotlivých herních objektů.

Ani mistr samozřejmě nemůže všechno. Jednak jsou mu při programování některé funkce přímo zapovězeny (například ty, které hráčům bezprostředně odebírají nebo přidávají životní body), jednak je omezen samotným principem měničského řemesla. Jak jsme si už řekli, změny se provádějí pomocí zastínění, tedy tím, že se pro proměněný objekt vyrobí jiný objekt, který na přechodnou dobu vykonává některé jeho funkce. Měničský učeň příkazem změň vyrobí zastínění, které podle charakteru změny vykonává místo zastíněného objektu například funkci query_smell() (pokud byla změněna vůně objektu) nebo query_long() a query_long_night() (pokud byl změněn popis objektu). Měničský tovaryš příkazem přeonač vyrobí zastínění, které místo zastíněného objektu vykonává funkci init(), definující hráčské příkazy pro zacházení s objektem. Měničský mistr nyní může příkazem programuj připravit zastínění, které bude na přechodnou dobu vykonávat místo zastíněného objektu téměř libovolné funkce, ale nemůže vytvořit úplně nový objekt (je ostatně mistrem měničem, nikoli tvořičem), nemůže provádět žádné změny trvale a nemůže zasahovat do nitra samotných měněných objektů.

Psaní a spouštění programů editovat

Měničský mistr pracuje dvoukrokově. Nejprve příkazem programuj vytvoří (a uloží na disk) program budoucího zastínění, a následně příkazem spusť spustí vytvořený program na nějakém okolním objektu.[1] Pro nejjednodušší příklad si vyzkoušejme něco, co už jsme uměli udělat jako měničští učňové — ovšem nyní si to vyzkoušejme už opravdu programátorsky:

> programuj
Název programu: kousnedonosu
Soustředíš se na měnění...
...a z tvé mushle vyvstává nový program, tu zelený, tu nachový.
Text se zadává jako v ED --- pro obdržení nápovědy zadej 'h'.
Začínáš psát nový text.
:a
     1. string query_smell()
     2. {
     3. return wrap("Au! "+Ten(1,this_object())+" tě "+dan("kousl",this_object())+" do nosu!");
     4. }
     5. .
:x
Program "kousnedonosu" byl uložen.

Program, který jsme vytvořili, vidíme na číslovaných řádcích, které jsme do dosud prázdného programu kousnedonosu přidali editačním příkazem a (tedy append).[2] Na první řádce se nachází deklarace funkce query_smell(), což je funkce, která na dotaz zvenčí vrací zápach objektu; úvodní string znamená, že funkce vrací (znakový) řetězec, tedy nějaký text. Na druhé a čtvrté řádce vidíme složené závorky, které uvozují a zakončují definici toho, co má deklarovaná funkce dělat. A to je vysvětleno na třetí řádce: funkce má vrátit (to říká příkaz return) hezky naformátovaný text (to říká funkce wrap()), který vznikne poskládáním několika dílků, v niž bystrý čtenář rozpozná gramatické funkce, vysvětlené v 8. lekci našeho kurzu; funkce this_object() zde funguje stejně jako OBJ_TO v pseudoklauzurách. (Na pátém řádku programu pak vidíme jen tečku. Ta už k programu nepatří, to byl jen příkaz zakončující přidávání řádek.)

Když máme nyní program vytvořen a uložen, můžeme ho spouštět na libovolných objektech. Začněme v Matici oblíbeným svitkem:

> spusť "kousnedonosu" na svitku
Spustil jsi program "kousnedonosu" na zažloutlém svitku jen na chvíli.
> očichej svitek
Au! Zažloutlý svitek tě kousl do nosu!

Nyní se můžeme ptát, k čemu je to vlastně dobré. Měnit vůni tímto způsobem jsme dokázali už jako učni příkazem změň, a bylo to mnohem jednodušší. Proč se nyní pouštět do složité programátorské práce? Hlavní důvody jsou čtyři:

  • Pokud si nejprve vytvoříme a uložíme program, můžeme jej následně používat opakovaně, a to i kdykoli v budoucnu. Kdo zkoušel příkazem změň věrohodně změnit popis místnosti, ten jistě ví, kolik je to psaní. A nyní to stačí udělat jen jednou pro všechna budoucí použití na všemožných objektech, s nimiž se ve hře setkáme.
  • Uložený program můžeme dále vylepšovat a rozšiřovat. Kdo zkusil příkazem změň změnit popis místnosti a následně v něm objevil překlep, velmi ocení možnost opravit samotný překlep. Nyní ovšem můžeme též přidávat do svého programu nové funkce a zlepšovat účinek těch dosavadních.
  • Do programu můžeme uložit neomezeně funkcí najednou. Kdo zkoušel změnit příkazem změň některý předmět tak, aby měl odlišný popis, vůni, povrch a zvuk najednou, ten se nejspíše dočkal jen frustrace, protože než se mu podařilo změnit poslední vlastnost, první změna skončila, nebo mu prostě došly duševní body. Nyní si můžeme naprogramovat všechny tyto změny do jednoho programu a následně je najednou spustit na nějakém objektu.
  • Naše možnosti jsou nyní omezeny (téměř) jen našimi znalostmi LPC a programových knihoven mudu Prahy. Zatímco dosud jsme mohli provádět jen přesně vyjmenované množiny akcí, nyní můžeme spustit (až na několik blokovaných výjimek) jakoukoli funkci, kterou se naučíme. Nemusíme už trápit své spoluhráče náhodným pohybem, nýbrž můžeme je hned přenášet na druhý konec světa, nemusíme už panicky hledat zdroje vody poháněni hláškami o smrti žízní, nýbrž můžeme si udělat zdroj vody třeba ze své mušle. Mud patří nám![3]

Měničská poselství editovat

Stejně jako učeň a tovaryš, i měničský mistr trpí věčným nedostatkem duševních bodů. Zatímco však učeň a tovaryš musí trávit čas své regenerace třeba tím, že hledají léčivé byliny v horách nebo cvičí dovednost v boji šavlí na tu a tam se potulujících Sarumanových skřetech, mistr může během své regenerace dále zdokonalovat přímo své odborné dovednosti. Jednak může studovat dokumentaci funkcí LPC a programových knihoven v samotné Matici — o tom pohovoříme obšírněji v příští kapitole — jednak se může pustit do dobrodružnější části mistrovského studia a vyrazit do terénu. Na různých význačných místech světů mezi Prahy jsou totiž ukryta měničská poselství, která podrobně vysvětlují fungování některých částí hry — třeba jak se programátorsky zachází s vodou, jak s bylinami, jak s jízdními zvířaty atd.

Vedle těchto poselství mohou měničští mistři najít někde ve světech mezi Prahy určité služby, umožňující jim například zjišťovat programátorská jména objektů nebo nahlížet do programů některých předmětů, které se dají ve hře najít.

Nové možnosti v Matici editovat

Pravděpodobně každý měničský učeň si už na počátku v popisu Matice všimne zmínky, že prý do ní mistři Bratrstva chodí meditovat, kontemplovat a imaginovat. Ten či onen měnič si i vyzkoušel, zda náhodou nemůže užívat příkazů medituj, kontempluj a imaginuj.[4] S povýšením do mistrovské hodnosti nastala chvíle, kdy konečně může — a brzy zjistí, že se bez toho neobejde. Má-li totiž mistr programovat, potřebuje studovat programátorskou dokumentaci, aby se dozvěděl, jaké funkce má k dispozici (a jaké tedy může případně i předefinovávat), jaký vstup a výstup tyto funkce přesně vyžadují, co vlastně tyto funkce dělají. A právě k tomu jsou určeny zmíněné příkazy.

Imaginace editovat

Po příkladu uvedeném v první kapitole tohoto kroku můžeme začít imaginací. Ta zprostředkovává měničskému mistrovi dokumentaci konkrétních funkcí LPC nebo programových knihoven. Podívejme se tedy nejprve na popis funkce query_smell(), která na dotaz vrací zápach objektu:

> imaginuj query_smell
Imaginuješ 'query_smell', soustředěn na objekty světů mezi Prahy, a před tvým
duchovním zrakem vyvstávají tyto obrazy:
------------------------------------------------------------------------------
FUNKCE: query_smell
DEKLARACE: string query_smell()
POPIS:
   Vrací zápach, který objekt vydává při očichání.
VIZ: set_smell
SKUPINA: basic
ZDROJ: /i/item/smell.c
------------------------------------------------------------------------------

Samotný jednoduchý popis funkce nám v tomto případě asi neřekne nic, co bychom už nevěděli. Prozrazuje nám však mimochodem, že funkce query_smell() patří do skupiny funkcí basic, že je součástí programového modulu /i/item/smell.c a že nějak souvisí s funkcí set_smell(), na jejíž popis se můžeme podívat vzápětí. To už však přenecháme iniciativě čtenářově a zaměříme místo toho svou pozornost na funkci wrap(), kterou rovněž známe z příkladu v první kapitole:

> imaginuj wrap
Imaginuješ 'wrap', soustředěn na samotnou podstatu Prahů, a před tvým
duchovním zrakem vyvstávají tyto obrazy:
------------------------------------------------------------------------------
FUNKCE: wrap
DEKLARACE: varargs string wrap(string str, int len, int left)
POPIS:
   Zalomí řetězec 'str'. Parametr 'len' udává celkovou šířku textu; není-li
   udána, pak se zalamuje na 78 znaků.
   Je-li zadáno 'left', pak se celý text odleva odsadí o 'left' mezer
   ('len' přitom zůstává celkovou šíří včetně těchto 'left' mezer).
   Pro zadání 'left' bez zadání 'len' stačí zadat jako 'len' 0.
SKUPINA: string, simul_efun
VIZ: sprintf, copies, left, right, center, wrap_say
ZDROJ: /secure/simul_efun/string.inc
------------------------------------------------------------------------------

Všimněme si, že samotná úvodní hláška imaginace je zde odlišná — místo na objekty se prý nyní soustředíme na samotnou podstatu Prahů. To nám sděluje, že funkce wrap() nepatří mezi tzv. lokální funkce (neboli „lfuny“ v programátorské hantýrce), které vždy patří k určitému objektu, nýbrž že se jedná o tzv. externí funkci (neboli „efun“) — externí vůči jednotlivému objektu, vůči celku hry však naopak naprogramovanou v samotném jejím jádře.

V deklaraci funkce dále vidíme nějaké parametry — znakový řetězec, celé číslo, celé číslo — ovšem celá deklarace je uvozena slovem varargs, což znamená variabilní počet parametrů (anglicky arguments). To znamená, že při volání funkce nemusí být parametry zadány všechny, ba případně nemusí být zadány vůbec žádné. V případě wrap() by volání funkce úplně bez parametrů nedávalo smysl, protože by nebylo co zalamovat, ale druhý a třetí parametr je možno vynechat, a šířka zalomení textu a odsazení zleva se pak provedou podle implicitního nastavení.

Kontemplace editovat

Pomocí kontemplace může mistr nahlížet do tematických skupin lokálních i externích funkcí. Některé z těchto skupin jsme už poznali z dokumentace jednotlivých funkcí — basic, do níž patří funkce query_smell(), a string a simul_efun, do nichž patří funkce wrap(). S trochou angličtiny asi poznáme, že první z těchto tří skupin zahrnuje funkce v nějakém smyslu základní a druhá zas sdružuje funkce pracující se znakovými řetězci (tedy texty). Význam třetí skupiny pro nás zatím může zůstat zahalen tajemstvím. Jednu z těchto tří skupin si teď vyberme a zkusmo kontemplujme:

> kontempluj string
Kontempluješ 'string', pohroužen do hloubi objektů světů mezi Prahy, a z
pramene jejich bytí do tvého srdce vstupují jména... substitute a
resolve_define.
Pak hroužíš svou mysl do hloubi podstaty samotných Prahů, a z pramene jejich
bytí do tvého srdce vstupují jména... capitalize, crypt, explode, extract,
implode, lower_case, make_shared_string, md5_encrypt, member, member_array,
notify_fail, process_string, query_notify_fail, regexp, regexplode,
regreplace, sprintf, sscanf, stringp, strlen, strstr, terminal_colour, trim,
upper_case, parse_com, vycet, wrap, wrap_say, copies, center, left, right,
substr, strip, space, add_dot_to_msg, odhackuj, normstr, sysstr, zakoduj,
rozkoduj, capitalize, upper_case, lower_case, let_string_be, mixed2str a
str2mixed.

Každou z funkcí, o jejichž existenci jsme se takto dozvěděli, bychom nyní mohli imaginovat, tedy prohlédnout si její konkrétní dokumentaci.

Skupin funkcí je několik desítek, a všechny jsou vepsány do Matice a můžeme si je prohlédnout — právě jakožto ony zeleně a nachově zářící symboly, které jsou pro učně a tovaryše nečitelné. Zeleně září skupiny funkcí lokálních, nachově skupiny funkcí externích. Ty první pak při kontemplaci vnímáme pohroužením „do hloubi objektů světů mezi Prahy“, ty druhé „do hloubi podstaty samotných Prahů“.

Meditace editovat

Meditací mistr zjišťuje existenci funkcí, které mají v názvu určité slovo, resp. určitý shluk znaků. V dosavadním výkladu jsme si mohli všimnout, že názvy funkcí jazyka LPC jsou — jak tomu ve světě programování bývá — povětšinou odvozeny z angličtiny (pro samotné funkce jazyka LPC to platí stoprocentně, v případě funkcí obsažených v programových knihovnách mudu Prahy však jen částečně — u řady funkcí se zachovala v názvu němčina, užívaná vývojáři UNItopie, z níž Prahy převzaly celou řadu konceptů i konkrétních programových modulů, u řady dalších se objevuje v názvu čeština). Známe už funkci query_smell(), tedy se nám může zachtít prozkoumat další funkce souvisící se zápachem. Protože některé z nich budou mít jistě v názvu slovo „smell“, meditujme toto slovo:

> medituj smell
Medituješ 'smell', obrácen myslí k objektům světů mezi Prahy, a z plnosti
jejich jsoucna k tobě zaznívají jména... forbidden_smell, forbidden_smell_me,
notify_smell, notify_smell_me, query_smell, query_wet_smell, set_smell a
set_wet_smell.

Mezi funkcemi vidíme kromě naší staré známé query_smell() její již zmíněnou sestru set_smell(), ale pak funkce, které nám už svým jménem napovídají, že by mohly mít něco společného se zápachem věcí a postav, které jsou právě mokré. (Mimochodem, už jste si ve hře všimli, jak smrdíte, když zmoknete?) Nic nám nebrání je nyní jednotlivě imaginovat a zjistit, zda se v tomto odhadu nemýlíme, případně jak by šly tyto funkce dále využít.

Programování objektů editovat

S popsaným vybavením se můžeme pustit do programování takřka čehokoli, jen se nesmíme spolehnout na slepé zkoušení různých možností, nýbrž musíme si skutečně cíleně vyhledávat, co pro své programátorské cíle potřebujeme.

Nejprve si zkusme uvědomit, co vlastně chceme naprogramovat. Má to být třeba nějaký nástroj, který nás někam přesune, abychom nemuseli pořád běhat stovky herních kilometrů? Pravděpodobně nám pak pomůže meditace slůvka „move“ a prozkoumání možností jednotlivých funkcí. Chceme si umět vyrobit potravu z libovolného objektu? Pak bychom mohli zkusit kontemplovat food, jeden ze zelených symbolů zářících v Matici.

Jak se dotyčné funkce konkrétně používají, zjistíme jednak tu a tam z příkladů v jejich dokumentaci, jednak z měničských poselství nebo dalšími zprvu skrytými způsoby, které si musíme postupně objevit a osvojit. Můžeme též nahlížet do rozličné online dokumentace k LPC (nějaké odkazy najdeme na úvodní stránce tohoto kurzu, jeden přesnější níže v nepovinných úkolech).

A konečně, musíme se připravit na to, že naše programátorské pokusy mnohdy nebudou fungovat. Někdy uděláme chybu už v samotném zápisu programu — pak program nepůjde vůbec spustit a bude nás na chybu upozorňovat[5] — jindy program spustit půjde, ale bude dělat něco jiného, než jsme chtěli. Pak je potřeba prostě hledat chyby, snažit se je opravovat a program znovu spouštět, než dosáhneme cíle.

Vlastně to zní velmi jednoduše. Protože to ale tak jednoduché není, náš kurz na tomto místě nekončí, ale pokračuje popisem jednotlivých význačných možností, které nám LPC a programové knihovny Prahů nabízejí.

Úkoly editovat

Povinné editovat

  • Prohlédněte si symboly v Matici a vyzkoušejte si mistrovskou meditaci, kontemplaci a imaginaci.
  • Podle příkladu v první kapitole tohoto kroku napište a uložte program, který bude nějak měnit zápach objektu. Vyzkoušejte jej tím, že jej spustíte na nějakém okolním objektu.

Dobrovolné editovat

  • Zkuste si vytvořit program, který by kompletně zamaskoval nějaký objekt, tedy změnil mu označení, popis, povrch, zápach i zvuk.
  • Nahlédněte do online dokumentace LPC, vyhledejte si jména některých funkcí, která zatím neznáte, a zkuste pomocí meditace a imaginace v Matici zjistit, zda jsou k dispozici též mezi Prahy.

Pomocné stránky editovat

Poznámky editovat

  1. Ti, kdo sledují vývoj Bratrstva měničů delší dobu, si na tomto místě možná uvědomí, že něco je jinak, než bylo dříve. Původně se totiž oba zmíněné kroky realizovaly příkazem programuj. V herní praxi se však ukázalo, že provádění těchto výrazně odlišných kroků jedním příkazem mate, ale především je pro měniče velmi (a zbytečně) frustrující, když samotné napsání a uložení programu podléhá občasnému neúspěchu. Díky oddělení obou kroků může nyní mistr napsat program a uložit si jej na disk vždy se stoprocentním úspěchem, zatímco spustit program jako zastínění nějakého objektu se mu nepovede zdaleka v každém případě.
  2. Jak nám příkaz programuj hned prozradil, zadáním editačního příkazu h (tedy help) získáme základní nápovědu k programátorskému editoru. Je sice velmi primitivní a omezený textovým rozhraním, ale jakmile si na něj zvykneme, zvládneme s ním všechno potřebné.
  3. K tomuto nadšenému výkřiku budiž doplněno varování, že ani největší smrtelný mistr Bratrstva nemá moc srovnatelnou s anděly, jejichž úkolem je udržovat hru funkční. Není proto radno snažit se ve hře jen zkoušet hranice možností a vytvářet herní chaos, protože spravedlivý hněv andělů dokáže být velmi důrazný.
  4. Co se přesně stane, když v Matici užije některého z těchto příkazů měničský učeň nebo tovaryš, si laskavý čtenář vyzkoušiž sám.
  5. To nesmíme zaměňovat s obyčejným Spuštění se nepodařilo., značícím, že nám tentokrát nepřála měničská pravděpodobnost.