Računari 3

Škola igara avantura

U "Računarima 2" smo posvetili dosta prostora onima koji žele da pišu akcione igre. Ovoga puta se, prirodno, obraćamo onima koji su najpre utrošili silne dane da provedu Binga kroz Wilderland a zatim i nekoliko časova na razmatranje pitanja "kako li je ovaj program napisan?".

Dejan Ristanović

Posmatrano sa programerske strane, pisanje igara avantura je daleko jednostavnije od pisanja akcionih igara; potrebno je samo solidno poznavanje bejzika (posebno rada sa alfanumericima). Kod avantura je, međutim, obilje dobrih i originalnih ideja daleko potrebnije nego za pisanje akcionih igara. Avanture su, dakle, prava stvar za maštovite početnike!

Ako kupite neku avanturu koja košta desetak funti i pokušate da je listate, čeka vas iznenađenje: program je u celini pisan na bejziku! Zar strane softverske firme nemaju dovoljno poznavalaca mašinskog jezika? Naravno da imaju ali se pokazalo da je pisanje igre avanture na mašincu nepotrebno razmetanje; za ove igre nije neophodno prebrzo izvršavanje ali je potrebno da računar razmatra mnogo različitih situacija i analizira raznorazne reakcije igrača što se na nekom višem programskom jeziku (u našem slučaju bejziku) obavlja daleko lakše nego na jezicima nižeg nivoa. Avanture, dakle, mogu da pišu i oni koji se užasavaju "pikovanja" i "poukovanja" po memoriji njihovog kompjutera.

Pisanje igara avantura je daleko bolja škola za profesionalnog programera nego što bi se reklo na prvi pogled. Svaki autor nekog poslovnog paketa za obradu podataka ili, pogotovu, kompajlera nekog programskog jezika treba da predvidi sve moguće ulaze (kako tačne tako i pogrešne) i pobrine se da računar u takvim slučajevima izbegne krah koji bi doveo do gubitka već unetih podataka. Ovakav zanat može dobro da se "ispeče" pisanjem avantura u kojima se neće javljati 'Type mismatch', 'Nonsence in BASIC' ili neka slična poruka kada igrač otkuca POJEDI HELIKOPTER.

U toku ove Škole zajednički ćemo napisati jednu umereno jednostavnu igru - avanturu koja se zove 'Zli dvorac'. Ukoliko do sada niste imali kontakt sa igrama ovoga tipa (što je krajnje neverovatno) ili niste uspeli da nađete zajednički jezik sa kompjuterom koji govori jedino Engleski, nije loša ideja da najpre otkucate program i provedete izvesno vreme otkrivajući tajne ove igre. Dobrim poznavaocima bejzika bismo predložili da ubede (kako li se to radi?) nekoga drugoga da im otkuca ovaj program jer će u protivnom nehotice otkriti neke od tajni igre koja će izgubiti na draži.

"Zli dvorac", pisan na računaru sa standardnim Microsoftovim bejzikom, ima oko 8 kilobajta i zahteva još otprilike toliko za nizove i promenljive koje koristi (vlasnici Spectruma 48 K će morati da modifikuju program prema sugestijama koje dajemo na kraju teksta) dok druge komercijale avanture umeju da zauzmu i po pedesetak kilobajta. Ipak, najgori način da pišete program ovoga tipa je da sednete, uključite kompjuter i pomislite: "Teško meni, treba da napišem šesnaest kilobajta programa". Savetujemo vam da se za početak ne približavate računaru; uzmite olovku i papir i pokušajte da zamislite osnovni scenario vaše igre.

Vreme, mesto i pravila

Vreme u kome se smeštaju igre avanture je najčešće daleka prošosti ili daleka budućnost. U poslednje vreme se javljaju i avanture iz svakodnevnog života kao što je Kontrabant. Kontrabant je prva ozbiljna avantura pripremljena kod nas i deo je kasete sa programima za Spectruma koju izdaje Radio Študent. Tema je u pravom smislu savremena: kako uvesti računar u Jugoslaviju. Izgovor za zadržavanje na dalekoj prošlosti ili budućnosti su razne vrste magije koje se vrlo dobro slažu sa igrama ovoga tipa. Priznaćete da je prilično teško tražiti od nekoga da ozbiljno shavti igru u kojoj se ispred "Beograđanke" pronalazi čarobni štap ili zarobljena princeza koju čuva vukodlak!

Pošto smo odredili istorijski trenutak u koji stavljamo našu avanturu, treba da odlučimo o ciljevima koje igrač treba da postigne. Obično se od njega traži da pobegne sa nekoga mesta ili da se vrati negde ili da sakupi neke vredne predmete (ukoliko želite da igrač oslobodi nekoga (ili, da budemo precizniji, neku) možete i njega (nju) da dodate spisku vrednih predmeta).

Prema zadacima koje igrač treba da obavi pripremamo okvirnu mapu mesta događaja, u našem slučaju 'Zlog dvorca'. U ovom trenutku mapa je daleko od detaljne; potrebno nam je samo da uočimo osnovni raspored prostorija koje su bitne za igru a docnije ćemo dodati i mnogo "slepih hodnika". Okvirna mapa 'Zlog dvorca' i okoline je data na prvoj slici.

Pošto ste nacrtali okvirnu mapu, treba da izaberete informacije koje ćete saopštiti igraču na početku igre. Tih nekoliko rečenica treba da budu takve da probude u njemu interes za avanturu, i da mu eventualno, na zavijen način, kažu nešto o zadacima koje treba obaviti. Evo onoga što treba da zna čovek koji se usudi da priđe Zlom dvorcu.

'Zli dvorac se nalazi blizu samoga kraja sveta, okružen močvarom koja je na ivici ogromne i strašne provalije. Njegovi krivi i padu skloni tornjevi se jezivo pružaju ka uvek tamnom i oblačnom nebeskom svodu. Ni jedan zid, ni jedan ugao nije prav, ni jedan prozor nije čitav ali ni kroz jedan ne dopire nikakva svetlost. Ni malo čudno, niko ne živi dvorcu ili, da budemo precizniji, ni jedan čovek ne živi u njemu...

Priča se da je, u nekoj dalekoj prošlosti, najbogatiji čovek na svetu, bežeći od svojih neprijatelja, proveo poslednje dane u dvorcu plaćajući zlatom gostoprimstvo zlih sila koje su mu prodale predmete neophodne za opstanak. Začudo, niko nikada nije video njegovo telo...'

Crtanje mape

Sledeći korak je crtanje precizne mape dvorca. Najlakše ćemo je dobiti ako najpre nacrtamo matricu sa onoliko polja koliko želimo da imamo lokacija (u našem slučaju se neke lokacije odnose i na okolinu dvorca) a zativ svako polje označimo brojem počevši od nule, baš kao na slici 2.

Na matrici, koristeći običnu olovku, ucrtavamo zidove i vrata. Zatim, u skladu sa njima, obeležavamo svaku prostoriju imenom koje odgovara našem scenariju. Mi smo izabrali imena kao što je "ugao sveta", "soba puna paučine", "duboki podrum..." ali i sasvim ovozemaljske nazive kao što je "kuhinja", "pretsoblje", "biblioteka"... Osim imena prostorija, treba da zamislite načine na koje se iz jedne sobe stiže u drugu tj. da rasporedite vrata. Neka vrata mogu da budu i jednosmerna ali za to morate da smislite jak razlog. U našoj avanturi se, na primer, ulazna vrata zamka zatvaraju kada prođete kroz njih čime "personal dvorca" sprečava bekstvo kukavica koje bi zlim silama uskratile zadovoljstvo da ih same unište. Moguće prevce kretanja je najlakše označavati stranama sveta, pri čemu je sever na gornjem kraju mape. Obično se koriste engleske skraćenice N, S, E, W za sever, jug, istok i zapad respektivno. U Zlom dvorcu je moguće koristiti kako engleske skraćenice tako i naše rečenice "idi na sever", "idi na zapad" i slično.

Ubacujući stepenice, podrumska vrata i tavanske prozore kojima se stiže iz sobe u sobu stvarate deo utiska trodimenzionalnosti. Kada završite ovu Školu možete, naročito ako posedujete računar sa RAM-om solidnih "dimenzija", da pokušate da napišete pravu trodimenzionalnu avanturu dodajući, na primer, podrum u pokrovlje našem dvorcu. Treba da imate u vidu da se na ovim dodatnim nivoima obavezno nalazi veliki broj soba, približno jednak broju soba u prizemlju. Vredne objekte ćete, naravno, sakriti u najudaljenije budžake poslednjeg sprata.

Specijalne efekte možete da dobijete dajući isto ime različitim lokacijama. U avanturi "Jerusalim" koja je pisana za TRS 80 četiri objekta nose naziv ULICA JERUSALIMA. Da biste se "ispetljali" iz ove ulice morate najpre da znate u kome se od njenih komponanti nalazite a zatim da primenite neki algoritam kretanja. Obzirom da smo se truduli da 'Zli dvorac' ne bude preteška avantura, nismo u nju ubacili zagonetke ovoga tipa.

Sledeća tačka "dnevnog reda" su blaga koja treba smestiti u prostorije. Ova blaga mogu da budu prave dragocenosti poput zlata i dijamanata ili tajanstveni planovi i dokumenti ili, jednostavno, tragovi koji pomažu da se reši neka zagonetka. Osim objekata koji mogu da se ponesu, treba uključiti i ormane, stolove, vrata i sličnu "nepokretnu imovinu". Neki od ovih predmeta mogu da imaju fioke, pregrade i slične delove koje igrač najpre treba da ispita da bi ih iskoristio dok drugi mogu da budu samo lažni tragovi. U našoj avanturi se, na primer, u ormanu nalazi kaput na kome treba pronaći džep u kome je ključ.

Pre nego što konačno rasporedite blaga, treba da zamislite i prepreke koje će ih čuvati: avantura u kojoj bi igrač jednostavno obišao sve prostorije i pokupio blaga bi bila previše jednostavna. Neka blaga treba da budu čuvana posebno pažljivo i da zahtevaju posedovanje određenog broja predmeta da bi se osvojila. U programu 'Sphinx adventure' koji je pisan za BBC B jedno od blaga čuva slon. Da bi se slon oterao treba dovesti miša a miša, opet, treba uhvatiti pomoću sira i mišolovke koje treba najpre pronaći.

U gornjem primeru sir i mišolovka nisu nikakvi posebno vredni objekti; njih igrač treba da pronađe da bi rešio neku zagonetu a zatim može da ih baci. Možete da se odlučite da dodate neke naoko vredne i korisne ali inače sasvim nepotrebne predmete iako ovako nešto nije u skladu sa "fer plejom".

Na slici 3. je prikazana mapa 'Zlog dvorca' i okoline na kojoj su ucrtani zidovi, pravci kretanja i blaga koja igrač treba da pronađe. Blaga su, kao što vidimo, obeležena brojevima 1-8 (nešto docnije ćemo videti zašto ni jedno blago nije označeno brojem 0) i neka od njih su čuvana na odgovarajući način koji je takođe ubeležen.

Korisni objekti i zagonetke

Neka od blaga mogu, osim same vrednosti, imati i neku sekundarnu funkciju. U našoj avanturi svećnjak je, najpre, potreban da bi se upalila sveća ali predstavlja i "blago" bez koga igra ne može da se završi. Ostale koristne objekte treba da upišemo na spisak dragocenosti numerišući ih brojevima 9, 10, 11... Igru ćemo otežati ukoliko ne uvodimo predmete koji imaju očiglednu funkiju: umesto ključa možemo, na primer, negde da sakrijemo zlatnu ukosnicu. Važno je, međutim, da je upotreba predmeta opšte poznata, makar i iz crtanih filmova: u gornjem primeru nije bilo važno da li se slonovi stvarno boje miševa ili ne.

Treba takođe smestiti objekte na logična i pristupačna mesta. Ponekad se, u nepažnji, dogodi da smestimo ključ u sobu koju čuva aždaja koju treba ubiti mačem koji je sakriven u kovčeg koji ne možemo da otvorimo bez ključa. Ovakve greške ćemo, doduše, otkriti u fazi testiranja programa ali će tada biti daleko teže ispraviti ih.

Sledi pravljenje spiska zagonetki koje igrač treba da reši. Obzirom da je 'Zli dvorac' jednostavna avantura, pripremili smo za nju samo devet zagonetki koje su ispisane na slici 4. Na kraju teksta ćemo napisati nekoliko reči o eventualnim proširenjima programa koja se uglavnom svode na dodavanje novih problema.

Spisak imenica i glagola

Pošto ste pripremili kompletan scenario, pristupate formiranju kompjuterovog rečnika. Obično korisnik komunicira sa računarom pomoću kratkih rečenica koje se sastoje od glagola i imenice. Ukoliko pišete avanturu kod koje će se komunikacija odvijati na srpskohrvatskom jeziku, u nekim slučajevima je nužno koristiti povratnu zamenicu 'se' a neophodan je i poneki prilog. Očekujte, osim toga, i ogromne probleme sa padežima. Zato je zgodno primeniti mali trik koji korisnici avantura retko primete: reči mogu da se prepoznaju samo po prvih nekoliko slova, najčešće tri. Obzirom da je 'Zli dvorac' školski primer avanture, nismo želeli da se služimo trikovima pa smo se potrudili da izaberemo reči koje će se uklopiti u naše rečenice.

Spisak glagola koje kompjuter poznaje uz imenice na koje se glagoli odnose je dat na slici 5. Glagole smo, kao što se vidi, obeležili brojevima 1, 2, ... dok je nula rezervisana za situaciju u kojoj traženi glagol nije pronađen na listi. Uvrstili smo i naredbe UPOMOC i INVENTAR koje, respektivno, daju igraču spisak naredbi koje računar poznaje kao i spisak predmeta koje trenutno nosi. U složenijim avanturama naredba UPOMOC je daleko složenija: u odgovoru na nju računar u nekim slučajevima daje igraču indicije o rešenju nekog problema. Ukoliko ste igrali Hobbita svakako znate da je najveća veština u tumačenju odgovora koje računar daje kada otkucate HELP.

Neke reči mogu da imaju isto značenje (npr. uzmi i ponesi) omogućavajući igraču da otkuca rečenicu koja mu prva padne na pamet. Uštedećete određeni memorijski prostor ako te reči tretirate istim potprogramima što znači da ovakve sinonime treba uočiti od samoga početka.

Glavni plan

Na slici 6 je dat konačni plan naše avanture. Vidimo da su sve prostorije označene brojevima, da su označeni svi prolazi i vrata, da je svaki objekat obeležen brojem i smešten na odgovarajuće mesto te da su upisani razni problemi sa kojima će se igrač suočiti (raster, na primer, označava mračne predele, upisana je magična barijera...).

Glavni plan je poslednji trenutak da izmenite ponešto u scenariju avanture; kada ga konačno usvojite, preostaje samo tehnički posao pisanja programa. Na tržištu mogu čak da se nađu i programi koji, na osnovu glavnog plana, sami pišu igre-avanture! Pomoću jednog takvog programa je, uzgred budi rečeno, pisana čak i igra Kontrabant. Ovo pominjemo zbog toga što pisanje igre avanture po komplikovanom scenariju početniku može da izgleda nedostižno. Treba, ipak, imati poverenja u sebe: došli smo do mesta od koga bi čak i kompjuter mogao da nastavi dalje; zar da budemo gluplji od kompjutera?

Smeštanje podataka

Došlo je, najzad, vreme da počnemo da pišemo program. Taj program, najpre, mora da poseduje malu biblioteku podataka u kojoj treba da se nalaze imena svih soba i objekata kao i čitava mapa dvorca. Za ovakvo smeštanje koristimo nizove i matrice.

Niz podataka možemo da zamislimo kao poštanske fahove. Cedulja smeštena u svakom fahu predstavlja samostalni elemenat koji, ipak, ima logičku vezu sa ceduljama u ostalim pregradama. Čitav niz podataka ima ime (npr. A, B, NIZ i slično) dok se njegovi elementi razlikuju po brojevima (npr. A(0), A(1), ... , A(N)). Sa N smo obeležili takozvanu dimenziju niza koja označava broj njegovih elemenata. Da bi računar znao koliko memorijskog prostora da rezerviše za neki niz, na samom početku programa koristimo naredbu DIM iza koje pišemo imena svih nizova koje ćemo koristiti i njihove dimenzije.

U Zlom dvorcu se koristi više nizova. Prvi i najlakše shvatljiv je niz D$( ) koji sadrži imena i opise svih prostorija u zamku i okolini. Obzirom da, prema glavnom planu, zamak ima 64 prostorije, koristićemo DIM D$(63) (zašto ne DIM D$(64)?). Imena svih lokacija će biti zapamćena prema redosledu svojih karakterističnih brojeva.

Potreban nam je, zatim, niz R$( ) čiji će elementi čuvati informacije o mogućim pravcima kretanja. Ukoliko, na primer, R$(0) ima vrednost "SE", iz prostorije broj 0 može da se pođe na jug i na istok. Niz R$( ) ima 64 elementa kao i niz D$( ).

Niz O$( ) sadrži imenice i ostale reči koje se javljaju iza glagola u naredbama koje kompjuter razume. Da bi olakšali promenu broja elemenata rečnika, uveli smo promenljivu W koja označava broj imenica a zatim koristili DIM O$(W), naredbu koju razumeju jedino jezici tipa bejzika. Ukoliko poželite da proširite rečnik računara jednostavno povećajte W i dodajte nekoliko novih DATA naredbi.

Niz V$( ) dopunjava rečnik glagolima. Slično imenicama, uvedena je promenljiva V koja označava broj glagola koje kompjuter razume. Prema našoj ranijoj ideji, V ima vrednost 25 pri čemu se V$(0) koristi za situaciju u kojoj glagol nije prepoznat.

Na prvi pogled bi se reklo da nam nije potrebno više nizova. Podrobnije razmišljanje nas, medutim, upozorava da na neki način treba registrovati lokacije pojedinih objekata kao i spisak objekata koje igrač nosi sa sobom. Jedan od načina da rešimo ovaj problem je uvođenje niza L( ) koji sadrži lokacije pojedinih predmeta i niz C( ) koji sadrži brojeve objekata koje igrač nosi sa sobom. Ukoliko je broj objekata koji mogu da se nose G (u našem slučaju G=18), koristićemo DIM L(G), C(G). Naprednije programere upozoravamo na mogućnost da, po cenu izvesnog usporenja programa, uštedimo memorijski prostor za niz C( ) time što bi 0 kao lokacija nekog objekta označavala da ga igrač poseduje.

Pored svih pomenutih, potreban nam je i niz flegova F( ). Elementi ovoga niza imaju vrednosti 0 sve dok igrač ne pronađe objekat N posle čega F(N) dobija vrednost 1. Vrednost 0 označava, dakle, normalno ili neaktivno stanje nekog objekta dok vrednost 1 označava neku njegovu aktivnost (npr. upaljena sveća, vidljiv predmet itd.). Obzirom da neke imenice (sever, jug, prsten...) nemaju potrebe za svojim različitim stanjima, neki flegovi se koriste za "specijalne efekte". Sveći su, na primer, potrebna dva flega: F(17) označava da li ju je igrač našao u fioci a F(0) - da li je sveća upaljena. Možete da popišete nekorišćene flegove i koristite ih za proširenja igre.

Najlakši (ali ne i najracionalniji, bar kod većine računara) način da se podaci smeste u nizove je korišćenje READ - DATA naredbi. Da bismo, na primer, preneli nazive lokacija u D$, koristimo naredbe:

FOR I=0 TO 63
READ D$(I)
NEXT I
DATA ...

Početno stanje flegova je daleko lakše postaviti. Kada nekom bejzik računaru kažemo da dimenzioniše niz, svi njegovi elementi će imati vrednost nula. Nekoliko flegova (u našem slučaju 2, 17, 18, 23, 26 i 28) u početku treba da dobije vrednost 1 što najlakše postižemo jednostavnim LET naredbama.

Ukoliko posedujemo kompjuter sa manje memorije (na primer ZX 81 sa 16 Kb RAM-a) ili računar koji nema READ - DATA naredbe, moraćemo najpre da otkucamo program a zatim da unesemo podatke i snimimo ih na kasetu zajedno sa samim programom. Na taj način smo izbegli da dugi komentari budu jednom smešteni u DATA naredbu a drugi put u zonu (alfa)numeričkih promenljivih. Postoje i toliko pametni bejzik interpretatori (jedan takav ima TRS 80) da automatski izbegavaju ovo prenošenje sve dok korisnik ne zatraži promenu nekog na ovaj način unetog podatka i tako štede memorijski prostor i programerovo vreme.

Struktura programa

U skladu sa modernim programerskim standardima, razložićemo problem na niz operacija koje kompjuter treba da obavi a zatim realizovati svaku od njih. Čitajući dalji tekst biće neophodno da s vremena na vreme konsultujete sekcije samoga programa i tako u praksi proverite ono o čemu govorimo. Posle izvesnog vremena primetićete da se sve lakše snalazite u dugom listingu i da svaka naredba postepeno dobija smisao. Ukoliko ne možete da uočite namenu neke naredbe, možete da pokušate da je izmenite ili čak izostavite i posmatrate rad programa.

Prvi posao koji računar treba da obavi je inicijalizacija. Ona se sastoji od dodeljivanja vrednosti promenljivima i elementima nizova i odvojena je u potprogram koji se nalazi na samom kraju glavnog programa. Zbog čega smo ovo učinili? Pokazuje se da sve GOTO i GOSUB naredbe brže pronalaze linije koje su bliže početku programa. Inicijalizacija se obavlja samo jednom i nema nikakve svrhe da opterećuje početak programa koji će se izvršvati ogroman broj puta u toku igre.

Dolazimo do početka "glavne petlje" u kojoj računar najpre obaveštava igrača o mestu na kome se nalazi. Za to se koristi promenljiva RM u kojoj je stalno smešten broj potrebne prostorije tako da PRINT D$(RM) ispisuje njen opis. Sledi obaveštenje o mogućim pravcima kretanja koje je nešto teže pripremiti. Znamo da su ovi pravci smešteni u promenljivu R$(RM) koju, dakle, treba razdvojiti na slova. To postižemo primenom naredbe MID$: MID$(R$(RM),I,1) izdvaja I-to slovo promenljive R$(RM). Jasno je da I predstavlja indeks petlje koji uzima vrednosti 1, 2, ... sve do dužine alfanumerika R$(RM) koju određujemo primenom funkcije LEN.

Treba, posle ovoga, da štampamo imena predmeta koje igrač vidi. To postižemo naredbama:

FOR I=1 TO G
IF L(I)=RM AND F(I)=0 THEN PRINT "Vidiš ";O$(I);"."
NEXT I

Vidimo da računar proverava da li je lokacija objekta I koju čuva promenljiva L(I) jednaka broju prostorije u kojoj se trenutno nalazi igrač (RM) a zatim i da li je predmet vidljiv (F(I)=0). Ukoliko su oba uslova ispunjena, štampa se O$(I) to jest ime predmeta. Ova naredba se ponavlja za svaki vidljiv predmet to jest G puta.

Ostaje još da se štampa eventualna poruka koja iskazuje reakciju računara na prethodni igračev postupak. Moguće je, naime, da računar nije bio u stanju da razume ili, u datim okolnostima, izvrši igračev nalog i da treba pružiti obaveštenje o tome. Moguće je, osim toga, da računar saopšti igraču ono što je pročitao u nekoj knjizi ili na nekoj cedulji. Sva ova komunikacija se obavlja pomoću promenljive M$. Pošto je, sa PRINT M$, štampana njena vrednost, računar izvršava M$="Šta?", naredbu koja će vam se u prvi mah učiniti čudnom. Malo dublje razmišljanje nas, međutim, uverava u korisnost ove naredbe: ostatku programa se nudi mogućnost da promeni sadržaj promenljive M$ (ukoliko ste sami kucali program, svakako se sećate toga da se većina naredbi završava sa M$="..."). Ukoliko ni jedna "sekcija" programa nije uspela da razume igračevu naredbu i promeni M$, naredba je bila sasvim nerazumljiva ili pogrešno otkucana čemu komentar "Šta" odlično pristaje.

Sledeća sekcija programa je izuzetno jednostavna: računar ispisuje "Šta da radim" a zatim igračev odgovor smešta u promenljivu Q$ primenom naredbe INPUT.

Faza do koje dolazimo je, za promenu, veoma složena i predstavlja srce čitavog programa: računar treba da analizira Q$, razdvoji je na imenicu i glagol a zatim da pronađe te reči u svome rečniku i kodira ih njihovim brojevima. Pošto nam je za sada cilj samo da shvatimo kako program radi u globalu, nećemo se više zadržavati na ovoj fazi; docnije ćemo joj posvetiti čitavo poglavlje.

Ukoliko se tokom analize pokazalo da instrukcija nema smisla, treba pripremiti poruku o tome i vratiti se na početak glavne petlje da bi se očekivala sledeća igračeva naredba. Ukoliko instrukcija izgleda logično (programeri bi rekli da je sintaksno ispravna ali da je njena semantika (značenje) i dalje pod znakom pitanja), računar izvršava potprogram koji će do kraja analizirati i eventualno izvršiti naredbu. Obzirom da svaka rečenica koju igrač otkuca treba da počne glagolom, najjednostavnije je čitavu sintaksnu analizu zasnovati na izdvajanju i numerisanju tog glagola brojem između 1 i 26 koji će čuvati promenljiva VB. Zatim ćemo izvršiti ON VB GOSUB n1, n2, ..., n26 gde je, na primer, sa n2 označen linijski broj bejzik naredbe koja tretira glagol čiji je broj u jeziku koji kreiramo 2.

Pošto je izvršena akcija koja se sastoji u promeni neke od promenljivih ili elemenata nizova i čiji rezultat sumira M$, kontrola se vraća glavnom programu koji proverava da li postoji neka izuzetno prioritetna poruka koju bi trebalo ispisati. Ukoliko, na primer, upalite sveću i nastavite da se krećete sa njom, promenljiva LL će biti umanjivana za 1 posle svakog vašeg poteza. Ukoliko je sveća blizu dogorevanja, računar će vas upozoriti na to. Ovo upozorenje se ne odnosi na vašu prethodnu akciju; ono je, kako bi rekli programeri, "sistemske prirode".

Na kraju preostaje samo da se izvrši jednostavna GOTO naredba koja ponovo započinje glavnu petlju. Glavna petlja je, dakle, neka vrsta procedure iz koje se izlazi jedino kada neki od potprograma (to je potprogram koji realizuje naredbu SKOR) detektuje kraj igre u kom slučaju biva izdata odgovarajuća poruka i izvršena naredba END. 'Zli dvorac' je avantura koja je prijateljski nastrojena prema korisniku pa ne postoji mogućnost da on usput pogine (premda treba primetiti da igrač može da zapadne u nevolju iz koje nema izlaza bez posedovanja nekog predmeta što je, na neki način, ekvivalentno sa smrtnim ishodom) ali i sami znate da u većini komercijalnih avantura postoji jedan pozitivan i mnoštvo "smrtnih" izlaza iz glavne petlje.

Analiza naredbe

Vraćamo se, kao što smo obećali, trenutku kada je igrač otkucao naredbu koja se sastoji od dve reči (u principu glagola i imenice) koje je računar zapamtio u promenljivoj Q$. Računar, najpre, treba da razdvoji alfanumerik Q$ na reči koje prepoznaje po praznom prostoru kojim su odvojene. To činimo naredbama:

10 V$="":W$=""
20 FOR I=1 TO LEN(Q$)
30 IF MID$(Q$,I,1)=" " AND V$="" THEN V$=LEFT$(Q$,I-1)
40 IF MID$(Q$,I+1,1)<>"" AND V$<>""THEN W$ = MID$(Q$,I+1,LEN(Q$)-1):I=LEN(Q$)
50 NEXT I
60 IF W$="" THEN V$=Q$

Naredba 30 pokušava da pronađe blanko simbol u alfanumeriku Q$. Ukoliko joj to uspe, promenljiva V$ dobija vrednost prve reči stringa. Potom računar traži prvi sledeći neprazan simbol (za slučaj da su reči odvojene sa nekoliko praznih mesta) i ostatak rečenice smešta u W$. Naredba 60 ima smisla u slučaju da je igrač otkucao samo jednu reč (npr. SKOR). U tom slučaju nije nađen blanko simbol pa ni V$ ni W$ nisu dobili nikakve vrednosti. Zahvaljujući, međutim, naredbi 60, čitava reč koju je igrač otkucao biva preneta u V$.

Sledi kodiranje (autori bejzik interpretatora bi rekli tokenizacija) igračeve naredbe. Potrebno nam je da oformimo promenljivu VB koja će sadržati redni broj glagola koji je otkucan i smešten u V$. Ništa lakše:

10 VB=0
20 FOR I=1 TO V
30 IF V$=V$(I) THEN VB=I
40 NEXT I

Program je toliko jednostavan da ga ne treba ni komentarisati. Pokušajte, ipak, da sebi dokažete da ste ga razumeli tako što ćete ga dopuniti programom koji izračunava broj objekta na listi i smešta ga u promenljivu OB.

Ukoliko u spisku reči koje računar poznaje nije pronađena ona koju je igrač otkucao, VB ili OB imaju vrednost nula. Ovakva situacija je dobra indicija za prijavljivanje greške ali treba primetiti da uspešno kodiranje još ne označava ispravnu konstrukciju: već smo rekli da ispravna sintaksa nužno ne povlači i ispravnu semantiku. Greške tipa "OTVORI SVEĆU" će biti otkrivene i prijavljene tek docnije.

Sa prijavljivanjem greški, reklo bi se, nema mnogo problema. Zahvaljujući malom triku koji smo primenili dodeljujući promenljivoj M$ vrednost "Šta?" na samom početku glavne petlje, bilo bi sasvim dovoljno da program prepozna sve ispravne situacije dok bi neprepoznavanje značilo da M$ ne treba menjati. Ovakvo razmišljanje, međutim, upravo pravi razliku između inventivnog i neinventivnog programera.

Loš program ima jednu ili samo nekoliko poruka o greškama dok dobar program prepoznaje svakakve situacije i prevazilazi ih. Svaki igrač će mnogo više voleti da mu računar, kada otkuca "Ponesi vrata" odvrati sa "Što ih ti ne poneseš?" umesto sa "Šta?"!

U 'Zlom dvorcu' se obavljaju razni testovi ulaznih podataka. Najpre računar ispituje da li je W$ veće a OB jednako nuli što označava da je igrač otkucao glagol bez imenice (ova situacija još ima šansi da se povoljno okonča ukoliko je otkucani "glagol" SKOR, UPOMOC ili INVENTAR ali računar za sada evidentira potencijalnu grešku komentarom GLUPO koji ne mora nužno biti prikazan). Testira se, zatim, i da li je nepoznat glagol praćen imenicom sa liste u kom slučaju biva štampano nešto poput "Ne mogu da..." praćeno rečenicom smeštenom u Q$. Na kraju sekcije testova računar izvšava IF VB=0 THEN VB=V+1. Ova naredba predstavlja neku vrstu sigurnosnog ventila ali samo za neke računare. Ukoliko VB ima vrednost nula, naredba ON VB GOSUB će izazvati nastavak rada ili ON RANGE grešku (zavisno od kompjutera). Zato smo predvideli jedan nepostojeći glagol čiji je broj V+1 i koji upućuje program na "praznu" naredbu RETURN.

Kada je sve provereno, naredba ON VB GOSUB izvršava jedan od potprograma kojim se realizuju naredbe. U okviru tog potprograma biva kompletirana analiza ulaznih podataka a zatim se nalog izvršava ili biva izdata poruka o grešci. U okviru ovih potprograma treba primetiti mnogobrojne logičke funkcije AND, OR i NOT koje su kao stvorene za ovakve primene.

Već smo pominjali situacije u kojima je nastupio neki nepredviđeni događaj koji zahteva trenutnu pažnju igrača. Ukoliko se, na primer, nađemo u gornjoj kuli, postoji velika šansa da nas napadnu šišmiši. U tom slučaju čak i valjane naredbe bivaju stalno odbijane sve dok ne ne uništimo dosadne šišmiše. Možete li da zamislite još neku zagonetku ovoga tipa kojom biste dopunili 'Zli dvorac'?

Kretanje po dvorcu

Ostalo nam je još da objasnimo deo programa koji omogućava kretanje po dvorcu i okolini. Kretanje na sever možemo, kao što znamo, da ostvarimo kako sa IDI NA SEVER tako i kucanjem običnog N. Pokušaćemo da objasnimo kako radi deo programa koji čine linije 750-1080.

Najpre se promenljivoj D dodeljuje vrednost koja odgovara pravcu kretanja koji je igrač izabrao (1 za sever, 2 za jug, 3 za zapad, 4 za istok, 5 za gore i 6 za dole). Linija 760 to radi u slučaju da je igrač otkucao samo jedno slovo (N, S, W, E, U ili D) dok sledećih 6 linija rešavaju slučaj kada su otkucane tri reči (npr. 'idi na sever'). Linije 830-880 su, na neki način, veštački dodane i tretiraju igračevo kretanje gore odnosno dole na paru postojećih stepenica. Ova kretanja se, kao što vidimo, svode na obično kretanje na neku od strana sveta.

Linije 890-960 tretiraju neke specijalne situacije u kojima računar treba da onemogući igračevo kretanje. To kretanje mogu da spreče duhovi, magična barijera, živi pecak u močvari, mračni predeli i težak čamac koji možemo da nosimo samo kratko vreme.

Ukoliko je sve u redu, računar treba da promeni igračevu lokaciju. Taj posao obavljaju linije 970-1040. Analizira se R$(RM), string koji, kao što znamo, sadrži sve moguće pravce kretanja. Ukoliko je pravac kretanja moguć, promenljiva RM dobija novu vrednost i fleg 35 biva postavljen na vrednost 1. Na samom kraju (linija 1050) računar proverava da li je fleg 35 setovan; ukoliko nije, igrač je tražio kretanje u nemogućem pravcu i treba izdati poruku 'Tuda ne mogu'. Linija 1070, najzad, za sva vremena zatvara ulazna vrata kada igrač jednom prođe kroz njih. Izlaz iz kuće je moguć kroz dvorišna vrata, zatrpani prozor i primenom čarolije.

Modifikacije programa

Kada ste razumeli kako 'Zli dvorac' radi, možete da ga modifikujete i učinite jednostavnijim ili složenijim; pojednostavljenju ćete, jasno, pristupiti ako vaš kompjuter nema dovoljno memorije da primi program u sadašnjem obliku.

Vlasnici ZX Spectruma moraju da modifikuju program da bi uopšte mogao da funkcioniše. Potrebno je, najpre, dodati LET ispred svake naredbe dodeljivanja što kod Microsoft-ovog bejzika nije nužno. Zatim treba sve alfanumerike u DATA listama (linije iza 1810) omeđiti navodnicima (npr. 1810 DATA "upomoc", "inventar", "idi"...). Otkucajte, najzad, sve programske linije sa slike 7 kojima zamenjujete neke linije glavnog programa. Treba primetiti da je organizacija nizova unekoliko promenjena pošto kod Spectruma indeksi nizova počinju od 1 a ne od nule.

Kako otežati igru...

Klasično otežanje igre je uvođenje vremenskog limita. Možete, na primer, da zahtevate da igrač završi posao do ponoći jer se tada dešavaju grozne stvari. Posle svakoga poteza treba, jednostavno, smanjiti vrednost nekog brojača i ispitati da li je on došao do nule; sličan princip je primenjen i kod dogorevanja sveće.

Možete, zatim, da ograničite broj predmeta koje igrač sme da nosi. Pokušajte da isplanirate ovo ograničenje tako da zadatak može da se obavi samo na jedan način ali se potrudite da rešenje bude moguće!

Uvedite, zatim, veoma redak događaj (primenom naredbe RND) koji "baca" igrača na neko zabačeno mesto u zamku i lišava ga nekih predmeta koje skriva na stara ili neka nova mesta. Možete da dodate i zatvorske ćelije koje zadržavaju igrača izvesno vreme pod pretnjom oduzimanja nekih dragocenih predmeta. Ima, naravno, mesta i za dodavanje drugih stanovnika zamka i problema sa njima.

Unapredite sistem bodovanja tako da dragoceniji predmeti donose više poena kao i kazne koje se sastoje od oduzimanja poena u nekim situacijama. U poslednjem slučaju je potrebno obezbediti način na koji igrač može da "zaradi" oduzete poene i završi igru.

Dodajte, najzad, mogućnost da se u nekom trenutku situacija (sadržaji nizova i promenljivih) snimi na traku kako bi se igra sutradan nastavila. Rešavanje ovoga problema može korisno da posluži kao motivacija za upoznavanje načina na koji vaš kompjuter opšti sa kasetofonom!

Na slici 8 je, najzad, dato nekoliko naredbi koje dodaju ton u raznim situacijama. Avanturu ćete učiniti daleko interesantnijom ukoliko dodate neke grafičke efekte.

 

horizontal rule

 

Mapa 'Zlog dvorca' sa upisanim dragocenostima

1. Dragocena slika (čuva je magična barijera i zaključana vrata)

2. Dijamantski prsten (skriven u mrtvačkom sanduku)

3. Knjiga sa čarolijama (sakrivena u tajnoj sobi iza lažnog zida)

4. Zlatni pehar (nalazi se iza zaključanih vrata a čuva ga parališućih duh)

5. Magični zamotuljak (čuvaju ga šišmiši)

6. Vrećica sa zlatnim novčićima (sakrivena u mraku)

7. Statua od ebonovine (sakrivena u mraku)

8. Zlatni svećnjak

 

horizontal rule

 

Problemi i rešenja

Problem         
Rešenje         
Potrebni objekti         
Previše mračno         
Upali sveću         
Sveća, svećnjak, šibice         
Napadaju šišmiši         
Pošpricaj šišmiše         
Superbum sprej         
Tajna soba         
Probij lažni zid         
Sekira         
Zaključna vrata         
Otključaj ih         
Ključ         
Parališući duh         
Usisaj ga         
Usisivač, baterije         
Magična barijera         
Kaži magičnu reč         
Magična cedulja         
Močvara         
Uzmi čamac         
Čamac         
Zatrpani prozor         
Iskopaj rupu         
Lopata         
Mrtvački sanduk         
Otvori ga         
-         

 

horizontal rule

Rečnik igre

Br. Glagol Imenice Značenje
0 - - Glagol nije pronađen
1 upomoc - Prikazuje rečnik
2 inventar - Predmeti koje igrač nosi
3 idi strane sveta Kretanje
4 n - Kretanje na sever
5 s - Kretanje na jug
6 w - Kretanje na zapad
7 e - Kretanje na istok
8 u - Kretanje uz stepenice
9 d - Kretanje niz stepenice
10 uzmi predmeti Uzimanje vidljivog predmeta
11 digni predmeti Sinonim za uzmi
12 ispitaj bilo šta Ispitivanje osobina predmeta
13 otvori vrata, fioka Očigledno
14 pročitaj knjige, cedulja, zamotuljak Prikazivanje tajnih poruka
15 kaži bilo šta Očigledno
16 kopaj rupa Očigledno
17 upotrebi lopata, konopac Probijanje zida ili vešanje
18 popni se - Penjanje uz konopac
19 upali sveća Očigledno
20 ugasi sveća Očigledno
21 pošpricaj šišmiši Ubijanje insekata superbumom
22 uključi usisivač Usisavanje duhova
23 otključaj vrata Očigledno
24 baci predmeti Ostavljanje objekta
25 skor - Prikazivanje skora
26 sidji - Silaženje niz konopac

 

horizontal rule

Listing programa

[napomena: Zli dvorac je pisan i testiran na Acorn BBC B računaru. Verzija koja sledi je neznatno promenjena tako da se uspešno prevodi i na PC-ju, korišćenjem GWBASIC-a ili QBASIC-a. PC verzija nije detaljno testirana, tako da se može desiti da u nekoj grani programa naiđete na problem, ali će se on verovatno lako rešiti sitnom sintaksnom izmenom naredbe. Alternativno, možete da pokušate sa već prevedenim programom koji ćete preuzeti klikom ovde.

10 REM
20 REM
30 REM
40 REM  *************************
50 REM  *       Zli dvorac      *
60 REM  *************************
70 REM
80 REM
90 REM  "Racunari u vasoj kuci" 3
100 REM
110 REM
120 REM prema programu 'Haunted House'
130 REM  Jenny Tyler i Lesa Howartha
140 REM
150 REM    Dejan Ristanovic 1984.
160 REM
170 V = 26: W = 36: G = 18
171 DIM R$(63), D$(63), O$(W), V$(V)
172 DIM C(W), L(G), F(W)
180 GOSUB 1742
190 CLS : PRINT "Zli Dvorac"
200 PRINT "----------"
210 PRINT "Nalazim se"
220 PRINT D$(RM)
230 PRINT "Pravci kretanja:";
240 FOR I = 1 TO LEN(R$(RM))
250 PRINT MID$(R$(RM), I, 1); ",";
260 NEXT I
270 PRINT
280 FOR I = 1 TO G
290 IF L(I) = RM AND F(I) = 0 THEN PRINT "Vidim "; O$(I); "."
300 NEXT I
310 PRINT "========================="
320 PRINT M$: M$ = "Sta?"
330 INPUT "Sta da radim"; Q$
340 V$ = "": W$ = "": VB = 0: OB = 0
350 FOR I = 1 TO LEN(Q$)
360 IF MID$(Q$, I, 1) = " " AND V$ = "" THEN V$ = LEFT$(Q$, I - 1)
370 IF MID$(Q$, I + 1, I) <> " " AND V$ <> "" THEN W$ = MID$(Q$, I + 1, LEN(Q$) - 1): I = LEN(Q$)
380 NEXT I
390 IF W$ = "" THEN V$ = Q$
400 FOR I = 1 TO V
410 IF V$ = V$(I) THEN VB = I
420 NEXT I
430 IF W$ = "se" OR VB = 26 THEN W$ = "konopac": OB = 14: GOTO 470
440 FOR I = 1 TO W
450 IF W$ = O$(I) THEN LET OB = I
460 NEXT I
470 IF W$ > "" AND OB = 0 THEN M$ = "Glupo!"
480 IF VB = 0 THEN VB = V + 1
490 IF W$ = "" THEN M$ = "Recenica obicno ima subjekat i predikat"
500 IF VB > V AND OB > 0 THEN M$ = Q$ + " ti!"
510 IF VB > V AND OB = 0 THEN M$ = "Ne radim besmislice!"
520 IF VB < V AND OB> 0 AND C(OB) = 0 THEN M$ = "Nemam " + W$
530 IF F(26) = 1 AND RM = 13 AND VB <> 21 AND VB > 2 THEN M$ = "Napadaju sismisi!": GOTO 190
540 IF RM = 44 AND RND(2) = 1 AND F(24) <> 1 THEN F(27) = 1
550 IF F(0) = 1 THEN LL = LL - 1
560 IF LL < 1 THEN F(0)="0" 570 ON VB GOSUB 610, 680, 750, 750, 750, 750, 750, 750, 750, 1090, 1090, 1150, 1190, 1260, 1300, 1340, 1370, 1420, 1470, 1520, 1540, 1570, 1600, 1630, 1650, 1450, 1740 580 IF LL="10" THEN M$="Sveca mi dogoreva!" 590 IF LL="1" THEN LL="0:" M$="Sveca je izgorela!" : F(0)="0" 600 GOTO 190 602 REM naredba 'upomoc' 610 PRINT "Znam sledece reci:" 620 FOR I="1" TO V 630 PRINT V$(I); ","; 640 NEXT I 650 M$ : PRINT 660 GOSUB 1730 670 RETURN 672 REM naredba 'inventar' 680 PRINT "Nosim:" 690 FOR I="1" TO G 700 IF C(I)="1" THEN PRINT O$(I); ","; 710 NEXT I 720 M$ : PRINT 730 GOSUB 1730 740 RETURN 742 REM naredbe za kretanje 750 D="0" 760 IF OB="0" THEN D="VB" 3 770 IF OB="19" THEN D="1" 780 IF OB="20" THEN D="2" 790 IF OB="21" THEN D="3" 800 IF OB="22" THEN D="4" 810 IF OB="23" THEN D="5" 820 IF OB="24" THEN D="6" 830 IF RM="20" AND D="5" THEN D="1" 840 IF RM="20" AND D="6" THEN D="3" 850 IF RM="22" AND D="6" THEN D="2" 860 IF RM="22" AND D="5" THEN D="3" 870 IF RM="36" AND D="6" THEN D="1" 880 IF RM="36" AND D="5" THEN D="2" 890 IF F(14)="1" THEN M$="Bup!!! Pao sam sa drveta!" : F(14)="0:" RETURN 900 IF F(27)="1" AND RM="52" THEN M$="Duhovi mi ne daju da mrdnem!" : RETURN 910 IF RM="45" AND C(1)="1" AND F(34)="0" THEN M$="Osecam magicnu barijeru na zapadu" : RETURN 920 IF (RM="26" AND F(0)="0)" AND (D="1" OR D="4)" THEN M$="Sasvim je mracno" : RETURN 930 IF RM="54" AND C(15) <> 1 THEN M$ = "Zaglibio sam se": RETURN
940 IF C(15) = 1 AND NOT (RM = 53 OR RM = 54 OR RM = 55 OR RM = 47) THEN M$ = "Sad malo ti nosi camac!": RETURN
950 IF (RM > 26 AND RM < 30) AND F(0)="0" THEN M$="Ja u mrak ne idem!" : RETURN 960 F(35)="0:" RL="LEN(R$(RM))" 970 FOR I="1" TO RL 980 U$="MID$(R$(RM)," I, 1) 990 IF (U$="N" AND D="1" AND F(35)="0)" THEN RM="RM" 8: F(35)="1" 1000 IF (U$="S" AND D="2" AND F(35)="0)" THEN RM="RM" + 8: F(35)="1" 1010 IF (U$="W" AND D="3" AND F(35)="0)" THEN RM="RM" 1: F(35)="1" 1020 IF (U$="E" AND D="4" AND F(35)="0)" THEN RM="RM" + 1: F(35)="1" 1030 NEXT I 1040 M$="O.K." 1050 IF F(35)="0" THEN M$="Tuda ne mogu!" 1060 IF D < 1 THEN M$="Kud' da idem?" 1070 IF RM="41" AND F(23)="1" THEN R$(49)="SW" : M$="Vrata su se zalupila" : F(23)="0" 1080 RETURN 1082 REM naredba 'uzmi' 1090 IF OB> G THEN M$ = "Ne mogu da uzmem " + W$: RETURN
1100 IF L(OB) <> RM THEN M$ = "A gde je?"
1110 IF F(OB) <> 0 THEN M$ = "Koji " + W$ + "?"
1120 IF C(OB) = 1 THEN M$ = "Vec ga imam!"
1130 IF OB > 0 AND L(OB) = RM AND F(OB) = 0 THEN C(OB) = 1: L(OB) = 65: M$ = "Imam " + W$
1140 RETURN
1142 REM  naredba 'otvori'
1150 IF RM = 43 AND (OB = 28 OR OB = 29) THEN F(17) = 0: M$ = "Otvorio sam fioku"
1160 IF RM = 28 AND OB = 25 THEN M$ = "Zakljucano!"
1170 IF RM = 38 AND OB = 32 THEN M$ = "Bas je uzasno!": F(2) = 0
1180 RETURN
1182 REM  naredba 'ispitaj'
1190 IF OB = 30 THEN F(18) = 0: M$ = "Nesto je tu!!!"
1200 IF OB = 31 THEN M$ = "Odvratno mi je."
1210 IF (OB = 28 OR OB = 29) THEN M$ = "Vidim fioku"
1220 IF OB = 33 OR OB = 5 THEN GOSUB 1260
1230 IF RM = 43 AND OB = 35 THEN M$ = "Ima nesto ispod..."
1240 IF OB = 32 THEN GOSUB 1150
1250 RETURN
1252 REM  naredba 'procitaj'
1260 IF RM = 42 AND OB = 33 THEN M$ = "To su demonske reci!"
1270 IF (OB = 3 OR OB = 36) AND C(3) = 1 AND F(34) = 0 THEN M$ = "Tajanstvena magicna rec je XZANFAR."
1280 IF C(5) = 1 AND OB = 5 THEN M$ = "Napis je na stranom jeziku."
1290 RETURN
1292 REM  naredba 'kazi'
1300 M$ = "O.K. '" + W$ + "'"
1310 IF C(3) = 1 AND OB = 34 THEN M$ = "** CAROLIJA **": IF RM <> 45 THEN RM = RND(63)
1320 IF C(3) = 1 AND OB = 34 AND RM = 45 THEN F(34) = 1
1330 RETURN
1332 REM  naredba 'kopaj'
1340 IF C(12) = 1 THEN M$ = "Nisam ja destruktivac!"
1350 IF C(12) = 1 AND RM = 30 THEN M$ = "Iscupao sam gomilu greda": D$(RM) = "Kraj otvora u zidu": R$(RM) = "NSE"
1360 RETURN
1362 REM  naredba 'upotrebi'
1370 IF C(14) <> 1 AND RM = 7 THEN M$ = "Nije vreme za igru!!"
1380 IF OB = 14 AND C(14) = 1 THEN PRINT : INPUT "Obesio sam se... To je kraj!"; X$: RUN
1390 IF OB = 13 AND C(13) = 1 THEN M$ = "WHUUSH"
1400 IF OB = 13 AND C(13) = 1 AND RM = 43 THEN R$(RM) = "WN": D$(RM) = "U radnoj sobi sa skrivenim separeom": M$ = "Probio sam tanki zid."
1410 RETURN
1412 REM  naredba 'popni se'
1420 IF OB = 14 AND C(14) = 1 THEN M$ = "Nije pricvrsceno!"
1430 IF OB = 14 AND C(14) <> 1 AND RM = 7 AND F(14) = 0 THEN M$ = "Vidim sumu i liticu na jugu": F(14) = 1: RETURN
1440 RETURN
1442 REM  naredba 'sidji'
1450 IF OB = 14 AND C(14) <> 1 AND RM = 7 AND F(14) = 1 THEN M$ = "Idem dole.": F(14) = 0
1460 RETURN
1462 REM  naredba 'upali'
1470 IF OB = 17 AND C(17) = 1 AND C(8) = 0 THEN M$ = "Opeci cu se!"
1480 IF OB = 17 AND C(17) = 1 AND C(8) = 0 THEN M$ = "Cime da je upalim?"
1490 IF OB = 17 AND C(17) = 1 AND C(9) = 1 AND C(8) = 1 AND LL = 0 THEN M$ = "Izgorela je!"
1500 IF OB = 17 AND C(17) = 1 AND C(9) = 1 AND C(8) = 1 AND LL > 1 THEN M$ = "Jeste da zmirka ali bar svetli!": F(0) = 1
1510 RETURN
1512 REM  naredba 'ugasi'
1520 IF F(0) = 1 THEN F(0) = 0: M$ = "Ugasena je."
1530 RETURN
1532 REM  naredba 'pospricaj'
1540 IF OB = 26 AND C(16) = 1 THEN M$ = "Hssssss"
1550 IF OB = 26 AND C(16) = 1 AND F(26) = 1 AND RM = 13 THEN F(26) = 0: M$ = "PFFT! Gotovi su!"
1560 RETURN
1562 REM  naredba 'ukljuci'
1570 IF OB = 10 AND C(10) = 1 AND C(11) = 1 THEN M$ = "Ukljucen je.": F(24) = 1
1580 IF F(27) = 1 AND F(24) = 1 THEN M$ = "Usisao sam duhove.": F(27) = 0
1590 RETURN
1592 REM  naredba 'otvori'
1600 IF RM = 43 AND (OB = 27 OR OB = 28) THEN GOSUB 1150
1610 IF RM = 28 AND OB = 25 AND F(25) = 0 AND C(18) = 1 THEN F(25) = 1: R$(RM) = "SEW": D$(RM) = "Kraj velikih otvorenih vrata": M$ = "Kljuc se okrece."
1620 RETURN
1622 REM  naredba 'baci'
1630 IF C(OB) = 1 THEN C(OB) = 0: L(OB) = RM: M$ = "Izvrseno!"
1640 RETURN
1642 REM  naredba 'skor'
1650 M$ = ""
1660 S = 0
1670 FOR I = 1 TO 8
1680 IF C(I) = 1 THEN S = S + 1
1690 NEXT I
1700 IF S = 8 AND C(15) <> 1 AND RM <> 57 THEN PRINT : PRINT "Prikupio sam sve!": PRINT "Treba jos da izadjem..."
1710 IF S = 8 AND RM = 57 THEN PRINT "Dolazak ovde duplira skor!": S = S * 2
1720 PRINT "Skor je "; S: IF S > 9 THEN PRINT : PRINT "B R A V O. Avantura je zavrsena!": END
1730 PRINT : PRINT : INPUT "Pritisni RETURN za nastavak"; Q$
1740 RETURN
1742 REM  inicijalizacija nizova
1770 DATA 46,38,35,50,13,18,28,42,10,25,26,4,2,7,47,60,43,32
1780 FOR I = 1 TO G
1790 READ L(I)
1800 NEXT I
1810 DATA upomoc,inventar,idi,n,s,w,e,u,d,uzmi,digni,otvori,ispitaj,procitaj,kazi,kopaj,upotrebi,popni,upali,ugasi,pospricaj,ukljuci,otkljucaj,baci,skor,sidji
1820 FOR I = 1 TO V
1830 READ V$(I)
1840 NEXT I
1850 DATA SE,WE,WE,SWE,WE,WE,SWE,WS
1860 DATA NS,SE,WE,NW,SE,W,NE,NSW
1870 DATA NS,NS,SE,WE,NWUD,SE,WSUD,NS
1880 DATA N,NS,NSE,WE,WE,NSW,NS,NS
1890 DATA S,NSE,NSW,S,NSUD,N,N,NS
1900 DATA NE,NW,NE,W,NSE,WE,W,NS
1910 DATA SE,NSW,E,WE,NW,S,SW,NW
1920 DATA NE,NWE,WE,WE,WE,NWE,NWE,W
1930 FOR I = 0 TO 63
1940 READ R$(I)
1950 NEXT I
1960 DATA u tamnom uglu,u zapustenoj basti,kraj velike gomile drva,u dvoristu kraj otpadaka
1970 DATA na gradilistu,u sumi,u gustoj sumi,kod suvog drveta
1980 DATA na uglu kuce,na ulazu u kuhinju,u kuhinji,u perionici sudova
1990 DATA u sobi punoj prasine,sa zadnje strane kule,na cistini kraj kuce,na puticu
2000 DATA uz zid kuce,iza trema,u tamnom alkovu,u mracnoj sobici
2010 DATA na dnu spiralnih stepenica,u sirokom prolazu,kraj klizavih stepenica,na vrhu grebena
2020 DATA blizu srusenog zida,u sumornom prolazu,u kucnoj elektricnoj centrali,u svecanom hodniku
2030 DATA kraj okovanih drvenih vrata,u svecanoj sali,u podrumu sa zatrpanim prozorom,na putu ka litici
2040 DATA kraj eksera na kome visi kaput,ulaznom holu,u dnevnoj sobi,u tajnom sobicku
2050 DATA kraj strmih mramornih stepenica,u trpezariji,u dubokom podrumu s mrtvackim sandukom,na putu ka litici
2060 DATA u ormanu,u predvorju,u biblioteci sa zlim knjigama,radnoj sobi sa stolom i rupom u zidu
2070 DATA u zlokobnoj sobi punoj paucine,u ledenom prolazu,u avetinjskoj sobi,na strmom putu kraj mocvare
2080 DATA na verandi punoj komadica stakla,pred glavnim ulazom,u prednjem tornju,u vlaznom hodniku
2090 DATA na gornjoj galeriji,na mocvarnoj strani zida,u mocvari,na raskvasenoj stazi
2100 DATA na krivini,na putu ka gvozdenim vratima,na putu,ispod prednjeg tornja
2110 DATA kod gomile opalog maltera,kod velikog odronjenog kamena,pokraj propalog svoda,na uglu sveta
2120 FOR I = 0 TO 63
2130 READ D$(I)
2140 NEXT I
2150 DATA sliku,prsten,magicnu cedulju,pehar,zamotuljak,novcice,kip,svecnjak
2160 DATA sibice,usisivac,baterije,lopatu,sekiru,konopac,camac,superbum,svecu,kljuc
2170 DATA na sever,na jug,na zapad,na istok,gore,dole
2180 DATA vrata,sismise,avet,fioku,sto,kaput,otpatke
2190 DATA sanduk,knjige,xzanfar,zid,caroliju
2200 FOR I = 1 TO W
2210 READ O$(I)
2220 NEXT I
2230 F(18) = 1: F(17) = 1: F(2) = 1: F(26) = 1: F(28) = 1: F(23) = 1: LL = 60: RM = 57: M$ = "O.K."
2240 RETURN
2260 REM Dejan Ristanovic 1984.

horizontal rule