Skip to main content

Java Übung 26 – Das erste kleine Java Spiel

In dieser Java Übung geht es darum ein kleines Java-Spiel zu erstellen.
Und zwar Zahlen raten.

Was kannst du dir darunter vorstellen?
Du gibst einen bestimmten Wertebereich an.
Zum Beispiel 0 bis 100.

Und das Java Programm erstellt eine Zufallszahl in diesem Bereich.
Dann fordert dich das Programm auf, die Zahl zu raten.

Du gibst deine Rateversuche in die Konsole ein.
Und nach jedem Versuch sagt das Programm, ob die Zahl richtig oder falsch ist.

Außerdem soll dir das Programm eine Hilfe geben.
Es sagt dir, ob die zu erratende Zahl größer oder kleiner, als dein Rateversuch ist.

Am Ende, wenn du die Zahl erraten hast, bekommst du die Anzahl deiner Versuche mitgeteilt.

Na Interesse, an so einem Spiel?
Na dann…

  • Erstelle eine Klasse „ZahlenRaten“.
  • Lege in dieser Klasse eine statische Methode „rateZahl“ an.
    Diese Methode bekommt beim Aufruf eine ganze Zahl übergeben.
    Und diese ganze Zahl ist der Wertebereich für die Zufallszahl.
  • Und dann fordert dich die Methode auf Zahlen zu raten.
  • Nach jedem Versuch bekommst du Hilfe.
    Wenn dein Versuch größer ist, als die Zufallszahl dann erfolgt die Bildschirmausgabe:
    „Du liegst falsch! Die zu erratende Zahl ist kleiner“
    Ansonsten
    „Du liegst falsch! Die zu erratende Zahl ist größer“
  • Nachdem du irgendwann die richtige Zahl erraten hast, erfolgt die Konsolenausgabe:
    „Richtig! Du hast „+zaehler+“ Durchgänge benötigt.“
  • Und der „zaehler“ ist die Variable, welche deine Rateversuche zählt.
  • Die Methode wird in der main-Methode der Klasse „ZahlenRaten“ aufgerufen.
    Aus Kontrollzwecken übergebe der Methode das Argument 100. (Wertebereich für Zufallszahl)

Also dann – leg los.
Ich wünsche dir ganz viel Spaß bei der Lösung dieser Java Übung.


Die Lösung dieser Java Übung vollziehe ich in drei Schritten.

Am besten ist….
Du löst diese Übung schrittweise.

Dazu suchst du dir die einzelnen Probleme heraus und beginnst diese nach und nach zu lösen.
Zu jeder Lösung eines Problems lässt du dir, eine Bildschirmausgabe zur Überprüfung zurückgeben.

Das wären die drei Probleme.

  • Problem 1:
    Die Klasse, die Methoden, die Variablen und Zufallszahl müssen erstellt werden.
    Die Zufallszahl soll ganzzahlig sein.
    Mittels einer Konsolenausgabe soll die Zufallszahl überprüft werden.
  • Problem 2:
    Es muss eine Struktur geschaffen werden, welche den Nutzer auffordert, Zahlen einzugeben.
    Diese Zahlen sollen mit der Zufallszahl verglichen werden.
    Die Anzahl der Rateversuche soll gezählt werden.
    Auch das soll als Konsolenausgabe zurückgegeben werden.
  • Problem 3:
    Die Hilfestellung „Die Zahl ist größer oder kleiner“ soll implementiert werden.

So und jetzt beginnen wir die Probleme zu lösen.

So kannst du eine ganzzahlige Zufallszahl anlegen.

Was benötigst du?
Als erstes brauchst du die Klasse.

Dann benötigst du eine statische Methode „rateZahl“, welche einen Parameter vom Datentyp Integer erwartet.

Weiterhin brauchst du eine lokale Variable, welche die ganzzahlige Zufallszahl speichert.
Die Zufallszahl soll in einem gewissen Wertebereich liegen.
Dazu musst du also den Methodenparameter mit der Zufallszahl verrechnen.

Hier der Javacode dazu:
In der main-Methode wird die rateZahl-Methode mit dem Argument 100 aufgerufen.


public class ZahlenRaten {

public static void main(String[] args) {
	rateZahl(100);
}
}

Somit wurde der Wert 100 für die lokale Variable „wertebereich“ festgelegt.
Innerhalb der rateZahl-Methode wurde jetzt eine weitere lokale Variable, namens „zufallsZahl“ angelegt.


public class ZahlenRaten {

	static void rateZahl(int wertebereich){		
		int zufallsZahl;	
	}

	public static void main(String[] args) {
		rateZahl(100);
	}
}

Diese Variable ist vom Datentyp Integer.
Es handelt sich somit um eine ganze Zahl.

Bisher steckt in dieser Variablen aber noch kein Wert.
Da soll jetzt die Zufallszahl rein.
Und Zufallszahlen kannst du mit der Methode Math.Random() erzeugen.
Die Math.Random-Methode ist eine Klassenmethode aus der Standardklasse Math.
Diese Methode liefert dir einen zufälligen Komma-Wert zwischen 0 und 1.


public class ZahlenRaten {

	static void rateZahl(int wertebereich){		
		int zufallsZahl = Math.random();	
	}

	public static void main(String[] args) {
		rateZahl(100);
	}
}

Dann wird dieser Kommawert mit der Variablen „wertebereich“ multiplziert.

Beim Aufruf der Methode „rateZahl“ (in der main-Methode) haben wir für den „wertebereich“ die Zahl 100 festgelegt.
Und wenn eine Kommazahl zwischen 0 und 1 mit 100 multipliziert wird, entsteht eine Kommazahl zwischen 0 und 100.
Somit hast du eine zufällige Kommazahl zwischen 0 und 100.


public class ZahlenRaten {

	static void rateZahl(int wertebereich){		
		int zufallsZahl = ( Math.random()*wertebereich);
		
		}

	public static void main(String[] args) {
		rateZahl(100);
	}
}

Und diese Kommazahl wird in einen Integer-Wert gewandelt.
Am Ende steckt jetzt in der Variablen „zufallszahl“ eine zufällige ganzzahlige Zahl zwischen 0 und 100.


public class ZahlenRaten {

	static void rateZahl(int wertebereich){		
		int zufallsZahl = (int)( Math.random()*wertebereich);
			
	}

	public static void main(String[] args) {
		rateZahl(100);
	}
}

Und aus Testzwecken lasse ich mir dies, über die System.out.println()-Anweisung auf der Konsole ausgeben.


public class ZahlenRaten {

	static void rateZahl(int wertebereich){		
		int zufallsZahl = (int)( Math.random()*wertebereich);
		
		System.out.println(zufallsZahl);//Zur Überprüfung die Rückgabe der Zufallszahl	
	}

	public static void main(String[] args) {
		rateZahl(100);
	}
}

Probiere es an dieser Stelle ebenfalls und führe das Programm einmal aus.

Und welche Konsolenausgabe erscheint?
Eine Zahl zwischen 0 und 100, oder?

Okay…
Dann können wir uns um das Raten kümmern.

So kannst du die einzelnen Rateversuche darstellen.

Der jeweilige Rateversuch soll über eine Nutzereingabe erfolgen.

Du brauchst also ein Scanner-Objekt, um die Nutzereingabe zu speichern.
Scanner scanner = new Scanner(System.in);

Da die Zahl, welche du eingibst ebenfalls ganzzahlig ist, musst du diese in einer Integer-Variablen speichern.
Dazu rufst du die Methode nextInt() am Scanner-Objekt auf.
int eingabe = scanner.nextInt();

Und du benötigst eine Aufforderung zur Eingabe deines Rateversuches.
System.out.println("Gib eine Zahl zwischen 0 und "+wertebereich+" ein!");

Also bis hierher sieht der Code so aus:


import java.util.Scanner;//Importanweisung für den Scanner

public class ZahlenRaten {

	static void rateZahl(int wertebereich){		
		int zufallsZahl = (int)( Math.random()*wertebereich); //Zufallszahl
		
		System.out.println(zufallsZahl); //Aus Kontrollzwecken
		Scanner scanner = new Scanner(System.in); //Scanner-Objekt
		
		System.out.println("Gib eine Zahl zwischen 0 und "+wertebereich+" ein!");
		int eingabe = scanner.nextInt();//Eingabe wird gespeichert
	}

	public static void main(String[] args) {
		rateZahl(100);
	}
}

Bis hierher hast du die Grundstruktur dafür gelegt, eine Zufallzahl zu erzeugen und einen Rateversuch zu speichern.
Mehr nicht.

Kommen wir zum Raten.
Du sollst solange aufgefordert werden weiter zu raten, bis die Zahl in der Variable „eingabe“ mit der Zahl in der Variable „zufallszahl“ übereinstimmt.
Da du nicht weißt, wie oft du raten musst – ist die for-Schleife hier unpraktisch.

Viel besser ist für dieses Beispiel eine while-Schleife.
Und die Schleifenbedingung lautet:

„Rate solange bis der Wert in der Variablen „eingabe“ gleich ist dem Wert in der Variablen „zufallszahl“.

Oder anders gesagt:

„Solange sich beide Werte unterscheiden – rate weiter.

Somit lautet die Schleifenbedingung:
(zufallsZahl != eingabe)

Immer dann, wenn die Eingabe nicht mit der Zufallszahl übereinstimmt- geht es in die Schleife.

Und was passiert in der Schleife:
Erst einmal erfolgt eine Info, dass die Eingabe falsch war.
System.out.println("Du liegst falsch!");

Dann muss eine neue Eingabe erfolgen.
eingabe = scanner.nextInt();

Also würde das Ganze bis hierhin so aussehen:


import java.util.Scanner;//Importanweisung für die Scanner-Klasse

public class ZahlenRaten {

	static void rateZahl(int wertebereich){		
		int zufallsZahl = (int)( Math.random()*wertebereich);//Zufallszahl
		
		System.out.println(zufallsZahl); //Aus Kontrollzwecken
		Scanner scanner = new Scanner(System.in);//neues Scanner Objekt
		
		System.out.println("Gib eine Zahl zwischen 0 und "+wertebereich+" ein!");
		int eingabe = scanner.nextInt();//Eingabe wird gespeichert
		
		while (zufallsZahl != eingabe){
			System.out.println("Du liegst falsch!");//Rückinfo
			eingabe = scanner.nextInt();//neue Eingabe
			
		}//Schleifenende
		System.out.println("Richtig!");//Falls Eingabe richtig
	}

	public static void main(String[] args) {
		rateZahl(100);
	}
}

An dieser Stelle macht es Sinn, das Ganze auszuprobieren.
Führe das Programm deshalb einmal aus.
Gib einmal die richtige Zahl ein und schau was passiert.

Und im zweiten Versuch nimmst du eine falsche Zahl.

Und? Läuft’s?
Also dann weiter..

Bis jetzt fehlt noch die Eingabe welche die Anzahl der Versuche speichert.

  • Also ein Zähler.
  • Der Zähler startet bei eins.
    Denn der Erste Rateversuch zählt schon mit.

Also wenn der erste Versuch komplett richtig ist- das Programm nicht in die Schleife springt – bleibt es bei einem Versuch.
int zaehler=1;

Und bei jedem Schleifendurchlauf wird der Zähler dann um eins erhöht.
zaehler++;

Bevor wir als letzten Schritt die Hilfestellung implementieren.
Hier der komplette Code.


import java.util.Scanner;

public class ZahlenRaten {

	static void rateZahl(int wertebereich){		
		int zufallsZahl = (int)( Math.random()*wertebereich);
		
		System.out.println(zufallsZahl);
		Scanner scanner = new Scanner(System.in);
		
		System.out.println("Gib eine Zahl zwischen 0 und "+wertebereich+" ein!");
		int eingabe = scanner.nextInt();
		int zaehler=1;//Zähler startet bei eins
		
		while (zufallsZahl != eingabe){
			System.out.println("Du liegst falsch!");
			eingabe = scanner.nextInt();
			zaehler++;//Zähler wird bei jedem Durchlauf um eins erhöht
			
		}
		System.out.println("Richtig! Du hast "+zaehler+" Durchgänge benötigt.");//Anzahl der Durchgänge
	}

	public static void main(String[] args) {
		rateZahl(100);
	}
}

Probiere es wieder aus.
Gib verschiedene Zahlen ein und lass den Zähler zählen.

Jetzt kommt die Hilfestellung.

So kannst du die Hilfestellung implementieren.

Für die Hilfestellung musst du Werte abfangen.

Und Werte fängst du mit if und else Blöcken ab.
Somit könnte die Anweisung im if Block lauten:

„Wenn die Zufallszahl kleiner als die Eingabe ist- Dann erscheint die Konsolenausgabe:
Du liegst falsch! Die zu erratende Zahl ist kleiner“

Die Bedingung für den if-Block würde somit lauten:
(zufallsZahl < eingabe)

Und im Falle, dass die Eingabe kleiner ist - muss lediglich die Bildschirmanweisung angepasst werden.

Der komplette Code zu dieser Java Übung:


import java.util.Scanner;//Importanweisung für die Scanner Klasse

public class ZahlenRaten {

	static void rateZahl(int wertebereich){		
		int zufallsZahl = (int)( Math.random()*wertebereich);//Zufallszahl wird gespeichert
		
		System.out.println(zufallsZahl); //Aus Kontrollzwecken - kann jetzt gelöscht werden
		Scanner scanner = new Scanner(System.in);//neues Scanner-Objekt
		
		System.out.println("Gib eine Zahl zwischen 0 und "+wertebereich+" ein!");
		int eingabe = scanner.nextInt();//Speicherung des ersten Rateversuchs
		int zaehler=1;//Zählvariable um die Rateversuche zu zählen
		
		while (zufallsZahl != eingabe){
			if (zufallsZahl<eingabe){
			System.out.println("Du liegst falsch! Die zu erratende Zahl ist kleiner");
			}
			else {
				System.out.println("Du liegst falsch! Die zu erratende Zahl ist größer");
			}
			eingabe = scanner.nextInt();//neuer Rateversuch
			zaehler++;//Rateversuch wird um eins erhöht
			
		}
		System.out.println("Richtig! Du hast "+zaehler+" Durchgänge benötigt.");
	}

	public static void main(String[] args) {
		rateZahl(100);
	}
}

Das Programm wäre fertig.
Die Anweisung zur Konsolenausgabe der Zufallszahl kannst du einfach löschen.
Dann funktioniert das Spiel auch ohne Vorsagen. 🙂

Ein kleines, vielleicht mittelgroßes Problem bleibt.
Und zwar doppelter Code.
Schau dir diese Bild dazu einmal an.

Java Übung doppelter Code

Die Anweisung für die nächste Bildschirmeingabe findest du in der Schleife.
int eingabe = scanner.nextInt();
Aber genau die gleiche Anweisung befindet sich auch außerhalb der Schleife.

Wenn du später in diesem Programm Dinge ändern willst, musst du es an zwei Stellen machen.
Ein Grundsatz der Programmierung lautet:

"Vermeide doppelten Code!"

Denn doppelter Code führt später zu doppelter Nachbesserung.
Und wenn du an zwei oder mehr Stellen nachbessern musst- führt dies zu Fehlern.
Bzw. das Risiko, dass du an einer Stelle Codeanteile änderst - an der anderen nicht - steigt.

Also dann…
Das Problem bei diesem Programm ist, dass du immer mindestens einen Rateversuch benötigst.

Egal was kommt - Mindestens einmal musst du raten.
Deshalb musste auch der Schleifenzähler bei eins starten und nicht bei null.

Wenn du mindestens einen Rateversuch benötigst, ist eine do-while Schleife besser.

Und zwar beginnt so eine do-while-Schleife mit dem Keyword do.

Dann kommt ein Codeblock.
Und in diesen Codeblock kommen dann die Schleifenanweisungen, wie

  • If und else Blöcke
  • Die Infos
  • Das Hochzählen des Schleifenzählers
  • Die neue Eingabe

Also all das, was du bereits in der while-Schleife im Rumpf hast.
Der Do-Block ist somit der Rumpf.

Im Do-Block musst du dann allerdings alle drei Bedingungen festlegen:

  1. Zufallszahl < Eingabe
  2. Zufallszahl > Eingabe
  3. Und Zufallszahl = Eingabe

do {
			if (zufallsZahl == eingabe) {
				System.out.println("Richtig! Du hast " + zaehler + " Durchgänge benötigt.");
			} else if (zufallsZahl < eingabe) {
				System.out.println("Du liegst falsch! Die zu erratende Zahl ist kleiner");
			} else {
				System.out.println("Du liegst falsch! Die zu erratende Zahl ist größer");
			}
}

Was bringt es?
Der Unterschied besteht darin, dass die Schleifenbedingung nicht im Kopf steht.
Stattdessen steht diese im Rumpf.

Das wiederum führt dazu, dass die Schleife immer mindestens einmal durchlaufen wird.
Somit kann auch der Schleifenzähler bei null starten.

So würde die Lösung dieser Java Übung mit do while Schleife aussehen:


import java.util.Scanner;

public class ZahlenRaten {

	static void rateZahl(int wertebereich) {
		int zufallsZahl = (int) (Math.random() * wertebereich);

		System.out.println(zufallsZahl); // Aus Kontrollzwecken
		Scanner scanner = new Scanner(System.in);

		//System.out.println("Gib eine Zahl zwischen 0 und "+wertebereich+" ein!");
		int eingabe = 0;//Eingabe startet jetzt bei Null
		int zaehler = 0;// Startet bei Null

		do {
			System.out.println("Gib eine Zahl zwischen 0 und " + wertebereich + " ein!");
			eingabe = scanner.nextInt();
			zaehler++;
			if (zufallsZahl == eingabe) {
				System.out.println("Richtig! Du hast " + zaehler + " Durchgänge benötigt.");
			} else if (zufallsZahl < eingabe) {
				System.out.println("Du liegst falsch! Die zu erratende Zahl ist kleiner");
			} else {
				System.out.println("Du liegst falsch! Die zu erratende Zahl ist größer");
			}
		} 
               while (zufallsZahl != eingabe);//Schleifenbedingung im Fuß
	}

	public static void main(String[] args) {
		rateZahl(100);
	}
}

Die fett markierten Anteile sind jetzt alle neu.
Der Schleifenzähler kann bei Null starten, da ja mindestens ein Schleifendurchlauf stattfindet.

Die Aufforderung zur Eingabe einer Zahl kann raus.
Diese habe ich in diesem Beispiel auskommentiert.

Die Eingabe findet jetzt auch nicht mehr außerhalb der Schleife statt.
Da die Variable dennoch eine lokale ist, muss diese einen Wert (0) haben.

So das war es.

Also immer wenn du feststellst:

"Ich muss im Rumpf der Schleife Code schreiben, welchen ich außerhalb der Schleife schon einmal geschrieben habe".

Dann solltest du überlegen:

"Ist es notwendig, dass die Schleife mindestens einmal durchlaufen werden muss?"

Wenn du diese Frage mit Ja beantwortest - dann wähle statt der while Schleife eine do while Schleife.


Ähnliche Beiträge

Lassen wir Java rechnen – Die Rechenoperationen für Variablen

Java rechnen

Ich liebe Mathe. In der Biographie „Der Mann, der die Zahlen liebte“, stellt Paul Hoffmann das Mathematikgenie Paul Erdös vor. Erdös war eines der größten Genies des 20 Jahrhunderts. Er arbeitete mit zahlreichen Wissenschaftlern zusammen und verfasste durchschnittlich mehr Publikationen im Jahr, als andere Mathematiker im ganzen Leben. Da Erdös sich mit sehr vielen Theoremen […]

So lassen sich Java Strings in char zerlegen

Java Strings zerlegen char

Java Strings sind Zeichenketten. Und diese Zeichenketten lassen sich aufsplitten und in ihre Einzelteile zerlegen. Ich möchte dir in diesem Beitrag Möglichkeiten vorstellen, wie du Strings in Character-Datentypen zerlegen, extrahieren und die Einzelteile in Arrays speichern kannst.

Der wichtige Unterschied zwischen Java Methoden

Java Methoden Unterschied

Jetzt machen wir Nägel mit Köpfen. Dieses Sprichwort stammt aus den Anfängen des Industriezeitalters. Denn früher wurden Nägel nicht industriell, sondern per Hand gefertigt. Und da kam es schon einmal vor, dass versehentlich Nägel ohne Kopf produziert wurden. Was blieb ist das Sprichwort „Nägel mit Köpfen“ Und dieses steht sinngemäß für eine schnelle, qualitativ hochwertige […]

Java Übung 27 – Auf zur Mathe-Olympiade

Java Übung Mathe Olympiade

In dieser Java Übung möchte ich mit dir ein Programm erstellen, welches ein Mathematik-Test oder eine Mathe-Olympiade simuliert. Du kennst das vielleicht noch aus der Schule. Matheolympiade- Da wurden aus allen vier Grundrechenarten, Aufgaben formuliert. Die Schüler mussten diese Aufgaben lösen. Die Lehrer kontrollierten die Lösungen. Und der Schüler, welcher die wenigsten Fehler hatte – […]

Heap & Stack – Die Speicherverwaltung in Java

Java Speicher

Java nutzt eine interne Speicherverwaltung. Eigentlich sind es mehrere. Uns interessieren lediglich zwei. Da das Thema Speicherverwaltung recht umfangreich ist, habe ich dir im Folgenden einmal die wichtigsten Artikel zusammengestellt. Die zwei Speichersysteme von Java Java Methoden werden auf dem Stack gestapelt. Der Speicher auf dem Java Methoden zu Hause sind, nennt sich Stack Speicher. […]

Der Java Datentyp boolean im Interview

Java boolean

Nein, ich bin nicht verrückt. Aber… Neulich traf ich zufällig den Java Datentyp boolean. 🙂 Er erklärte sich bereit, mir ein Interview zu geben. In diesem Interview geht es um die Werte, welcher dieser Wertetyp annehmen kann. Und in diesem Zusammenhang geht es auch um Logik. Also lassen wir uns doch die Logik vom direkten […]

So implementierst du Instanzmethoden in deine Java Klasse

Java Instanzmethoden

In einen der letzten Beiträge habe ich dir gezeigt, wie du eine Klasse anlegen kannst. Ich habe die Klasse „Mensch“ oder „Human“ angelegt und wir haben die erste Instanzvariable implementiert. Dein Code sollte jetzt so aussehen: public class Human { int size=156;//size in centimeter } In diesem Beitrag werde ich dir zeigen, wie du Java […]

So legst du Utility Klassen in Java an

Java Utility Klassen

Utility Java Klassen – was ist das? Man nennt diese auch Hilfsklassen von Java. Diese Utility Klassen sind Java Klassen, welche lediglich Methoden und Konstanten anbieten. Am Beispiel: Die Klasse Math ist so eine klassische Utility Klasse. Wozu braucht man solche Klassen? Diese Klassen sind so etwas wie ein Werkzeugkoffer für jedes Java Programm. Hier […]

So kannst du Eclipse installieren

Eclipse installieren

Das Schöne an Eclipse ist, es läuft auf sämtlichen Betriebssystemen. Eclipse wird einfach auf der Webseite des Herstellers herunter geladen und kann dann installiert werden. Dabei stehen dir verschiedene Versionen zur Verfügung.