Im Folgenden ist der Code des selbstlernenden Spiels „Tiere Raten“

Werbung
Aufgabe:
Im Folgenden ist der Code des selbstlernenden Spiels „Tiere Raten“ abgedruckt. Der
Code ist noch nicht lauffähig. Damit das Spiel gespielt werden kann, müssen in der
Klasse „Tiere Raten“ einige Dinge ergänzt werden.
Hinweise zu der Farbwahl der Texte/Wörter:
Orange ist angegeben, wo etwas ergänzt werden soll.
Einige Abschnitte sind grau gedruckt. Um den Code ergänzen zu können, ist es nicht
notwendig, dass diese verstanden werden.
Methoden sind rot angegeben.
Die Aufrufe der Methoden, sind in grünem Text gedruckt.
Kommentare sind blau geschrieben.
1
Klasse "Frageknoten"
import java.util.StringTokenizer;
public class Frageknoten
{
int fragenummer;
String frage;
boolean istAntwortJ;
String antwortJ;
int fragenummerJ;
boolean istAntwortN;
String antwortN;
int fragenummerN;
// Die Parameter werden dem Frageknoten übergeben und den Variablen
zugeordnet.
public Frageknoten(int neueFragenummer, String neueFrage, String
neueAntwortJ, String neueAntwortN)
{
fragenummer = neueFragenummer;
frage = neueFrage;
istAntwortJ = true;
antwortJ = neueAntwortJ;
istAntwortN = true;
antwortN = neueAntwortN;
}
2
// Hier werden die Parameter für oben eingelesen - bzw. übergeben. Es wird eine
Tabelle von der Form | fragenummer | frage | istAntwort für ja | Antwort oder
neueFragenummer | istAntwort für nein | Antwort oder neueFragenummer |
eingelesen. Achtun: Hier haben wir einen anderen „Fragknoten“ als oben – es
werden andere Parameter übergeben.
public Frageknoten(String zeile)
{
//Der StringTokenizer liest eine Zeile ein - von ; zu ;.
StringTokenizer st = new StringTokenizer(zeile, ";");
//Der erste eingelesene String wird in einen int umgewandelt und als
fragenummer abgespeichert
fragenummer = Integer.parseInt(st.nextToken());
//Der nächste String wird auf "frage" abgespeichert.
frage = st.nextToken();
//Der nächste String wird auf faJ abgespeichert.
String faJ = st.nextToken();
//Je nachdem, ob faJ "F" oder etwas anderes lautet, wird "istAntwortJ" auf true
oder false gesetzt.
if (faJ.equals("F"))
istAntwortJ = false;
else
istAntwortJ = true;
//Wenn die Antwort gegeben werden kann, kann diese auf antwortJ gesetzt
werden, sonst wird die neue Fragenummer gegeben.
if (istAntwortJ)
antwortJ = st.nextToken();
else
fragenummerJ = Integer.parseInt(st.nextToken());
String faN = st.nextToken();
if (faN.equals("F"))
istAntwortN = false;
else
istAntwortN = true;
3
if (istAntwortN)
antwortN = st.nextToken();
else
fragenummerN = Integer.parseInt(st.nextToken());
}
//Aufbau der Zeile
String alsZeile()
{
String zeile = "";
zeile += fragenummer + ";";
zeile += frage + ";";
if (istAntwortJ)
zeile += "A;" + antwortJ;
else
zeile += "F;" + fragenummerJ;
zeile += ";";
if (istAntwortN)
zeile += "A;" + antwortN;
else
zeile += "F;" + fragenummerN;
return zeile;
}
}
4
Klasse "TiereRaten"
// Die Fragen sind unter "fragen.txt" gespeichert. Ganz einfache Startfragen sind
unter "frage2.txt" gespeichert.
import java.io.*;
import java.util.TreeMap;
import java.util.Scanner;
import java.util.Iterator;
public class TiereRaten
{
//Wir betrachten den Knoten der aktuellen Frage
Frageknoten aktuelleFrage;
//Liste, in welcher alle Fragen zwischengespeichert werden
TreeMap fragen;
//brauchen wir, um eingegebenen Text einzulesen
Scanner scanner = new Scanner(System.in);
public TiereRaten(String dateiname)
{
// Damit wird das Teminal bei einem Neustart wieder geleert.
System.out.print((char) 12);
//Hier wird das eigentliche Spiel aufgerufen. Es wird nach dem Dateinamen
gefragt, damit man weiss, welche Datei eingelesen werden soll.
Methode ergänzen(dateiname);
}
void spielen(String dateiname)
{
//Das Try braucht es nur, damit man allfällige Fehler beim Einlesen abfangen
kann: catch
try
{
//Es wird ein "TreeMap" erstellt, in welchem dann die Fragen abgelegt
werden.
fragen = new TreeMap();
//Es wird beim Einlesen der Fragen gefragt, aus welcher Datei die Fragen
übernommen werden sollen: dateiname
Methode ergänzen(dateiname);
5
while(true)
{
//Das eigentliche Spiel
Methode ergänzen ();
Methode ergänzen ();
if (Methode ergänzen ()==false)
break;
}
}
//Gibt an, falls es beim Einlesen einen Fehler gibt. Wenn dies im "Try"
geschieht.
catch (IOException e)
{
e.printStackTrace();
//Dies wird bei einem Einlesefehler ausgegeben.
System.out.println("Beim Einlesen ist ein Fehler aufgetreten.");
}
}
//Es wird gefragt, aus welcher Datei die Fragen eingelesen werden sollen.
void fragenEinlesen(String dateiname)
{
try {
//Der Reader wird gebraucht, um Daten aus einem .txt-File einlesen zu
können.
BufferedReader in = new BufferedReader(new FileReader(dateiname));
while (true)
{
//Das Lesen geschieht zeilenweise
String zeile = in.readLine();
//Bei einer leeren Zeile wird abgebrochen ansonsten läuft die while(true)Schleife weiter.
if (zeile == null )
break;
//Jede Zeile wird zu einem Frageknoten (Das Einlesen geschieht in der
Klasse Frageknoten!)
Frageknoten frageknoten = new Frageknoten(zeile);
//Alle Fragezeilen werden der Reihe nach dem TreeMap übergeben.
//Mit dem .put werden die Daten in den TreeMap übertragen
fragen.put(frageknoten.fragenummer, frageknoten);
}
}
6
//Gibt an, falls es beim Einlesen einen Fehler gibt. Wenn dies im "Try"
geschieht.
catch (IOException e)
{
e.printStackTrace();
//Ausgabe, falls beim Einlesen ein Fehler aufgetreten ist.
System.out.println("Beim Einlesen ist ein Fehler aufgetreten.");
}
}
//Hier (throws IOExeption) werden die Einlesefehler nicht behandelt - wenn es ein
solcher gibt, geht das Programm einen Schritt zurück, bis zu einer Stelle, wo die
Einlesefehler abgefangen werden.
void spielLoop() throws IOException
{
// Frage 1 aus dem TreeMap als aktuelle Frage setzen
aktuelleFrage = (Frageknoten)fragen.get(1);
System.out.println("");
System.out.println("Beantworte im Folgenden alle Fragen mit j für Ja und n für
Nein:");
while(true)
{
System.out.println("");
System.out.println(aktuelleFrage.frage);
String antwort = scanner.nextLine();
//Wenn die Frage mit Ja beantwortet wurde.
//== funktioniert bei Strings nicht. Da braucht man .equals("")
if ( antwort.equals("j") )
{
//Wenn es eine Antwort gibt:
if (aktuelleFrage.istAntwortJ)
{
//Aufruf der Methode "" mit dem Parameter true
Methode ergänzen(true);
break;
}
//Wenn es keine Antwort gibt.
else
//Neue Frage wird zur aktuellen Frage
aktuelleFrage = (Frageknoten)fragen.get(aktuelleFrage.fragenummerJ);
}
7
//Wenn die Frage mit Nein beantwortet wurde.
else if (ergänzen)
{
//Wenn es eine Antwort gibt:
if (ergänzen)
{
//Aufruf der Methode "" mit dem Parameter false
Methode ergänzen(false);
break;
}
//Wenn es keine Antwort gibt:
else
//Neue Frage wird zur aktuellen Frage.
aktuelleFrage = (Frageknoten)fragen.get(aktuelleFrage.fragenummerN);
}
//Mit q kann man aussteigen.
else if (antwort.equals("q") )
return;
}
}
//Methode, welche fragt, ob der Baum angesehen werden will.
void fragebaumAnsehen()
{
System.out.println("");
System.out.println("Möchtest du den Fragenbaum sehen (j/n)?");
String baumAnsehen = scanner.nextLine();
if (baumAnsehen.equals("j") )
{
System.out.println("");
//Diese Methode zeigt den Baum an.
Methode ergänzen( true, (Frageknoten)fragen.get(1), 0);
}
}
8
//Methode, in welcher gefragt wird, ob es ein neues Spiel geben soll.
boolean neuesSpiel()
{
System.out.println("");
System.out.println("Möchtest du noch einmal spielen? (j/n)?");
//Liest die Antwort (j/n) ein und speichert sie auf "nochmals"
ergänzen;
//Bei "Strings" geht "==" nicht.
if (nochmals.equals("j"))
return true;
else
{
System.out.println("");
System.out.println("Möchtest du deine Fragen speichern (j/n)?");
//Hier wird eingelesen, ob der Spielverlauf gespeichert werden möchte.
String speichern = scanner.nextLine();
if (ergänzen)
{
System.out.println("Gib einen Dateinamen ein:");
String dateinameNeu = scanner.nextLine();
//Methode, in welcher die neuen (und aktuellen) Fragen gespeichert werden
dateiSchreiben(dateinameNeu);
}
return false;
}
}
9
//Hier wird die Antwort überprüft.
void antwortPruefen(boolean jaAntwort)
{
String antwortTier;
//Wenn die letzte Frage mit Ja beantwortet wurde und eine Antwort vorhanden
ist.
if (jaAntwort)
antwortTier = aktuelleFrage.antwortJ;
//Wenn die letzte Frage mit nein beantwortet wurde und die Antwort
vorhanden ist.
else
antwortTier = aktuelleFrage.antwortN;
System.out.println("");
System.out.println("Ist das Tier an das du denkst ein(e) " + ergänzen + "?");
String aw = scanner.nextLine();
if ( aw.equals("j") )
{
System.out.println("");
//Antwort, wenn die Antwort korrekt war.
System.out.println("Ich weiss alles!!");
System.out.println("");
}
//Wenn das geratene Tier nicht korrekt war:
else if ( aw.equals("n") )
Methode ergänzen(jaAntwort, antwortTier);
}
void neuesTierLernen(boolean jaAntwort, String antwortTier)
{
System.out.println("");
System.out.println("An welches Tier hast du dir dann gedacht? Gib das Tier
ein: ");
String neuesTier = scanner.nextLine();
System.out.println("");
System.out.println("Gib eine Frage ein, die ein(e) " + antwortTier + " von
einem " + neuesTier + " unterscheidet:");
String neueFrage = scanner.nextLine();
System.out.println("");
System.out.println("Wir die Frage für den/die/das " + neuesTier + " mit Ja
beantwortet (j/n)?");
10
String zuordnung = scanner.nextLine();
String jaTier, neinTier;
//Wenn die neue Frage mit Ja zum neuen Tier führt:
if ( zuordnung.equals("j") )
{
ergänzen;
ergänzen;
}
//Wenn die neue Frage mit Nein zum neuen Tier führt:
else
{
ergänzen;
ergänzen;
}
//Ruft die neue Methode auf, welche der neuen Frage eine neue Nummer
gibt.
int neueFragenummer = gibNeueFragenummer();
//Es wird ein neuer Frageknoten erstellt.
Frageknoten neuerFrageknoten = new Frageknoten(neueFragenummer,
neueFrage, jaTier, neinTier );
//Die neue Frage wird in den TreeMap eingelesen.
fragen.put(neueFragenummer, neuerFrageknoten);
//Anpassung der aktuellen Frage - falls es bei Ja eine (falsche) Antwort gab.
if (jaAntwort)
{
//Jetzt gibt es keine Antwort mehr, sondern eine neuen Frage.
aktuelleFrage.istAntwortJ = false;
//Die Antwort wird gelöscht.
aktuelleFrage.antwortJ = null;
//Der neuen Frage zur aktuelle Frage wird die neue Fragenummer
zugeordnet.
aktuelleFrage.fragenummerJ = neueFragenummer;
}
//Anpassung der aktuellen Frage - falls es bei Nein eine (falsche) Antwort
gab.
else
{
aktuelleFrage.istAntwortN = false;
aktuelleFrage.antwortN = null;
aktuelleFrage.fragenummerN = neueFragenummer;
}
}
11
//Methode, welche eine neue Fragenummer zuordnet.
int gibNeueFragenummer()
{
//Hier wird der letzte Frageknoten als "letzte Frage" abgespeichert.
Frageknoten letzteFrage = (Frageknoten) fragen.get(fragen.lastKey());
//Es wird eine neue Fragenummer generiert, welche um eines höher ist, als die
Nummer der letzten Frage.
return letzteFrage.fragenummer + 1;
}
//Methode, welche die neue Frage abspeichert - unter "dateiname"
void dateiSchreiben(String dateiname)
{
//Fehler beim Schreiben werden abgefangen.
try {
PrintWriter datei = new PrintWriter( new FileWriter( dateiname));
Iterator itr = fragen.values().iterator();
//So lange es weitere Zeilen gibt, werden die Frageknoten als Zeilen
abgespeichert.
while(itr.hasNext())
{
Frageknoten fk = (Frageknoten)itr.next();
datei.println(fk.alsZeile());
}
//Speichert die gelesenen Daten in die Datei.
datei.flush();
} catch ( IOException e ){
System.out.println( "Konnte Datei nicht erstellen" );
}
}
12
//Methode, welche den Baum anzeigt.
void frageBaumAnzeigen(boolean jaFrage, Frageknoten frageknoten, int
baumtiefe)
{
//Methode, welche angibt, wie weit der Einzug bei den einzelen Baumzeilen sein
soll (ähnlich Tabulator)
Methode ergänzen(baumtiefe);
System.out.println( (jaFrage? "Ja" : "Nein") + "-Frage: " + frageknoten.frage);
if (frageknoten.istAntwortJ)
{
einruecken(baumtiefe+1);
System.out.println("Ja-Antwort:" + frageknoten.antwortJ);
}
else
frageBaumAnzeigen(true,
(Frageknoten)fragen.get(frageknoten.fragenummerJ), baumtiefe+1);
if (frageknoten.istAntwortN)
{
einruecken(baumtiefe+1);
System.out.println("Nein-Antwort:" + frageknoten.antwortN);
}
else
frageBaumAnzeigen(false,
(Frageknoten)fragen.get(frageknoten.fragenummerN), baumtiefe+1);
}
//"Tabulator"
void einruecken(int tiefe)
{
for (int i = 0; i < tiefe*4; i++ )
System.out.write(' ');
}
}
13
Herunterladen