- COMP.CS.140
- 5. Periytyminen
- 5.6 ⌛⌛ Sanan arvaus
⌛⌛ Sanan arvaus¶
Tehtävään on tarjolla valmista materiaalia etätietovarastossa:
Materiaali on varaston
round5/wordgame
-hakemistossa.WordGameTest.java
: valmis testiohjelma toteutuksesi testaamiseen.words.txt
: ohjelman tuntemat sanat.input1.txt
jaoutput1.txt
: testisyöte ja sitä vastaava tuloste.input2.txt
jaoutput2.txt
: testisyöte ja sitä vastaava tuloste.
Johdanto¶
Eräs klassinen sanan arvauspeli etenee alla kuvatulla tavalla. Pelissä on osapuolina pelinjohtaja, joka voi olla esimerkiksi tietokone, sekä pelaaja.
Pelinjohtaja valitsee jonkin sanan näyttämättä sitä pelaajalle, ja lisäksi on määritetty suurin sallittu virheiden (virheellisten arvausten) määrä. Tämän jälkeen askelia 2 ja 3 toistetaan vuorotellen niin kauan, kunnes joko pelaaja arvaa koko sanan, tai pelaajan tekemien virheiden määrä ylittää suurimman sallitun määrän.
Pelinjohtaja näyttää pelaajalle valitsemansa sanan nykytilanteen niin, että jokaisen toistaiseksi tuntemattoman kirjaimen kohdalla on merkki ‘_’.
Pelaajan vuoro. Pelaaja arvaa joko yksittäisen kirjaimen tai koko sanan.
Jos pelaaja päättää arvata koko sanan, pitää arvauksen mennä täsmälleen oikein.
Ellei pelaajan arvaus ole täsmälleen oikein, tulkitaan arvaus virheeksi. Tällöin virheiden määrää kasvatetaan yhdellä eikä sanasta paljasteta mitään lisätietoa ellei peli pääty (katso alla).
Jos arvattu sana oli täsmälleen oikein, peli päättyy pelaajan voittoon.
Jos pelaaja arvaa yksittäisen kirjaimen, niin:
Jos kirjain esiintyy pelinjohtajan sanassa, pelinjohtaja paljastaa kaikki kyseisen kirjaimen esiintymät sanasta. Jos sana tulee oikein arvatun kirjaimen myötä kokonaan arvatuksi, peli päättyy pelaajan voittoon.
Jos kirjainta ei esiinny sanassa tai kirjain oli jo aiemmin arvattu, on kyseessä virhe. Tällöin virheiden määrää kasvatetaan yhdellä.
Jos pelaajan virheiden määrä ylittää suurimman sallitun määrän, loppuu peli pelaajan häviöön. Samalla pelinjohtaja paljastaa valitsemansa sanan kokonaisuudessaan pelaajalle.
Pelin toteutus¶
Tehtävän palautus koostuu Maven-projektista. Sijoita pom.xml
-tiedosto paikallisen tietovarastosi
round5/wordgame
-hakemistoon ja tee tähän hakemistoon src/main/java
-niminen alihakemisto.
Tee luokkatiedostot WordGame.java ja GameStateException.java ja liitä ne
fi.tuni.prog3.wordgame
-nimiseen pakkaukseen. Tiedostojesi tulee olla siten hakemistossa
round5/wordgame/src/main/java/fi/tuni/prog3/wordgame
.
Toteuta sanan arvauspeli luokkana WordGame
, jolla on seuraavat julkiset ominaisuudet:
Sisäinen staattinen luokka
WordGameState
, jonka olioon voi tallettaa pelin tilanteen: sanan, tehtyjen virheiden lukumäärän, suurimman sallitun virheiden lukumäärän sekä sanan toistaiseksi tuntemattomien kirjainten (paljastamattomien merkkien ‘_’) lukumäärän. Staattinen sisäinen luokka poikkeaa hieman tavallisesta sisäisestä luokasta. Tärkein ero on se, että staattisen sisäisen luokan saatavilla ovat ulkoisesta luokasta ainoastaan sen staattiset piirteet. Tästä ei tarvitse huolestua, koskaWordGameState
-luokan ei tässä tehtävässä pitäisi käsitellä ulkoista luokkaansaWordGame
millään tavalla. Muista vain lisätä sisäisen luokan otsikkoonstatic
-määre.Tilaan talletetaan sana sellaisena, kuin se näytettäisiin pelaajalle: arvaamattomat kirjaimet esitetään merkeillä ‘_’.
Julkiset funktiot
String getWord()
,int getMistakes()
,int getMistakeLimit()
jaint getMissingChars()
, jotka palauttavat asianomaiset arvot.Tee
WordGame
-luokkaan kätkettyWordGameState
-tyyppinen attribuutti, jos haluat hyödyntääWordGameState
-luokkaa pelin logiikan toteuttamiseen tarvittavien tietojen säilyttämiseen. Jos toimit näin, niin palauta attribuutin (päivitetty) arvo, kun jostainWordGame
-luokan metodista on tarpeen palauttaa pelin tila. Toinen vaihtoehto on tehdäWordGame
-luokkaan lisäattribuutteja, joissa on samoja tietoja kuinWordGameState
-luokassa ja luodaWordGameState
-luokasta olio lisäattribuuttien arvojen avulla aina, kun on tarpeen palauttaa pelin tila.Ei yhtään julkista rakenninta! Tee kätketty rakennin, jotta Java ei tee automaattisesti julkista oletusrakenninta.
Rakennin
WordGame(String wordFilename)
, joka lukee pelissä käytettävissä olevat sanat parametrin ilmoittamasta tiedostosta.Tiedoston oletetaan sisältävän yhden sanan per rivi ilman ylimääräistä tyhjää tilaa.
Tee
WordGame
-luokalle säiliötyyppinen kätketty attribuutti sanojen tallentamiseen. TaulukkolistaArrayList<String>
lienee tähän tehtävään sopivin säiliö. Luo rakentajassa säiliöolio ja liitä se attribuutin arvoksi. Lisää sanat rakentajassa säiliöön samassa järjestyksessä kuin ne ovat tiedostossa.Alempana viitataan sanan indeksiin. Ensimmäisen luetun sanan indeksi on 0, toiseksi luetun sanan indeksi on 1 ja niin edelleen. Lisäksi alempana oletetaan, että sanojen kokonaislukumäärä on
N
.Tee
WordGame
-luokalle kätketty attribuutti, jonka arvo ilmaisee onko peli käynnissä (aktiivinen) vai pysähdyksissä (passivinen). Aseta tälle attribuutille rakentajassa arvo, joka kertoo pelin olevan pysähdyksissä. Attribuutin luontevin tyyppi lieneeboolean
.
Jäsenfunktio
void initGame(int wordIndex, int mistakeLimit)
aloittaa uuden pelin. Rakentajan ensimmäinen parametri määrää arvattavan sanan siten, että sanojen säiliöstä valitaan sana, jonka indeksiarvo onwordIndex % N
. Aseta valittu sanaWordGame
-luokan kätketyn attribuutin arvoksi. Toinen parametrimistakeLimit
kertoo sallittujen virheiden maksimimäärän. Tämän tiedon voi säilöä vaihtoehtoisesti pelin tilalle tehtyynWordGameState
-tyyppisen attribuutin olioon, kun nyt luot ja asetat attribuutille arvon tai jonkin toisenWordGameState
-attribuutin arvoksi. Alusta samalla muut tarvittavat attribuutit, jos toteutatWordGame
-luokan ilmanWordGameState
-attribuuttia. Uusi peli aloitetaan välittömästi riippumatta siitä, oliko aiempi peli mahdollisesti vielä käynnissä. Aseta siksi pelin käynnissäolon tuntevalle attribuutille arvoksi suoraan tieto siitä, että peli on käynnissä.Jäsenfunktio
boolean isGameActive()
, joka palauttaa tiedon, onko peli parhaillaan käynnissä.Jäsenfunktio
WordGameState getGameState()
, joka palauttaa pelin tämänhetkisen tilanteen kuvaavanWordGameState
-olion.Heittää poikkeuksen
GameStateException("There is currently no active word game!")
, ellei peli ole parhaillaan käynnissä.Palauta joko
WordGameState
-tyyppisen attribuutin arvo tai palautaWordGame
-luokan attribuuttien arvojen avulla luotuWordGameState
-tyyppinen olio.
Jäsenfunktio
WordGameState guess(char c)
, joka päivittää pelin tilan vastaamaan kirjaimenc
arvausta ja palauttaa päivitetyn tilan kuvaavanWordGameState
-olion.Tarkista aivan aluksi onko peli käynnissä. Heitä poikkeus
GameStateException("There is currently no active word game!")
, jos peli on pysäytetty.Vertaile arvattua kirjainta arvattavan sanan kirjaimiin siten, että aakkoston kokoa ei huomioida. Esimerkiksi suuraakkonen A ja pienaakkonen a katsotaan samaksi merkiksi.
Peli pysähtyy, jos sana on arvauksen myötä arvattu kokonaan oikein tai väärien arvausten lukumäärä ylittyy. Päivitä tarvittaessa pelin käynnissäolon tuntevalle attribuutille arvoksi tieto siitä, että peli on pysähtynyt.
Palauta joko
WordGameState
-tyyppisen attribuutin päivitetty arvo tai palautaWordGame
-luokan attribuuttien arvojen avulla luotuWordGameState
-tyyppinen olio.
Jäsenfunktio
WordGameState guess(String word)
, joka päivittää pelin tilan vastaamaan arvaustaword
ja palauttaa päivitetyn tilan kuvaavanWordGameState
-olion. Funktio toimii vertailua lukuun ottamatta aivan kuinWordGameState guess(char c)
-funktio. Tässä funktiossa verrataan merkkien asemasta kokonaista arvattua sanaa arvattavaan sanaan.
Edellä viitattiin tyyppiä GameStateException
oleviin poikkeuksiin. Tällaista poikkeusluokkaa
ei ole valmiina vaan sekin pitää toteuttaa erikseen. Toteuta siis edellisten lisäksi luokka
GameStateException
, joka perii Javan luokkakirjaston luokan Exception
ja jonka ainoa jäsen
on julkinen muotoa GameStateException(String msg)
oleva rakennin, joka ainoastaan välittää
parametrin “msg” yliluokan rakentimelle. Kyseessä on siis varsin yksinkertainen luokka.
Alla tarjottu testimateriaali selventänee luokalta WordGame
odotettua toimintaa.
Automaattiset sekä alla kuvatut testit olettavat, että teet projektitiedostoosi pom.xml
seuraavat määritykset:
artifactId
-elementin arvo onwordgame
.version
-elementin arvo on1.0
.maven.compiler.source
jamaven.compiler.target
-elementtien arvo on17
tai pienempi. Tarkistimella on asennettuna Java 17, joten tätä uudempaa versiota ei voi käyttää.Onejar-liitännäisen määritys, jonka
mainClass
-elementin arvo onWordGameTest
, joka on alla kuvattu valmiina annettu testiluokka.
Toteutuksen testaus¶
Voit testata luokkiasi tiedostossa WordGameTest.java
annetun valmiin testiohjelman,
tiedostoissa words.txt
, input1.txt
ja input2.txt
annettujen testidatojen ja
tiedostoissa output1.txt
ja output2.txt
annettujen esimerkkitulosteiden avulla.
Aseta WordGameTest.java
Maven-projektisi alihakemiston src/main/java
juureen ja muut
tiedostot Maven-projektisi juurihakemistoon pom.xml
tiedoston seuraksi. Edellä on huomattava,
että WordGameTest.java
ei sisällä pakkausmääritystä, joten sitä ei siksi aseteta syvempään
alihakemistoon.
Voit tämän jälkeen kääntää ohjelman komennolla mvn package
ja suorittaa testin X
antamalla komennon
java -jar target/wordgame-1.0.one-jar.jar words.txt inputX.txt
projektin juurihakemistossa. Numeroa X
käyttävän suorituksen pitäisi tuottaa vastaavassa
tiedostossa outputX.txt
kuvattu tuloste. Huomaa, että
kaikki tulostukset tapahtuvat testiohjelmassa. Luokan WordGame
funktiot eivät tulosta mitään.
A+ esittää tässä kohdassa tehtävän palautuslomakkeen.