TXT game


Popis aplikace

Jedná se o textovou RPG hru. Její příběh je zasazen do blíže nespecifikovaného světa skřetů, trpaslíků a jiných potvor. Historické období není určeno, proto se ve hře můžete setkat s nečekanými věcmi.
Soubojový systém, jak jsem zjistil, je v podstatě převzat z Dračího doupěte. Postava má charakterizující vlastnosti: SÍLA, ODOLNOST, ÚTOK a OBRANA. Útočné číslo se počítá SÍLA + 0..ÚTOK, přičemž když padne 0 je kritický neúspěch, to znamená že váš / potvory útok se v tomto kole ruší. Obrané číslo se počítá jako ODOLNOST + 0..OBRANA. Když je útočné číslo větší než obrané číslo, tak vaše postava/potvora přijde o životy odpovídající rozdílu útočného a obraného čísla. Všechny vlastnosti vašeho hrdiny můžete zlepšit / zhoršit pomocí různých mečů, štítů, brnění a lektvarů.

Na této mapě se odehrává příběh:

Popis instalace

Stačí rozbalit zip archív včetně podadresářů do vámi vybraného adresáře

Návod ke spuštění a ovládání

Spuštění

V příkazovém řádku MS-DOS spustit soubor TXTgame.exe z adresáře, kam jste hru rozbalili.
V prostředí Windows poklepání na ikonku TXTgame

Ovládání

Ovládání hry připomíná příkazový řádek MS-DOS, u příkazů a parametrů se nerozlišují malá a VELKÁ písmena.

Seznam všech příkazů:

Popis činnostiPříkazParametrKde se musí daná věc na kterou je příkaz použit nacházet
chůze do další lokace jdi, bez, g jméno dveři další místnost
zvednuti predmetu do invetare seber, zvedni, t jméno předmětu místnost
zahozeni predmetu na zem zahod, poloz, p jméno předmětu prava ruka, leva ruka, telo, inventar
prohlednuti predmetu zkoumat, ukaz, e jméno předmětu mistnost
utok na potvoru zabij, utok, a jméno potvory mistnost
zkoumani lokace koukam, l ----- současná místnost
ukazani vlastnosti postavy char, c ----- -----
ukazani inventare inv, i ----- -----
uchopeni predmetu z inventare leva, prava, telo jméno předmětu inventář
pouziti predmetu z inventare pouzij, use, u jméno předmětu inventář
konec hry konec ----- -----

Příklad: JDI veznice, ZABIJ skret, INV, CHAR
Poznámka: Je jedno, jestli použijete příkaz JDI nebo G, mají úplně stejnou funkci. To platí u všech ostatních příkazů.

Popis řešení

Popis hrubého řešení programu

Procedura LoadWorld pomocí dalších procedur a funkcí načte xml soubor a vytvoří z něj datovou strukturu. Tata datová struktura je tvořena lineárním seznamem místností, který je ještě navíc provázán dalšími ukazateli, které představují jednotlivé dveře do dalších místností. Každá místnost obsahuje další 2 lineární seznamy: seznam potvor a seznam předmětů. Každá potvora může obsahovat další předměty. Datová struktura tohoto světa vypadá takto:

Hráč je reprezentován záznamem, ve kterém je definována jeho síla,obrana, to co má na sobě, dále ukazatel na inventář, což je seznam itemů a ukazatel na aktuální místnost.
Vlastní hra funguje tak, že v cyklu se nejprve volá procedura CheckAtckCr, která zjistí jestli na vaši postavu útočí první postova v místnosti. Pokud ano tato procedura zavolá proceduru souboj. Jako další volá proceduru CtiVstup, která vám pokládá otázku: "Co chces delat?" a vrací hodnotu příkazu a parametru. Příkaz a parametr jsou poslány do další procedury DoAction, která si v převodní tabulce z unity MeziTab zjistí, jaká konstanta odpovídá příkazu. Tato konstanta je selektor větvení, který určuje, jaká procedura se zavolá. Pokud žádná procedura neodpovídá konstantě, což znamená, že příkaz je chybný, vypíše se chybová hláška. Vědšině těmto procedurám se posílá parametr (string), vědšinou jméno potvory nebo předmětu. Tento cyklus končí pokud životy vaší postavy (curLive) jsou menší než 0, nebo proměná run je false. Proměná run se změní na false v případě, že zabitá potvora, sebraný předmět nebo místnost do která jste přišli má proměnou endg = true.
Celý program je rozdělen do 5 unit a hlavního programu. V unitě datastr jsou naimlementovány 3 lineární seznamy, procedury a funkce pro práci s nimi a zásobník. Zásobník se používá pouze v proceduře LoadWorld pro ukládání ukazatelů na poslední místnost/potvoru/předmět.


Výpis typů, proměných, laviček procedur a funkcí v unitě DataStr:

Zásobník

procedure Init (var Zasobnik: UkPolozka);
inicializace zásobníku, nastavení vrcholu a dna na nil

function Empty (Zasobnik: UkPolozka): boolean;
pokud je zásobník prázdný vrací true

function Push (t: zTyp; m: UkRoom; c:UkCreature; i:UkItem; var Vrchol: UkPolozka):boolean;
přidání do zásobíku
Protože jsem v Pascalu nepřišel na způsob jak přetypovat typovaný ukazatel, musí se do parametru t zadat o který ukazatel se jedná, ten pak přiřadit správnému parametru a zbylé nastavit na nil (není nutné).

function Pop (var Vrchol: UkPolozka):pointer;
odebere prvek ze zásobníku, s prvkem se již dál nepracuje, proto je ukazatel netypový

Práce s místnostmi

procedure rLoadDoors(s: string; var dl: tDoorList);
Naplní pole Doors v aktuální místnosti jménami místností kam se dá jít

function rNew (at: AttList; n: byte; p: pTab): UkRoom;
Vytvoří záznam odpovídající nové místnosti a vrátí na ní ukazatel, parametry které nebyly v XML souboru zadány nastaví na počáteční hodnotu

procedure rAdd ( nova: UkRoom; var world: UkRoom);
Přidá (novou) místnost na začátek lineárního seznamu kam ukazuje proměná world

function rSearch (jmeno: string; svet: UkRoom): UkRoom;
Vrátí adresu odpovídající jménu místnosti v parametru jmeno

procedure rInitDoors(var svet: UkRoom);
volá se po načtení celého světa, pro každé dveře ve všech místnostech zavolá prceduru rSearch a výslednou adresu uloží do pole dveří Doors ke jménu dveří

function rSearchDoor(d: string; m: UkRoom): UkRoom;
podle jmena d najde odpovídající adresu místnosti, funkce navenek je stejná jako u rSearch, ale prohledává pouze konkrétní místnost, Rychlé!!!

Práce s předměty

function iNew(Atrib: AttList;n: byte; p:pTab): UkItem;
Pomocí Atrib listu z funkce gettag a prevodní tabulky vytvoří záznam předmět a vrátí na něj ukazetel

function iSearch (jmeno: string; predmet: UkItem): UkItem;
Najde adresu předmětu odpovídajíci jménu v seznamu na který ukazuje předmět

procedure iAdd (novy: UkItem; var kam: UkItem);
Přidá novy na začátek seznamu kam ukazuje kam

procedure iAddToEnd (novy: UkItem; var iList: UkItem);
Vhodné pro přidávání celého seznamu k jinému. POMALÉ!!!

function iRemove (predmet: UkItem; var ItemList: UkItem): UkItem;
Odebere předmět z itemlistu a vrátí jeho adresu

procedure iMove (var i, odkud, kam: UkItem);
přesune předmět mezi dvěmi seznami

Práce s potvorami


function cNew(Atrib: AttList;n: byte; p:pTab): UkCreature;
viz iNew

procedure cAdd (nova: UkCreature; var kam: UkCreature);
viz iAdd

function cRemove (potvora: UkCreature; var cList: UkCreature): UkCreature;
vir iRemove

function cSearch (jmeno: string; potvora: UkCreature): UkCreature;
viz i Search




V unitě MeziTab jsou dvě převodní tabulky sloužící pro převod řetězce na číselnou konstantu. Jsou zde deklarovány 2 sady konstant. Jedna sada slouží při vytváření datové struktury ze souboru, ve funkcích rNew, iNew, cNew. Druhá sada slouží jako dekodér příkazů z příkazového řádku. Kařdá tabulka se musí zvlášt inicializovat. K tomu slouží procedure InitTabVstup(var T: pTab); a procedure InitTabPar(var T: pTab);
Převod je realizován funkcí function Preved(T: pTab; k: string): byte;


Unita barvy se mela starat o vsechny vystupy na obrazovku. Jsou v ni pouze procedury na změnu barvy, aby se v programu nemuselo vypisovat např.: textcolor(yellow) s procedury s parametrem string. Tyto procedury obsahují pouze změnu barvy a standartní proceduru write/writeln


Unita infoFile obsahuje pouze informativní text s popisem ovládání


Unita Parser - obsahuje tyto funkce:

function openFile (var f: text; name: string): boolean;
funkce na otevření textového souboru f se jménem name, vrací true pokud otevření proběhlo úspěšně

function UpString(s: string): string;
Velice využívaná funkce. Převede každý znak z řetězce string na velké písmeno a znak opět vrátí do řetězce. Např.: aHoj --) AHOJ

function getTag(var f:text;var name: string;var fl: byte;var n: byte;var att: Attlist;var count:string):boolean;
Vlastní funkce na parsrování XML souboru. Načte vždy jeden tag a vrátí true pokud načtení proběhlo v pořádku. Používá další funkce, ale ty pro výsledné řešení nemají další význam. V proměných jsou tyto data:
name - jmeno tagu
fl - STARTTAG/ENDTAG/SINGLETAG
n - pocet atributů
att - pole od 1 do MAXATT záznamů 2 řetězců: name a value
count - text před tagem


Vlastní program obsahuje funkci Loadworld(f:text):UkRoom Která vytvoří celou datovou strukturu místností / potvor / předmětů. Dále procedury pro vytvoření hlavní (Vaší) postavy a prácí s ní (přidávání / ubírání věcí do / z inventáře, používání předmětů,...). Dále jsou zde procedury rVypis, iVypis, cVypis pro vypisovani vlastnosti. Důležitá je procedura souboj. Je to kompletní soubojový systém s výpisem průběhu a následným přendáním vypadlých předmětů. Po skončení hry se volají procedury CloseWorld, která uvolňuje pamět místností / potvor / předmětů a procedura freeHero, ktera uvolni dynamicky alokovane promene u hrdiny (inventář). Procedury tvořící celé komunikační rozhraní s hráčem jsou CtiVstup(var typ, hod: string); a DoAction (t,hod: string); volané v tomto pořadí. Pro inicializaci celé hry je nutné zavolat proceduru initGame na kterou navazuje procedura menu.


Pro případné další otázky pište na email