/* Tehtävä 2. Arvostelusta. * * Max. pisteet 8. Jakautui (2+2+2+2) jokaiselle kohdalle a-d. * * Tarkastaja Asko Saura, as@iki.fi * * En rokottanut pienistä huolimattomuusvirheistä, mikäli osoitti * toisaalla yksiselitteisesti, että tietää metodilla olevan tyhjätkin * sulut tms. Samoin lohkon lopettavien aaltosulkujen "}" puutteen * sai anteeksi. *kumarrus* * * Hyvät vastaukset, joita saattoi vain arvostaa, muttei arvostella, * saivat Nalle Puh & Nasu -leiman, poislukien joku yksi nippu, jota * tarkastaessani leima oli kotona. * * Mallivastaukset seuraavasti: * 2a) public class Pelaaja Pelaaja.java * 2b-c) public final class PelaajaKirjasto PelaajaKirjasto.java * 2d) public class Peli Peli.java * * sijaitsevat osoitteessa: * http://iki.fi/as/JOkoeS98/ * * Sivua ylläpidetään helmikuun loppuun. * */ /////////////////////////////////////////////////////////////////////// public class Pelaaja { public static final int MIN_MYÖNTEISYYS = -10; public static final int MAX_MYÖNTEISYYS = 10; public static final double MIN_VOIMA = 0.0; public static final double MAX_VOIMA = 1.0; private static final String OLETUSNIMI = "(ei nimeä)"; private static final String OLETUSKUVAUS = "(ei kuvausta)"; private String nimi; // ei null private String kuvaus; // ei null private int myönteisyys; // [MIN_MYÖNTEISYYS,MAXMYÖNTEISYYS] private double voimakkuus; // [MIN_VOIMA,MAX_VOIMA] public Pelaaja(String uusiNimi, String uusiKuvaus, int uusiMyönteisyys, double uusiVoimakkuus) { this.asetaNimi(uusiNimi); this.asetaKuvaus(uusiKuvaus); this.asetaMyönteisyys(uusiMyönteisyys); this.asetaVoimakkuus(uusiVoimakkuus); } public boolean asetaVoimakkuus(double uusiVoimakkuus) { this.voimakkuus = validoiVoimakkuus(uusiVoimakkuus); return this.voimakkuus == uusiVoimakkuus; } public boolean asetaMyönteisyys(int uusiMyönteisyys) { this.myönteisyys = validoiMyönteisyys(uusiMyönteisyys); return this.myönteisyys == uusiMyönteisyys; } public boolean asetaNimi(String uusiNimi) { if(uusiNimi == null) { this.nimi = OLETUSNIMI; return false; } else { this.nimi = uusiNimi; return true; } } public boolean asetaKuvaus(String uusiKuvaus) { if(uusiKuvaus == null) { this.kuvaus = OLETUSKUVAUS; return false; } else { this.kuvaus = uusiKuvaus; return true; } } public String annaNimi() { return this.nimi; } public String annaKuvaus() { return this.kuvaus; } public int annaMyönteisyys() { return this.myönteisyys; } public double annaVoimakkuus() { return this.voimakkuus; } public double annaPainoarvo() { return this.myönteisyys * this.voimakkuus; } public String toString() { return "Pelaajan nimi: "+this.nimi+ "\n kuvaus: "+this.kuvaus+ "\n myönteisyys: "+this.myönteisyys+ "\n voimakkuus: "+this.voimakkuus+ "\n painoarvo: "+this.annaPainoarvo(); } public static int validoiMyönteisyys(int koeMyönteisyys) { if (koeMyönteisyys < MIN_MYÖNTEISYYS) return MIN_MYÖNTEISYYS; else if (koeMyönteisyys > MAX_MYÖNTEISYYS) return MAX_MYÖNTEISYYS; else return koeMyönteisyys; } public static double validoiVoimakkuus(double koeVoimakkuus) { if (koeVoimakkuus < MIN_VOIMA) return MIN_VOIMA; else if (koeVoimakkuus > MAX_VOIMA) return MAX_VOIMA; else return koeVoimakkuus; } } /* 2 a) Arvostelusta. * * Max. pisteet 2 * * Josta pois: * * -1 Ei tehty Sanity Checkejä (tarkistettu ja korjattu virheellisiä * parametrejä. Sallitut arvoalueethan * ovat tiedossa.) * -½ tai -1 Puuttuvia ominaisuuksia. * * -1 Lue-luokan käyttö täällä (esim. konstruktorissa, tai * tai sanity checkissä.) * Tämä on väärä suunnittelupäätös. Tietorakenteen * konstruktori ei lue keneltäkään, vaan arvaa parhaan kykynsä * mukaan tai kertoo ohjelmallisesti epäonnistuneensa. * Exceptionit ovat sallittuja ja suositeltavia. * * Kuitenkin pääpiirteissään oikea vastaus sai puolikkaan pisteen, * vaikka olisikin pari virhettä. * * Nollat sai, mikäli ei osannut tehdä konstruktoreja tai metodeja. * * this:in käyttöä ei arvosteltu. * * Tähän kelpasi vastaukseksi hyvin minimalistinenkin Pelaaja-luokka, * kunhan sitä kykeni käyttämään muissa kohdissa (b-d). */ ////////////////////////////////////////////////////////////////////// /* 2 b-c) */ public final class PelaajaKirjasto { private PelaajaKirjasto() {} /* Arvostelusta. * * Tätä ei vaadittu. On OK laittaa nämä metodit Pelaaja-luokkaan. * Sakotin virheistä myös luokan määrittelyssä, ja kerroin vastineeksi * oikean tavan. * */ //////////////////////////////////////////////////////////////////////// public static void järjestä(Pelaaja[] pelaajat) { if(pelaajat == null) return; for(int i = 0; i < pelaajat.length; i++) { if(pelaajat[i] == null) return; } for(int i = 0; i < pelaajat.length; i++) { for(int j = i; j < pelaajat.length; j++) { if(pelaajat[i].annaPainoarvo() < pelaajat[j].annaPainoarvo()) { Pelaaja apu = pelaajat[i]; pelaajat[i] = pelaajat[j]; pelaajat[j] = apu; } } } } /* Arvostelusta * * Max. pisteet 2 * * Noita kahta ensimmäistä Sanity Checkiä ei arvosteltu. Ei niitä * kukaan laittanut vastaukseensakaan. Tärkeitä ne silti ovat. * * Varsinaisen algoritmin virheistä meni piste, * samoin private-kenttien käytöstä Pelaaja-luokan ulkopuolelta. * * Yleisiä virheitä: * * Koetettiin verrata suoraan pelaajat[i] < pelaajat[j]. * Olioita ei verrata noin ainakaan Javassa. -1 p. * * Koetettiin järjestää double-taulukoita Pelaaja-taulukoiden asemesta. -1 p. * */ //////////////////////////////////////////////////////////////////////// /* Tämä mallivastaus ei lue sitkeästi arvoalueiden ulkopuolisia * myönteisyyksiä ja voimia. Tämä siksi, että sitkeä luku * sotkee syöttövirran uudelleenohjauksen. You get the idea. */ public static Pelaaja luePelaaja() { System.out.println("Luen pelaajan tiedot."); System.out.print("Syötä pelaajan nimi : "); String nimi = Lue.rivi(); System.out.print("Syötä pelaajan kuvaus : "); String kuvaus = Lue.rivi(); System.out.print("Syötä pelaajan myönteisyys "+ "["+Pelaaja.MIN_MYÖNTEISYYS+","+Pelaaja.MAX_MYÖNTEISYYS+"] : "); int myönt = Lue.kluku(); if(myönt != Pelaaja.validoiMyönteisyys(myönt)) { System.out.println("Syötit virheellisen myönteisyyden. Korjasin sen "+ "oletusarvoksi."); } System.out.print("Syötä pelaajan voimakkuus "+ "["+Pelaaja.MIN_VOIMA+","+Pelaaja.MAX_VOIMA+"] : "); double voima = Lue.dluku(); if(voima != Pelaaja.validoiVoimakkuus(voima)) { System.out.println("Syötit virheellisen voimakkuuden. Korjasin sen "+ "oletusarvoksi."); } return new Pelaaja(nimi, kuvaus, myönt, voima); } /* Arvostelusta. * * Max. pisteet 2 * * Puuttuvia ominaisuuksia (nimi, kuvaus, voima, myönteisyys): * -1 p. * Ei virheentarkistusta missään: -1 p. * Väärä konstruktorin käyttö: -1 p. */ } ///////////////////////////////////////////////////////////////////////// /* 2 d) */ public final class Peli { public static void main(String[] args) { System.out.println("Luen ja järjestän myönteisyyden mukaan haluamasi "+ "määrän pelaajia"); int lkm; do { System.out.print("Syötä pelaajien lukumäärä : "); lkm = Lue.kluku(); } while (lkm < 1); Pelaaja[] pelaajat = new Pelaaja[lkm]; for(int i = 0; i < pelaajat.length; i++) { pelaajat[i] = PelaajaKirjasto.luePelaaja(); } PelaajaKirjasto.järjestä(pelaajat); System.out.println("\nTässä pelaajat järjestettynä:\n"); for(int i = 0; i < pelaajat.length; i++) { System.out.println(pelaajat[i]); } } } /* Arvostelusta. * * Max pisteet 2. * Siitä pisteitä pois seuraavasti: * * -1 sallitaan negatiiviskokoisen taulukon luontiyritys: * (int lkm = -1; Pelaaja[] pelaajat = new Pelaaja[lkm];) * -1 ei osata käyttää kirjastoluokan nimeä metodin kutsussa: * oikein: PelaajaKirjasto.järjestä(..) * väärin: järjestä(...) ja jotain import-sekoilua * -1 ei osata luoda taulukkoa * oikein: Pelaaja[] pelaajat = new Pelaaja[lkm]; * -1 jätetään tekemättä joku kohta. * * Kuitenkin niin, että muuten oikea vastaus, jossa on kaksi ylläolevista, * tuotti ½ pistettä. * * On sallittua päättää kiinteä pelaajien lukumäärä. * ("Päätä itse, miten ohjelma tietää...") * * Erityisen hyviä olivat vastaukset, joissa lukumäärää ei tarvinnut * kiinnittää ennalta, eli dynaamiset taulukoinnit. */