1. Johdanto 1.1. Tehtävä Lausekielinen ohjelmointi (Laki) -kurssin toisena harjoitustyönä ohjelmoidaan Java-kielellä Tetris-pelin [1] tekstipohjainen muunnelma Txtris. Pelissä on kenttä, jonka yläreunaan ilmestyy palikoina tunnettuja kuvioita, jotka tippuvat kohti kentän alareunaa. Pelaaja voi omalla vuorollaan siirtää palikkaa askeleen vasemmalle tai oikealle, kiertää palikkaa 90 asetetta vastapäivään, tipauttaa palikan alas, lopettaa pelin tai olla tekemättä mitään. Peli siirtää omalla vuorollaan palikkaa yhden askeleen alaspäin. Palikka tippuu alas, kunnes vastaan tulee alareuna tai toinen palikka. Jos pohjalle päätynyt palikka tuottaa yhdestä neljään vain palikan merkistä koostuvaa riviä, peli poistaa kyseiset rivit ja palkitsee pelaajaa pisteillä. Kentän yläreunaan tulee uusi palikka, kun edellinen palikka on päätynyt tavalla tai toisella pohjalle. Peli jatkuu niin kauan kunnes pelaaja päättää lopettaa tai kenttä on niin täynnä, että uusi palikka ei enää mahdu kentälle. 1.2. Pelikenttä Peliä pelataan 22 12 -kokoisella kentällä, joka esitetään ohjelmassa vastaavan kokoisena kaksiulotteisena taulukkona. Taulukon alkiot vastaavat kentän paikkoja ja alkioiden arvot paikkojen sisältöä. Kentän paikkoihin viitataan jatkossa taulukon alkioiden tapaan kahdella nollasta alkavalla indeksillä. Kentän ensimmäinen paikka (0, 0) on kentän vasemmassa yläkulmassa. Viimeinen paikka (21, 11) on puolestaan kentän oikeassa alakulmassa. Luontevin valinta alkion tyypiksi lienee char, koska harjoitustyössä paikkojen sisältö esitetään merkeillä. Pelikentällä on pisteellä ('.') piirretty yhden merkin levyinen reuna. Sisäpaikoissa on palikoita ja kentän taustaa. Palikat esitetään suurella x-kirjaimella ('X') ja tausta välilyönnillä (' '). Mikään sisäpaikkojen merkeistä ei saa olla kentän reunalla. Palikoita on seitsemää tyyppiä, jotka kaikki koostuvat neljästä merkistä. Palikoiden muodot ja kirjaimet, joilla palikoihin viitataan jatkossa on esitetty taulukossa 1. Taulukossa on listattu myös palikoiden merkkien paikat, kun palikka on alkuasemassaan kentän yläreunassa. Paikat määritellään vasemmalta oikealle ja ylhäältä alas. Taulukko 1: Eri tyyppisten palikoiden muodot ja palikoiden merkkien paikat alkuasemassa. Esimerkiksi O-tyyppisen palikan merkit (ylävasen, yläoikea, alavasen ja alaoikea) ovat aluksi paikoissa (1, 4), (1, 5), (2, 4) ja (2, 5). Palikan kiertopaikka on lihavoitu. (I) (J) (L) (O) (S) (T) (Z) XXXX (1, 4) (1, 5) (1, 6) (1, 7) XXX X (1, 4) (1, 5) (1, 6) (2, 6) XXX X (1, 4) (1, 5) (1, 6) (2, 4) XX XX (1, 4) (1, 5) (2, 4) (2, 5) XX XX (1, 5) (1, 6) (2, 4) (2, 5) XXX X (1, 4) (1, 5) (1, 6) (2, 5) XX XX (1, 4) (1, 5) (2, 5) (2, 6) Palikan merkkien keskinäinen järjestys on aina sama kuin alkuasemassa palikan myöhemmästä asemasta riippumatta. Palikkaa kierretään aina toisen merkin suhteen. Kunkin palikan kiertopaikka on lihavoitu taulukossa 1. Jos esimerkiksi J- Lausekielinen ohjelmointi Syksy 2012 Jorma Laurikkala 1 / 15
tyyppistä palikkaa kierretään 180 astetta, katsotaan palikan ensimmäiseksi merkiksi edelleen aluksi paikassa (1, 4) ollut merkki, vaikka uudessa asennossa kyseinen merkki on vasemmalta oikealle ja ylhäältä alas lukien kuvion alemman rivin viimeinen merkki. On erittäin tärkeää, että paikkojen keskinäinen järjestys säilyy, jotta palikan kierto tapahtuisi aina samalla tavalla. Tästä syystä harjoitustyöohjelman on pyydettävä palikan alkuaseman paikat apuluokalta (luku 3.2) ja palikan paikat on kierrettävä samaisen apuluokan avulla. Kuvassa 1a on esitelty eräs pelin lähtötilanne, jossa J-tyyppinen palikka on alkuasemassa. Kentän sisäpaikoissa on palikan lisäksi vain taustaa. Palikkaa on siirretty askel vasemmalle (kuva 1b) ja kierretty yhden kerran (kuva 1c). Ohjelma on siirtänyt palikkaa yhden askeleen alas käyttäjän kummankin valinnan jälkeen. Kuva 1: a) kenttä lähtötilanteessa, b) pelaaja siirtänyt palikkaa vasemmalle ja ohjelma siirtänyt palikkaa alas ja c) pelaaja kiertänyt palikkaa ja ohjelma siirtänyt palikkaa alas. Palikan kiertopaikan merkki on lihavoitu. 1.3. Pelin kulku (a) Peliä pelataan vuorottain siten, että ensin on pelaajan ja sitten ohjelman vuoro kunnes kenttä on täynnä tai pelaaja päättää lopettaa pelin. Ohjelma sijoittaa aluksi palikan alkuasemaansa, mikäli mahdollista. Palikkaa ei voida sijoittaa kentälle, jos yhdessä tai useammassa alkuaseman paikoissa on jo palikkamerkki. Palikkaa ei tipauteta alkuasemaansa, jotta peli olisi helpompi toteuttaa. (b) (c) Lausekielinen ohjelmointi Syksy 2012 Jorma Laurikkala 2 / 15
Pelaaja voi siirtää palikkaa yhden askeleen vasemmalle tai oikealle, kiertää palikkaa 90 astetta vastapäivään, tipauttaa palikan kentän pohjalle tai jättää palikan paikoilleen. Palikka ei voi olla reunalla eikä yhden tai useamman palikan päällä. Tipautettu palikka putoaa alaspäin, kunnes palikan merkkiä tai merkkejä vastaan tulee joko alareuna tai palikkamerkki tai -merkkejä. Palikka jää nykyiseen asemaansa, jolloin toiminto käytännössä ohitetaan, jos siirto tai kierto ei onnistu reunan tai toisen palikan vuoksi. Ohjelma yrittää siirtää omalla vuorollaan palikkaa kentällä yhden rivin alaspäin. Siirto katsotaan mahdottomaksi samoin periaattein kuin tipautetun palikan päätellään tulleen pohjalle: Palikka jää nykyiseen asemaansa, mikäli välittömästi yhden tai useamman palikan merkin alla on alareuna tai yksi tai useampia yhden tai useamman aiemman palikan merkkejä. Kun palikka on joko pelaajan tai ohjelman toimesta kentän pohjalla, tutkitaan onko kentällä täysiä rivejä, joiden sisäpaikoissa on pelkästään palikkamerkkejä. Yhdellä palikalla voidaan palikan tyypistä ja pelitilanteesta riippuen muodostaa nollasta neljään tällaista riviä. Ohjelma poistaa täydet rivit ja antaa pelaajalle jokaisesta poistettavasta rivistä 100 pistettä. Vajaat rivit saattavat siirtyä poiston seurauksena alaspäin. Harjoitustyötä on helpotettu siten, että apuluokassa (luku 3.2) on metodi, jolla täydet rivit voi poistaa. Ohjelma yrittää sijoittaa kentälle uuden palikan mahdollisten täysien rivien poiston jälkeen. Peli loppuu, jos uusi palikka ei mahdu kentälle. Jos ohjelma lopetetaan käyttäjän toimesta, ohjelma ei enää yritä siirtää palikkaa eikä poista rivejä. Ohjelman idea karkealla tasolla pseudokoodina: Algoritmi Txtris jatketaan T; do { if (palikka mahtuu kentälle) Aseta seuraava palikka kentälle; else jatketaan F; while (jatketaan AND palikka ilmassa) { Lue käyttäjän valinta; if (käyttäjä jatkaa peliä) { Suorita tai ohita toiminto; Yritä siirtää palikkaa askel alas; } else jatketaan F; } if (jatketaan) Poista rivit; } while (jatketaan); Lausekielinen ohjelmointi Syksy 2012 Jorma Laurikkala 3 / 15
Kuvan 2a tilanteeseen päädytään kuvasta 1c, kun palikkaa kierretään toisen kerran, palikka siirretään vasempaan reunaan ja palikka tipautetaan kentän pohjalle. Ohjelma arpoo seuraavaksi I-tyylisen palikan ja sijoittaa sen kentän yläreunaan. Käyttäjä tipauttaa I-palikan heti alas ja ohjelma antaa L-tyylisen palikan (kuva 2b). L-palikkaa on siirretty oikealle, kierretty kahdesti ja siirretty oikeaan reunaan. Tämän jälkeen vuoroja on ohitettu, kunnes palikka on paikallaan ja alin sisärivi on täynnä (kuva 2c). Lopuksi ohitetaan vielä yksi vuoro, jolloin ohjelma poistaa täyden rivin, palkitsee käyttäjää 100 pistellä, siirtää poistettavaa riviä edeltävän rivin merkit alimmalle sisäriville ja sijoittaa O-tyylisen palikan kentälle (kuva 2d). (c) (d) (a). XXXX..X..XXX. (b).x..xxxxxxx..x X..XXXXXXXXXX..X X. Kuva 2: a) ensimmäinen palikka on tipautettu siirron ja kierron jälkeen alas, b) toinen palikka on tipautettu suoraan alas, c) kolmatta palikkaa on siirretty ja kierretty ja se on laskettu alariville vuoroja ohittamalla ja d) täyttynyt alarivi on poistettu. 1.4. Valmiin koodin käytöstä Kurssin verkkosivuilla on apuluokka, jossa on metodit palikan paikkojen tuottamiseen, paikkojen kiertämiseen ja täysien rivien poistamiseen (luku 3.2). Palikkoja ei saa luoda muulla tavoin, jotta oma ohjelma tuottaisi palikat aina samassa järjestyksessä kuin malliratkaisu. Apuluokkaa käyttäen on varmaa myös, että yksittäisen palikan merkit ovat aina oikeassa keskinäisessä järjestyksessä, jolloin kierto toimii samoin ajatellulla tavalla. Harjoitustyön teossa saa käyttää kurssin verkkosivuilla julkaistuja mallivastauksia joko sellaisenaan tai muokattuna. Huomaa, että osa 11. 13. viikkoharjoituksen tehtävistä ja niiden mallivastauksista on tarkoitettu avuksi harjoitustyön teossa. Lausekielinen ohjelmointi Syksy 2012 Jorma Laurikkala 4 / 15
Tiedustele harjoitustyön ohjaajaan mielipidettä, jos Javan API:sta sattuu löytymään palvelu, jolla harjoitustyö ratkeaa kovin helposti. Harjoitustyön ohjaajaan kannattaa ottaa yhteyttä muutenkin, mikäli on epävarma siitä mitä saa tehdä ja mitä ei. Harjoitustyö tehdään itse omalla ajalla. Kaverien kanssa saa keskustella, mutta suora kopiointi eli plagiointi on kiellettyä. Verkosta löytyviä ja harjoitustyötä muistuttavia ohjelmia saa ajaa, mutta niiden koodia ei saa kopioida. Muualta kuin kurssisivuilta poimitun koodin käyttö katsotaan plagioinniksi. Kurssisivuilla mahdollisesti julkaistavan mallivastauksen tavukoodin purkaminen lähdekoodiksi katsotaan plagioinniksi. 1.5. Pakollisuus ja korvaavuudet Harjoitustyö on pakollinen. Ainoa poikkeus tähän sääntöön ovat harjoitustyön korvanneet opiskelijat. Harjoitustyön voi korvata A) muiden oppilaitosten opinnoilla, B) edellisellä Laki-kurssilla hyväksytyllä toisella harjoitustyöllä tai C) edellisten kohtien tapaisella painavalla syyllä. Kohdan A perusteella on annettu kaikki opintoasiain amanuenssin (Heli Rikala) kurssin vastuuopettajalle (Jorma Laurikkala) esittämät korvaavuudet. Kohdan B ja C perusteella annettavista harjoitustyökorvaavuuksista on tarkemmat tiedot kurssin kotisivuilla. B- ja C- kohtien osalta on tärkeintä muistaa, että harjoitustyö korvautuu vain, jos ottaa yhteyttä kurssin vastuuopettajaan. (Tähän mennessä tulleet yhteydenotot ja sopimukset on kirjattu ylös eikä uusia yhteydenottoja näiltä osin tarvita.) 2. Ohjelman toiminnot Seuraavassa esitellään ohjelman toiminnallisuutta pienten esimerkkien avulla. Laajempia esimerkkiajoja julkaistaan kurssin kotisivujen Harjoitustyöt Harjoitustyö 2 -kohdassa. Tietojen lukemiseen näppäimistöltä käytetään In-luokan operaatiota. Myös In-luokka löytyy kurssin sivuilta. Huomaa, että harjoitustyössä syötteiden lukuun ei saa käyttää muita keinoja (esimerkiksi Scanner-luokkaa sellaisenaan), jotta töiden puoliautomaattinen tarkistus (luku 6) onnistuisi paremmin. Ohjelmassa on komennot palikan siirtoon askel vasemmalle tai oikealle (luku 2.3), palikan kiertoon (luku 2.4), palikan tipauttamiseen (2.5), pelaajan vuoron ohittamiseen (luku 2.6) ja ohjelma lopettamiseen (luku 2.7). Tehtävän helpottamiseksi oletetaan, että ohjelmalle annetaan aina syöte sitä luettaessa ja että syöte on aina oikean tyyppinen (char). 2.1. Tervehdystekstin tulostaminen Käynnistyessään ohjelma tulostaa näytölle tähtimerkeillä (' * ') kehystetyn viestin: *************** * T X T R I S * *************** Tämä teksti tulostetaan vain kerran. Lausekielinen ohjelmointi Syksy 2012 Jorma Laurikkala 5 / 15
2.2. Komennon lukeminen Heti tervehdysrivien jälkeen tulostetaan pisterivi "Points: x", missä x on pisteiden lukumäärä ( 0). Pelin alkaessa pisteitä on nolla. Välittömästi pisterivin jälkeen tulostetaan kenttä (luku 1.2), jonka yläreunassa on apuluokan (luku 3.2) metodilla arvottu palikka. I-tyyppisen palikan merkit ovat alkuasemassa kentän toisella rivillä, kun taas muun tyyppisten palikoiden merkit ovat toisella ja kolmannella rivillä (luku 1.2). Kentän tulostamisen jälkeen tulostetaan omalle rivilleen ohjerivi "" ja jäädään odottamaan käyttäjän komentoa seuraavalla rivillä. Esimerkki lähtötilanteesta, jossa ohjelma on arponut ensimmäiseksi J-tyyppisen palikan: *************** * T X T R I S * *************** 2.3. Palikan siirtäminen vasemmalle tai oikealle Palikkaa voidaan siirtää askel kerrallaan joko vasemmalle ('<') tai oikealle ('>'). Palikka ei liiku ja käyttäjän vuoro katsotaan ohitetuksi, jos palikka yritetään siirtää reunan tai toisen palikan päälle. Siirretään alkuasemassaan olevaa palikkaa (luku 2.2) yksi paikka vasemmalle: < Lausekielinen ohjelmointi Syksy 2012 Jorma Laurikkala 6 / 15
2.4. Palikan kiertäminen Palikkaa voidaan kiertää 90 astetta vastapäivään pienellä r-kirjaimella ('r'), mikäli kierretty palikka ei päädy reunan tai toisen palikan päälle. Kierron epäonnistuessa käyttäjän vuoro katsotaan ohitetuksi: palikan paikat eivät muutu ja vuoro siirtyy ohjelmalle. Kierto tehdään aina apuluokan (luku 3.2) metodilla. Kierretään kerran palikkaa, jota siirrettiin edellisessä luvussa käyttäjän toimesta askel vasemmalle ja ohjelman toimesta askel alas: r 2.5. Palikan tipauttaminen Palikka tipautetaan kentän pohjalle pienellä d-kirjaimella ('d'). Tipautuksessa palikkaa siirretään suoraan alaspäin, kunnes palikan merkkiä tai merkkejä vastaan tulee alareuna tai yksi tai useampi yhteen tai useampaan toiseen palikkaan kuuluva merkki. Ohjelma arpoo pudottamisen jälkeen uuden palikan ja esittää sen kentän yläreunassa. Oletetaan, että edellisessä luvussa kierrettyä palikkaa kierretään uudelleen ja siirretään kahdesti vasemmalle: <.X..XXX. Lausekielinen ohjelmointi Syksy 2012 Jorma Laurikkala 7 / 15
Kun palikka tipautetaan, se päätyy vasten kentän alareunaa ja kentän yläreunaan ilmestyy uusi I-tyylinen palikka: d. XXXX..X..XXX. 2.6. Pelivuoron ohittaminen Pelaaja voi jättää vuoronsa käyttämättä syöttämällä ohjelmalle merkin, jota ei ole varattu komennoksi. Ohjelma ei siten luokittele mitään merkkiä virheelliseksi syötteeksi. Esimerkeissä vuoro ohitetaan pienellä a-kirjaimella ('a'). Tipautetaan edellisessä luvussa saatu I-palikka ja siirretään seuraavaksi saatua L- palikkaa neljästi oikealle sekä kierretään tätä palikkaa vielä kahdesti: r. X.. XXX..X..XXXXXXX. Lausekielinen ohjelmointi Syksy 2012 Jorma Laurikkala 8 / 15
Ohitetaan sitten vuoro joitakin kertoja: a. X..X XXX..XXXXXXX. Palikan pitkä sivu saadaan kentän toiseksi viimeiselle riville ohittamalla vuoro vielä kerran: a.x X..XXXXXXXXXX. Huomaa, että riviä ei poisteta vielä, vaikka palikka onkin jo pohjalla, koska käyttäjän viimeinen vuoro on käyttämättä. Rivi poistettaisiin, jos palikka olisi tipautettu, koska tipautetun (luku 2.5) palikan ajatellaan olevan pois käyttäjän käsistä. 2.7. Pelin lopettaminen Peli voidaan lopettaa syöttämällä ohjelmalle pieni q-kirjain ('q'). Tällöin ei enää siirretä palikkaa tai anneta pisteitä. Lopetettaessa tulostetaan uudelleen pisterivi ja kenttä ja aivan lopuksi omalle rivilleen lyhyet jäähyväiset "Bye, see you soon." (Ohjeriviä ei tulosteta, koska komentoja ei enää lueta.) Lopetetaan peli edellisessä luvussa jäätyyn tilanteeseen: Lausekielinen ohjelmointi Syksy 2012 Jorma Laurikkala 9 / 15
q.x X..XXXXXXXXXX. Bye, see you soon. Ohjelma toimii yllä kuvatulla tavalla myös, kun kentälle ei enää mahdu uutta palikkaa. Oletetaan, että pelaaja on lopettamisen sijasta ohittanut yllä olevassa tilanteessa yhden vuoron (luku 2.8) ja täyttänyt sitten kenttää palikoita tiputtelemalla: d Points: 100. XXXX..X XX X. Tipautetaan palikka, jolloin kenttä täyttyy ja ohjelma pysähtyy: d Points: 100. XXXX..X XX X. Bye, see you soon. Lausekielinen ohjelmointi Syksy 2012 Jorma Laurikkala 10 / 15
2.8. Täysien rivien poistaminen Kentälle voi muodostua nollasta neljään täyttä riviä, kun palikka on lopullisella paikallaan. Ohjelma poistaa täydet rivit ja palkitsee niistä ellei käyttäjä ole lopettanut ohjelmaa (luku 2.7). Poistuneiden rivien tilalle siirretään kentälle jääneitä vajaita rivejä. Palataan luvun 2.6 tilanteeseen ja oletetaan, että käyttäjä jatkaa peliä ohittamalla vuoronsa vielä kerran: a Points: 100.X X. jolloin täyttynyt rivi poistetaan, pelaajalle annetaan 100 pistettä, kaksi palikkamerkkiä sisältävä vajaa rivi siirtyy askeleen alaspäin ja seuraava palikka arvotaan ja sijoitetaan kentän yläreunaan. 3. Koodista 3.1. Yleistä Ohjelma kirjoitetaan tuttuun tapaan main-operaation sisältävään luokkaan. Ensimmäisestä harjoitustyöstä poiketen ohjelma jaetaan metodeihin. Metodien lukumäärä riippuu osin ohjelmoijasta ja osin hyvästä ohjelmointitavasta; ohjelmaan ei saa kirjoittaa liian pitkiä metodeja. Ohjelmassa on vältettävä saman koodin kopioimista eri paikkoihin, koska toistuvasta koodista voi kirjoittaa asianomaisista paikoista kutsuttavan metodin. Muista noudattaa hyvää ohjelmointitapaa: sisennä koodia johdonmukaisesti luettavuuden parantamiseksi, kommentoi riittävästi ja oikeissa paikoissa, liitä jokaiseen metodiin yleisluonteinen kommentti, nimeä vakiot, muuttujat ja metodit järkevästi, käytä vakioita, pidä rivit riittävän lyhyinä, käytä välejä lauseissa ja erota loogiset kokonaisuudet toisistaan väliriveillä, pidä metodit järkevän mittaisia metodin tulisi mahtua yhdelle A4-kokoiselle sivulle ja vältä attribuutteja. Lausekielinen ohjelmointi Syksy 2012 Jorma Laurikkala 11 / 15
Voit palauttaa hyvän ohjelmointitavan mieleen lukemalla luentomateriaalin 13. ja 24. luvut [2, 3]. Tarpeettomien attribuuttien käyttöä tulee välttää. Erityisesti parametrilistojen kautta tapahtuvaa tiedonvälitystä ei saa korvata järjestelmällisesti attribuuteilla, koska tällöin rikotaan karkeasti modulaarisuusperiaatetta. Modulaarisessa ohjelmoinnissa on tavoitteena jakaa koodi helposti ymmärrettäviin ja hallittaviin kokonaisuuksiin, jotka kommunikoivat ympäristönsä kanssa selkeästi määritellyn liittymän (parametrilista ja paluuarvo) kautta. Attribuutit näkyvät kaikkiin metodeihin, jolloin ohjelman tietoja voidaan muuttaa missä tahansa moduulien liittymät ohittaen. Harjoitustyössä saa käyttää korkeintaan yhtä attribuuttia hyvin perustelluista syistä eikä attribuutti saa olla kaksiulotteinen taulukko. Huomaa, että harjoitustyö on ratkaistavissa täysin ilman attribuutteja. final-määreellä esiteltyjä vakioituja attribuutteja (eli luokkavakioita) voi käyttää vapaammin, koska vakioarvoisen attribuutin arvoa ei voida muuttaa metodeissa. Sisennä koodi välilyönnein. Älä käytä sisentämiseen tabulaattoria, jotta koodisi näkyisi samanlaisena myös ohjaajan editorissa. Erityisesti välilyöntejä ja tabulaattorimerkkejä ei saa käyttää sekaisin, koska tällöin on varmaa etteivät sisennykset näy ajatellulla tavalla. Ohjelman nimen tulee olla Txtris, jolloin lähdekoodi on Txtris.java nimisessä tiedostossa. 3.2. Palikoiden tuottaminen, kierto ja täysien rivien poisto Palikat on tuotettava satunnaisessa järjestyksessä, jotta pelissä olisi enemmän haastetta. Toisaalta satunnaisuuden tulisi olla toistettavissa, jotta ratkaisun ja mallivastauksen toimintaa voidaan vertailla. Onneksi myös Java-kieli osaa toistaa satunnaislukujen jonon, kun satunnaislukugeneraattori alustetaan niin sanotulla siemenluvulla. Siemenluku välitetään harjoitustyölle luentomateriaalin 23. luvussa esiteltynä komentoriviparametrina [4]. Interaktiivisesti suoritettavalle ohjelmalle annetaan esimerkiksi siemenluku 900 seuraavasti: java Txtris 900 Uudelleenohjausta käytettäessä komento voi olla esimerkiksi: java Txtris 900 < syote_tehtanto1_900.txt > tulos.txt Harjoitustyössä oletetaan, että käyttäjä osaa antaa aina yhden ja vain yhden komentoriviparametrin, joka on kokonaisluku. Kurssin verkkosivuilta on julkaistu HT2Apu- ja TxtrisTest-luokat. HT2Apu on apuluokka, jossa on neljä julkista metodia (katso luokan 4. kohta). Näistä rakentajaa ja annapalikanpaikat-metodia tarvitaan palikoiden arpomiseen. TxtrisTest-luokka käsittelee komentoriviparametrin ja kutsuu esimerkinomaisesti HT2Apu-luokan metodeja. Luokan main-metodissa muunnetaan komentorivi inttyyppiseksi luvuksi ja käsitellään mahdolliset virhetilanteet. HT2Apu-luokkaa edustava olio luodaan antamalla muunnettu siemenluku annetaan luokan rakentajalle. Lausekielinen ohjelmointi Syksy 2012 Jorma Laurikkala 12 / 15
Voit käyttää TxtrisTest-luokkaa sellaisenaan oman ohjelmasi lähtökohtana tai kopioida luokasta tarvittavat osat omaan ohjelmaan. Molemmissa tapauksissa kannattaa ehdottomasti jättää main-metodi nykyiseen muotoonsa ja sijoittaa pääsilmukka muualle, jotta main-metodista ei tule liian pitkä. Olion kautta kutsumalla saadaan käyttöön annapalikanpaikat-metodi, joka arpoo uuden palikan. Metodi palauttaa valitsemansa palikan paikkojen rivi- ja sarakeindeksit taulukossa, kun palikka on alkuasemassaan. Kullakin taulukon rivillä on yhden merkin paikkatiedot: rivin ensimmäisessä alkiossa on merkin rivi-indeksi ja toisessa alkiossa on merkin sarakeindeksi. Taulukossa on aina neljä riviä, koska kaikki palikat koostuvat neljästä merkistä. Esimerkiksi siemenluvulla 900 luotu olio valitsee ensimmäisellä annapalikanpaikat-metodin kutsulla J-tyyppisen palikan ja palauttaa paikkataulukon, jonka arvot ovat: { { 1, 4 }, { 1, 5 }, { 1, 6 }, { 2, 6 } } Näin pelin alussa palikan merkkien tulee olla kentän paikoissa (1, 4), (1, 5), (1, 6) ja (2, 6). Kuvassa 1a ja luvussa 2.2 annettu tulosteessa merkit ovat paikoillaan. J- kuvion kolme ensimmäistä merkkiä ovat kentän toisen rivin viidennessä, kuudennessa ja seitsemännessä sarakkeessa ja viimeinen merkki kolmannen rivin seitsemännessä sarakkeessa. Palikoiden paikat ja paikkojen muodostamat kuviot on annettu taulukoissa 1 ja annapalikanpaikat-metodin kommenteissa, joista saa vielä tarkemman käsityksen metodin toiminnasta. Apuluokan kolmas julkinen metodi on kierrapalikanpaikat, joka kiertää parametrinaan saamiaan palikan paikkoja 90 astetta vastapäivään toisen paikan suhteen. Metodia on helpointa kutsua In-luokan metodien tapaan luokan nimen avulla, koska tällöin ei tarvita HT2Apu-luokan oliota. Metodi palauttaa paluuarvonaan paikkataulukon, joka sisältää kierrettyjen paikkojen rivi- ja sarakeindeksit. Huomaa, että metodi ei tarkista ovatko uudet laillisia. Jos yllä annetut J-palikan paikat kierretään, ovat uuden paikkataulukon arvot: { { 2, 5 }, { 1, 5 }, { 0, 5 }, { 0, 6 } } joista paikat (0, 5) ja (0, 6) ovat laittomia, koska palikka ei saa olla reunalla. Myös tämän metodin toiminnasta saa lisätietoja perehtymällä kommentteihin. Älä käytä muita menetelmiä kuin annapalikanpaikat- ja kierrapalikanpaikat-metodit uuden palikan arpomiseen ja palikan paikkojen kiertämiseen, jotta palikat käyttäytyvät varmasti samalla tavoin kuin malliratkaisussa. Luo HT2Apu-luokan olio täsmälleen yhden kerran siemenlukua käyttäen, koska uudelleen luotaessa siemenlukuun liittyvä satunnaislukujen jono alkaa alusta, vaikka luotaessa käytettäisiin samaa siemenlukua. Älä muuta HT2Apu-luokkaa millään tavalla. Älä kopioi luokan metodeja ohjelmaasi. Lausekielinen ohjelmointi Syksy 2012 Jorma Laurikkala 13 / 15
HT2Apu-luokan neljäs julkinen metodi on poistarivit, joka poistaa parametrinaan saamasta kentästä täydet rivit ja palauttaa paluuarvonaan poistettujen rivien lukumäärän (0 4). Tätä metodia ei ole pakko käyttää. Voit halutessasi kirjoittaa itse paremman metodin rivien poistoon, jos olet täysin varma, että metodisi toimii aina samoin kuin poistarivit-metodi. Harjoitustyöohjelmaa suoritettaessa ja käännettäessä on pidettävä huolta siitä, että Java-kääntäjä ja -tulkki löytävät HT2Apu-luokan. Helpointa on kopioida HT2Apu-luokka (HT2Apu.java-tiedosto) In-luokan tapaan samaan hakemistoon, jossa ohjelmasi on. 4. Dokumentointi Harjoitustyöstä kirjoitetaan dokumentti, jonka tulee sisältää seuraavat asiat: 1. Kansilehdellä tekijän nimi, opiskelijanumero, sähköpostiosoite, yksikkö ja tutkinto-ohjelma. Sivun keskellä tulisi olla suuremmalla fontilla dokumentin nimi. Kurssin kotisivuilla on annettu esimerkinomainen kansilehti. 2. Lyhyt kuvaus ohjelman toiminnasta. Voit kuvailla ohjelman toimintaa joko täysin vapaamuotoisena tekstinä (korkeinaan puoli sivua) tai pseudokoodina (korkeintaan kaksi sivua). Pseudokoodissa olisi hyvä olla operaatioita ja muuttujia. Huomaa, että käytit kumpaa lähestymistapaansa hyvänsä, niin tärkeintä on ohjelman keskeisen logiikan hahmottelu yleisellä tasolla. 3. Omia ajatuksia. Esimerkiksi: Oliko työ helppo, sopiva vai vaikea? Jos helppo tai vaikea, niin miksi? Mitä uutta opittiin? Oliko työstä mitään hyötyä tekijälleen? Montako tuntia työn tekemiseen meni? Dokumentin leipäteksti kirjoitetaan 12 pisteen fontilla ja yhdellä rivinvälillä. Valmiin tekstin lukeminen pariin otteeseen ei ole huonompi idea. Dokumentin kirjoitus tekstinkäsittelyohjelmalla sekä ohjelmasta löytyvän oikolukutoiminnon käyttäminen tekstin tarkistamiseen on myös suotavaa. Dokumentti on palautettava PDF-muodossa. Muut tiedostomuodot eivät kelpaa. Luvussa 6 ja kurssin verkkosivuilla kerrotaan tarkemmin dokumentin ja koodin palauttamisesta. 5. Harjoitustyön ohjaus Harjoitusryhmien vetäjät vastaavat ryhmäläistensä töiden ohjauksesta. Apua saa sekä sähköpostitse että henkilökohtaisesti. Ohjaajat ovat tavattavissa yliopistolla kurssin verkkosivuilla myöhemmin julkaistavina aikoina. Kurssin vastuuopettaja auttaa harjoitustyöongelmissa myös muitakin kuin oman ryhmänsä opiskelijoita. Pyri kuitenkin ottamaan ongelmatilanteissa yhteys ensin oman harjoitusryhmän vetäjään, koska vastuuopettajalla on toisinaan kiire. Muista myös, että tehtävänantoon ja Javan piirteiden käyttöön liittyvissä epävarmoissa tilanteissa kannattaa aina kysyä ohjaajalta. Lausekielinen ohjelmointi Syksy 2012 Jorma Laurikkala 14 / 15
6. Harjoitustyön palautus Ohjelma ja dokumentti täytyy palauttaa sähköisesti maanantaihin 28.1.2013 klo 16.00 mennessä WETO-järjestelmään. Tarkemmat palautusohjeet julkaistaan myöhemmin kurssin verkkosivuilla. Harjoitustöiden tarkistus perustuu tulosteiden puoliautomaattiseen vertailuun. Tästä syystä edellä annettuja tulostemäärittelyjä on seurattava pilkulleen eikä In-luokan virheilmoituksia saa mennä muuttamaan. Puoliautomaattinen vertailu helpottaa opettajan työtä, jolloin hänelle jää enemmän aikaa mielekkäämpään työhön eli ohjelman rakenteen ja ohjelmointitavan tutkimiseen. Opiskelijat hyötyvät tästä perusteellisempien kommenttien muodossa. Lisäaikaa työn tekoon voi saada muutaman päivän vain hyvästä syystä. Lisäajasta on sovittava harjoitusryhmän vetäjän kanssa ajoissa eli viimeistään päivää tai paria ennen palautuksen takarajaa. Ennen palautusta on syytä varmistaa, että dokumentissa on mukana kaikki edellä mainitut kohdat. Lisäksi kannattaa tarkistaa, että ohjelma toimii varmasti oikein viimeisten muutosten jälkeen. 7. Harjoitustyön arvostelu Harjoitustyö arvostellaan asteikolla hyväksytty/hylätty. Hylkäyksen perusteena voi olla esimerkiksi ohjelman virheellinen toiminta, hyvän ohjelmointitavan noudattamatta jättäminen, huono dokumentti ja/tai plagiointi. Plagiointiin liittyy sanktio, joka koskee molempia opiskelijoita. (Toiselta opiskelijalta tämän tietämättä kopioidun koodin käyttö johtaa kopioijan koko kurssisuorituksen hylkäämiseen.) Hylätty työ on korjattava pääsääntöisesti viikon sisällä hylkäyksestä. Lähteet [1] Wikipedia-yhteisö: Tetris, http://en.wikipedia.org/wiki/tetris (Luettu viimeksi 11.12.2012.) [2] J. Laurikkala: Lausekelinen ohjelmointi -kurssin luentorunko, luku 13, http://www.sis.uta.fi/~laki/luennot/luento08/ (Luettu viimeksi 11.12.2012.) [3] J. Laurikkala: Lausekelinen ohjelmointi -kurssin luentorunko, luku 24, http://www.sis.uta.fi/~laki/luennot/luento13/ (Luettu viimeksi 11.12.2012.) [4] J. Laurikkala: Lausekelinen ohjelmointi -kurssin luentorunko, luku 23, http://www.sis.uta.fi/~laki/luennot/luento13/ (Luettu viimeksi 11.12.2012.) Lausekielinen ohjelmointi Syksy 2012 Jorma Laurikkala 15 / 15