Initial commit of the source files.

This commit is contained in:
Bernhard Tellenbach 2017-09-17 17:07:06 +02:00
parent b0f8ac3fd7
commit 8f9d45557f
5 changed files with 686 additions and 0 deletions

76
src/Gegenstand.java Normal file
View File

@ -0,0 +1,76 @@
/**
* Diese Klasse modeliert einen Gegenstand
* mit seinem Namen und seiner Beschreibung sowie
* seinem Gewicht.
*
* @author tebe
* @version 1.0
*
*/
public class Gegenstand {
private final String name;
private final String beschreibung;
private final int gewicht;
/**
* Erzeugt einen Gegenstand mit Namen und
* Gewicht aber ohne genauere Beschreibung.
*
* Der Name darf nicht null sein und das
* Gewicht muss groesser als 0 sein.
*
* @param name Der Name des Gegenstands
* @param gewicht Das Gewicht des Gegenstands
*/
public Gegenstand(String name, int gewicht) {
this(name, "", gewicht);
}
/**
* Erzeugt einen Gegenstand mit Namen und
* Gewicht und genauere Beschreibung.
*
* Name und Beschreibung duerfen nicht null sein und das
* Gewicht muss groesser als 0 sein.
*
* @param name Der Name des Gegenstands
* @param gewicht Das Gewicht des Gegenstands
*/
public Gegenstand(String name, String beschreibung, int gewicht){
this.name = name;
this.gewicht = gewicht;
this.beschreibung = beschreibung;
if(! istDefinitionGueltig()) {
throw new IllegalArgumentException(
"Gegenstandsdefinition ist ungueltig.");
}
}
private boolean istDefinitionGueltig(){
return !(name == null || beschreibung == null || gewicht <= 0);
}
/**
* @return Der Name des Gegenstands
*/
public String gibName() {
return name;
}
/**
* Gibt die Beschreibung des Gegenstandes zurueck.
* Falls der Gegenstand ueber keine Beschreibung
* verfuegt, wird ein leerer String zurueckgegeben.
* @return Die Beschreibung des Gegenstands
*/
public String gibBeschreibung() {
return beschreibung;
}
/**
* @return Das Gewicht des Gegenstands
*/
public int gibGewicht() {
return gewicht;
}
}

40
src/Parser.java Normal file
View File

@ -0,0 +1,40 @@
import java.util.Scanner;
/**
* Dieser Parser liest Benutzereingaben und wandelt sie in Befehle um. Bei jedem
* Aufruf liest er eine Zeile von der Konsole und versucht, diese als einen
* Befehl aus bis zu zwei Woertern zu interpretieren. Er liefert den Befehl als
* ein Objekt der Klasse Befehl zurueck.
*
* Der Parser verfuegt ueber einen Satz an bekannten Befehlen. Er
* vergleicht die Eingabe mit diesen Befehlen. Wenn die Eingabe
* keinen bekannten Befehl enthaelt, dann liefert der Parser ein als
* unbekannter Befehl gekennzeichnetes Objekt zurueck.
*
* @author tebe
* @version 18.10.2013
*/
class Parser {
// Lieferant fuer eingegebene Befehle
private Scanner leser = new Scanner(System.in);
/**
* @return Der naechste Befehl des Benutzers.
*/
public Befehl liefereBefehl() {
Befehl befehl;
String eingabezeile; // fuer die gesamte Eingabezeile
System.out.print("> "); // Eingabeaufforderung
eingabezeile = leser.nextLine();
String[] woerter = eingabezeile.split(" ");
if (woerter.length >= 2) {
befehl = new Befehl(woerter[0], woerter[1]);
} else {
befehl = new Befehl(woerter[0], null);
}
return befehl;
}
}

46
src/Person.java Normal file
View File

@ -0,0 +1,46 @@
import java.util.ArrayList;
/**
* Diese Klasse modeliert eine Person, die einen Namen
* hat und einen Rucksack traegt. Im Rucksack kann sie
* Gegenstaende herumtragen. Gegenstaende sollen nur dann in den
* Rucksack gepackt werden, wenn der Rucksack nicht schwerer wird
* als die Tragkraft der Person.
*
* @author tebe
* @version 1.0
*
*/
public class Person {
private final String name;
private final int tragkraft;
private final ArrayList<Gegenstand> rucksack = new ArrayList<Gegenstand>();
/**
* Erzeugt eine Person mit Namen und Tragkraft.
* @param tragkraft
*/
public Person(String name, int tragkraft) {
this.tragkraft = tragkraft;
this.name = name;
}
public ArrayList<Gegenstand> getRucksack() {
return rucksack;
}
/**
* Gibt die Tragkraft zurueck.
* @return Die Tragkraft
*/
public int gibTragkraft() {
return tragkraft;
}
/**
* @return Der Name der Person
*/
public String gibName() {
return name;
}
}

169
src/Raum.java Normal file
View File

@ -0,0 +1,169 @@
import java.util.ArrayList;
import java.util.Set;
import java.util.HashMap;
/**
* Diese Klasse modelliert Raeume in der Welt von Zuul.
*
* Ein "Raum" repraesentiert einen Ort in der virtuellen Landschaft des
* Spiels. Ein Raum ist mit anderen Raeumen ueber Ausgaenge verbunden.
* Fuer jeden existierenden Ausgang haelt ein Raum eine Referenz auf
* den benachbarten Raum. In einem Raum koennen sich Personen und
* Gegenstaende befinden.
*
* @author tebe (Original: Michael Koelling und David J. Barnes)
* @version 1.0
*/
class Raum
{
private final String beschreibung;
private final ArrayList<Person> person = new ArrayList<Person>();
private final ArrayList<Gegenstand> gegenstand = new ArrayList<Gegenstand>();
private final HashMap<String, Raum> ausgaenge = new HashMap<String, Raum>();
/**
* Erzeuge einen Raum mit einer Beschreibung. Ein Raum
* hat anfangs keine Ausgaenge, Personen oder Gegenstaende.
* @param beschreibung enthaelt eine Beschreibung in der Form
* "in einer Kueche" oder "auf einem Sportplatz".
*/
public Raum(String beschreibung)
{
this.beschreibung = beschreibung;
}
/**
* Definiere einen Ausgang fuer diesen Raum.
* @param richtung Die Richtung, in der der Ausgang liegen soll
* @param nachbar Der Raum, der ueber diesen Ausgang erreicht wird
*/
public void setzeAusgang(String richtung, Raum nachbar)
{
ausgaenge.put(richtung, nachbar);
}
/**
* Die Person betritt den Raum und wird fortan als im Raum
* befindlich gelistet.
* @param person Person, welche den Raum betritt
*/
public void betreten(Person person)
{
this.person.add(person);
}
/**
* Die Person mit der angegebenen Nummer wird aus dem Raum entfernt
* und wird fortan nicht mehr als im Raum befindlich gelistet.
* Falls eine Person mit dieser Nummer nicht existiert, wird 'null'
* zurueckgegeben.
* @param nummer Nummer der Person
* @return Person, die den Raum verlassen hat
*/
public Person verlassen(int nummer)
{
boolean ungueltigerIndex = person.isEmpty() ||
nummer > person.size()-1 || nummer < 0;
return ungueltigerIndex ? null : person.remove(nummer);
}
/**
* Der Gegenstand wird in den Raum gelegt und wird fortan als im
* Raum befindlich gelistet.
* @param gegenstand Gegenstand, welcher in den Raum gelegt wird
*/
public void hineinlegen(Gegenstand gegenstand)
{
this.gegenstand.add(gegenstand);
}
/**
* Der Gegenstand mit der angegebenen Nummer wird aus dem Raum entfernt
* und wird fortan nicht mehr als im Raum befindlich gelistet.
* Falls ein Gegenstand mit dieser Nummer nicht existiert, wird 'null'
* zurueckgegeben.
* @param nummer Nummer des Gegenstands
* @return Gegenstand, der herausgenommen wurde
*/
public Gegenstand herausnehmen(int nummer)
{
boolean ungueltigerIndex = gegenstand.isEmpty() ||
nummer > gegenstand.size()-1 || nummer < 0;
return ungueltigerIndex ? null : gegenstand.remove(nummer);
}
/**
* @return Die kurze Beschreibung dieses Raums (die dem Konstruktor
* uebergeben wurde).
*/
public String gibKurzbeschreibung()
{
return beschreibung;
}
/**
* Liefere eine lange Beschreibung dieses Raums, inkl.
* Beschreibung des Rauminhaltes (Gegenstaende, Personen,...).
* @return eine lange Beschreibung dieses Raumes.
*/
public String gibLangeBeschreibung()
{
return "Sie sind " + beschreibung + ".\n"
+ gibAusgaengeAlsString()
+ gibGegenstaendeAlsString()
+ gibPersonenAlsString();
}
private String gibGegenstaendeAlsString() {
String text = "Keine Gegenstaende im Raum.\n";
if(gegenstand.size()>0) {
int counter = 0;
text = "Gegenstaende im Raum:\n";
for( Gegenstand objekt : gegenstand) {
text += " " + counter++ + ": " + objekt.gibName() + "\n";
}
}
return text;
}
private String gibPersonenAlsString() {
String text = "Keine Personen im Raum.\n";
if(person.size()>0){
text="Personen im Raum:\n";
int counter = 0;
for( Person objekt : person) {
text += " " + counter++ + ": " + objekt.gibName() + "\n";
}
}
return text;
}
/**
* Liefere eine Zeichenkette, die die Ausgaenge dieses Raums
* beschreibt, beispielsweise
* "Ausgaenge: north west".
* @return eine Beschreibung der Ausgaenge dieses Raumes.
*/
private String gibAusgaengeAlsString()
{
String ergebnis = "Ausgaenge:";
Set<String> keys = ausgaenge.keySet();
for(String ausgang : keys)
ergebnis += " " + ausgang;
return ergebnis + "\n";
}
/**
* Liefere den Raum, den wir erreichen, wenn wir aus diesem Raum
* in die angegebene Richtung gehen. Liefere 'null', wenn in
* dieser Richtung kein Ausgang ist.
* @param richtung die Richtung, in die gegangen werden soll.
* @return den Raum in der angegebenen Richtung.
*/
public Raum gibAusgang(String richtung)
{
return ausgaenge.get(richtung);
}
}

355
src/Spiel.java Normal file
View File

@ -0,0 +1,355 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
/**
* Dies ist die Hauptklasse der Anwendung "Die Welt von Zuul".
* "Die Welt von Zuul" ist ein sehr einfaches, textbasiertes Adventure-Game. Ein
* Spieler kann sich in einer Umgebung bewegen, die Kontrolle von anderen Personen
* im Raum uebernehmen und Gegenstaende einpacken, sofern seine Tragkraft ausreicht.
* Das Spiel sollte auf jeden Fall noch weiter ausgebaut werden, damit es interessanter wird!
*
*
* Diese Instanz dieser Klasse erzeugt und initialisiert alle anderen Objekte
* der Anwendung: Sie legt alle Raeume und einen Parser an und startet das
* Spiel. Sie wertet auch die Befehle aus, die der Parser liefert und sorgt fuer
* ihre Ausfuehrung.
*
* @author tebe (Original: Michael Koelling und David J. Barnes)
* @version 1.0
*/
public class Spiel {
private Parser parser;
private Raum aktuellerRaum;
private Person spieler;
/**
* Erzeuge ein Spiel und initialisiere die Spielwelt.
*/
public Spiel() {
spielweltErzeugen();
parser = new Parser();
}
/**
* Baut die Spielewelt auf. Erzeugt die Raeume mit Verbindungen und fuellt
* diese mit Personen und Gegenstaenden.
*/
private void spielweltErzeugen() {
spieler = new Person("Captain Kirk", 20);
ArrayList<Raum> raeume = raeumeAnlegen();
fuellenMitPersonen(raeume);
fuellenMitGegenstaenden(raeume);
}
/**
* Erzeuge alle Raeume, verbinde ihre Ausgaenge miteinander.
*
* @return Die angelegten Raeume
*/
private ArrayList<Raum> raeumeAnlegen() {
HashMap<String, Raum> raum = new HashMap<String, Raum>();
// die Raeume erzeugen
raum.put("draussen", new Raum("vor dem Haupteingang der Universitaet"));
raum.put("hoersaal", new Raum("in einem Vorlesungssaal"));
raum.put("cafeteria", new Raum("in der Cafeteria der Uni"));
raum.put("labor", new Raum("in einem Rechnerraum"));
raum.put("buero", new Raum("im Verwaltungsbuero der Informatik"));
// die Ausgaenge initialisieren
raum.get("draussen").setzeAusgang("osten", raum.get("hoersaal"));
raum.get("draussen").setzeAusgang("sueden", raum.get("labor"));
raum.get("draussen").setzeAusgang("westen", raum.get("cafeteria"));
raum.get("hoersaal").setzeAusgang("westen", raum.get("draussen"));
raum.get("cafeteria").setzeAusgang("osten", raum.get("draussen"));
raum.get("labor").setzeAusgang("norden", raum.get("draussen"));
raum.get("labor").setzeAusgang("osten", raum.get("buero"));
raum.get("buero").setzeAusgang("westen", raum.get("labor"));
// Startraum
aktuellerRaum = raum.get("draussen");
ArrayList<Raum> raumliste = new ArrayList<Raum>();
for (Raum r : raum.values()) {
raumliste.add(r);
}
return raumliste;
}
/**
* Verteilt eine Anzahl Personen auf eine Liste von Raeumen. Die Zuteilung
* erfolgt auf Basis einer Zufallsstrategie.
*
* @param raum
* Liste der Raeume
*/
private void fuellenMitPersonen(ArrayList<Raum> raum) {
ArrayList<Person> person = new ArrayList<Person>();
person.add(new Person("Dr. Hans Muster", 40));
person.add(new Person("Peter Stark", 80));
person.add(new Person("Anna Pfister", 45));
person.add(new Person("Prof. Dr. Luna Berger", 35));
int counter = 0;
while (person.size() > 0) {
if (Math.random() > 0.5) {
raum.get(counter).betreten(person.get(0));
person.remove(0);
}
counter = (counter + 1) % raum.size();
}
}
/**
* Verteilt eine Anzahl Gegenstaende auf eine Liste von Raeumen. Die
* Zuteilung erfolgt auf Basis einer Zufallsstrategie.
*
* @param raum
* Liste der Raeume
*/
private void fuellenMitGegenstaenden(ArrayList<Raum> raum) {
ArrayList<Gegenstand> gegenstand = new ArrayList<Gegenstand>();
gegenstand.add(new Gegenstand("Sehr schwerer Laserpointer", 1));
gegenstand.add(new Gegenstand("Beamer", 12));
gegenstand.add(new Gegenstand("Workstation", 10));
gegenstand.add(new Gegenstand("Wandtafel", 250));
gegenstand.add(new Gegenstand("Mineralwasser (6x1.5L)", 9));
gegenstand.add(new Gegenstand("Laptoptasche mit Laptop", 5));
gegenstand.add(new Gegenstand("Flipchart", 11));
gegenstand.add(new Gegenstand("Whiteboard", 8));
gegenstand.add(new Gegenstand("Toeggelikasten", 30));
int counter = 0;
while (gegenstand.size() > 0) {
if (Math.random() > 0.5) {
raum.get(counter).hineinlegen(gegenstand.get(0));
gegenstand.remove(0);
}
counter = (counter + 1) % raum.size();
}
}
/**
* Die Hauptmethode zum Spielen. Laeuft bis zum Ende des Spiels in einer
* Schleife.
*/
private void spielen() {
willkommenstextAusgeben();
// Die Hauptschleife. Hier lesen wir wiederholt Befehle ein
// und fuehren sie aus, bis das Spiel beendet wird.
boolean beendet = false;
while (!beendet) {
Befehl befehl = parser.liefereBefehl();
beendet = verarbeiteBefehl(befehl);
}
System.out.println("Danke fuer dieses Spiel. Auf Wiedersehen.");
}
/**
* Einen Begruessungstext fuer den Spieler ausgeben.
*/
private void willkommenstextAusgeben() {
System.out.println();
System.out.println("Willkommen zu Zuul!");
System.out
.println("Zuul ist ein neues, unglaublich langweiliges Spiel.");
System.out.println("Tippen sie '" + Befehlswort.HILFE
+ "', wenn Sie Hilfe brauchen.");
System.out.println();
System.out.println(aktuellerRaum.gibLangeBeschreibung());
}
/**
* Verarbeite einen gegebenen Befehl (fuehre ihn aus).
*
* @param befehl
* Der zu verarbeitende Befehl.
* @return 'true', wenn der Befehl das Spiel beendet, 'false' sonst.
*/
private boolean verarbeiteBefehl(Befehl befehl) {
boolean moechteBeenden = false;
Befehlswort befehlswort = befehl.gibBefehlswort();
switch (befehlswort) {
case UNBEKANNT:
System.out.println("Ich weiss nicht, was Sie meinen...");
break;
case UMSEHEN:
umsehen();
break;
case HILFE:
hilfstextAusgeben();
break;
case GEHE:
wechsleRaum(befehl);
break;
case BEENDEN:
moechteBeenden = beenden(befehl);
break;
case UEBERNIMM:
uebernimm(befehl);
break;
case NIMM:
nimm(befehl);
break;
default:
System.out.println("Befehlswort ohne zugehoerige Aktion.");
break;
}
return moechteBeenden;
}
/**
*
*/
private void umsehen() {
System.out.println("Sie sind: " + spieler.gibName());
System.out.println(aktuellerRaum.gibLangeBeschreibung());
}
/**
* Packt den spezifizierten Gegenstand in den Rucksack
* des Spielers und entfernt ihn aus dem aktuellen Raum.
*
* Falls der bezeichnete Gegenstand nicht vorhanden ist, aendert sich nichts.
*
* @param befehl Der auszufuehrende Befehl
*/
private void nimm(Befehl befehl) {
if (befehl.hatZweitesWort()) {
int kennummer = Integer.parseInt(befehl.gibZweitesWort());
gegenstandEinpacken(kennummer);
} else {
System.out.println("Geben Sie die Nummer des Gegenstands an.");
}
}
/**
* Packt den Gegenstand mit der gegebenen
* Nummer, falls vorhanden, in den Rucksack
* des Spielers und entfernt ihn aus dem aktuellen Raum.
*
* @param nummer Nummer des Gegenstands
*/
private void gegenstandEinpacken(int nummer) {
Gegenstand gegenstand = aktuellerRaum.herausnehmen(nummer);
if (gegenstand == null) {
System.out.println("Es gibt keinen Gegenstand mit dieser Nummer: "
+ nummer);
} else {
if (spieler.gibTragkraft() >= berechneGewicht(spieler.getRucksack()) + gegenstand.gibGewicht()) {
System.out.println("Gegenstand eingepackt: " + gegenstand.gibName());
spieler.getRucksack().add(gegenstand);
} else {
System.out
.println("Gegenstand konnte nicht eingepackt werden.");
aktuellerRaum.hineinlegen(gegenstand);
}
}
}
/**
* Berechnet das Gewicht der Gegenstaende in dieser Liste
* @param rucksack Die Liste mit Gegenstaenden
* @return Das Gewicht der Gegenstaende
*/
private int berechneGewicht(ArrayList<Gegenstand> rucksack) {
int gewicht = 0;
for(Gegenstand gegenstand : rucksack) {
gewicht += gegenstand.gibGewicht();
}
return gewicht;
}
/**
* Uebernimmt die Kontrolle der spezifizierten Person. Der Spieler steuert
* anschliessend neu diese Person.
*
* Falls die bezeichnete Person nicht vorhanden ist, aendert sich nichts.
*
* @param befehl
* Der auszufuehrende Befehl
*/
private void uebernimm(Befehl befehl) {
if (befehl.hatZweitesWort()) {
int nummer = Integer.parseInt(befehl.gibZweitesWort());
personUebernehmen( nummer);
} else
{
System.out.println("Geben Sie die Nummer der Person an.");
}
}
/**
* Uebernimmt, falls vorhanden, die Kontrolle der
* Person mit der spezifizierten Nummer.
*
* @param nummer Nummer der Person
*/
private void personUebernehmen(int nummer) {
Person person = aktuellerRaum.verlassen(nummer);
if (person == null) {
System.out.println("Es gibt keine Person mit Nummer " + nummer);
} else {
aktuellerRaum.betreten(spieler);
spieler = person;
System.out.println("Sie kontrollieren nun " + spieler.gibName());
}
}
/**
* Gib Hilfsinformationen aus. Hier geben wir eine etwas alberne und unklare
* Beschreibung aus, sowie eine Liste der Befehlswoerter.
*/
private void hilfstextAusgeben() {
System.out.println("Sie haben sich verlaufen. Sie sind allein.");
System.out.println("Sie irren auf dem Unigelaende herum.");
System.out.println();
befehleAusgeben();
}
/**
* Gibt eine Liste der vorhandenen Befehlswoerter aus.
*/
private void befehleAusgeben() {
System.out.println("Ihnen stehen folgende Befehle zur Verfuegung:");
System.out.println(Befehlswort.gibBefehlsworteAlsText());
}
/**
* Versuche, in eine Richtung zu gehen. Wenn es einen Ausgang gibt, wechsele
* in den neuen Raum, ansonsten gib eine Fehlermeldung aus.
*/
private void wechsleRaum(Befehl befehl) {
if (!befehl.hatZweitesWort()) {
// Gibt es kein zweites Wort, wissen wir nicht, wohin...
System.out.println("Wohin moechten Sie gehen?");
return;
}
String richtung = befehl.gibZweitesWort();
// Wir versuchen, den Raum zu verlassen.
Raum naechsterRaum = aktuellerRaum.gibAusgang(richtung);
if (naechsterRaum == null) {
System.out.println("Dort ist keine Tuer!");
} else {
aktuellerRaum = naechsterRaum;
System.out.println(aktuellerRaum.gibLangeBeschreibung());
}
}
/**
* Der Befehl zum Beenden wurde eingegeben. Ueberpruefe den Rest des
* Befehls, ob das Spiel wirklich beendet werden soll.
*
* @return 'true', wenn der Befehl das Spiel beendet, 'false' sonst.
*/
private boolean beenden(Befehl befehl) {
if (befehl.hatZweitesWort()) {
System.out.println("Was soll beendet werden?");
return false;
} else {
return true;
}
}
}