Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Java: Ongelma if-lauseen kierrosten uudelleenaloittamisessa

Tommittaja [01.01.2009 04:07:59]

#

niin mulla on tämmöinen ongelma: tohon alla olevaan ohjelmaan pitäis saada laitettua boolean ja int arvoja samaan if- lauseeseen..

public class Peli {
	public static void main(String[] args) {
		System.out.println("\n****Luvunarvauspeli****\n");

			double raha = 0;
			int arvaukset;

			while (raha >= 0) {
				int koneenluku = (int)(10*Math.random());
				for (arvaukset=3; arvaukset>0; --arvaukset) {
		System.out.println("Syötä luku 0-9 arvataksesi koneen luvun");

	        int arvaus = Lue.kluku();

			if (arvaukset == 3 && arvaus == koneenluku) {
				raha += 30;
				System.out.println("Arvasit oikein! Sinulla on nyt "+raha+" euroa");
			}
			else if (arvaukset == 2 && arvaus == koneenluku) {
				raha += 20;
				System.out.println("Arvasit oikein! Sinulla on nyt "+raha+" euroa");
			}
			else if (arvaukset == 1 && arvaus == koneenluku) {
				raha += 10;
				System.out.println("Arvasit oikein! Sinulla on nyt "+raha+" euroa");
			}
			else if (arvaukset > 1 && arvaus < koneenluku) {
				System.out.println("Liian pieni!");
			}
			else if (arvaukset > 1 && arvaus > koneenluku) {
				System.out.println("Liian suuri!");
			}
			else if (arvaukset == 1 && arvaus != koneenluku) {
				raha -= 8.9;
				System.out.println("Arvasit väärin! sinulla on nyt "+raha+" euroa");
			}
			else {
				System.out.println("Virhe syötteessä!");
			}
				}
			}
	}
}

koska pitäis saada joka oikean arvauksen jälkeen aina uusi kierros, jossa voi arvata 3 kertaa taas, vaikka nyt se jatkaa samaa 3 arvauksen kierrosta vaikka arvaisi oikein...

yritin laittaa sinne tämmöistä:

if (arvaukset == 3 && arvaus == koneenluku) {
				raha += 30 && arvaukset == 3;
				System.out.println("Arvasit oikein! Sinulla on nyt "+raha+" euroa");

mutta ei toimi koska "ei voi käyttää int ja boolean arvoja samassa lauseessa".. :'(

Grez [01.01.2009 05:06:14]

#

Tutkitaanpa seuraavaa koodia..

raha += 30 && arvaukset == 3;

Suoraan huomataan että siinä ei ole mitään järkeä. Mutta sitten voidaan myös lähemmin tarkastella, mitä se tekee:

raha += 30 kasvattaa raha:n arvoa 30 ja palauttaa rahaan sijoitetun arvon (joka on mielestäni double)

arvaukset == 3 tarkistaa muuttujan arvaukset arvon ja palauttaa true jos arvaukset on kolme tai false jos arvaukset on jotain muuta. Tässähän ollaan koodissa, joka toteutuu jos arvaukset on kolme, joten se palauttaa aina true.

Sinulla on siis nyt kaksi palautettua arvoa. Ensimmäinen on double ja jälkimmäinen on boolean.

Sitten yrität tehdä totuusarvojen ja-operaation näille kahdelle tulokselle, joista ensimmäinen ei ole totuusarvo. Ja tästä tulee virheilmoitus.

Jotta tuon koodin voisi korjata, niin pitäisi keksiä mitä siinä yritetään tehdä. Äkkiseltään näyttäisi, että oikea ratkaisu olisi korvata koko rivi seuraavalla:

raha += 30;

Tämä ratkaisu sillä perusteella että mielestäni on turhaa tutkia muuttujan sisältöä, kun tiedetään tulokseksi tulevan true ja koska tulosta ei kuitenkaan käytetä mihinkään.

Ylipäätään koko koodi on mielestäni hämärä. Tekisin sen itse jotenkin tähän tyyliin

import java.io.*;
public class Peli {
	public static void main(String[] args) {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		System.out.println("\n****Luvunarvauspeli****");

		double raha = 0;	//Rahaa alussa
		int arvaukset;

		while (raha >= 0) {
			int koneenluku = (int)(10*Math.random());

			System.out.println("\nKone arpoi uuden luvun");

			for (arvaukset=3; arvaukset>0; --arvaukset) {
				int arvaus=-1;
				while (arvaus==-1) {
					System.out.println("Syötä luku 0-9 arvataksesi koneen luvun");

					try {
						String vastaus = in.readLine();
						if (vastaus==null) {
							System.out.println("Kiitos pelaamisesta");
							System.exit(0);
						}
						int tarkistettava = Integer.parseInt(vastaus);
						if (tarkistettava >= 0 && tarkistettava <= 9) {
							arvaus = tarkistettava;
						} else {
							System.out.println("Numero ei ollut väliltä 0-9");
						}
					} catch (IOException ioe) {
						System.out.println("IO virhe luettaessa arvausta");
						System.exit(1);
					} catch (NumberFormatException e) {
						System.out.println("Numero ei ollut sallitussa muodossa");
					}
				}

				if (arvaus == koneenluku) {
					raha += (arvaukset * 10);
					System.out.println("Arvasit oikein! Sinulla on nyt "+raha+" euroa");
					break;
				} else if (arvaus < koneenluku) {
					System.out.println("Liian pieni!");
				} else {
					System.out.println("Liian suuri!");
				}
			}
			if (arvaukset==0) {
				raha -= 8.9;
				System.out.println("Et arvannut lukua "+ koneenluku +"! sinulla on nyt "+raha+" euroa");
			}
		}
		System.out.println("Rahaa on liian vähän (alle 0e) uuden kierroksen aloittamiseen.\nKiitti rahoistasi :D");
		System.exit(0);
	}
}

Sinänsä noilla säännöillä kyllä mieluusti pelaisin tuota peliä jos saisi oikeaa rahaa. Tuossahan jää keskimäärin 8,33 e per pelattu kierros voitolle. Vaikka tuo 8,9 euroa olisi kierrosmaksu, eli sen joutuisi maksamaan vaikka voittaisi, niin siltikin jäisi keskimäärin 2,1 euroa voitolle per kierros.

Tommittaja [01.01.2009 14:57:15]

#

joo toi oli vaan yhden kirjan tehtävä ja toi Lue.kluku() lukee syötteen int- muodossa..

jlaire [01.01.2009 18:50:18]

#

Grez kirjoitti:

Tutkitaanpa seuraavaa koodia..

raha += 30 && arvaukset == 3;

Suoraan huomataan että siinä ei ole mitään järkeä. Mutta sitten voidaan myös lähemmin tarkastella, mitä se tekee:

raha += 30 kasvattaa raha:n arvoa 30 ja palauttaa rahaan sijoitetun arvon ...

Eikös && tule laskujärjestyksessä aiemmin kuin +=, joten tuo rivi on sama kuin tämä:

raha += (30 && arvaukset == 3);

ja eri kuin tämä:

(raha += 30) && arvaukset == 3;

?

Tommittaja [01.01.2009 19:52:38]

#

kiitos vastauksista! sain toimimaan break:in kanssa..mutta mun ei tarvi käyttää noita bufferedreadereita ym. koska mulla on oma luokka jolla voi lukea liukulukuja, kokonaislukuja, char-arvoja ja string arvoja..

Grez [01.01.2009 21:43:20]

#

funktio kirjoitti:

ja eri kuin tämä...

Uskon että olet oikeassa.

Tuossakaan tapauksessa en ymmärrä miksi rahaan halutaan lisätä totuusarvo joka on totuusarvojen ja-operaatio arvoista 30 (kokonaisluku) ja true (totuusarvo)

tommittaja kirjoitti:

mutta mun ei tarvi käyttää noita bufferedreadereita

Tarkoitus ei ollutkaan sanoa että niitä tarvitsisi käyttää. Mutta jos olisin laittanut koodin, jossa käytän Lue -luokkaa, jota ei ole kenelläkään muulla kuin sinulla, niin minä tai muut lukijat eivät olisi voineet testata tuota koodiani.

Katsoin siis paremmaksi pistää täydellisen koodin, jonka voi kääntää ihan peruskirjastoilla.

Jackal von ÖRF [01.01.2009 22:08:42]

#

Java 5 myötä Lue-luokalle tms. ei juurikaan ole käyttöä, koska jo Javan peruskalustossa on syötteen lukemiseen kätevä java.util.Scanner-luokka.

http://java.sun.com/javase/6/docs/api/java/util/Scanner.html

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta