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ň