Adventura -=-=-=-=-=- The best defense against logic is ignorance. Protože se prologácká databáze hodí téměř na všechno, je velmi snadné do ni popsat bludiště nějaké hry. Navíc se pravidla hodí pro zápis různých problémů ve hře a proto je prolog vlastně ideální jazyk pro popis adventur. Jednu takovou jsem tu napsal. Bludiště se skládá ze tří místností - zahrady, chodby, a záchodu. Chodba spojuje záchod a zahradu. Ze záchodu na zahradu jze ještě vyskočit oknem, ale zpátky to už nejde: % Bludiště connect(zachod,zahrada). connect(zachod,chodba). zachod<--->chodba<--->zahrada connect(chodba,zachod). | ^ connect(zahrada,chodba). +----------------------+ connect(chodba,zahrada). % Popisy pro jednotlivé místnosti describe(papir,'proste toaletak'). describe(zachod,'Jsi na zachode..nelibe to tu voni'). describe(zahrada,'Jsi na zahrade..ptaci zpivaji, slunce sviti...'). describe(chodba,'Jsi na chodbe..vede ze zachodu na zahradu'). Na záchodě se nachází papír, který když vemete a položíte na zahradu, dostanete vynadáno za znečišťování životního prostředí: %Umístění předmětů location(papir,zachod). akce :- location(papir,zahrada), %Pokud je papír na zahradě write(' Vrhla se na tebe duchodkyne z holi a utloukla te ze slovy'),nl, write(' "Takhle znecistovat zivotni prostredi! Kam se ten svet riti!" ' smrt. A nyní jenom napsat vlastní engine pro hru. Ta musí měnit popis světa podle toho, jak se hra vyvíjí. K tomu slouží dva predikáty - assert, který přidá nějaký predikát do databáze a retract, který ho zruší. Napřed budeme potřebovat predikáty pro popis situace. Klasické textovky většinou popisují kde jsi, co vidíš a kam jdeš. To jde napsat jednoduše. Pozice hráče se bude určovat pomocí predikátu you, který bude vždy pravdivý pouze pro místnost, kde hráč právě stojí. popis :- %vypíše popis místnosti you(L), %do L uloží pozici hráče describe(L,X),%popis místnosti L write(X),nl. %vypíše cesty :- %vypise všechny cesty s místnosti you(L), %uloží do L pozici hráče connect(L,X), %zjistí cestu z L a do X uloží cíl-tady se děla backtracin %pokud je předmětů v místnosti víc write(X), %vypíše cílovou místnost write(' '), %oddělí slova fail. %selže,aby se system pokusil najít dalsi cestu a také ji vy cesty :- %to se vyvolá,když už není žádná cesta k vypsaní nl. %novy řádek-konec výpisu vydis :- %vypíše předmety v místnosti you(L), location(X,L), write(X), write(' '), fail. vydis :- nl. mistnost :- %všechno to zavolá popis, %Vypíše popis místnosti write('cesty:'),%Vypíše cesty z místnosti cesty, write('vydis:'),%Vypíěe předměty vydis, Další důležitá část jsou příkazy. Klasické příkazy jsou jdi, seber, polož a inventář. Příkaz jdi musí zrušit starý predikát you a vytvořit nový, který ukazuje do nové místnosti. Sbírání a pokládání předmětů lze vyřešit tak, že se budou přesouvat do speciální místnosti you. Mezi příkazy jde zahrnout i predikát, který hráče zabije - smrt. To lze vyřešit tak, že přesune hráče do speciální místnosti nebe. inventar :- %vypíše,co uzivatel nese-funguje stejne jako vidíš location(X,you), %pro místnost you write(X), write(' '), fail. inventar :- nl. jdi(X) :- %funkce na chození you(L), connect(L,X),%musí existovat cesta z L do X retract(you(L)), %Zruší spojení se starou místností assert(you(X)). %Zavede do databáze novou pozici jdi(X):- %V případě, že cesta nevede-prvni jdi selhalo write(' Tam to nejde. '),nl. smrt :- you(L), retract(you(L)), %Vezme hráče se staré pozice assert(you(nebe)). %a přesune ho do nebe zvedni(X) :- %Zvedne předmět you(L), location(X,L),%Předmět musí být v místnosti L retract(location(X,L)),%Zruší spojení předmetu s místností assert(location(X,you)),%a předá ho hráči write(' Zvedl jsi '),write(X),nl.%vypíše to zvedni(X) :- %V případě že předchozí predikát selhal write(X),write(' tu nikde neni'). poloz(X) :- %Položí predmet location(X,you), you(L), retract(location(X,you)), assert(location(X,L)), write(' Polozil jsi'),write(X),nl. poloz(X) :- write(X),write(' u sebe nemas'). Vlastní herní smyčka potom musí jenom žádat hráče o příkaz, ten provédst a v případě, že se hráč objevil v nebi zkončit. Pro jednoduchost použiju pro čtení příkazu predikátu read(X), který načte term z klávesnice do X a call, který daný příkaz vyvolá. Příkazy bude tedy hráč zadávat ve stejném formátu jako na příkazové řádce prologu. done :- %zjišťuje jestli hra nezkoncila you(nebe), write(' Sice jste zemrel ale nevadi...vlastne sjte hru vyhral '). %Hlavni smycka akce :- %Toto je posledni z akcí-nic se nestalo. To je proto,aby %volaní akce z go neselhalo a nezrušilo tím provadění %celé hry nl. go :- done. %Tímto je zaručeno aby hra zkoncila v případě %že je konec go :- %vlastní herní smyčka mistnost, write('>> '), %Prompt read(X), %Načte term z klávesnice call(X), %Vznese načtenoý dotas akce, %Provede všechny akce go. %Smyčka pomocí rekurze Nakonec je ještě nutné hráče někam umístit - you(zachod). a hra je hotova. Toto je příklad hry: 1 ?- [pll]. pll compiled, 0.03 sec, 6,300 bytes. Yes 2 ?- go. Jdi na zachode..nelibe to tu voni cesty:zahrada chodba vydis:papir >> |: zvedni(papir). Zvedl jsi papir Jdi na zachode..nelibe to tu voni cesty:zahrada chodba vydis: >> |: jdi(chodba). Jsi na chodbe..vede ze zachodu na zahradu cesty:zachod zahrada vydis: >> |: inventar. papir Jsi na chodbe..vede ze zachodu na zahradu cesty:zachod zahrada vydis: >> |: poloz(papir). Polozil jsi papir Jsi na chodbe..vede ze zachodu na zahradu cesty:zachod zahrada vydis:papir >> |: zvedni(papir). Zvedl jsi papir Jsi na chodbe..vede ze zachodu na zahradu cesty:zachod zahrada vydis: >> |: jdi(zahrada). Jsi na zahrade..ptaci zpivaji, slunce sviti... cesty:chodba vydis: >> |: >> |: poloz(papir). Polozil jsi papir Vrhla se na tebe diva duchodkyne z holi a utloukla te ze slovy "Takhle znecistovat zivotni prostredi! Kam se ten svet riti!" Sice jste zemrel ale nevadi...vlastne sjte hru vyhral Yes výheň