Tampereen teknillinen yliopisto Ohjelmistotekniikan laitos OHJ1160 Laaja Ohjelmointi 2 Harjoitustyö Avaruusseikkailu 2001 + 11 Nyyti Kinnunen 222500 kinnune8 nyyti.kinnunen@tut.fi 1
1 Ohjelman rakenne 1.1 Ohjelman tietorakenteet Ohjelma tallentaa kartan yksiulotteiseen Aurinkokunta vektoriin. Jokainen vektorin alkio vastaa yhtä aurinkokuntaa. vector <Aurinkokunta*> aurinkokunnat; Ohjelma tallentaa pelaajat yksiulotteiseen Pelaaja vektoriin. Jokainen vektorin alkio vastaa yhtä pelaajaa. vector <Pelaaja*> pelaajat; 1.2 Funktioiden kutsukaavio 2
2 Moduulit 2.1 Pääohjelma Pääohjelma huolehtii pelin pyörimisestä. Pelin alussa luodaan Peli joka sisältää itse pelin. Tämän jälkeen kutsutaan funktiota alustus, joka alustaa pelin. Ennen jokaista kierrosta kutsutaan funktioita loppunut ja pattitilanne. Mikäli pelaaja voi pelata vuoronsa, kutsutaan kierros funktiota, joka huolehtii vuorosta. Kutsuu Peliluokan funktioita loppuiko, pattitilanne, alustus ja vuoro. 2.2 Luokka Peli 2.2.1 Luokan kuvaus Peli luokka pitää sisällään kaikki peliin liittyvät muuttujat, funktiot ja luokat. 2.2.2 Rajapinta vector<pelaaja*> pelaajat: Pelissä olevat pelaajat vector<aurinkokunta*> aurinkokunnat: Pelissä olevat aurinkokunnat unsigned int vuorossa: vuorossa olevan pelaajan paikka pelaajat vektorissa ifstream fin: Alustustiedosto string alustustiedosto: Alustustiedoston nimi Komentotulkki tulkki: Pelin käyttämä komentotulkki unsigned int x: Galaksin leveys unsigned int y: Galaksin korkeus string tagi_avaus: Alustustiedostosta luettava avaustagi string tagi_lopetus: Alustustiedostosta luettava lopetustagi int pelaajat_maara: Pelissä olevien pelaajien määrä pelin alussa static const int TYHJA_ASCII = 32: ASCII arvo välilyönnille static const int TAB_ASCII = 9: ASCII arvo tabille 2.2.3 Funktio: alustus bool alustus(); true: Alustus onnistui false: Alustus epäonnistui Kutsuu funktioita jotka lukevat alustustiedoston ja alustavat pelin. Käytetään pelin alustamiseen Kutsutaan ennen pelin alkua mainista. 3
2.2.4 Funktio: loppuiko bool loppuiko(); true: Peli loppui. false: Peli ei loppunut. Tarkistaa, onko peli loppunut. Peli loppuu mikäli kaikki planeetat on asutettu, pelissä on vain yksi pelaaja, pelaaja syöttää lopeta komennon tai syöte loppuu. Tarkastaa loppuiko peli. Kutsutaan pääohjelmasta ennen jokaista vuoroa. 2.2.5 Funktio: pattitilanne bool pattitilanne(); true: Pelaaja on pattitilanteessa. false: Pelaaja ei ole pattitilanteessa. Tarkastaa voiko pelaaja tehdä vuoroa kuluttavaa toimintoa. Mikäli voi, tulee pelaajan vuoro normalisti. Muuten pelaaja poistetaan pelistä. Tarkastaa onko pelaaja pattitilanteessa. 2.2.6 Funktio: vuoro void vuoro(); void Hoitaa pelaajan vuoron. Kutsuu komentotulkkia, joka palauttaa käyttäjän antaman komennon ja parametrit. Komennon perusteella kutsutaan funktioita. Päivittää vuorossa olevaa pelaajaa. Kutsuu luokkien Aurinkokunta, Pelaaja ja Komentotulkki funktioita. 4
Hoitaa pelaajan vuoron. Kutsutaan pääohjelmasta mikäli peli ei ole loppunut. 2.2.7 Funktio: tulosta pelaajat void pelaajat(); void Tulostaa pelissä olevat pelaajat ja pelaajien pisteet. Tulostaa pelitilanteen. Kutsutaan funktiosta vuoro. 2.2.8 Funktio: tulosta kartta void tulosta_kartta(); void Tulostaa pelissä olevan kartan. Mikäli pelaaja on käynyt aurinkokunnassa, näytetään onko siellä pelaajaa. Mikäli pelaaja ei ole käynyt aurinkokunnassa tulostetaan?. Käytetään kartan tulostamiseen. Pelaaja saa tietoa galaksista, jossa pelataan. 2.2.9 Funktio: voittajan tulostus void voittajan_tulostus(); void Tulostaa pelin voittajan/voittajat pelin loputtua. Kutsutaan funktiosta loppuiko pelin loputtua. 5
2.2.10 Funktio: muistin vapautus void muistin_vapautus(); void Vapauttaa ohjelman varaaman muistin pelin loputtua. Kutsutaan mainista mikäli peli loppuu. 2.2.11 Funktio: poista pelaaja void poista_pelaaja(); void Poistaa pelaajan pelistä. Kutsutaan mikäli pelaaja luovuttaa tai jää jumiin. Kutsutaan funktioista vuoro ja pattitilanne. 2.2.12 Funktio: alustus yleiset bool alustus_yleiset(); true: yleisten alustus onnistui false: yleisten alustus ei onnistunut Lukee alustustiedostosta yleiset ja alustaa pelin niiden osalta. Kutsutaan alustusfunktiosta. Suorittaa osan pelin alustuksesta. 2.2.13 Funktio: alustus pelaajat 6
bool alustus_pelaajat(); true: Pelaajien alustus onnistui bool: Pelaajien alustus ei onnistunut Lukee alustustiedostosta pelaajat ja alustaa pelin niiden osalta. Kutsutaan alustusfunktiosta. Suorittaa osan pelin alustuksesta. 2.2.14 Funktio: alustus aurinkokunnat bool alustus_aurinkokunnat(); true: Aurinkokuntien alustus onnistui bool: Aurinkokuntien alustus ei onnistunut Lukee alustustiedostosta aurinkokunnat ja alustaa pelin niiden osalta. Kutsutaan alustusfunktiosta. Suorittaa osan pelin alustuksesta. 2.2.15 Funktio: valtaus void valtaus(); void Valloittaa aurinkokunnan. Pelaaja jolla on aurinkokunnan täyttyessä eniten planeettoja saa koko aurinkokunnan itselleen. Kutsutaan liiku funktiosta. 2.3 Luokka Pelaaja 2.3.1 Luokan kuvaus Pelaaja luokka kuvaa pelin pelaajaa. Luokka sisältää pelaajan tiedot ja mahdollistaa pelaajan liikkumisen. 7
2.3.2 Rajapinta string nimi: Pelaajan nimi. int id: Pelaajan id. int pisteet: Pelaajan pisteet. vector<aurinkokunnat*> kaydyt: Aurinkokunnat, joissa pelaaja on käynyt. Aurinkokunta* sijainti: Aurinkokunta, jossa pelaaja sijaitsee. 2.3.3 Funktio: lenna bool lenna(aurinkokunta* kohde, vector<pelaaja*> pelaajat, bool liike); Aurinkokunta* kohde$: Aurinkokunta, johon pelaaja haluaa lentää. vector<pelaaja*> pelaajat: Pelissä olevat pelaajat. bool liike: Yritetäänkö liikkua vai tarkastetaanko vain voidaanko liikkua true: Pelaaja onnistui liikkumaan haluttuun kohteeseen. false: Pelaaja ei voinut liikkua haluttuun kohteeseen. Laskee, voiko pelaaja liikkua haluttuun aurinkokuntaan. Mikäli voi ja sitä on haluttu, pelaaja liikutetaan uuteen paikkaan. Käytetään ohjelmassa pelaajien liikuttamiseen ja pattitilanteen tarkastuksessa. Kutsutaan, kun pelaaja antaa komennon liiku, lenna, matkusta tai tutki ja pattitilanteesta. 2.3.4 Funktio: asuta bool asuta(int planeetta_kohde); int planeetta_kohde: Planeetta, joka halutaan asuttaa true: Pelaaja onnistui asuttamaan planeetan. false: Planeettaa ei voitu asuttaa. Tarkastaa voiko pelaaja asuttaa halutun planeetan ja asuttaa sen mikäli se onnistuu. Planeetan asuttamiseen. Kutsutaan funktiosta vuoro 2.3.5 Funktio: kuutukikohta 8
bool kuutukikohta(int planeetta_kohde); int planeetta_kohde: Planeetta, jonka kuuhun halutaan tehdä kuutukikohta true: Pelaaja onnistui rakentamaan kuutukikohdan false: Planeetan kuuhun ei voitu rakentaa kuutukikohtaa. Tarkastaa voiko pelaaja rakentaa planeetan kuulle kuutukikohdan ja tekee sen mikäli se onnistuu. Kuutukikohdan rakentamiseen. Kutsutaan funktiosta vuoro 2.4 Luokka Aurinkokunta 2.5 Luokan kuvaus Luokka mallintaa aurinkokuntaa. Sisältää planeettoja ja niiden kuut. Sisältää funktiot planeettojen ja kuiden asuttamiseen. 2.5.1 Rajapinta string nimi: Aurinkokunnan nimi int x: Aurinkokunnan sijainnin xkoordinaatti. int y: Aurinkokunnan sijainnin ykoordinaatti. vector<planeetta> planeetat: Aurinkokunnassa sijaitseavt planeetat. struct Planeetta: Planeettaa kuvaava tietue. 2.5.2 Struct: Planeetta Muuttujat: string nimi: Planeetan asuttajan nimi. int id: Planeetan asuttajan id. bool kaasu: true: kaasu planeetta, false: asuttava planeetta. bool kuu: true: planeetalla on kuu, false: planeetalla ei ole kuuta. bool siirtokunta: true: planeetalle on perustettu siirtokunta, false: planeetalla ei ole siirtokuntaa. bool kuutukikohta: true: planeetan kuuhun on perustettu on kuutukikohta, false: planeetan kuuhun ei ole perustettu kuutukikohtaa. Kuvaa aurinkokunnassa olevaa planeettaa. 2.5.3 Funktio: muunna bool muunna(int planeetta); 9
int planeetta: Planeetta, jota pelaaja yrittää muuntaa asumiskelpoiseksi. true: Pelaaja onnistui muuttamaan planeetan asumiskelposeksi. false: Pelaaja ei onnistunut muuttamaan planeettaa. Muuttaa kaasuplaneetan asumiskelpoiseksi. Käytetään kaasuplaneettojen muuttamiseen asuinkelpoiseksi. Kutsutaan pelaajan syöttäessä komento muunna tai tuunaa. 2.5.4 Funktio: listaa void listaa(); void Listaa parametrina annetun aurinkokunnan planeetat, niiden siirtokunnat ja kuutukikohdat mikäli pelaaja on käynyt kyseisessä aurinkokunnassa. Käytetään aurinkokunnan sisällön tarkasteluun. Kutsutaan pelaajan syöttäessä komento kartta tai galaksi. 2.6 Luokka Komentotulkki 2.7 Luokan kuvaus Luokka toimii pelin komentotulkkina. Se kysyy käyttäjältä syötteen, selvittää sen ja parsii sen parametrit. 2.7.1 Rajapinta static const int KPL = 21: Pelissä olevien komentojen määrä string komennot[kpl]: Pelissä olevat komennot. string syote: Käyttäjän syöttämä teksti Komento komento: Lopullinen käyttäjän syöttämä komento ja parametrit Komento parsittu: Syötteestä erilleen parsitut komento ja parametrit, ei tulkittu. 10
2.7.2 Funktio: komento kayttajalta bool komento_kayttajalta(); true: Käyttäjältä onnistuttiin lukemaan syöte ja tulkitsemaan se false: Käyttäjältä ei onnistuttu lukemaan syötettä tai tulkitsemaan sitä. Lukee käyttäjältä syötteen ja tulkitsee sen. Kutsutaan vuorofunktiossa. Funktio kutsuu komentoa parsinta, joka suorittaa varsinaisen parsinnan. 2.7.3 Funktio: parsinta bool parsinta(); true: Käyttäjän antama syöte onnistuttiin parsimaan. false: Käyttäjän syötettä ei onnistuttu parsimaan. Parsii käyttäjän syötteestä komennon ja parametrit. Kutsuu komennon s elvitysfunktiota. Kutsutaan komento k ayttajaltafunktiosta. 2.7.4 Funktio: komennon selvitys bool komennon_selvitys(); true: Komento tunnistettiin pelin komennoksi false: Komentoa ei tunnistettu pelin komennoksi 11
Vertaa parsittua komentoa pelin oikeisiin komentoihin. Kutsutaan funktiosta parsinta. 12
3 Loppudokumentaatio 3.1 Muutokset alkuperäiseen suunnitelmaan Suurin rakenteelinen muutos tapahtui luokissa. Peliin lisättiin Peliluokka kokoamaan pelin tarvitsemat luokat ja tietorakenteet yhteen. Peli käyttää kaikkia muita harjoitustyön luokkia eli Pelaaja, Aurinkokunta ja Komentotulkki. Alkuperäisessä suunnitelmassa Aurinkokunta ja Pelaaja luokat riippuivat toisistaan. Luokkia muutettiin niin, että Pelaajaluokka riippuu Aurinkokuntaluokasta. Tästä johtuen luokkien funktioita jouduttiin siirtämään toiselle luokalle. Komentotulkki toteutettiin omana luokkanaan alkuperäisestä suunnitelmasta poiketen. Harjoitustyö käyttää pointtereita enemmän kuin alkuperäisessä suunnitelmassa oli ajateltu. Pointterit helpottivat tiedon säilytystä ja välitystä eri ohjelmien osien välillä. 3.2 Kuvaus harjoitustyön tekemisestä Alku oli kankea, sillä tajusin alkuperäisen suunnitelman luokkien virheelliset riippuvuussuhteet vasta koodauksen aloittamisen jälkeen, kun koodi ei suostunut millään kääntymään. Jouduin suunnitelemaan ohjelmaani uusiksi ja aloitin työn koodaamisen alusta, minkä jälkeen sain koodin kääntymään. Ohjelmointiin meni aikaa reilu viikko aktiivista koodausta. Ohjelmoinnissa tuli kiire, sillä en aloittanut tarpeeksi ajoissa ja vappu pääsi yllättämään. Ohjelman toiminnallisuudet ja viimeistely valmistuivat kaikki muutamassa päivässä, mikä näkyy koodin laadussa. Tiedän pystyväni tuottamaan parempaa koodia, kuin ohjelma monilta osin on. Tästä johtuen en ole täysin tyytyväinen harjoitustyöhöni. Varsinkin viimeistelyssä on parantamisen varaa. Harjoitustyö ei ollut vaikea koodattava ja jonkinlainen ratkaisu tuli mieleen kaikkiin ohjelman osien toteutukseen nopeasti. Opin työtä tehdessäni itsestäni koodarina, millaisia ratkaisuja teen, missä on kehitettävää ja miten kiireessä koodaaminen onnistuu. Etenkin pointterien käyttäminen ja muistinhallinta helpottuivat harjoitustyötä tehdessä. 3.3 Palautetta Harjoitustyön aihe ei ollut kiinnostava. Sen koodaaminen vei paljon aikaa, mutta itse peli on tylsä. Harjoitustyön tehtävänanto oli osittain sekava ja sitä lukiessa löysi usein asioita joita ei aikaisemmin ollut huomannut. Mielestäni se oli ryhmitelty huonosti, mikä aiheutti sekavuutta sillä tehtävänantoa joutui rullailemaan edestakaisin esimerkiksi yhtä toiminnallisuutta tehdessä. Kurssin irkkikanava, missä assarit ja muut opiskelijat vastaavat kysymyksiin on mielestäni yksin kurssin suurimmista vahvuuksista. Muiden virheistä oppiminen nopeutti useasti omaa koodausta ja muut tiesivät vastauksia omiin ongelmiin kunhan vain uskaltaa kysyä. Tulevaisuudessaki pitää uskaltaa myöntää tarvitsevansa apua, joten siltäkin kannalta irkkikanava toimii kurssissa hyvin. Välipalautusdokumentin dokumenttipohja nopeutti ja helpotti ainakin omaa työtäni. Palautuksesta tuli siistimpi ja tiesi että siihen tulee dokumentoitua halutut asiat. Muuten olisi varmasti jäänyt jotain tärkeää laittamatta. Varsinkin latexilla tehdyssä valmis dokumenttipohja nopeutti kun ei tarvinnu alkaa metsästää netistä komentoja. Valmis dokumenttipohja toimi ainakin itselläni ilman ongelmia. 13
Kurssin luennot olivat hyviä ja on hienoa että kurssin asioista on koottu kirja. Kirja ei kuitenkaan toimi minään muuna kuin luentojen tukena. Siitä on vaikea opiskella asioita ja kaikki on esitetty esimerkkien kautta. Tästä johtuen se on vaikea lukuinen ja asia on piilotettu esimerkkeihin. Kirjassa ei ole kunnollista hakemistoa ja avainsanat ovat lipsuneet johonkin tekstin sekaan. Mielestäni kurssikirjana toimisi paremmin jokin valmis c++ kirja. 14