Tehtävät viikolle 2

Pakolliset tehtävät on merkitty harmalla taustavärillä. Punaisella taustavärillä merkatut ovat kontrollitehtäviä, jotka näytetään ohjaajalle harjoitustilaisuudessa!

HUOM: nimeä tiedostot otsikossa olevan sanan mukaan

JarjestettyKahvikassa

Kahvikassa

Toteuta luokka Kahvikassa, joka toteuttaa rajapinnan Laskuri.

public interface Laskuri {
	public void kasvataArvoa();
	public void vahennaArvoa();
	public int annaArvo();	
}

Toteuta luokalle konstruktori, joka ottaa parametrikseen kahvikassan omistajan nimen. Lisää luokalle myös toString()-metodi, joka tulostaa omistajan nimen ja juotujen kahvien määrän. Kahvikassan toString()-metodin tulee tulostaa esimerkiksi seuraavaa omistajalle "Matti L."

Matti L. on juonut 0 kahvia

Comparable

Lisää luokalle Kahvikassa toinen rajapinta Comparable, joka ottaa tyyppiparametrikseen rajapinnan Laskuri, ja toteuta sen vaatima metodi compareTo(Laskuri laskuri). Toteuta järjestys juotujen kahvien lukumäärän perusteella, siten, että eniten juoneet tulevat viimeisenä.

Kahvikassan järjestys

Toteuta pääohjelma siten, että kahvikassat tallennetaan ArrayList-olioon. Koska kahvikassat on lista, ja sen alkiot toteuttavat Comparable-rajapinnan, voidaan se järjestää helposti käyttämällä Javan valmista Collections-luokkakirjastoa.

Täydennä alla olevaa pääohjelmaa vinkkien perusteella.

public class JarjestettyKahvikassa {
  
  public static void main(String[] args) {
    // luo kahvikassat-olio
    
    Kahvikassa mattiV = new Kahvikassa("Matti V.");
    Kahvikassa mattiL = new Kahvikassa("Matti L.");
        
    kahvikassat.add(mattiV);
    kahvikassat.add(mattiL);
        
    mattiV.kasvataArvoa();
    mattiV.kasvataArvoa();
    System.out.println(kahvikassat);
    
    System.out.println("Järjestetään!");
    // järjestä kahvikassat
    
    System.out.println(kahvikassat);
    
    mattiL.kasvataArvoa();
    mattiL.kasvataArvoa();
    mattiL.kasvataArvoa();
    mattiL.kasvataArvoa();
    System.out.println(kahvikassat);
    
    System.out.println("Järjestetään!");    
    // järjestä kahvikassat
    
    System.out.println(kahvikassat);
  }
}

Tulostuksen pitää näyttää seuraavalta (huomioi järjestys!)

[Matti V. on juonut 2 kahvia, Matti L. on juonut 0 kahvia]
Järjestetään!
[Matti L. on juonut 0 kahvia, Matti V. on juonut 2 kahvia]
[Matti L. on juonut 4 kahvia, Matti V. on juonut 2 kahvia]
Järjestetään!
[Matti V. on juonut 2 kahvia, Matti L. on juonut 4 kahvia]

Opiskelijat

Opiskelijat pistejärjestyksessä

Ensimmäisen viikon tehtävissä toteutettiin opiskelijoiden vertailu toiseen opiskelijaan metodilla compareTo(Opiskelija opiskelija). Lisää luokalle Opiskelija luennolla nähty Javan valmis rajapinta Comparable siten, että sille asetetaan tyyppiparametriksi luokka Opiskelija. Tämän jälkeen kokeile toteutusta seuraavalla ohjelmapätkällä.

ArrayList<Opiskelija> opiskelijat = new ArrayList();
Opiskelija mattiP = new Opiskelija("Matti", "P");
mattiP.asetaKoepisteet(25);
mattiP.asetaHarjoituspisteet(25);
opiskelijat.add(mattiP);
Opiskelija mattiV = new Opiskelija("Matti", "V");
mattiV.asetaKoepisteet(10);
mattiV.asetaHarjoituspisteet(29);
opiskelijat.add(mattiV);
Opiskelija mattiL = new Opiskelija("Matti", "L");
mattiL.asetaKoepisteet(16);
mattiL.asetaHarjoituspisteet(29);
opiskelijat.add(mattiL);

System.out.println("Opiskelijat alkuperäisessä järjestyksessä:");
for(Opiskelija opiskelija: opiskelijat) {
  System.out.println(opiskelija.annaSukunimi() + ", " + opiskelija.annaEtunimi());
}
      
Collections.sort(opiskelijat);
System.out.println();
System.out.println("Opiskelijat järjestettynä:");
for(int i = 0; i < opiskelijat.size(); i++) {
	Opiskelija op = opiskelijat.get(i);
  System.out.println((i+1) + ": " + op.annaSukunimi() + ", " + op.annaEtunimi());
}

Tulostuksen tulee olla seuraavanlainen:

Opiskelijat alkuperäisessä järjestyksessä:
P, Matti
V, Matti
L, Matti

Opiskelijat järjestettynä:
1: P, Matti
2: L, Matti
3: V, Matti

Opiskelijat käänteisessä järjestyksessä

Lisää edellisen tehtävään opiskelijoiden tulostaminen käänteisessä järjestyksessä. Tulostuksen tulee olla seuraavanlainen.

Opiskelijat alkuperäisessä järjestyksessä:
P, Matti
V, Matti
L, Matti

Opiskelijat järjestettynä:
1: P, Matti
2: L, Matti
3: V, Matti

Opiskelijat käänteisessä järjestyksessä:
3: V, Matti
2: L, Matti
1: P, Matti

Arrays ja Collections

Java tarjoaa Collections-luokan kaltaisen luokkakirjaston myös taulukoille. Luokkakirjasto Arrays tarjoaa järjestämis- ja hakufunktioita taulukoile. Tässä tehtävässä toteutetaan hakeminen käyttäen kumpaakin. Voit tehdä koko tehtävän saman pääohjelman sisään.

Luominen

Kysy käyttäjältä taulukon kokoa, ja luo sen kokoinen double[] - taulukko. Luo myös ArrayList-olio, jonka tyyppiparametrina on Double.

Taulukon ja listan täyttäminen

Lisää taulukkoon ja ArrayList-olioon taulukon koon verran samoja satunnaisia liukulukuja. Saat satunnaiset liukuluvut luokkakirjaston Math tarjoamalla metodilla random().

Yksi alkio lisää

Lisää taulukkoon ja ArrayList-olioon vielä yksi liukuluku, 0.5. Huomaa että joudut luomaan uuden double[]-taulukon, jonka koko on yhtä suurempi kuin alkuperäinen, ja kopioimaan alkuperäisen taulukon sisällön uuteen taulukkoon, ennen kuin saat lisättyä uuden luvun. Kannattanee käyttää Arrays-luokkakirjaston tarjoamaa copyOf()-metodia tähän.

Järjestä taulukko ja ArrayList-olio ja testaa järjestystä

Järjestä double[]-taulukko Arrays-luokan tarjoamalla järjestysmetodilla. Järjestä ArrayList-olio Collections-luokan tarjoamalla järjestysmetodilla. Huomaa että Double-luokka toteuttaa valmiiksi Comparable-rajapinnan!

Testaa järjestystä käymällä taulukko ja ArrayList-olio läpi yksi alkio kerrallaan. Jos taulukon indeksissä i olevan alkion ja ArrayList-olion indeksissä i olevien arvojen erotus ei ole 0, tulosta virheviesti. Tulosta lopuksi merkkijono "Valmis!" Ohjelman ei pitäisi tulostaa yhtäkään virheviestiä.

Metro

Vaunupari

Yksi metrojuna muodostuu vaunupareista. Esimerkiksi tässä kuvassa metrojuna muodostuu kolmesta vaunuparista, joista vaunupari 119-120 on mainosteippailtu.

Tee luokka vaunupari, joka ottaa konstruktorissaan vaunujen numerot (kaksi kokonaislukua)

Testausohjelman runko kaikkiin seuraaviin metrotehtäviin.

public class Main {

	private static int virheita = 0;

	public static void main(String[] args) {

		// Vaunuparien luonti tähän

		System.out.println(m101_m102);

		// Testit tähän (seuraavassa tehtävässä)

		if (virheita > 0)
			System.out.println("Virheitä: " + virheita);
		else
			System.out.println("Tehtävä valmis!");
	}

	public static void virhe(String viesti) {
		virheita++;
		System.out.println("Virhe toteutuksessa: " + viesti);
	}
}

Testiohjelman tulostuksen tulee olla seuraava:

Vaunupari 101-102
Tehtävä valmis!

Raideleveys ja istumapaikkojen määrä

Jokaisessa vaunuparissa on 130 istumapaikkaa (65 / vaunu). Raideleveys on 1524mm.

Muuta vaunuparin toteutusta siten, että vaunupari toteuttaa rajapinnan Metrokalusto

public interface Metrokalusto {

    public int annaRaideleveys();
    public int annaIstumapaikkojenLkm();

}	

Testit pääohjelmaan:

if (m101_m102.annaRaideleveys() != 1524)
    virhe("Vaunuparin raideleveys ei ole oikein");

if (m101_m102.annaIstumapaikkojenLkm() != 130)
    virhe("Vaunuparissa pitää olla 130 istumapaikkaa");

Kytkentä

Vaunupareja voi kytkeä toisiinsa: video vaunuparien kytkemisestä.

Toteuta rajapinta Kytkettava, jossa on kaksi metodia: public boolean kytke(Kytkettava kytkettava) ja public boolean irrota(Kytkettava kytkettava)

Testit

		
if (m101_m102.kytke(m101_m102))
    virhe("Vaunuparia ei voi kytkeä itseensä");

if (!m101_m102.kytke(m103_m104))
    virhe("Vaunupari ei kytkeydy");

if (m101_m102.kytke(m103_m104))
    virhe("Vaunupari on jo kytketty, ei voi enää kytkeä");

if (m101_m102.irrota(m105_m106))
    virhe("Vaunuparia ei ole kytketty tähän vaunupariin");

if (!m101_m102.irrota(m103_m104))
    virhe("Vaunupari ei irroitu");

if (m101_m102.irrota(m103_m104))
    virhe("Vaunupari on jo irroitettu");

M100

Toteuta luokka M100, joka ottaa konstruktorissaan parametrinään ArrayList-listan vaunupareja.

M100 aamuJuna = new M100(aamunVaunut);  // kolme vaunuparia
M100 iltaJuna = new M100(illanVaunut);  // kaksi vaunuparia

System.out.println(aamuJuna);
System.out.println();
System.out.println(iltaJuna);

Tulosteen pitää näyttää seuraavalta:

Metrojuna: 3 vaunuparia. 
 Vaunuparit: Vaunupari 105-106 Vaunupari 103-104 Vaunupari 101-102 

Metrojuna: 2 vaunuparia.
 Vaunuparit: Vaunupari 105-106 Vaunupari 103-104

M100 metrokalusto

Myös luokka M100 toteuttaa rajapinnan Metrokalusto.

Toteuta raideleveys siten, että olio palauttaa ensimmäisen vaunuparin raideleveyden ja istumapaikkojen lukumäärä on kokoonpanon vaunujen istumapaikkojen yhteenlaskettu määrä.

Testit

if (aamuJuna.annaRaideleveys() != 1524)
    virhe("Junan raideleveys ei ole oikein");

if (aamuJuna.annaIstumapaikkojenLkm() != 390)
    virhe("Täysipitkässä junassa on pitää olla 390 istumapaikkaa");

if (iltaJuna.annaIstumapaikkojenLkm() != 260)
    virhe("2/3 junassa on pitää olla 260 istumapaikkaa");

Deeveri

Toteuta seuraava tilanne: Dv12 dieselveturi 2717 vetää perässään vaunuparia.

Toteuta siis luokka Dv12 joka toteuttaa rajapinnan Kytkettava

Dv12 deeveri_2717 = new Dv12(2717);
System.out.println(deeveri_2717);
System.out.println();

if (!deeveri_2717.kytke(m103_m104))
    virhe("Vaunupari ei kytkeydy");

System.out.println(deeveri_2717);

if (deeveri_2717.kytke(m103_m104))
    virhe("Vaunupari on jo kytketty, ei voi enää kytkeä");

if (deeveri_2717.irrota(m105_m106))
    virhe("Vaunuparia ei ole kytketty tähän deeveriin");

if (!deeveri_2717.irrota(m103_m104))
    virhe("Vaunupari ei irroitu");

if (deeveri_2717.irrota(m103_m104))
    virhe("Vaunupari on jo irroitettu");

Ylläolevan testiohjelman tulostus on seuraava:

Dv12 2717

Dv12 2717
 kytketty: Vaunupari 103-104

Deeveri 3x

Toteuta seuraava tilanne: Kolme deeveriä kytketty toisiinsa.

if (!deeveri_2555.kytke(deeveri_2730))
    virhe("Dv12 2555 ei kytkeydy Dv12 2730");

if (!deeveri_2714.kytke(deeveri_2555))
    virhe("Dv12 2714 ei kytkeydy Dv12 2555");

System.out.println(deeveri_2730);
System.out.println(deeveri_2555);
System.out.println(deeveri_2714);

Tulostuksen pitää olla seuraava:

Dv12 2730
Dv12 2555
 kytketty: Dv12 2730
Dv12 2714
 kytketty: Dv12 2555
 kytketty: Dv12 2730	

Mäkihyppy

Mäkihyppääjä ja kilpailun alku

Toteutetaan ensimmäinen versio mäkihyppääjää kuvaavasta luokasta.

Hyppääjällä on nimi sekä tieto ensimmäisen ja toisen hypyn pituudesta. Tässä vaiheessa hyppyihin ei vielä liity tyylipisteitä. Voit olettaa, että hyppyjen pituuksien tyyppi on int.

Kilpailu kuvataan myös omana luokkanaan. Kilpailulla on nimi ja kilpailuun liittyy joukko hyppääjiä. Kilpailu talettaa hyppääjäoliot ArrayList:iin. Hyppääjät luodaan Kilpailun konstruktorin suorituksen yhteydessä. Voit joko kysyä hyppääjien nimet käyttäjältä, vai "kovakoodata" ohjelmaan joukon hyppääjiä:

	
  hyppaajat.add(new Makihyppaaja("Nykänen"));
  hyppaajat.add(new Makihyppaaja("Ahonen"));
  hyppaajat.add(new Makihyppaaja("Olli"));
  hyppaajat.add(new Makihyppaaja("Amman"));

Ensimmäinen hyppykierros

Pääohjelma luo kilpailuolion ja kutsuu sen metodia kayKilpailu(). Ruvetaan toteuttamaan metodia ja tehdään hyppääjäluokkaan tarvittavat lisäykset.

Kilpailun aluksi hyppääjät laitetaan satunnaiseen hyppyjärjestykseen. Luokasta Collections löytyy tähän valmis metodi, etsi metodi Java API:sta. Hyppyjärjestys tulostetaan näytölle:

	
Garmisch-Partenkirchen 2010 
1. kierroksen hyppyjärjestys: 
 Amman
 Ahonen
 Olli
 Nykänen

Toteuta hyppääjille metodi public int hyppaa(int kierros), joka arpoo annetun kierroksen hypylle pituuden. Hypyn pituuden tulee olla 60-120 metriä. Ohjeet kokonaisluvun arpomiseen löytyvät tämän viikon luentomateriaalista. Metodi palauttaa hypyn pituuden, jotta kutsuja voi tulostaa sen.

Kilpailu-olion kayKilpailu()-metodi laittaa jokaisen hyppääjän hyppäämään ensimmäisen kierroksen hyppynsä. Hyppyjen tiedot myös tulostetaan:

	
ensimmäinen kierros:
 Amman 1. kierroksella 68 metriä
 Ahonen 1. kierroksella 88 metriä
 Olli 1. kierroksella 92 metriä
 Nykänen 1. kierroksella 72 metriä

Hyppääjien vertailu

Jotta tuloslista eli ArrayList:issa olevat hyppääjäliot voidaan järjestää, on hyppääjien toteutettava rajapinta Comparable. Mäkihyppääjien vertailu perustuu hyppyjen pituuteen.

Ensimmäisen kierroksen jälkeinen järjestys tulostetaan:

ensimmäisen kierroksen tulokset:
1. Olli ensimmäinen hyppy: 92 metriä
2. Ahonen ensimmäinen hyppy: 88 metriä
3. Nykänen ensimmäinen hyppy: 72 metriä
4. Amman ensimmäinen hyppy: 68 metriä

Huom: vaikka kayKilpailu() on toistaiseksi ainoa luokan Kilpailu julkinen metodi, älä laita kaikka toiminnalisuutta suoraan metodin sisään vaan määrittele luokalle sopivia apumetodeja, jotka huolehtivat esim. yhden hyppykierroksen hyppäämisestä.

Toinen kierros ja lopputulokset

Toinen kierros hypätään ensimmäisen kierrosten tuloksen mukaisessa käänteisessä järjestyksessä:

toinen kierros:
 Amman 2. kierroksella 78 metriä
 Nykänen 2. kierroksella 86 metriä
 Ahonen 2. kierroksella 58 metriä
 Olli 2. kierroksella 70 metriä

Lopulta tulostetaan tuloslista, jonka järjestys perustuu hyppyjen yhteenlaskettuun pituuteen.

Garmisch-Partenkirchen 2010 lopputulokset:
1. Olli ensimmäinen hyppy: 92 metriä,toinen hyppy: 70 metriä
2. Nykänen ensimmäinen hyppy: 72 metriä,toinen hyppy: 86 metriä
3. Ahonen ensimmäinen hyppy: 88 metriä,toinen hyppy: 58 metriä
4. Amman ensimmäinen hyppy: 68 metriä,toinen hyppy: 78 metriä

Hyppyolio ja tyylipisteet

Muutetaan hyppääjää siten, että hyppääjä ei suoraan talleta hyppyjen pituuksia, vaan hypin tiedot tallettaa luokan Hyppy olio. Hypyllä on pituuden lisäksi tyylipisteet. Tyylipisteet talletetaan 5:n kokoiseen taulukkoon. Voit olettaa, että tyylipisteet ovat todellisuudesta poiketen kokonaislukuja. Hypyn pituudelle ja tyylipisteille arvotaan arvot hypyn konstruktorissa.

Kokonaispisteiden laskeminen

Hyppääjien vertailu perustuu tyylipisteiden ja hypyn pituuden perusteella laskettavaan kokonaispistemäärään. Muuta ohjelmaasi siten, että se laskee hyppääjien pisteet wikipediassa esitetyn mukaan. Oleta, että mäen K-piste on 90

Hyppyjen yhteydessä tulostataan pituuden lisäksi tyylipisteet:

	
ensimmäinen kierros:
 Nykänen 1. kierroksella 91 metriä
  tyylipisteet   tyylipisteet 11 18 13 16 12
 Ahonen 1. kierroksella 96 metriä
  tyylipisteet   tyylipisteet 15 14 18 18 17
 Olli 1. kierroksella 62 metriä
  tyylipisteet   tyylipisteet 17 19 20 13 16
 Amman 1. kierroksella 52 metriä
  tyylipisteet   tyylipisteet 15 20 11 11 19

Järjestäminen siis tapahtuu pisteiden perusteella. Tuloslistoissa ilmoitetaan myös hyppyjen pituudet:

	
Garmisch-Partenkirchen 2010 lopputulokset:
1. Ahonen pisteitä 222 ensimmäinen hyppy: 96 metriä, toinen hyppy: 74 metriä
2. Nykänen pisteitä 213 ensimmäinen hyppy: 91 metriä, toinen hyppy: 71 metriä
3. Olli pisteitä 202 ensimmäinen hyppy: 62 metriä, toinen hyppy: 81 metriä
4. Amman pisteitä 170 ensimmäinen hyppy: 52 metriä, toinen hyppy: 68 metriä

Sokkelolle jatkoa

Tämä tehtäväsarja jatkaa viime viikolla tehtyä Sokkelo-sarjaa.

Pisteet

Lisää pelaajalle attribuutti pisteet, joka saa alkuarvokseen 1000. Muuta pelaajan toteutusta myös siten, että jokainen liikkuminen vähentää pisteitä yhdellä.

Muuta pelaajan toString()-metodin toteutusta siten, että se tulostaa sijainnin lisäksi myös pisteet pelaajan pisteet. Sokkelo-ohjelman tulostuksen tulee olla seuraavanlainen muutoksen jälkeen:

XXXXXXXXXXXXX
XO  X X     X
X X   X XXX X
X XXX     X X
X X X XXX   X
X X   X X X X
X   X     X M
XXXXXXXXXXXXX
Pelaaja sijainnissa (1, 1), pisteet 1000

Anna liikkumissuunta: o
XXXXXXXXXXXXX
X O X X     X
X X   X XXX X
X XXX     X X
X X X XXX   X
X X   X X X X
X   X     X M
XXXXXXXXXXXXX
Pelaaja sijainnissa (2, 1), pisteet 999

Anna liikkumissuunta: y
Ei voi liikkua!
Anna liikkumissuunta: o
XXXXXXXXXXXXX
X  OX X     X
X X   X XXX X
X XXX     X X
X X X XXX   X
X X   X X X X
X   X     X M
XXXXXXXXXXXXX
Pelaaja sijainnissa (3, 1), pisteet 998

Anna liikkumissuunta: 

Aarre

Lisätään sokkeloon aarteita. Aarre merkitään sokkeloa esittävässä taulukossa arvolla 3, ja piirretyssä sokkelossa merkillä 'A'. Luo luokka Aarre jolla on sijainti, eli x ja y-koordinaatit, ja lisää aarteiden huomioonottaminen Sokkelo-luokkaan. Aarteet kannattanee tallettaa ArrayList-tyyppiseen olioon.

Aarteita voi olla sokkelossa useampia kuin yksi, esimerkiksi seuraavassa sokkelossa on kaksi aarretta.

int[][] taulukko = {
	{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
	{1, 2, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1},
	{1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1},
	{1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1},
	{1, 0, 1, 3, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1},
	{1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1},
	{1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, -1},
	{1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1},
	{1, 0, 1, 0, 0, 0, 1, 0, 1, 3, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1},
	{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};

Sokkelo-ohjelman ajaminen yllä olevalla taulukolla tuottaa seuraavanlaisen tulosteen:

XXXXXXXXXXXXXXXXXXXXX
XO  X X     X X X  XX
X X   X XXX X    X  X
X XXX     X X XX  X X
X XAX XXX        XX X
X X   X X X XXX   X X
X   X   X X   X X X M
X X X X     X X X   X
X X   X XAX     X X X
XXXXXXXXXXXXXXXXXXXXX
Pelaaja sijainnissa (1, 1), pisteet 1000
Anna liikkumissuunta: 

Sijaitseva

Rajapinta sijaitseva määrittellään seuraavasti:

public interface Sijaitseva {
  public int annaX();
  public int annaY();
  public char annaMerkki();
  public boolean onkoSijainnissa(int x, int y);
}

Muuta luokkien Aarre ja Pelaaja toteutusta siten, että ne toteuttavat rajapinnan Sijaitseva. Muuta myös sokkelon tulostamista siten, että Sijaitseva-rajapinnan toteuttavat oliot tulostetaan sokkeloon niiden annaMerkki()-metodin palauttaman merkin avulla.

Aarteiden kerääminen

Kun pelaaja liikkuu aarteen päälle, eli kun pelaajan ja aarteen sijainti on sama, pelaaja saa 100 pistettä ja aarre poistetaan kartalta. Toteuta aarteen kerääminen. Ohjelman tulostuksen tulee olla seuraavanlainen:

XXXXXXXXXXXXXXXXXXXXX
XO  X X     X X X  XX
X X   X XXX X    X  X
X XXX     X X XX  X X
X XAX XXX        XX X
X X   X X X XXX   X X
X   X   X X   X X X M
X X X X     X X X   X
X X   X XAX     X X X
XXXXXXXXXXXXXXXXXXXXX
Pelaaja sijainnissa (1, 1), pisteet 1000

Anna liikkumissuunta: a
XXXXXXXXXXXXXXXXXXXXX
X   X X     X X X  XX
XOX   X XXX X    X  X
X XXX     X X XX  X X
X XAX XXX        XX X
X X   X X X XXX   X X
X   X   X X   X X X M
X X X X     X X X   X
X X   X XAX     X X X
XXXXXXXXXXXXXXXXXXXXX
Pelaaja sijainnissa (1, 2), pisteet 999

Anna liikkumissuunta: a

...

XXXXXXXXXXXXXXXXXXXXX
X   X X     X X X  XX
X X   X XXX X    X  X
X XXX     X X XX  X X
X XAX XXX        XX X
X XO  X X X XXX   X X
X   X   X X   X X X M
X X X X     X X X   X
X X   X XAX     X X X
XXXXXXXXXXXXXXXXXXXXX
Pelaaja sijainnissa (3, 5), pisteet 992

Anna liikkumissuunta: y
XXXXXXXXXXXXXXXXXXXXX
X   X X     X X X  XX
X X   X XXX X    X  X
X XXX     X X XX  X X
X XOX XXX        XX X
X X   X X X XXX   X X
X   X   X X   X X X M
X X X X     X X X   X
X X   X XAX     X X X
XXXXXXXXXXXXXXXXXXXXX
Pelaaja sijainnissa (3, 4), pisteet 1091

Anna liikkumissuunta: a
XXXXXXXXXXXXXXXXXXXXX
X   X X     X X X  XX
X X   X XXX X    X  X
X XXX     X X XX  X X
X X X XXX        XX X
X XO  X X X XXX   X X
X   X   X X   X X X M
X X X X     X X X   X
X X   X XAX     X X X
XXXXXXXXXXXXXXXXXXXXX
Pelaaja sijainnissa (3, 5), pisteet 1090

...

ArrayList-luokassa on metodin remove(), jolla voidaan poistaa tietty alkio listalta. Huomaa kuitenkin että jos alkio poistetaan kesken listan läpikäynnin siten, että listan läpikäyntiä jatketaan, päädytään todennäköisesti indeksiongelmiin. Aarteen löytyessä kannattakin tämän hetkisellä osaamisellamme ottaa viite siitä ylös, ja poistaa se toiston jälkeen.

Mörkö!

Mikään sokkelo ei olisi tarpeeksi haasteellinen ilman mörköä.

Merkitään mörkö sokkeloon numerolla 99, ja kirjaimella 'W'. Toteuta Morko-luokka siten, että se toteuttaa rajapinnan Sijaitseva. Lisää mörölle myös metodi liiku(), joka liikuttaa mörköä satunnaiseen suuntaan siten, ettei se voi kävellä seinien läpi. Kutsu mörön metodia liiku() aina pelaajan liikkumisen jälkeen. Liikuta mörköä vain jos se ei ole samassa ruudussa pelaajan kanssa.

Voit luoda Morko-olion Sokkelo-luokan konstruktorissa, ja antaa sille viitteen luotavaan Sokkelo-olioon esimerkiksi seuraavasti.

if (this.sokkelo[rivi][alkio] == 99) {
  this.morko = new Morko(this, alkio, rivi);
  this.sokkelo[rivi][alkio] = 0; // oletetaan että alkio on tyhjä muuten, mörön tulostus tapahtuu erikseen
}

Kokeile mörön toteutusta seuraavalla sokkelolla.

int[][] taulukko = {
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
  {1, 2, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1},
  {1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1},
  {1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1},
  {1, 0, 1, 3, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1},
  {1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1},
  {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, -1},
  {1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1},
  {1, 0, 1, 0, 0, 99, 1, 0, 1, 3, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1},
  {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};

Pelin tulostus voi olla esimerkiksi seuraavanlainen.

XXXXXXXXXXXXXXXXXXXXX
XO  X X     X X X  XX
X X   X XXX X    X  X
X XXX     X X XX  X X
X XAX XXX        XX X
X X   X X X XXX   X X
X   X   X X   X X X M
X X X X     X X X   X
X X  WX XAX     X X X
XXXXXXXXXXXXXXXXXXXXX
Pelaaja sijainnissa (1, 1), pisteet 1000

Anna liikkumissuunta: a
XXXXXXXXXXXXXXXXXXXXX
X   X X     X X X  XX
XOX   X XXX X    X  X
X XXX     X X XX  X X
X XAX XXX        XX X
X X   X X X XXX   X X
X   X   X X   X X X M
X X XWX     X X X   X
X X   X XAX     X X X
XXXXXXXXXXXXXXXXXXXXX
Pelaaja sijainnissa (1, 2), pisteet 999

Pelaajan syöminen

Annetaan mörölle mahdollisuus pelaajan syömiseen.

Jos mörkö ja pelaaja ovat samassa ruudussa, pelaaja menettää 500 pistettä ja peli päättyy. Pelin päättyessä syödyksi tulemiseen tulostetaan teksti "-- NOM NOM NOM --".

Pelin tulostus voisi olla esimerkiksi seuraavanlainen

XXXXXXXXXXXXXXXXXXXXX
XO  X X     X X X  XX
X X   X XXX X    X  X
X XXX     X X XX  X X
X XAX XXX        XX X
X X   X X X XXX   X X
X   X   X X   X X X M
X X X X     X X X   X
X X  WX XAX     X X X
XXXXXXXXXXXXXXXXXXXXX
Pelaaja sijainnissa (1, 1), pisteet 1000

Anna liikkumissuunta: a
XXXXXXXXXXXXXXXXXXXXX
X   X X     X X X  XX
XOX   X XXX X    X  X
X XXX     X X XX  X X
X XAX XXX        XX X
X X   X X X XXX   X X
X   X   X X   X X X M
X X XWX     X X X   X
X X   X XAX     X X X
XXXXXXXXXXXXXXXXXXXXX
Pelaaja sijainnissa (1, 2), pisteet 999

Anna liikkumissuunta: a
XXXXXXXXXXXXXXXXXXXXX
X   X X     X X X  XX
X X   X XXX X    X  X
XOXXX     X X XX  X X
X XAX XXX        XX X
X X   X X X XXX   X X
X   X   X X   X X X M
X X X X     X X X   X
X X  WX XAX     X X X
XXXXXXXXXXXXXXXXXXXXX
Pelaaja sijainnissa (1, 3), pisteet 998

... 

Anna liikkumissuunta: a
XXXXXXXXXXXXXXXXXXXXX
X   X X     X X X  XX
X X   X XXX X    X  X
X XXX     X X XX  X X
X XAX XXX        XX X
X X   X X X XXX   X X
X   X   X X   X X X M
X XOX X     X X X   X
X X  WX XAX     X X X
XXXXXXXXXXXXXXXXXXXXX
Pelaaja sijainnissa (3, 7), pisteet 992

Anna liikkumissuunta: a
XXXXXXXXXXXXXXXXXXXXX
X   X X     X X X  XX
X X   X XXX X    X  X
X XXX     X X XX  X X
X XAX XXX        XX X
X X   X X X XXX   X X
X   X   X X   X X X M
X X XWX     X X X   X
X XO  X XAX     X X X
XXXXXXXXXXXXXXXXXXXXX
Pelaaja sijainnissa (3, 8), pisteet 991

Anna liikkumissuunta: o
XXXXXXXXXXXXXXXXXXXXX
X   X X     X X X  XX
X X   X XXX X    X  X
X XXX     X X XX  X X
X XAX XXX        XX X
X X   X X X XXX   X X
X   X   X X   X X X M
X X X X     X X X   X
X X OWX XAX     X X X
XXXXXXXXXXXXXXXXXXXXX
Pelaaja sijainnissa (4, 8), pisteet 990

Anna liikkumissuunta: o
XXXXXXXXXXXXXXXXXXXXX
X   X X     X X X  XX
X X   X XXX X    X  X
X XXX     X X XX  X X
X XAX XXX        XX X
X X   X X X XXX   X X
X   X   X X   X X X M
X X X X     X X X   X
X X  WX XAX     X X X
XXXXXXXXXXXXXXXXXXXXX
Pelaaja sijainnissa (5, 8), pisteet 489

-- NOM NOM NOM --