import java.util.List; import java.util.Arrays; import java.util.Collections; import java.util.Random; import javax.swing.JOptionPane; /** * Luokka Matikka, joka asettaa ötököiden maksimi- ja minimimäärän, * arpoo käytetyt satunnaisluvut laskua ja sen tulosta varten ja * tarkistaa käyttäjän arvauksen oikeellisuuden. Tässä versiossa * lasketaan ainoastaan positiivisilla kokonaisluvuilla, koska * ohjelman kohderyhmä koostuu alle kouluikäisistä. * * @author Karoliina Tiuraniemi * @version 1.0 18.1.2009 * */ public class Matikka { private int maksimi = 10; private int minimi = 1; private int luku1; private int luku2; private int tulos; private int tulos0; private int tulos1; private int tulos2; private int arvaus; private static final Random rand = new Random(); /** * Luokan Matikka konstruktori. * */ public Matikka(){ } /** * Ylikirjoitettu konstruktori, joka luo uuden matikkaolion * käyttäen annettuja parametrejä. * @param maksimi joka asetetaan uuden matikan maksimiksi * @param minimi joka asetetaan uuden matikan minimiksi */ public Matikka(int maksimi, int minimi){ this.asetaMaksimi(maksimi); this.asetaMinimi(minimi); } /** * Metodi, joka antaa laskun ensimmäisen luvun * @return this.luku1 */ public int annaLuku1() { return this.luku1; } /** * Metodi, joka antaa laskun toisen luvun * @return this.luku2 */ public int annaLuku2() { return this.luku2; } /** * Metodi, joka antaa laskun ensimmäisen vastausvaihtoehdon * @return this.tulos0 */ public int annaTulos0() { return this.tulos0; } /** * Metodi, joka antaa laskun toisen vastausvaihtoehdon * @return this.tulos1 */ public int annaTulos1() { return this.tulos1; } /** * Metodi, joka antaa laskun kolmannen vastausvaihtoehdon * @return this.tulos2 */ public int annaTulos2() { return this.tulos2; } /** * Metodi, joka antaa laskun oikean vastauksen * @return this.tulos */ public int annaTulos(){ return this.tulos; } /** * Metodi, joka asettaa laskettavien ötököiden maksimimäärän. * Maksimi on korkeintaan 30 ja vähintään 5. * @param maksimi */ public void asetaMaksimi(int maksimi){ // maksimin on oltava vähintään 5. if (maksimi < 5){ this.maksimi = 5; } if (maksimi >= 5){ this.maksimi = maksimi; } if (maksimi > 30) { System.out.println("Liian suuri maksimi, määrätään " + "maksimiksi 30"); this.maksimi = 30; } System.out.println("Laskujen maksimitulos " + this.maksimi); } /** * Metodi, joka asettaa laskettavien ötököiden minimimäärän. * Maksimin ja minimin väli on oltava vähintään 5. Minimi on * vähintään 0. * @param minimi */ public void asetaMinimi(int minimi){ if (minimi >= this.maksimi){ if (this.maksimi > 5){ this.minimi = this.maksimi - 5; } else if (this.maksimi == 5){ this.minimi = 1; } String teksti = "Valitsemasi minimi " + minimi + " ei käy, kun maksimi on " + this.maksimi + ".\n " + "Asetetaan minimiksi " + this.minimi + "."; System.err.println(teksti); JOptionPane.showMessageDialog(null, teksti, "Virheellinen minimiarvo", JOptionPane.WARNING_MESSAGE); } // jos minimiksi halutaan asettaa 1 ja maksimin arvo on 5, minimi on 1 else if (minimi == 1 && this.maksimi == 5){ this.minimi = 1; } // jos minimi on suurempi kuin 1, se saa olla // korkeintaan maksimi - 5. else if (minimi > 1 && minimi <= this.maksimi - 5){ this.minimi = minimi; } System.out.println("Laskujen minimitulos " + this.minimi); } /** * Arpoo tulokseksi luvun väliltä [this.minimi, this.maksimi] * @return luku */ public int arvoTulos(){ // minimiarvoon lisätään satunnainen luku, joka on korkeintaan // maksimin ja minimin erotus + 1. int satunnaisluku = rand.nextInt(this.maksimi - this.minimi + 1); int luku = this.minimi + satunnaisluku; System.out.println("Minimi " + this.minimi); System.out.println("Satunnaisluku " + satunnaisluku); System.out.println("Tulokseksi on arvottu " + luku); return luku; } /** * Arpoo laskettavan määrän ötököitä (ja tulostaa tekstiversiossa *). * Lukun on väliltä [this.minimi, this.maksimi] * Tason 1 tehtävä. * */ public void arvoMontako(){ this.tulos = this.arvoTulos(); int x = 0; System.out.println("Kuinka monta tähteä näet ruudulla?"); while (x < this.tulos){ System.out.print("* "); x++; } System.out.println(""); } /** * Arpoo ratkaistavan laskun, jonka tulos on korkeintaan maksimi. * Tason 2 tehtävä. */ public void arvoLasku(){ this.tulos = this.arvoTulos(); if (this.tulos > 0){ this.luku1 = rand.nextInt(this.tulos); this.luku2 = this.tulos - this.luku1; } System.out.println("Mikä on seuraavan laskun vastaus?"); System.out.println(luku1 + " + " + luku2 + " = "); } /** * Apumetodi, joka lisää pienen satunnaisen luvun toiseen lukuun. * @param numero1 * @return numero2, jos lisäys on mahdollinen tai * -1, jos lisäys ei ole mahdollinen. */ public int lisaaSatunnainen(int numero1){ // valitaan kohtalaisen pieni luku, korkeintaan 20% maksimista // tehdään pyöristetystä luvusta Integer. Luku on vähintään 1. int pieni = (int) Math.ceil(maksimi*rand.nextDouble()*0.2); // System.out.println("Pieni satunnainen luku on " + pieni); // tarkistetaan, että numeroon1 voidaan vielä lisätä edes yksi // ennen maksimin saavuttamista if (numero1 <= maksimi - 1){ // lisätään numeroon1 luku väliltä [1, pieni] int numero2 = numero1 + 1 + rand.nextInt(pieni); // jos arvottu numero menee yli maksimin, lisätään numeroon1 vain // luku 1. if (numero2 > maksimi){ numero2 = numero1 + 1; } return numero2; } return this.maksimi; } /** * Apumetodi, joka vähentää pienen satunnaisen luvun toisesta luvusta. * @param numero1 * @return numero2, jos vähennys on mahdollinen tai * -1, jos vähennys ei ole mahdollinen. */ public int vahennaSatunnainen(int numero1){ // valitaan kohtalaisen pieni luku, korkeintaan 20% maksimista // tehdään pyöristetystä luvusta Integer. Luku on vähintään 1. int pieni = (int) Math.ceil(maksimi*rand.nextDouble()*0.2); // System.out.println("Pieni satunnainen luku on " + pieni); // tarkistetaan, että numerosta1 voidaan vielä vähentää edes yksi // ennen nollaa if (numero1 >= 1){ // vähennetään numerosta1 luku väliltä [1, pieni] int numero2 = numero1 - 1 - rand.nextInt(pieni); // jos arvottu numero menee negatiiviseksi, vähennetään numerosta1 // vain luku 1. if (numero2 < 0){ numero2 = numero1 - 1; } return numero2; } return 0; } /** * Metodi, joka arpoo muut näytettävät vaihtoehdot oikealle tulokselle. * Valetulokset voivat olla joko 1) molemmat suurempia kuin oikea tulos, 2) * molemmat pienempiä kuin oikea tulos tai 3) yksi suurempi ja yksi pienempi * kuin oikea tulos. * */ public void arvoVaihtoehdot(){ double arpa = rand.nextDouble(); /* 1) molemmat suurempia kuin oikea tulos. * tarkistetaan, että tuloksen ja maksimin välissä on vielä kaksi * mahdollista muuta lukua. */ if (arpa < 0.3 && this.maksimi - this.tulos >= 3) { // System.out.println("Molemmat suurempia"); this.tulos1 = this.lisaaSatunnainen(this.tulos); this.tulos2 = this.lisaaSatunnainen(this.tulos1); } /* * Jos ei onnistu, tulos on jo maksimi tai arpa heittää suoraan tähän, * kokeillaan kävisikö * 2) molemmat pienempiä kuin oikea tulos. * tarkistetaan, että tuloksen ja nollan välissä on vielä kaksi * mahdollista muuta lukua. */ else if (this.tulos == this.maksimi || (arpa < 0.6 && this.tulos >= 3)) { // System.out.println("Molemmat pienempiä"); this.tulos1 = this.vahennaSatunnainen(this.tulos); this.tulos2 = this.vahennaSatunnainen(this.tulos1); } /* * Jos ei onnistu tai arpa heittää suoraan tähän, valitaan * 3) yksi suurempi ja yksi pienempi kuin oikea tulos. */ else { //System.out.println("Yksi suurempi ja yksi pienempi"); this.tulos1 = this.lisaaSatunnainen(this.tulos); this.tulos2 = this.vahennaSatunnainen(this.tulos); } List tulokset = Arrays.asList(this.tulos, this.tulos1, this.tulos2); // sekoitetaan tulokset Collections.shuffle(tulokset); System.out.println("Valitse näistä oikea vastaus:"); // talletetaan sekoitetut tulokset muuttujiin ja tulostetaan ne this.tulos0 = (Integer) tulokset.get(0); System.out.println(this.tulos0); this.tulos1 = (Integer) tulokset.get(1); System.out.println(this.tulos1); this.tulos2 = (Integer) tulokset.get(2); System.out.println(this.tulos2); } /** * Varsinainen arvausmetodi, jolla asetetaan arvaukselle arvo. * @param arvaus */ public void asetaArvaus(int arvaus){ this.arvaus = arvaus; System.out.println("Arvauksesi on " + this.arvaus); } /** * Tarkistaa, onko (pelaajan antama) arvaus oikein. * @return true jos arvaus on yhtä kuin tulos, * false muulloin. */ public boolean tulosOikein(){ if (this.arvaus == this.tulos){ System.out.println("Laskit oikein!"); return true; } System.out.println("Laskit väärin."); return false; } }