TextEd

V 0.99.24.9

Libor Tinka & Jakub Grós

INTERNÍ DOKUMENTACE

 

1. Obecné informace

1.1 Licenční ujednání

1.2 Popis programu a ovládání

1.3 Minimální a doporučená konfigurace

1.4 Seznam souborů

1.5 Kontakt na autory

1.6 Deník programátora

 

2. Uživatelská příručka 

DŮLEŽITÉ UPOZORNĚNÍ:

Tento program je prezentován jako nadstavba enginu pro
práci s grafickými okny.
Nejedná se ještě o plně funkční verzi, tudíž v něm
nezakládejte větší projekty.
Plně funkční verze (1.01.x.y BETA) bude k dispozici
na oficiální webové stránce projektu TextEd.
Autoři děkují za pochopení.

3. Programátorská příručka

PŘÍLOHA: "Tvorba textových her v Pascalu"

1. Obecné informace

1.1 Licenční ujednání

Tento program lze volně šířit k užívání, vzdělávání a jiným účelům, nikdy však za finanční náhradu. Firma SGP Systems může zdrojový kód programu a všechny jeho dodatečné soubory distribuovat bez omezení. Pozměňování zdrojového kódu je autorem povoleno jen v případě, že ten nebude dále šířen pod stejným názvem a označením verze, nebo vydáván za originální. Totéž se týká i ostatních souborů v rámci projektu TextEd.

Použití úseků zdrojového kódu v jiném programu šířeném za účelem zisku lze pouze se svolením autora (nevztahuje se na použití funkcí enginu v souladu s návodem na použití enginu v programátorské příručce).

1.2 Popis programu a ovládání

Program TextEd (zatím nekompletní) zpracovává projektový soubor, který následně "kompiluje" do formy vhodné pro přehrávač her (zatím též nehotový). Program pracuje na bázi grafických oken, jejichž počet je omezen pamětí počítače, ale ta stačí bohatě i pro možnost, kdy jsou všechna okna TextEdu otevřena zaráz. Okna lze přesouvat nebo přes sebe různě překrývat, zavírat a vyvolávat k nim příslušné kapitoly nápovědy. Všechny tyto úkony lze provádět výhradně myší. S prvky v oknech se pracuje přibližně stejně, jako je tomu v operačních systémech Windows.

Klávesnice se používá jen v případě editace textu v
textových oknech. Některé ovládací prvky se od standardního
editoru ve Windows liší:

SHIFT+šipky/HOME/END ... označení bloku
INSERT ................. načtení bloku
SHIFT+INSERT ........... vypsání bloku

1.3 Minimální a doporučená konfigurace

Program by měl běžet na libovolném počítači typu PC pod systémy MS-DOS nebo Windows. Doporučuji však rychlý procesor pro plynulejší překreslování grafiky.

1.4 Seznam souborů

TEXTED.ARC - architektura programu 
TEXTED.B00
...
TEXTED.B07 - banky s grafikou programu
(písmo, okna; kurzory)
TEXTED.BMP - obrázek mloka
* TEXTED.C - přeložený kód programu TextEd v jazyce C
* TEXTED.CIN - pomocný soubor překadače SGP Baltazara
TEXTED.EX - předloha pro vytváření textové aplikace
TEXTED.EX2 - -//- 
TEXTED.HEL - tato nápověda 
* TEXTED.HTM - interní dokumentace ve formátu HTML
* TEXTED.ICO - ikona programu
TEXTED.LEN - délky znaků proporcionálního písma 
TEXTED.LNG - jazykový balíček (CZ,EN,GE)
TEXTED.SGP - zdrojový kód programu
TEXTED-S.HTML - krátký popis programu v HTML

* nejsou nutné ke správnému běhu programu

1.5 Kontakt na autory

programátor: Libor Tinka
Kuršova 981/6
BRNO, 635 00
Česká republika
GSM: 420603712259
ICQ: 173706336
e-mail: ltinka@seznam.cz

grafik: Jakub Grós
Sokolovská 277
Uherské Hradiště, 686 01
Česká republika
GSM: 420737809278
e-mail: jagous2@seznam.cz

1.6 Deník programátora

24.7.2003

Poslední dobou jde všechno docela pomalu, jednak protože jsou prázdniny a jednak taky proto, že se mi moc nechce pracovat,
ale to vlastně souvisí s prvním bodem. Zbytek prázdnin strávím v Hradišti, takže bych chtěl udělat další kroky k dokončení
projektu. Mluvil jsem s Liborem Barešem ohledně struktury kódu. Zdá se mu dobrá, ale okna by nedělal pomocí seznamu, spíš
pomocí dynamického pole. To je sice v "céčku" celkem běžná záležitost, ale já s něčím takovým ještě nedělal, takže se budu
muset mrknout na internet. Dynamická pole použiji na položky oken a pak se uvidí. Bude to už z půlky objektově orientované
programování, ale to je možná ještě nadsázka.

27.7.2003

Jsem teď na chatě s rodinou, takže práce půjde a taky jde pomalu, skoro vůbec. Mám před sebou ještě srpen, takže to asi
nechám na doma. Už jsem se naučil základní práci s dynamickými poli, takže vytváření prvků oken shrnu do dvou funkcí.
Jedna už existuje: 'VytvorOkno'. Přibudou jenom parametry určující počty jednotlivých prvků, které bude nastavovat další
funkce. Všechny prvky okna budou využívat stejný datový typ, protože mají vesměs stejné parametry, takže by nemělo valný
smysl dělat pro každý prvek jiný typ, byl by z toho ještě "mišmaš". Co se týče grafiky, bude potřeba dát do kupy tlačítka a
co do návrhů, budu muset domyslet, jaké prvky oken vlastně budu chtít a jaké ne. Například ještě nevím, jak to bude s
rolovacími pásy a rolovacími nabídkami. To mi dělá zatím největší starosti.

30.7.2003

Vypadá to, že si zarchivuji další nedokončenou "preview" verzi TextEdu. Dodnes jsem se bál, že projekt nedokončím kvůli
problému s pamětí. Okna jsou tedy dělána pomocí seznamu (funguje bezvadně). Dodělal jsem ještě čištění paměti na konci
programu (prostě se volá funkce na zavření okna tak dlouho, dokud na ploše žádné není). Prvky oken jsou dělány pomocí
dynamického pole, což k mému podivu funguje. Bál jsem se ale nějakého kiksu, který taky přišel. Když jsem vytvořil
okno s tlačítkem, pak další prázdné a to prázdné zavřel, tlačítko se ztratilo. Když jsem to prázdné okno posunul, změnil
se jeho titulek, takže jsem cítil problém při práci s pamětí (vše co se týče oken mám totiž pomocí dynamických proměnných).
Chybu jsem nejprve vůbec nemohl najít ani pomocí vypisování hodnot na obrazovku, tak jsem hledal chybu v alokaci paměti.
Nakonec jediná funkce, kterou jsem nezkoumal, byla ta na zavírání oken, protože ta kromě dealokace okna odstraňuje taky
prvky v něm (to dynamické pole). Zprvu se mi zdála v pořádku, ale pak jsem zjistil, že jsem to s prvky hodně odfláknul.
Prostě jsem dal funkci 'free' na konec funkce, jenomže okno se zrušilo na začátku, takže přestal existovat i ukazatel
na místo, kde pole začíná. To mě nenapadlo, ale když jsem dealokační funkci dal do komentáře, okna a prvky v nich se
chovali bezproblémově. Takže to bylo jasné. Teď se musím trochu podrobněji podívat na dealokaci dynamického pole a
čistit ho dřív, než odstraním okna. Pak už budu programovat další prvky okna a taky jejich chování. Návrhy budu tedy
dělat rovnou v Baltazarovi. Po návrzích už se bude pracovat jenom na 'kernelu', který bude tou funkční stránkou programu.
mezitím se může brácha postarat o ostatní styly, jazyky atp.

1.8.2003

Pořád to nefunguje. Tentokrát alokace paměti pro prvky. Asi se nealokuje dost paměti, ale já opravdu nevím, kolik by jí
mělo být zapotřebí, protože i po přičtení délky textů k sizeof to pořád nestačí. Zkusím změnit způsob inicializace prvků,
protože zatím to mám tak, že se počítá s nějakou maximální délkou řetězce, takže se alokuje paměť, co se nezaplní. Možná
je problém tady - no nevím. Uvolňování paměti je možná v pořádku, alespoň to vypisuje stejné hodnoty.

Už jsem přišel na to, že alokace paměti pro řetězce je blbost. Řetězce se totiž dynamicky mění a v paměti se pro ně
vyhrazuje místo automaticky. Vrátil jsem se tedy zase o něco zpátky, protože ač fungují okna, nefungují okna s prvky.
Pokud vytvořím okno s prvky a potom další prázdné okno, to druhé nebude dobře pracovat. Chce to nějak lépe alokovat paměť
pro prvky, ale jak? Už jsem zkusil i realloc, ale to nefunguje, tak nevím. Budu ještě něco zkoušet a podívám se na jednu
dokumentaci na téma dynamických polí. Otázkou je: jak naalokovat víc paměti pro ukazatel v seznamu...

3.8.2003

Vypadá to, že v Jedovnicích zůstanu až do středy, takže ten problém s alokací buď vyřeším sám, nebo se budu moct poradit
až po příjezdu domů. No co se dá dělat.

7.8.2003

Do Hradiště jsem se vrátil už v úterý (5.8.) a napsal jsem 2 maily. Jeden do SGP a jeden Liboru Barešovi. Oba se stejnou
přílohou a stejným smyslem. Potřebuji pomoct s tou částí programu, kde se alokuje a dealokuje paměť pro prvky oken.
Odpověď jsem zatím nedostal, ale můžu bez toho pokračovat v projektu. Pracuji teď na textových oknech. Kolonky, kterými
jsem začal, jsou jen podmnožinou textových oken, protože mají prostě jen jeden řádek na výšku. Tím se taky zkomplikuje
editace, protože funkce pro editaci textu bude muset pracovat s různým počtem řádků a s různě dlouhým textem. Texty v
kolonkách budou typu string, který bohatě postačí, ale nikdy ve statické formě, protože by byl program moc náročný na paměť.
Všechno budu brát ze souboru a basta. Sice teď nevím, jak to budu řešit, ale to je problém budoucí doby.

20.8.2003

Čas kvapí a já jsem zase o kus dál. Bohužel jsem pořád neopravil tu chybu s pamětí, ale asi mám hotové editační okno i s
načítáním a vypisováním bloků textu (super). Je po půlnoci a já jsem rád, že mám něco za sebou. Taky je vlastně středa.
V pátek se vrátím do Brna po skoro měsíci stráveném v Uherském Hradišti a Jedovnicích. Četl jsem deník Partie, kde jsem
 dodělával poslední úpravy těsně před soutěží a měl jsem hrozný skluz, což teď doufám nebude. Zbytek prázdnin už budu
 úporně pracovat na projetku, abych měl hotové prostředí a návrhy a abych se mohl v klidu pustit do vlastního kernelu (ten
 bude zařizovat funkční stránku TextEdu). No tuším, že to nestihnu, ale to prostředí...

23.8.2003

Soutěž už byla vyhlášena (nejspíš 18.8., takže by bylo dobré se přihlásit do korespondenčního kola (nezávazně)). Udělám
to v září a teď budu mít týden čas, což věnuji především na projekt. Chyba s pamětí je už KONEČNĚ opravena a dokončil jsem
taky výběry. Zbývá ještě napsat výběrová okna a "zaškrtávátka", ale to bych mohl zvládnout ještě dnes. Zítra už snad budu
mít hotový vzhled programu. Nechám bráchu zpracovat skiny WinXP a taky si může udělat nějaké vlastní, ale musí být opravdu
pěkné. Deprimuje mne, že ještě nemám žádný vlastní program. S Partií jsem byl minulý rok touto dobou úplně jinde. Ach jo.
Soutěžit se bude opět v Brně a na INVEXu. Na soutěž se těším, ale pořád nemám nic moc v ruce. Bude taky potřeba dát něco
do prezentace - to už bude bráchova práce.

25.8.2003

Zatím to vypadá, že v programu nejsou žádné chyby, o kterých bych věděl. Vyzkoušel jsem všechny prvky okna naráz v jednom
okně a pracuje to. U každého prvku byl nějaký problém, ale ten jsem posléze vyřešil. Chtěl jsem se teď pustit do návrhu,
ale udělám nejdřív optimalizaci vykreslování. Funkce pro vykreslení plochy se bude nejspíš volat s nějakým parametrem,
který bude říkat, co se má vlastně vykreslovat. Buďto celá plocha, nebo jen přední okno, anebo jediný prvek. I vlastní
prvky okna by měli mít optimalizaci, takže to bude docela fuška. Hned jak se vrátím z města, pustím se do toho.

28.8.2003

Je to horší než minulý rok. Mnohem horší. A to jsem měl minule ještě štěstí, že se termín oprav prodloužil, teď mi může
pomoct jedině stávka učitelů. Optimalizoval jsem, co mě napadlo, ale jen do určité míry, takže celkově to jakž takž jde.
Dál už nemám čas hrát si s enginem, musím udělat funkční stránku programu. Veškeré informace o oknech jsou uloženy v
"architektonickém" souboru, který si ještě pomáhá jazykovým balíčkem, takže je program v lingvistické oblasti hodně
flexibilní. Nechci ale skončit u prezentace holého enginu, to nemá význam, když tam nebude ta - výplň. Jinak podobný
projekt už měl minulý rok jiný člověk, takže by to vypadalo jako napodobování. 

1.9.2003

Zítra už jdu do školy, takže se nastalo to, co jsem očekával - že bude hotový kernel do konce prázdnin. Dnes do školy
nejdu jenom díky stávce, zkusím udělat, co se dá. První týden školy se sice moc učit nebudu, ale budu mít povinnosti, takže
k počítači se dostanu tak na 3 hodiny denně, což je možná málo. Pak taky o víkendu... No nevím. Zjistil jsem další chybu -
neuvolňuje se paměť po zavření okna (grr). To dám asi dohromady, ale nemám ještě všechna okna hotová (čekal jsem to
jednodušší - ale prvky oken musím kreslit pomocí čísel; nemám na to žádný editor). Za tento týden už chci každopádně
dokončit ten kernel, abych měl klid v duši, mohl dokončovat zbývající práci a konečně předal bráchovi jeho úkoly (když
mu je dám těsně před uzávěrkou, nemůžu čekat, že mi je dá hotové další den).

6.9.2003

Optimalizace je hotová, takže teď můžu konečně pokračovat kernelem a tím začít i s předmětem programu. Kernel bude
vykonávat dvě hlavní činnosti. Bude naplňovat okna s textem a výběry a taky provádět všechny operace po kliknutí
tlačítkem, editaci textu atp. Vlastně tedy bude realizovat to, k čemu jsou jednotlivé prvky určeny.

8.9.2003

Ještě jsem přišel na malou chybu v optimalizaci (ta fungovala jen pro dvě okna) a navíc jsem zapomněl udělat optimalizaci
Ten displej se bohužel opravit nedá... Tento pátek (dnes je pondělí) už pojedu do Uherského Hradiště, takže teď bych rád
pokročil s tím kernelem. Udělal jsem kompletní návrh, jak bude vypadat projektový soubor, ale ještě nevím přesně, jak
budu do souboru přidávat položky. Jako jediná možnost se mi jeví vždycky překopírovat celý soubor a do kopie připsat
položku, ale to se mi zdá taky dost nepraktické.

10.9.2003

Přesně za týden touto dobou už budu odevzdávat soutěžní projekt. Problém je, aby k tomu došlo. Dokončil jsem optimalizaci,
co se týče výběrů (konečně) a taky jsem trochu ošetřil zbytečné překreslování okna když někdo klikne na titulek, ale
nepřesune ho. Původně jsem chtěl mít jednu funkci Kernel, ale lepší bude vytvořit dvě specifické funkce. Pojmenuji je
NaplnPrvek a ProvedAkci. Jedna se bude starat o to, aby se textová hodnota u vybraných prvků naplnila tím, co má obsahovat.
Okna dostanou ještě jeden parametr, který bude udávat, jestli jsou jejich hodnoty naplněné. Když nebudou, funkce NaplnPrvek
postupně naplní prvky typu textové okno (kolonka), výběr a textový výběr správnými řetězci typu string (často také v
závislosti na hodnotách v jiných prvcích - vztah mezi lokací a jejím popisem). Funkce NaplnPrvek se tedy bude volat při
vykreslování prvků v okně. Druhá funkce - ProvedAkci - se postará o správné provedení akce po stisknutí některého tlačítka.
Samotné rolování textu v textových výběrech nebo výběr z několika možností nic neprovádí. Změny se projeví až po stisknutí
tlačítka Hotovo. Většinou se bude pracovat s pracovním souborem (tam budou změny, které se projeví teprve aktualizací
projektového souboru pracovním), nebo se budou otevírat různá další okna. Dále je potřeba vytvořit funkce pracující
s daty projektu. Jednak je potřeba založit nový projektový soubor a soubor pracovní (kopie z projektového). Další funkce
bude projektový soubor aktualizovat a další budou přidávat/odebírat/editovat položky ze souboru. Vzorový projektový
soubor už jsem sepsal skoro celý (ještě chybí zpřesnění u logiky hry), ale ještě bude třeba napsat implicitní slovník, kde
budou základní příkazy. Ručně by to asi dalo dost práce, takže to sestavím v TextEdu. Momentálně už je pozdě, takže jdu
spát a zítra se do toho co nejdřív pustím. Zadal jsem si, že kernel budu mít do pátku hotový. Je to klíčová část projektu,
grafický engine je jen šikovný zprostředkovatel toho, o co mi vlastně v projektu jde.

11.9.2003

Před rokem jsem v toto datum odeslal Partii verze 1.01 (finální) a byl jsem se svým programem spokojený. Ačkoliv dnes musím
dělat hodně věcí do školy, dělám taky na projektu. Vzhledem k tomu hroznému skluzu, co mám, musím dnes dodělat
funkce, které budou operovat s projektovým souborem. Budou to tři funkce (podle posledního návrhu). Jedna má aktualizovat
původní soubor projektu souborem pracovním. Tahle funkce už je prakticky hotová (funguje). Přistupuje k souborům binárně
a kopíruje po blocích o velikosti 1 KB (to úplně stačí - i na 500 KB soubor je to blesk). Další funkce bude obstarávat
nastavení pozice na příslušný "tag" - a to buďto na první tag určité třídy (podle podružnosti), na nějaký tag v řadě, anebo
až za poslední kvůli přidávání. Jiná funkce se bude starat o překopírování zbytku souboru (po úpravách), takže s těmito
třemi funkcemi by mělo být možné vcelku rychle s projektem pracovat. Zítra už chci dokončit jádro, i když to bude asi pěkná
dřina. S dokončením Kernelu už by měl být TextEd schopen projektovat hry. Trochu musím ještě domyslet akce a podmínky, ale
to snad nebude tak hrozné. Pozítří bych měl pracovat na přehrávači her, což je sice taky kapitola sama o sobě, ale s tím,
jak je hra podána, to taky nebude tak obtížné. Jediným problémem je čas. Nečekal jsem totiž, že se to s enginem tak potáhne.
Ten přehrávač mi může trvat tak do pondělka, protože pak už budu muset dodělat všechno ostatní, jako je dokumentace
(chci ji mít hypertextovou v programu + HTML externí). Přinejhorším pošlu projekt bez interní dokumentace, ale tu bych musel
dodělat do 25.9. Budu prostě dělat, co to dá, takže jak skončím s jedním, hned začnu druhé a ať to trvá co nejkratší dobu.
Ten týden na opravy budu dělat dost hluboký testing, aby program při prezentaci nerupnul. Jinak samotný kód chci poslat
v upravené formě - tzn. ve strukturogramech. Předělávání do strukturogramů není moc intelektuálně náročné, ale tak dva dny
si to vezme. Musím brát ohled ještě na studování, takže toho času je neskutečně málo. Nejvíc práce prostě musím udělat
o víkendu.

25.9.2003

Jak jsem čekal, nestihl jsem ani při největším úsilí, čeho jsem chtěl. Možná jsem si dal laťku příliš vysoko... Nicméně mám hotový engine a základy jeho nadstavby, kterou použiji nikoliv jako samotný program, ale jenom jako demonstraci enginu. Nedá se nic dělat, projekt dokončím až během následujících dní ve volném čase, takže se budu muset podívat taky na web (stará stránka TextEdu je třeba aktualizovat). TextEd má dobrou myšlenku i základ, ale bude třeba jeho "hybridní" verzi brát s rezervou. Na druhou stranu to je projekt o poznání náročnější, než minulý rok.

PŘÍLOHA: "Tvorba textových her v Pascalu"

Obsah

1. Úvod

2. Vzhled a typ hry

3. Zpracování dat (mapa, slovník, dialogy, hypertext)

4. Zpracování příkazů

5. Logická část

6. Závěr - jak vlastně udělat textovku? (větší projekty)

1. Úvod

Jistě jste si už někdy nějakou textovku zahráli a tak víte, jaké je jejich kouzlo. Jestliže programujete, tak vás asi zajímalo, jak se tyto hry tvoří. Je skutečností, že každý programátor by tutéž hru naprogramoval zcela jinak, takže rozhodně neříkám, že právě moje řešení je optimální. V tomto článku dostanete jakýsi obecný návod na psaní takových her. Tento návod by měl naučit mírně pokročilého programátora jak vytvořit profesionální hru s příjemným prostředím a inteligentním jádrem. Také se naučíte, jak vlastně zpracovávat příkazy (resp. zkomoleniny, které hráči často v textovkách píšou, a které přelouská jen lepší hra), jak nakládat s daty (uložení mapy hry, větvené dialogy, šifrování, slovník hry, hypertext...), jak vlastně samotnou hru naprogramovat (logické jádro), jaké jsou možné varianty textových her apod. K tomu se navíc setkáte se spoustou věcí, jež lze využít nejen v textových hrách.

2. Vzhled a typ hry

Design je ta část, o které se často moc neuvažuje. Nevím jak vy, ale textový mód je podle mne pro textové hry naprosto ideální. Program by jste měli začít právě jeho inicializací (např. TextMode(CO80);), neboť  přestože normálně všechno pracuje jak má, může vaši hru spustit nějaký maník v jiném textovém módu, než pro jaký je hra napsána, a je z toho paseka. Textový mód navíc nabízí spoustu dalších možností (třeba přirozené rolování textu). Pokud budete pracovat v grafickém módu, pak rozhodně nevkládejte do hry obrázky! Kouzlo textových her spočívá právě na fantazii hráče, stejně jako u knížek. Můžeme však použít barvy. Když chceme, aby hra upoutala, neměli bychom házet vedle sebe všechny možné kontrastní nebo nedej bože blikající barvy, což by uživatele spíše odradilo (u takových her se hned ukáže, že ten, kdo ji psal toho o designu moc neví). Samozřejmě vás nechci navádět k monochromatickým textům, ale spíše k harmonii barev na obrazovce. Je skutečností, že hra by měla navozovat jakousi atmosféru a tak by se ve hře měla vyskytovat  jen vybraná škála barev. Zásadně nedoporučuji používat barevná pozadí přes celou obrazovku, která dost dráždí oči (s výjimkou modré, na které jsou oči málo citlivé, ale která je pořád horší než klasická černá). Můžete použít například velmi tmavou zelenou na pozadí, pokud se hra odehrává v lese nebo využít možnosti výjimečně použít bílé pozadí nejlépe pro nadpis s názvem hry v úvodní obrazovce. Můžete také dělat lineární přechody (text/pozadí může pomalu zčervenat, pokud hráč zemře). Každopádně by hra měla působit z hlediska barev uspořádaným dojmem. Zde je malá procedura, která pomocí portů nastavuje barvy:

procedure Pal(n,R,G,B: byte);
begin
 Port[$3C8] := n;
 Port[$3C9] := R;
 Port[$3C9] := G;
 Port[$3C9] := B;
end

Za n dosadíte index barvy a pak hodnoty R (červená), G (zelená) a B (modrá) určují zastoupení základních barev v určené barvě. Zjistil jsem, že procedura dokáže změnit jenom barvy číslo 0,1,2,3,4,5 a 7, což je však pro textovou hru naprosto dostačující. Jestliže chcete vrátit paletu zpět do původního stavu, stačí volat proceduru TextMode (znovu se nastaví textový mód, takže se smaže obrazovka). Standardní šestnáctibarevná paleta, kde počet odstínů pro každou složku je 64 (tedy 643 = 262 144 možných barev) je definována takto (u každého indexu barvy máte hodnoty složek R,G,B):

0: 0,0,0
1: 0,0,42
2: 0,42,0
3: 0,42,42
4: 42,0,0
5: 42,0,42
6: 42,21,0
7: 42,42,42
8: 21,21,21
9: 21,21,63
10: 21,63,21
11: 21,63,63
12: 63,21,21
13: 63,21,63
14: 63,63,21
15: 63,63,63

S tímto již můžete pracovat s barvami na vyšší úrovni, než dovoluje knihovna Crt. Možná jste narazili na problém, jak odstranit nepřetržitě blikající kurzor. Ten má jednu velkou nevýhodu -- ruší. Chcete-li mít třeba na začátku hry úvodní obrazovku, kurzor je na obrazovce nevítaným hostem. Textový kurzor také, ač se to nezdá, znervózňuje hráče, který zrovna přemýšlí. Samozřejmě nemůžeme kurzor úplně odstranit, ale můžeme nastavit jeho barvu na stejnou, jak má pozadí, takže nebude nic vidět. Jestliže bude ve hře třeba modré pozadí, je dobré začít takto:

...
TextColor(blue);TextBackGround(blue);ClrScr;
...

Představte si obrazovku standardního textového módu jako dvourozměrné pole, kde má každá buňka tohoto pole tři parametry: barva popředí, barva pozadí a znak. Kurzor na dané pozici má vždy takovou barvu, jako parametr barva popředí této pozice. Barvu kurzoru nemůžete přímo změnit příkazem TextColor, je nutné na danou pozici nanést nějaký znak (i kdyby to měla být mezera). Potom bude kurzor na této pozici viditelný. Procedura ClrScr smaže obrazovku, resp. nastaví všechny parametry barev buňky myšleného pole na aktuální barvu popředí a pozadí, a za znak vloží mezeru. Ze zkušenosti vím, že je praktické si kurzor schovávat na "poslední pozici" příkazem GotoXY(80,25) (pro textový mód CO80). Také je možné kurzor schovávat tako:

Procedure SchovatKurzor; Assembler;
Asm
MOV ax,$0100
MOV cx,$2607
INT $10
end;

Procedure UkazatKurzor; Assembler;
Asm
MOV ax,$0100
MOV cx,$0506
INT $10
end;

Teď už se ale budeme zabývat editačním řádkem. Následující kód ukazuje možné řešení editačního řádku (je funkční, takže si ho můžete klidně vytáhnout a použít):

program EditRadek;

uses Crt;

var k,poz,i,n,bpoz: integer;
    ch: Char;
    s: String;
    ins,last,snd: Boolean;
    buffer: array[1..101] of String[40];

procedure Vloz; {prida retezec do bufferu}
begin
 if (s<>'') and (s<>buffer[1]) then
 begin
  for i:=n downto 1 do buffer[i+1]:=buffer[i];
  Inc(n);buffer[1]:=s;
  if n=101 then n:=100;
 end;
end;

procedure Vypis(typ: boolean); {vypise akt. retezec (typ urcuje viditelnost kurzoru)}
begin
 GotoXY(1,25);write(' ');
 GotoXY(1,25);TextColor(15);write('> ');
 for i:=1 to Length(s)+1 do
 begin
  if i=poz then
  begin
   TextColor(15);
   if typ then if ins then write('Ű') else write('_');
  end;
  if i<=Length(s) then
  begin
   TextColor(14);write(s[i]);
  end;
 end;
 for i:=1 to 41-Length(s) do write(' ');
 TextColor(0);
end;

procedure Edit; {vlastni editacni radek}
begin
 s:='';poz:=1;ins:=False;last:=True;
 repeat
  if (k<>327) and (k<>335) then bpoz:=0;
  Vypis(True);
  GotoXY(80,25);ch:=readkey;
  if KeyPressed then
  begin
   ch:=readkey;k:=255+Ord(ch);
  end else k:=Ord(ch);
  if (k>31) and (k<255) then
  begin
   if snd then
   begin
    Sound(1000);Delay(1);NoSound;
   end;
   if Length(s)<40 then
   begin
    if ins then
    begin
     if poz<=Length(s) then s[poz]:=ch else s:=s+ch;
    end else Insert(ch,s,poz);
    Inc(poz);
   end;
  end else
  begin
   if (k=330) and (poz>1) then Dec(poz);
   if (k=332) and (poz<Length(s)+1) then Inc(poz);
   if (k=326) then poz:=1;
   if (k=334) then poz:=Length(s)+1;
   if (k=8) and (poz>1) then
   begin
    Delete(s,poz-1,1);Dec(poz);
   end;
   if (k=338) and (poz<=Length(s)) then Delete(s,poz,1);
   if k=337 then if ins then ins:=False else ins:=True;
   if k=27 then
   begin
    s:='';poz:=1;
   end;
   if k=321 then n:=0;
   if (k=327) and (bpoz<n) then
   begin
    if last then
    begin
     Vloz;last:=False;
    end;
    Inc(bpoz);s:=buffer[bpoz];poz:=Length(s)+1;
   end;
   if (k=335) and (bpoz>1) then
   begin
    Dec(bpoz);s:=buffer[bpoz];poz:=Length(s)+1;
   end;
   if k=318 then if snd then snd:=False else snd:=True;
  end;
 until k=13;
 Vloz;
 Vypis(False);writeln;
end;

begin
TextMode(CO80);TextColor(0);TextBackGround(0);ClrScr;
n:=0;snd:=True;
repeat
Edit;
until s='konec';
end.

Tento editační řádek má řadu funkcí, které uživateli zpříjemňují hru:

- vkládání - to je myslím samozřejmost, přesto však je zde úprava: lze vkládat jen "přípustné" znaky;

- mazání - také samozřejmost, ale i zde je vylepšení: mazat se dá jak text za kurzorem (backspace) tak i před ním (delete); klávesa ESC způsobí smazání celého textu naráz, takže se eliminuje zdlouhavé odmazávání nebo odeslání řetězce na výstup jen kvůli potřebě rychlého smazání celého řádku;

- editace - kurzor se dá pomocí klávesy insert přepínat na vkládací/přepisovací; lze kurzorem vplout do textu a tam aplikovat základní funkce, tedy vkládání a mazání. Klávesy home a end se dají též použít;

- buffer (zásobník) - buffer je velmi praktická věc; umožňuje, že si program může pamatovat až 100 posledních příkazů (teoreticky by jich však mohlo být i přes 1000), takže uživatel nemusí pracně opisovat poslední příkaz jen pokud chtěl udělat v textu malou změnu. Po zadání více než sta příkazů se buffer nečistí, ale pouze se pozice všech příkazů v bufferu posunou, čímž odpadne příkaz nejstarší. Buffer lze vyčistit klávesou F8. V bufferu se listuje šipkami nahoru/dolů; klávesa Page Up přesune akt. pozici v bufferu na první zadaný příkaz;

- zvuky - nemnoho uživatelů má rádo příjemné ťukání Speakeru při psaní, ale přesto je tu možnost vypnutí ozvučení. To se přepíná klávesou F5;

Toto jsou základní aspekty, které by měl dobrý editační řádek mít, aby maximálně uživateli zpříjemnil vkládání textu. Doufám, že jsem vám tím dopomohl ke zvýšení kvality vašich prográmků a programů. Pamatujte, že hra, kterou vytváříte, musí hráče co nejvíce upoutat a to jak vnějším vzhledem, tak i hratelností. Tento editační řádek se používá u klasických textovek, jaké zná snad každý. Na obrazovce se zobrazí popis lokace a vy vkládáte příkaz. Mezi textové hry se však řadí všechny hry, kde obrázky a zvuky nahrazuje pouze fantazie uživatele. Jeden ze způsobů, jak lze textovou hru zpracovat je styl oken (Spektristi znají z Indiana Jonese II od Fuxoftu). Tento styl hry dělá samotnou hru jednodušší, neboť má hráč již na výběr z možností. Nejlépe v okně se zobrazí popis lokace a pak se objeví menší okénko, kde má hráč na výběr ze základních příkazů. Potom si vybírá parametr daného příkazu a případně, jedná-li se třeba o příkaz použij, může si ještě vybrat, na co chce předmět použít. Asi nejlépe hratelná co do jednoduchosti je taková hra, kde má hráč možnost vybrat si z několika možností. Zde už stačí jen kombinovat a téměř vůbec nedochází k tzv. zákysům.

3. Zpracování dat (mapa, slovník, dialogy, hypertext)

V této kapitole si povíme něco o tom, jak nakládat s daty u textových her. Nejprve se budeme věnovat ukládání a načítání. Je silně nepraktické vkládat texty přímo do zdrojového kódu programu, i když se jedná o hru velice krátkou. Vlastní program by měl být jen nástrojem. Pokud by jste si chtěli vytvořit další hru, stačilo by jen mírně upravit program (logické jádro) a pak v textovém editoru (například v textovém editoru s kontrolou gramatiky jako je Word nebo i T602 :-) dodělat všechny ostatní texty. Také bych nedoporučoval ukládat vše jen do jednoho souboru, ale spíše by bylo lepší oddělit si mapu (všechny texty o pozicích a objekty + jejich synonyma) a slovník (příkazy a jejich synonyma). Teď si řekneme něco o způsobu zápisu a čtení. Nemá smysl používat komprimaci, jenom by to prodloužilo vyhledávání textu v souboru. To však neplatí při komprimaci po řádcích, o čemž je řeč níže. Je však dobré použít šifrování. Šifrování má zde jediný význam, a sice zabránit někomu cizímu, aby zasahoval do textů hry. Pro textovou hru postačí úplně primitivní šifrování, kdy se jen ke každému znaku přiřadí ekvivalent, nebo se šifruje podle hesla. O tom si však povíme něco později. Pokud v textové hře chcete uplatnit orientaci sever, jih, západ, východ, bude mapa dvourozměrná. V souboru je však mapa uložena jako jednorozměrná, a tak se musí převádět. Někdo chce ve hře mít i možnost chodit nahoru a dolů (vícepatrové domy, sklepení...). Nabídnu vám jedno obecné řešení, které je vhodné pro všechny druhy map (nemá totiž smysl zavádět třetí rozměr jen kvůli jedné či dvěma lokacím, kde lze jít i nahoru/dolů). Vytvořte si návěští se jmény lokací (např. <NAMESTI>, [OBCHOD]... - názvy jsou krátké, aby se dobře porovnávali s textem zadaným uživatelem; viz kap. Zpracování příkazu). Na dalším řádku pak budou názvy lokací, na které se lze dostat z této lokace a zbytek bloku už bude popis místní lokace. Můžete vše také obohatit tak, že řádek z popisem lokací, kam se dá jít bude vypadat například takto: namesti(s),obchod(z). Pokud pak uživatel ví, že na západě je obchod, může lokaci popsat jak názvem světové strany, tak i názvem samotné lokace. V každém bloku by se měl taky objevit seznam předmětů, které se v dané lokaci vyskytují a které zde lze použíti. Každý blok (tedy jednotka mapy v souboru) by měl obsahovat:

- návěští - identifikátor lokace

- popis okolí - seznam okolních lokací, které jsou přístupné (můžete si seznam rozdělit na dva, kde v jednom budou i lokace, kam se nedá jít a pokud uživatel bude chtít jít do této lokace, program odpoví zdůvodněním proč nelze jít na dané místo - v seznamu nepřístupných lokací by tedy mohl být ke každé lokaci připojen komentář)

- seznam předmětů - u každého předmětu by měla být charakteristika (zda se dá sebrat, prozkoumat či třeba použít (ale takových příkazů může být i více - dveře-otevřít) + komentáře)

- popiska - popis lokace; popiska by mohla obsahovat řetězce, které se budou/nebudou zobrazovat v závislosti na okolních událostech

- komentáře - speciální komentáře označené nejlépe čísly; které se vypisují pokud jsou vybrány v logickém jádře hry (pokud nemáte ten správný klíč, vypíše se k tomu komentář -- ten se však vztahuje pouze pro danou lokaci a proto ho nebudeme zařazovat do slovníku - to by se pak tento komentář vypisoval na libovolné pozici, což by bylo nesmyslné)

Rozhodně nešetřete na komentářích, které značně obohacují hru! Dobré je mít na jeden úkon i více komentářů, a program pak náhodně vybírá jeden z nich.

Přejdeme k slíbenému šifrování. Stejně jako u grafických her by neměla být grafika přístupná v klasických formátech, se kterými umí pracovat grafické editory, neměli by být přístupné texty u her, byť už jen kvůli dobrému pocitu, že si nikdo nebude hledat postup v datových souborech a nebude pomocí nich sestavovat návod. Vzhledem k tomu, že budeme potřebovat rychlé hledání ve slovníku a mapě, bude se nám hodit šifrování po řádcích (každý řádek bude šifrován zvlášť jako řetězec, takže na sobě nebudou jednotlivé řádky závislé). Je dobré, když je součástí šifry i komprimace, což je ideální, ale taky o něco náročnější. Opět vám nabídnu šifrovací/komprimační metody. První je ze všech nejrychlejší a zároveň nejprimitivnější. Spočívá v tom, že se ke každému znaku (předem) určí jiný znak. To je sice nejrychlejší, ale takto zašifrovaný soubor se dá dešifrovat tak, že si nějaký "cracker" nejrpve otevře nějaký velmi dlouhý dokument a pak určí početnost každého znaku. Dále si otevře náš zašifrovaný dokument a opět určí početnosti jednotlivých znaků. Nakonec jen přiřadí znaky abecedy k šifrovaným znakům na základě jejich početnosti a tak dešifruje celý dokument. Zbylé nedokonalosti při dekódování doladí a je hotov. Upraví si náš dokument podle sebe, sestaví návod a opačným způsobem opět zašifruje. Naše hra to nepozná. Toto je sice pravda, ale v praxi předpokládáme, že když už by někdo uměl takhle pěkně dešifrovat, zajímal by se o "větší ryby", než naši textovku. O návod na populárnější hru je totiž samozřejmě větší zájem. Tím nechci říct, že textovky jsou nepopulární, ale popularita případného dešifranta by nestála za jeho práci. Další šifra je časově přibližně stejně náročná, ale nezkušenému "crackerovi" by dala větší práci rozlousknout. Tato šifra by totiž užívala nějakého hesla. První písmeno řetězce by se změnilo podle prvního písmena hesla pomocí nějakého vztahu. Pokračovalo by se tak postupně se všemi znaky (u hesel kratších, než řetězec by se heslo opakovalo) až by se zakódoval celý řetězec. Opět by však zašifrovaný dokument obsahoval pravidelné sekvence délkou odpovídající délce hesla. Tato šifra je však naprosto dostatečná. Dalšímu posilování praktické účinnosti šifry můžeme docílit například systematickým zpřeházením znaků, což by mohlo případného "dekodéra" odradit. Rozhodně se vyvarujte časté chyby, kdy při komprimaci řádků posíláte na výstup znak s ASCII hodnotou 13 (ENTER). Při dešifrování dokumentu by totiž nedocházelo k načítání celých řádků. Pokud chcete mít svoji šifru nadstandardní, můžete se pokusit i o vlastní komprimaci. Komprimace využívá rozdílnosti mezi nižší variabilitou dokumentu a variabilitou, jakou by mít mohl. Tou variabilitou myslím využití znaků, které obsahuje ASCII tabulka, ale které se ve spisovném textu neobjevují za účelem zmenšení informačního objemu dat. U textových her je výhoda právě v tom, že používáte text jednoho jazyka, který se omezuje jen na abecedu a některé znaky (mezera, čárka...). Vy však můžete používat všechny znaky ASCII tabulky (s opatrností u ENTERu s ordinální hodnotou 13). Celý systém šifrování a komprimace však sestrojte až po dokončení hry a rozhodně si hru (nebo alespoň soubory, do kterých hodláte zasahovat) před tím zálohujte. Jakmile je hra hotová a vy víte, že už nebudete do souborů nijak zasahovat, můžete začít analýzou dat a vyhledáváním nejfrekventovanějších znaků, dvojic... samozřejmě byste mohli použít i existující silné komprimační metody jako ZIP nebo LHA(!), tím způsobem, že byste dekomprimovali všechna data předem do nějakého jiného souboru, ale pak v případě, že by uživatel hru násilně přerušil/přepnul by ve Windows aplikace/došlo by k výpadku proudu; našel by nový soubor s kompletními texty hry. Pokud byste naopak dekomprimovali soubor tak, abyste měli nakonec stále jeden, v některých případech může uživatel nahlédnout do textů, v jiných by zase celá hra spadla, protože byste dekomprimovali již dekomprimovaný soubor a výsledek by nebyl zrovna to, co očekáváte. Rozhodně se nepokoušejte o slabé komprimace typu RLE (Run Length Encoding), které jsou vhodné tak pro komprimaci obrázků o malém počtu barev a kde se předpokládají velké homogenní plochy. Doporučuji si po dokončení práce na datech všechna data projet a určit nejfrekventovanější dvojice/trojice znaků a za ty pak dosazovat speciální znaky (k tomu je však samozřejmě zapotřebí dekomprimační tabulka, aby bylo možné zpětně určit, který znak má přiřazenou kterou dvojici/trojici znaků). Komprimace jde ruku v ruce s šifrováním, takže můžete buď šifrovat dodatečně nebo předběžně (třeba pro zvýšení redundance). Při použití dobré vlastní komprimační metody však nebudete ani šifru potřebovat, neboť budou data skutečně nepřehledná. Teď se budeme zaobírat slovníkem. Možná je přesnější vyjádření tezaurus, tedy slovník na synonyma. Ten by měl sloužit, jak už je jistě vám všem jasné, k tomu, aby program chápal více příkazů. Slovník již není tak nutné šifrovat, ale doporučuji to. Co se týče struktury slovníku, měl by podobně jako mapa obsahovat vždy některé klíčové slovo a pak na řádcích (pro přehlednost raději na řádku a pak dělit mezerami, čárkami, středníky...) psát synonyma k danému slovu. Při použití srovnávací metody popsané v kap. Zpracování příkazu není zapotřebí psát synonyma tvarově podobná klíčovému slovu, neboť tato metoda hledá vždy nejpodobnější výraz k výrazu zadanému. Obecně však platí, že čím více synonym použijete, tím lépe program zadaným řetězcům porozumí:

...
<prozkoumej>
prohledej
prohledni
zkoumej
koumej
ohledej
...

Do slovníku zařaďte určitě synonyma základních příkazů. Také můžete doplnit synonyma objektů vyskytujících se ve hře, ale tady už je věc o něco složitější:

...
<dvere>
vrata,dvirka,vstup
otevri,rozraz
*
Jsou to masivní dveře z dubového dřeva.
Jsou to dřevěné dveře.
Dveře ze dřeva.
*
Nejdou otevřít.
Nejde to.
*
Á - už se otevírají!
Konečně se otevřeli.
...

pozn. synonyma a klíčová slova jsou ve slovníku bez diakritiky a malá kvůli porovnávání (viz kap. Zpracování příkazu)

Teď si to rozebereme. Na prvním řádku je klíčové slovo, podle kterého program pozná, o jakou věc se jedná, zná-li pouze jeho synonymum. To si najde na druhém řádku. Na třetím řádku máme možné příkazy nahrazující obecný příkaz použij. Mezi hvězdičkami je libovolný počet komentářů, z nichž jeden se vypíše při zkoumání daného objektu (dodává to hře větší "inteligenci") a pak jsou tu dva výčty komentářů pro dva případy: použití/otevření/rozražení dveří bylo úspěšné/neúspěšné. Takto vytvořená struktura se dá kdykoliv libovolně editovat. Pro úsporu několika desítek bytů můžete také místo hvězdiček dosadit třeba počet následujících vět. Jak si to zařídíte je zcela na vás, toto je pouze mnou doporučená struktura. Slovník můžete také doplnit o slovní spojení, která může uživatel napsat během hry, která nejsou příkazy a nic tedy nevykonávají, pouze na ně bude program reagovat nějakou smysluplnou větou místo obvyklého výrazu neporozumění (to že program příkazu nerozumí, lze vyjádřit mnoha rozličnými větami, které by neměli ve slovníku scházet). Poslední věcí, kterou by mohl slovník obsahovat může být i seznam "nesmyslných akcí" - když hráč napíše třeba použij klíč a bude na lokaci, kde nejsou dveře, program by měl na toto spojení odpovědět třeba tady ti klíč nepomůže. Hra se dá navíc obohatit dialogy a hypertextem. Obojí je tvořeno větvenou strukturou, která se musí také nějakým způsobem ukládat. Začneme dialogy. Dialog, neboli rozhovor je zastoupen v textových hrách minoritně, ale rozhodně je obohacuje, pokud je dostatečně větvený. Při rozhovoru se vypíše věta od protějšku a vy máte na výběr z několika možností. Pokud budete ve hře nějaké dialogy mít, doporučuji je psát zvlášť do souborů (kvůli přehlednosti), jednoduše je však lze shrnout i do souboru jednoho. Ukládání větvených struktur není nic složitého. Jistě jste se s ním už setkali, pokud znáte HTML. Internetové stránky obsahují převážně různé odkazy (ať už jsou to obrázkové/animované reklamy nebo zvýrazněná slova/věty. V kódu stránky je speciální tag pro označení odkazu, jehož parametrem je cílová adresa. Při kliknutí na odkaz neudělá prohlížeč nic jiného, než že si zapamatuje aktuální adresu (aby jste se mohli vracet zpátky) a zobrazí stránku na adrese cílové. U dialogů to vyřešíme podobně. Prostě tu bude věta protějšku a několik vět na výběr (na výstupu se zobrazí pouze věta - v souboru však bude věta označena třeba číslem adresujícím cíl). Při volbě věty se obrazí cílová věta a výběr a tak se pokračuje, dokud nezvolíte ukončení rozhovoru či neukončíte rozhovor jinak, než rozloučením. Zkrátka bude v souboru opět odkaz na ukončení rozhovoru či kód něčeho, co se má stát (třeba že od protějšku obdržíte nějaký předmět). Rozdílem mezi dialogy a hypertextem je tedy hlavně to, že byste se neměli vracet. Hypertext je možné dobře využít u her, kde máte výběr z možností. Místo toho, aby se okno s výběrem možností rozšiřovalo o základní úkony jako prozkoumej věc1,prozkoumej věc2, ... ,prozkoumej věcn; se prozkoumatelné objekty v popisce zvýrazní a pak bude zkoumání automatické při kliknutí na ně. Stejně tak u používání předmětů můžete prostě zobrazit inventář a pak stačí kliknout na předmět a na objekt, na který se má daný předmět použít.

Na parkovišti stojí <31;Ford><32;Porsche>.

U téhle ukázky už trochu předbíhám, ale považuji ji v tuto chvíli za nutnou. Tato věta může být popis lokace. Možná jste vydedukovali, že se v jednom případě zobrazí slovo Ford a v druhém případě slovo Porsche. Přesně tak tomu je. Ty případy jsou reprezentovány podmínkami, o kterých bude řeč v logické části. Toto číslo však může reprezentovat zároveň hypertextový odkaz. Tady je obecné vyjádření struktury souboru s dialogem:

1. věta
1. odpověď + odkaz 1
2. odpověď + odkaz 2
...
n. odpověď + odkaz n
*** ODDĚLOVAČ ***
odkaz 1
2. věta
1. odpověď + odkaz n+1
2. odpověď + odkaz n+2
...
x. odpověď + odkaz n+x
*** ODDĚLOVAČ ***
odkaz 2
3. věta
1. odpověď + odkaz n+x+1
2. odpověď + odkaz n+x+2
...
y. odpověď + odkaz n+x+y
...
...
odkaz n
1. odpověď + odkaz n+x+y+1
...
...
...

Toto

4. Zpracování příkazů

Co má program udělat potom, co uživatel stiskne ENTER? U mnohých textovek, které jsem hrál, byla tato část vyloženě odfláknutá. Když jsem například napsal k místo požadovaného K, program nepochopil, že chci skončit. U velmi zdařilých her však bylo možné napsat: k, konec, quit, end, finish, exit, chci skončit nebo už mě to nebaví, a program se otázal, zda už chci hru opravdu ukončit. To však není všechno, co by měla pořádná textovka umět. Program by měl sešrotovat nedopsaná slova, slepená slovní spojení (např. stulprozk - prozkoumej stůl), zkratky, překlepy, různě velká písmena -- ale i třeba diakritiku. Představme si, že nějaký Slovák hraje českou hru s anglickou klávesnicí... Nároky se zdají velké, ale já vám nabídnu univerzální algoritmus, který všechny tyto požadavky splňuje. Základní myšlenkou je nikoliv vybírat stejný příkaz, nýbrž příkaz nejpodobnější. To, co nám uživatel pošle na výstup musíme chápat jako prostý řetězec, jako surový materiál, který musíme dostatečně upravit, aby vzniklo úhledné spojení: příkaz-parametr. Ale teď už k samotnému algoritmu. Z řetězce, který na vstupu dostaneme odstraníme všechno, co není součástí české abecedy nebo číslic. To byl první chod. V dalším upravíme všechna písmenka tak, aby byla buď všechna velká, nebo všechna malá (podle toho, v jakém tvaru máme výrazy ve slovníku). Teď následuje mezikrok: vybereme všechna možná spojení pro aktuální lokaci. Teď už se vám to může zdát dost nesrozumitelné. Vysvětlím vám to tedy takto: upravíte zkrátka řetězec, který vám "odentroval" uživatel. Poté vyberete všechna možná spojení, tedy všechno, co jde v dané místnosti s tím, co má uživatel v inventáři dělat (pokud jste například v uzavřené místnosti, máte prázdný inventář a na zemi leží papír, všechna možná spojení mohou být: seber papír, prozkoumej papír; pokud bude sebrán, mohou přibýt další spojení jako: polož papír, použij papír...). Vytvoříte si nějaký pomocný soubor nebo pole, do kterého všechna tato spojení uložíte (upravená, tedy analogicky: seberpapir, prozkoumejpapir; polozpapir, pouzijpapir - neuvádím všechna synonyma - v praxi by jich mělo být hodně... vezmipapir, prohlednipapirek ...takže bude lepší spíše ten soubor). Máme tedy upravený řetězec v proměnné a upravená spojení v souboru (u každého spojení by však měl být popsán i jeho skutečný význam!). Nyní bude potřeba vědět, jak se porovnávají dva řetězce. Tímto problémem jsem se ještě nedávno horečně zabýval, ale už mám řešení, jak porovnat dvě slova tak, abychom  získali nějaké vyjádření jejich podobnosti jedním číslem (tedy nejlépe procentuálně). Tady je nejlepší zavést si nějakou funkci, protože tu bude algoritmus často volat; jejím vstupem budou dva řetězce a výstupem pak jejich procentuální podobnost. Teď si popíšeme, jak bude pracovat tato důležitá funkce. Na vstupu tedy máme dva řetězce, které bychom měli nějakým způsobem porovnat. Předpokládáme, že řetězce jsou už upraveny (ale nemusí být, funkce obecně porovnává jakékoliv dva řetězce, ale například písmena á a a jsou pro ni "stejně různá", jako písmena a a b). V prvé řadě si ujasníme, jakou použijeme citlivost porovnávání. Citlivost zde není nic jiného, než velikost bloků, které budeme porovnávat. Těmi bloky myslím části slova. Aby jste to úplně pochopili, předvedu vám názorně rozdělení slova ahoj při citlivosti 1, 2,3 a 4:

(citlivost 1): a, h, o, j

(citlivost 2): ah, ho, oj

(citlivost 3): aho, hoj

(citlivost 4): ahoj

Uvědomte si, že jednotlivé bloky se musejí překrývat s výjimkou maximální citlivosti (1), a že minimální citlivost má jen jeden blok, a tím je samotné slovo. Jistě tedy pochopíte, že při porovnávání s nejmenší citlivostí bude jen zjištění, zda jsou oba porovnávané řetězce shodné. U vyšších citlivostí už musíme porovnávat každý blok jednoho řetězce s každým blokem řetězce druhého, takže je celý proces časově náročnější. Bloky porovnáváme samozřejmě tím způsobem, že jen zjistíme, zda jsou shodné. Pokud jsou, přičte se 1 k nějaké proměnné, která měla na začátku porovnávání hodnotu 0, vyjadřuje tedy počet shod. Dále bychom měli mít na paměti, že nelze porovnávat blok s blokem, se kterým se už porovnávalo. Posledním krokem porovnávání už bude jen určit procentuální podobnost, kterou určíme z poměru počtu shod a počtu bloků většího řetězce. Je to opravdu jednoduché (po pochopení). Jestliže tomu však stále nerozumíte, zkuste se podívat do zdrojového textu. Při této metodě porovnávání nezáleží na pořadí prvků (znaků), takže vám porovnávací funkce při porovnávání řetězců abc a cab vrátí hodnotu 100, přestože podle vás jsou tato slova různě podobná. To je kvůli tomu, že uživatel si může klidně napsat jak prozkoumej stůl, tak i zkus ten stůl prozkoumat. Právě proto by nemělo záležet na posloupnostech. Nezávislost na posloupnosti klesá s citlivostí. Toto byl však jen způsob, jak porovnat dvě slova. V praxi tedy provedete porovnání každého spojení v souboru s naším upraveným řetězcem a všechny výsledky si zapíšete. Pochopitelně vyberete tu nejpodobnější variantu. Teprve je-li více nejpodobnějších možností (pokud se jejich procentuální podobnosti přesně rovnají), program oznámí, že zadanému příkazu nerozumí. Stejně tak si můžete určit limit, kdy už program nebude příkazu rozumět. Obecně je optimální dát si limit 50% (program nebude příkazu rozumět, bude-li mít nejpodobnější spojení s příkazem podobnost menší nebo rovnou padesáti procentům). Můžete si dát limit i 30%, takže bude program rozumět větším zkomoleninám, ale nešel bych pod 25%, protože pak už by program doslova rozuměl tomu, čemu by rozumět neměl, takže by vykonával příkazy, které si uživatel nepřeje jen proto, že jsou nejpodobnější něčemu jinému. Schopnost programu rozeznávat příkazy bych zvyšoval spíše zvětšováním jeho slovní zásoby, resp. přidáváním synonym do slovníku hry. Dělejte synonyma nejen u holých příkazů (sloves), ale i u jejich parametrů (podstatných jmen). Uvědomte si, že pro uživatele je příjemné, když na obrazovce vidí slovo krabička, ale on si může klidně použít slovo paklík jenom proto, že mu to lépe zní.

Samozřejmě, existují i rafinovanější metody, jak rozpoznat vložený řetězec, ale ty jsou podstatně komplikovanější, než tento jednoduchý a efektivní způsob. Výše uvedená doporučená metoda je obecným řešením, jak rozpoznávat řetězce s oddělovači i bez oddělovačů (resp. takové, kde uživatel odděluje slova mezerami a ty, kde používá zkráceniny ze dvou slov). Následující metoda už bude co do provedení náročnější, ale vysvětlit se dá jednoduše. Zadaný řetězec opět upravíme s tím, že ponecháme právě oddělovací znaménka (mezery, čárky, středníky...). Jestliže žádná oddělovací znaménka nebyla v řetězci přítomna, aplikujeme dříve uvedenou metodu. V opačném případě můžeme předpokládat, že uživatel příkazy oddělil, takže budeme odlišovat samostatná slova a hledat v nich spojení příkaz-parametr. Jestliže totiž použijme jednodušší metodu, uživatel napíše například větu: A co třeba dveře? Nechtěl by jsi je otevřít? V takovém případě by se celá věta slepila a pak by se hledalo nejpodobnější spojení. Pravděpodobně by se našlo, ale vzhledem k délce celé věty by se podobnost pohybovala okolo třinácti procent. A v takovém případě by věta neměla být přijata z výše uvedeného důvodu. Pokud tedy budou oddělovače přítomny, rozdělíme (upravenou) větu na jednotlivá slova a pak každé slovo zvlášť zkontrolujeme se samostatnými možnými příkazy (seber, použij...) a objekty (stůl, dveře...). Vyberou se dvě nejpravděpodobnější slova a ta se pak považují za potřebné spojení. Pochopitelně, pokud je byť jen jedno slovo z nich kriticky málo podobné jemu nejpodobnějšímu ekvivalentu, program by "neměl příkazu rozumět", stejně tak pokud jsou obě slova shodná (což by se mělo kontrolovat ještě před samotným porovnáváním s příkazy a objekty ve slovníku) nebo pokud jsou obě příkaz či objekt (toto se však zjistí až po porovnávání). Problémem je to, že jemnější porovnávání je zároveň i časově náročnější, což se projevuje u pomalých disků a opravdu pomalých počítačů. Proto (aby se nemusela zbytečně zvedat minimální konfigurace pro běh hry) je ideální přidat ke hře nastavení obsahující kromě nastavení barev (tím myslím třeba i nahrávání a ukládání barevných schémat a editace barev podle složek RGB) taky upravení jemnosti porovnávání.

Ještě může nastat třetí možnost, a sice že uživatel bude kombinovat celá slova a zkráceniny: Nemohl by jsi otdveře? Pravděpodobnost, že by uživatel takto psal je dost malá, ale přesto může dojít třeba k zapomenutí napsání mezery a pak by se aplikovala druhá metoda, která by nic nepoznala. Napíšu tedy i řešení této situace, které však bude pro všechny tři situace obecné a zároveň ze všech nejnáročnější na čas. Věta se pochopitelně upraví vyjma oddělovačů, podle kterých se pak rozdělí na jednotlivá slova. Nyní musíme každé slovo kontrolovat jak s příkazy tak s parametry tak i se spojeními. To je celé.

Nyní si to všechno shrneme. Nabídnul jsem vám tedy tři různé metody porovnávání, kde každá může být různě citlivá podle toho, jak jemně bude porovnávat slova. U každé metody se upraví věta. U první se navíc odstraní i oddělovací znaky a pak se porovnává se spojeními. U druhé metody se každé slovo věty porovnává s příkazy a objekty nebo pokud nebyly oddělovače použity, porovnává se se spojeními. U třetí metody se porovnávají slova s příkazy, parametry a navíc i se spojeními (tato metoda lze samozřejmě zrychlit například tím, že pokud nebyly použity oddělovače, porovnává se pouze se spojeními).

Nakonec uvedu  i to, že byste měli dávat přednost některým příkazům před jinými nehledě na podobnost. Příkladem bude třeba to, že ve větě bude písmeno s, které se podobá stejně slovům seber, ale i sever. Pokud nebude parametrem nějaký objekt,  který se dá sebrat, mělo by dostat přednost slovo sever, protože ten se pro svou významnost v mnoha textových hrách  zapisuje zpravidla jen jedním písmenem.

Zde máte funkci pro porovnávání dvou slov s maximální citlivostí (na úrovni písmen):

function Analysis(s1,s2: String): real;
var i,ii,sh: integer;
    p: array[1..40] of boolean;
begin
 for i:=1 to 40 do p[i]:=False;
 sh:=0;
 for i:=1 to Length(s1) do
 begin
  for ii:=1 to Length(s2) do
  begin
   if (s1[i]=s2[ii]) and (p[ii]=False) then
   begin
    p[ii]:=True;Inc(sh,2);
   end;
  end;
 end;
 analysis:=sh/(Length(s2)+Length(s1))*100;
end;

5. Logická část

Sice už víme, co dělat po zadání příkazu uživatelem. Předpokládejme tedy, že program už zpracoval příkaz a vyňal z něj důležitou dvojici příkaz-parametr, takže už víme, co se po nás chce. Teď jde o to vše realizovat. Celé logické jádro hry bych psal přímo do zdrojového kódu ve formě sledu podmínek. První, co uděláme, bude zjištění typu příkazu. Příkazy sbírání a u lepších her i pokládání předmětů znamenají jen výpis jednoho z komentářů z mapového souboru a přemístění jedné položky z pole do pole (resp. pohyb předmětu mezi inventářem a lokací). Dále jsou tu ještě primitivnější příkazy a sice příkazy pohybu (jdi, běž, utíkej, zamiř...) - opět vyberete jeden z komentářů a přesunete/nepřesunete se na požadovanou lokaci. Příkazy, které budou mít komplikovanější důsledky a které dělají hru interaktivní jsou spíše příkazy mluvení (viz. dialogy) a hlavně používání předmětů, ať už těch, co jsou v inventáři, nebo těch, se kterými se dá manipulovat, ale nelze je vzít. Všimněte si, že do slovníku jsem zařadil i kolokace, tj. speciální slovesa, která se pojí výhradně s daným objektem (např. otoč klikou, zatáhni (za) kliku, otevři dveře, sedni (si na) židli -- pro uživatele je lepší psát takto, než používat suché klíčové slovo použij: použij kliku, použij dveře... samozřejmě, slovíčko použij je na všechny objekty univerzální). Provedete-li tedy něco ve hře, musí se tato změna nějak zaznamenat. Dobré je mít na takové změny předem vytvořené pole (obvykle typu boolean). Každý "chlíveček" v poli pak reprezentuje nějakou změnu ve hře. Musíte však vědět, jakou má která položka pole funkci. Například pokusíte-li se projít dveřmi, program projde jádro hry (blok podmínek) a narazí na podmínku, která říká, že pokud nemáte klíč, vypíše se určitý komentář z mapy. Pokud však máte klíč, změní se třeba položka číslo deset, která označuje, zda jsou dveře zavřené, či otevřené. No a pokud budou dveře konečně otevřené, vy můžete projít. Tento způsob má jednu velkou výhodu. Dejme tomu, že vy budete dveře třeba rozrážet dynamitem. Dokud budou dveře v pořádku, v popisce se bude mluvit o masivních dubových vratech, ale jakmile je rozbijete, popiska se změní a už bude řeč o ohořelé díře. Přímo v datovém souboru, kde by byla popiska uložena by se totiž vyskytovali v textu speciální znaky (nejlépe třeba apostrofy nebo značky <, >), které by ohraničovali text, který se buď má nebo nemá zobrazovat v závislosti na stavu hodnoty v poli na pozici n. Například: Na parkovišti stojí <56'nějaký Ford'-'nějaké Porsche!'>. Znamená to, že pokud je hodnota buňky pole číslo 56 pravda (True nebo i False, záleží na tom, jak vše uzpůsobíte), pak se vypíše první věta. V opačném případě věta druhá. Toto je jeden z možných způsobů, jak to provést. Rozhodně je to mnohem jednodušší, než mít kvůli každé prkotině zavedenou zvláštní proměnnou. Program je pak mnohem úhlednější a lépe se v něm pak orientuje. Teď přejdu k části s podmínkami. Doporučuji tento blok psát do zdrojového kódu. Mohli byste totiž klidně napsat celou hru jako jeden textový soubor a program by pak byl jen jakýsi univerzální přehrávač. Zkoušel jsem to a věřte mi, je to dost nepraktické. Udělejte si v programu jakési jádro, které bude sestávat z podmínek. U každé podmínky je dost důležité přiřadit i komentář, abyste později věděli, k čemu vůbec slouží. Já osobně jsem použil místo čísel slovní označení, které má vždy číselný ekvivalent, jež ukazuje která položka v poli mu odpovídá.

6. Závěr - jak vlastně udělat textovku? (větší projekty)

Počítal jsem s tím, že jste si vše důkladně přečetli, ale stále vám není něco (nebo všechno) zcela jasné. Chcete-li tedy opravdu začít něco většího, co možná budete distribuovat či dokonce prodávat, poradím vám pomocí šablony, kde vycházím z obecného plánu tvorby větších projektů. To celé doplním o podrobnosti týkající se textových her:

Na takovou větší textovku je dobré vzít si prázdný sešit vyhrazený jen a pouze projektu. Začnete návrhy, pak si budete dělat poznámky (ty zaberou nejvíc místa), vychytávat mouchy a nakonec testovat.

1. Přesná specifikace programu

Musíme si ujasnit, co vlastně chceme dělat, a co od nás bude hráč chtít. V našem případě je potřeba sepsat celý návod na hru (vřele doporučuji začínat právě mapou a návodem). Jestliže chcete dělat nějakou textovku podle knížky, příběh bude muset být zjednodušen a dokonce i pozměněn, neboť hra musí být interaktivní, kdežto příběh volně plyne. Se vším začít je nejlepší po čerstvém dočtení, neboť pak nejrychleji vymyslíte průběh hry a tím i návod s mapou.

2. Návrh hlavních částí programu

Nejprve si vytvoříme a důkladně odzkoušíme všechny potřebné procedury a funkce (např. porovnávání slov). Musíme dopředu přesně vědět, jak má program fungovat. Předběžně si do sešitu nebo poznámkového bloku zapíšeme struktury formátů, šifrovací algoritmus atp. Během programování už byste neměli nad takovými věcmi přemýšlet. Teprve až je vše odzkoušeno a vše funguje, jak má, můžeme začít s tělem programu (ale samozřejmě to i tak znamená tvořit nějaké doplňkové procedury, které by bylo neekonomické tvořit před zahájením prací na projektu)

3. Vlastní tvorba

Pokud programujete s někým, je též potřeba, aby jste se shodli na každé části programu. Dva programátoři toho udělají víc, ale vždy každý jinak. Nejde o to, jakým způsobem to ten druhý naprogramoval, ale jestli je to plně funkční (rozumíte-li programování více, než váš kolega a jeho kód je funkční ale zbytečně dlouhý, nic vám nebrání ho opravit). Jeden z vás by měl být hlavní programátor (ten, kdo dělá tělo programu) a jeden programátor vedlejší (procedury, funkce, principy...). Návrhy děláte společně před zahájením tvorby.

4. Testování

Testování se provádí až po ladění programu. Ladění je jen oprava tzv. syntaktických chyb (chyby v gramatice programovacího jazyka, díky kterým program vůbec neběží) + úprava některých struktur. Testováním už zjišťujete chyby sémantické (ty, které nezabraňují programu fungovat, ale díky kterým program nefunguje tak, jak by jste si to přáli). Oprava takových chyb je někdy dost těžká, ale nezbytná. Uvědomte si, že každý složitější program má minimálně deset chyb. Textovky však nejsou tak složitý žánr, ale vždy je tam nějaká chyba, které si ani při testování nevšimnete. Takové chyby jsou buďto jen kosmetické vady, anebo se kriticky projeví při nějakém náhodném uživatelově kroku. Proto doporučuji při testování nejen celou hru podle návodu dohrát, ale také zkoušet různé cestičky - díry, díky kterým může celý program spadnout. Může se jednat byť jen o stisknutí nesprávné klávesy v nesprávnou chvíli.

Dobrý test by měl pokrýt všechny funkce programu a konkretizovat chyby (i kdyby jste  měli třeba kontrolně vypisovat na obrazovku obsah proměnných, které se normálně nezobrazují - takových metod je víc a tohle je jedna z nich).

a) Alfa testy - testy prováděné právě vámi, autory;

b) Beta testy - testy, které provádějí vámi vybraní lidé (mohou to být i obyčejní uživatelé);

5. Dokumentace

K hotové hře je dobré přikládat taky manuál. U textovek stačí malý návod přímo ve hře. Pokud si myslíte, že budete ještě někdy dělat další hru, je vhodné jen upravit program a předělat datové soubory. Je však známou skutečností, že po půl roce už prostě nevíte, jak jste to napsali, takže je dobré si udělat i tzv. interní dokumentaci, která slouží k tomu, že po jejím přečtení už jste schopni něco s programem dělat. Rozhodně si v programu dělejte komentáře. Čím víc jich bude, tím lépe se v programu po delší době budete orientovat.