Tech Filet

Kuten pelitkin, nämä tech filet olivat Suomipelit.comissa sivuston sulkeuduttua. Näin ollen niihin saattaa sisältyä epämääräisiä viitteitä asioihin, joita ei enää ole olemassa, ja joskus jokin saattaa näkyä väärin. Pahoitteluni.

Tech filet olivat yksittäisten kirjoittajien kirjoittamia, vähän blogimaisempia tekstejä, joiden tarkoitus oli esimerkiksi kertoa projektien etenemisestä, tai opettaa jotain yksittäisiä ohjelmointiin liittyviä asioita.

Palaa tech file -listaan

Parserin suunnittelua

13.10.2002 14:28 julkaistun artikkelin on kirjoittanut Lauri.

Tällä kertaa asiaa ei ole aivan niin paljon kuin viimeksi, mutta jotain kuitenkin. Käsittelen tässä päivityksessä siis lähinnä parserin tekemistä, kuten jo viime kerralla lupasin.

Ammattikorkeakoulussa olen oppinut sellaisen ajattelutavan, että suunnitteleminen on helpompaa, kun ensin tietää, mitä työkaluja on käytettävissä toteutukseen. Esimerkiksi ohjelman suunnittelu on helpompaa, kun ensin osaa ohjelmointikielen. Tämän takia AMK:ssa käydään ensin ohjelmoinnin peruskurssi, jolla opiskellaan C-kielen perusteet ja myöhemmin vasta keskitytään ohjelman suunnitteluun. Toki suunnittelun tärkeyttä alusta asti korostetaan, mutta tällä käytännönläheisellä järjestyksellä erotutaan yliopistosta, jossa ohjelmoinnin opiskelu aloitetaan kokonaan suunnittelusta. Itse olen huomannut tämän käytännönläheisemmän järjestyksen toimivaksi ja siksi aloitinkin parserin tekemisen ottamalla ensin selvää (kokeilemalla käytännössä), mitä toteutukseen tarvitsee ja loin tarvittavat työkalut toteutusta varten. Kun toteutuksesta oli jo jonkinlainen kuva, oli suunnittelu paljon helpompaa.

Niinpä ensin koodasin todella yksinkertaisen koodinpätkän, n. 30 riviä, joka luki annetun komennon sanoiksi, etsi sanoja vastaavan verbin sekä substantiivin ja tulosti ruudulle verbiin tallennetun vastauksen. Tämän prosessin aikana huomasin, että jotkin verbi- ja tavaraluokkien palautuksista eivät olleet oikein tarkoitukseen sopivia, joten muutin niitä hiukan erilaisiksi kuin olin alunperin suunnitellut. Tein myös valmiiksi muutamat tärkeät tulostukseen liittyvät funktiot. Yksi näistä funktioista liittyi vastauksessa olevien parametrien korvaamiseen niitä vastaavalla tiedolla. Tästä esivalmistelusta on siis se hyöty, että siinä vaiheessa, kun alan toteuttamaan parseria sunnitelman mukaiseksi, voin keskittyä olennaiseen, eikä minun tarvitse enää miettiä muita epäolennaisempia asioita.

Tämän jälkeen sitten aloinkin suunnittelemaan paperille parserin silmukkaa, mitä kaikkea siihen tarvitaan ja missä järjestyksessä asiat kannattaa hoitaa. Tässä karkea versio alustavasta pelisilmukasta sellaisena, kuin se tällä hetkellä on suunniteltuna:

1. Luetaan ja tutkitaan syötetty komento (verbit,substantiivit, yms.)
2. Tutkitaan onko komento mahdollista suorittaa.
- a) tutkitaan ensin repusta (inventory), onko siellä tarvittavaa tavaraa.
- b) jos ei, niin tutkitaan sitten onko sitä nykyisessä huoneessa.
3. Jos suorittaminen on mahdollista, niin tutkitaan mitä komento tekee (skriptit) ja suoritetaan komento.
- a) tutkitaan ensin onko kyseiselle komennolle (tietty verbi+substantiivi) erikoistapausta.
- b) jos ei ole erikoistapauksia, käytetään verbin perusskriptiä
4. Lopuksi etsitään komennolle oikea vastaus.
- a) Taas tutkitaan ensin erikoistapaukset
- b) ja sitten perusvastaukset.
5. Jos komento ei jostain syystä toimi (sille ei löydetty merkitystä tai tarvittavaa tavara ei löytynyt), vastataan pelaajalle sen mukaan.

Testatakseni silmukan toimivuutta, loin kuvitellun pelitilanteen ja kirjoitin paperille kohta kohdalta, mitä milloinkin tapahtuu ja miten peli etenee. Silmukka tuntui toimivalta, mutta tämän kaltainen testaus toi yllättäen esiin monia sellaisia asioita, joita en ollut tullut aikaisemmin edes ajatelleeksi. Huomasin esimerkiksi, että joihinkin komentoihin tarvitaan kaksi substantiivia, eikä yksi riitäkään. Komento joka testauksessa tuli esille, oli "Laita polttopuut takkaan". Tarvitaan siis erikseen kohde, johon komento kohdistuu, tässä tapauksessa siis takka. Huomasin myös sellaisen asian, että tavaroita voi huoneessa olla monen tyyppisiä. Kaikkia huoneissa olevista tavaroista pelaaja ei voi ottaa mukaansa. Takka on juuri tällainen. Sitä voi kyllä käyttää ("sytytä takka"), mutta sen kuitenkin on pysyttävä kiinteästi paikoillaan. Toinen tavaratyyppi on sellaiset tavarat, joita on iso kasa. Olkoon esimerkkinä nyt vaikka kivikasa. Siitä voi ottaa kiven, mutta kasa ei sen seurauksena kuitenkaan katoa mihinkään. Eli käytännössä kiviä on kasassa loputtomasti.

Mielenkiintoinen ongelma, joka ensimmäisenä parserin toteutuksessa tuli vastaan, oli ääkköset. Konsolissa, jossa peli tällä hetkellä toimii, on nimittäin käytössä eri ASCII-koodit ääkkösille, kuin kääntäjässä ja notepadin tekstiformaatissa. Niinpä ääkkösiä tulostaessa konsoliin ne näyttävät vain oudoilta erikoismerkeiltä ja toisin päin konsolista luettaessa ääkköset tulevat kääntäjälle kummallisina erikoismerkkeinä. Tämä taas johtaa siihen, ettei sanojen etsiminen toimi, kun syötteissä on eri ääkköset kuin peliin ladatuissa sanoissa. Ratkaisin ongelman lopulta niin, että aina kun käyttäjä konsolista syöttää tekstiä, syöte käydään lävitse ja kaikki ä:t ja ö:t muutetaan kääntäjän ASCII-formaattiin ja kun taas konsoliin tulostetaan jotain, niin sen ääkköset muutetaan ennen tulostusta konsolin formaattiin. Kulutin paljon aikaa järkevämmän ja yksinkertaisemman ratkaisun löytämiseksi, mutta lopulta päätin luovuttaa ja pysyä omassa ratkaisussani, kun en löytänyt mitään ja oma ratkaisuni kuitenkin toimii.

Tuolla keskustelualueella on tullut monenlaista ideaa ja kommenttia tekstiseikkailuista. Kiitoksia niistä! Yritän parhaani mukaan saada niitä toteutettua. Kuitenkin seuraava iso homma, jota ryhdyn tekemään, onkin sitten skriptien lataaminen ja tulkitseminen. Se on pelin etenemisen kannalta ehkä tärkein alue, koska kaikki mitä pelissä tapahtuu, pohjautuu lähes kokonaan skripteihin. Eli kerron siitä sitten seuraavassa päivityksessä.