Javakurs/Übungsaufgaben/Rennschnecke/Musterloesung
< Javakurs | Übungsaufgaben | Rennschnecke
Version vom 24. März 2010, 13:56 Uhr von Andre (Diskussion | Beiträge) (→Rennschnecke - Musterlösung)
Inhaltsverzeichnis
Rennschnecke - Musterlösung
Dies ist eine ausführliche Musterlösung der Aufgabenstellung. Vom Wettbüso gibt es zwei unterschiedliche Versionen, von denen die zweite die Zusatzaufgaben berücksichtigt.
Rennschnecke.java
package Schneckenrennen;
import java.util.Random;
/**
* Eine Schnecke, welche an Rennen teilnehmen kann.
* @author André Schulz
* @version 1.0
*/
public class Rennschnecke
{
private String name;
private String rasse;
private double vMax;
private double strecke;// zurückgelegte Strcke am Startpunkt
/**
* Konstruktor für Schnecken.
* @param name Name der Schnecke
* @param rasse Rasse der Schnecke
* @param vMax Maximalgeschwindigkeit der Schnecke
*/
public Rennschnecke(String name, String rasse, double vMax)
{
this.name = name;
this.rasse = rasse;
this.vMax = vMax;
this.strecke = 0;
}
/**
* Bewegt die Schnecke mit einer zufälligen Geschwindigkeit (im Abhängigkeit von der Maximalgeschwindigkeit).
*/
public void krieche()
{
Random random = new Random();
// Mximalgeschwindigkeit wird mit 0,01..1 multipliziert
this.strecke += vMax * (random.nextInt(100) + 1) / 100;
}
/**
* Gibt den Namen der Schnecke zurück.
* @return Name
*/
public String getName()
{
return name;
}
/**
* Gibt die Rasse der Schnecke zurück.
* @return Rasse
*/
public String getRasse()
{
return rasse;
}
/**
* Gibt die Maximalgeschwindigkeit zurück.
* @return Maximalgeschwindigkeit
*/
public double getVMax()
{
return vMax;
}
/**
* Gibt die bereits zurückgelegte Strecke zurück.
* @return zurückgelegt Strecke
*/
public double getStrecke()
{
return strecke;
}
public String toString()
{
return "(" + name + "." + rasse + ":" + vMax + "@" + strecke + ")";
}
/**
* Main-Methode (nur zum Testen)
* @param args (keine)
*/
public static void main(String[] args)
{
Rennschnecke snail = new Rennschnecke("andre", "human", 100);
System.out.println(snail);
}
}// class Rennschnecke
Rennen.java
package Schneckenrennen;
import java.util.ArrayList;
import java.util.Iterator;
/**
* Ein Rennen, an dem Schnecken teilnehmen.
* @author André Schulz
* @version 1.0
*/
public class Rennen
{
private String name;
private ArrayList<Rennschnecke> schnecken;
private double renndistanz;
/**
* Konstruktor für Schneckenrennen<br>
* (Punkt 3)
* @param name Name des Schneckenrennens
* @param renndistanz distance off the race
*/
public Rennen(String name, double renndistanz)
{
this.name = name;
//leere ArrayList von Schnecken
this.schnecken = new ArrayList<Rennschnecke>();
this.renndistanz = renndistanz;
}
/**
* Fügt eine Schnecke dem Rennen hinzu.<br>
*(Punkt 4)
* @param schnecke eine zum Rennen hinzuzufügende Schnecke
* @throws IllegalArgumentException wenn versucht wird eine Schnecke mehrmals hinzuzufügen
*/
public void addRennschnecke(Rennschnecke schnecke)
{
//überprüfen, ob die Schnecke schon am Rennen teilnimmt (Doppelteilnahme verhindern)
//(Zustazpunkt 1)
if (this.schnecken.contains(schnecke))
{
//Exception werfen, wenn die Schnecke schon am Rennen teilnimmt
//=> muss ein Programmierfehler sein
throw new IllegalArgumentException("This snail is alredy at this race!");
}
this.schnecken.add(schnecke);
}
/**
* Entfernt eine Schnecke aus dem Rennen.<br>
* (entfernt alle Schnecken, die den jeweiligen Namen haben)<br>
* (Punkt 5)
* @param name Name der zu entfernende(n) Schnecke(n)
*/
public void removeRennschnecke(String name)
{
Rennschnecke schnecke;
//Iterator um die ArrayList zu durchlaufen
Iterator<Rennschnecke> iter = schnecken.iterator();
//solange es noch Elemente in der ArrayList gibt...
while (iter.hasNext())
{
//...sich den nächsten Eintrag nehmen...
schnecke = iter.next();
//...und überprüfen ob der Name mit dem zu entfernenden Namen übereinstimmt...
if (schnecke.getName().equals(name))
{
//...wenn, dann diesen Eintrag aus der ArrayList entfernen
iter.remove();
}// if
}// while
}// removeSnail
public String toString()
{
//(Punkt 6)
//StringBuilder ist Classe um Strings zu "bauen"
StringBuilder sb = new StringBuilder();
//Metadaten des Rennens (Name, Teilnehmeranzahl, Distanz)
sb.append(this.name + "(" + this.schnecken.size() + ") :" + this.renndistanz + "\n");
//die gesamte ArrayList durchlaufen und alle Schnecke hinzufügen
for (Rennschnecke snail : this.schnecken)
{
sb.append(snail);
sb.append("\n");
}// for
//wenn es einen Gewinner gibt
if (this.getGewinner() != null)
{
//...dann wird er hinzugefügt
sb.append("Gewinner:");
sb.append(this.getGewinner());
}
else
{
//..ansonsten nicht
sb.append("Rennen noch nicht gestartet!");
}
sb.append("\n");
//den gebauten String in eine echte Zeichenkette konvertieren
return sb.toString();
}// toString
/**
* Methode liefert auch einen String, welcher das Rennen repräsentiert,
* doch ist der Aufbau etwas übersichtlicher. (tabellarisch)
* @return String-Repräsentation des Schneckenrennens
*/
public String getPrintString()
{
StringBuilder sb = new StringBuilder();
sb.append("Rennen: '");
sb.append(this.name);
sb.append("' Teilnehmer: ");
sb.append(this.schnecken.size());
sb.append(" Distanz: ");
sb.append(this.renndistanz);
sb.append("\nSchnecken:\n");
sb.append("+Name\t+Rasse\t+vMax\t+Strecke\n");
for (Rennschnecke snail : this.schnecken)
{
sb.append(snail.getName());
sb.append("\t");//zwischen den einzelnen Atributen der Schnecken wird ein TabStop eingefügt
sb.append(snail.getRasse());
sb.append("\t");
sb.append(snail.getVMax());
sb.append("\t");
sb.append(snail.getStrecke());
sb.append("\t\n");
}// for
if (this.getGewinner() != null)
{
sb.append("Gewinner:");
sb.append(this.getGewinner());
}
else
{
sb.append("Rennen noch nicht gestartet!");
}
sb.append("\n");
return sb.toString();
}//getPrintString
/**
* Gibt das Rennen tabellarisch auf der Konsole aus.
*/
public void print()
{
System.out.println(getPrintString());
}// print
/**
* Gibt den Gewinner des Rennens zurück.<br>
* (Gibt <code>null</code> zurück, wenn das Rennen noch nciht beendet wurde.)<br>
* (Punkt 8)
* @return Gewinner des Rennens
*/
public Rennschnecke getGewinner()
{
Rennschnecke gewinner = null;//bis jetzt ist noch keiner bekannt...
//durchlaufe alle Schnecken...
for (Rennschnecke schnecke : schnecken)
{
//...überprüfe ob eine die Renndistanz zurückgelegt hat
if (schnecke.getStrecke() > this.renndistanz)
{
//wenn bisher noch kein gewinner ermittelt wurde...
if (gewinner == null)
{
//...dann ist die Schnecke der gewinner
gewinner = schnecke;
}
else
{
//...andernfalls ist die Schnecke welche weiter ist der Gewinner
//(Zusatzpunkt 3)
if (schnecke.getStrecke() > gewinner.getStrecke())
{
gewinner = schnecke;
}
}
}// if
}// for
return gewinner;
}//getWinner
/**
* Gibt alle Schnecken zurück.
* @return alle Schnecken
*/
public ArrayList<Rennschnecke> getSchnecken()
{
return this.schnecken;
}
/**
* Gibt den Namen des Rennens zurück
* @return Rennname
*/
public String getName()
{
return this.name;
}
/**
* Lässt alle Schnecken ein mal kriechen.<br>
* (Punkt 9)
*/
public void lasseSchneckenKriechen()
{
for (Rennschnecke snail : schnecken)
{
snail.krieche();
}
}
/**
* Führt das Rennen durch<br>
* Bewegt alle Schnecken so lange, bis eine im Zeil ist.<br>
* (Punkt 10)
*/
public void durchfuehren()
{
System.out.println("Rennen '" + this.name + "' wird durchgeführt...");
//so lange es keinen Gewinner gibt...
while (this.getGewinner() == null)
{
//...alle Schnecken ein mal kriechen lassen.
this.lasseSchneckenKriechen();
}// while
}
/**
* Maim-Methode (nur zum Testen)
* @param args (keine)
*/
public static void main(String[] args)
{
Rennen testRennen = new Rennen("Test", 100000);
testRennen.addRennschnecke(new Rennschnecke("andre", "human", 100));
testRennen.addRennschnecke(new Rennschnecke("klaus", "human", 90));
testRennen.addRennschnecke(new Rennschnecke("hans", "human", 75));
System.out.println(testRennen);
testRennen.durchfuehren();
System.out.println(testRennen);
}
}// class Rennen
Wettbuero.java
package Schneckenrennen;
import java.util.ArrayList;
/**
* Wettbüro (einfache Version)
* @author André Schulz
* @version 1.0
*/
public class Wettbuero
{
private Rennen rennen;
private ArrayList<Wette> wetten;
private double faktor;
/**
* Konstruktor für ein Wettbüro.
* @param rennen das Rennen, welches dieses Wettbüro betreuen soll
* @param faktor der Faktor, welcher bei gewinnen ausgezahlt wird
* @throws IllegalArgumentException wenn versucht wird einen negativen Wetteinsatz zu verwenden
*/
public Wettbuero(Rennen rennen, double faktor)
{
// wenn der Wetteinsatz negativ sein soll => Fehler
// (Zusatzpunkt 2)
if (faktor < 0)
{
throw new IllegalArgumentException("Es dürfen keine Negativen Wetten abgeschlossen werden!");
}
this.rennen = rennen;
this.faktor = faktor;
this.wetten = new ArrayList<Wette>();
}
/**
* Fügt eine Wette hinzu.<br>
* (Punkt 2)
* @param schneckenname Name der Schnecke auf die gesetzt wird
* @param wetteinsatz der Wetteinsatz
* @param spielername Name des Spielers, welche doe Wette tätigt
*/
public void wetteAnnehmen(String schneckenname, double wetteinsatz, String spielername)
{
wetten.add(new Wette(schneckenname, wetteinsatz, spielername));
}
/**
* Führt das Rennen durch.<br>
* (Punkt 3)
*/
public void rennenDurchfuehren()
{
this.rennen.durchfuehren();
}
public String toString()
{
// (Punkt 4)
StringBuilder sb = new StringBuilder();
// zu erst das Rennen ausgeben
sb.append("Renen:\n");
sb.append(this.rennen);
sb.append("Wetten:\n");
// dann Wetten ausgeben, wenn vorhanden
if (wetten.size() > 0)
{
for (Wette wette : this.wetten)
{
sb.append(wette);
sb.append("\n");
}// for
}
else
{
sb.append("(keine)");
}
return sb.toString();
}// toString
/**
* Gibt das Wettbüro, mit dem dazugehörigen Rennen aus.
*/
public void print()
{
StringBuilder sb = new StringBuilder();
sb.append("Wettbüro für:\n");
sb.append(this.rennen.getPrintString());
sb.append("Wetten:\n");
if (wetten.size() > 0)
{
for (Wette bet : this.wetten)
{
sb.append(bet);
sb.append("\n");
}// for
}
else
{
sb.append("(keine)");
}
System.out.println(sb.toString());
}// print
/**
* Main-Methode (nur zum Testen)
* @param args (keine)
*/
public static void main(String[] args)
{
Rennen rennen = new Rennen("testRace", 100000);
rennen.addRennschnecke(new Rennschnecke("andre", "human", 100));
rennen.addRennschnecke(new Rennschnecke("klaus", "human", 90));
rennen.addRennschnecke(new Rennschnecke("hans", "human", 75));
Wettbuero wettbuero = new Wettbuero(rennen, 1.5);
// TODO Wetten hinzufügen
wettbuero.print();
wettbuero.rennenDurchfuehren();
wettbuero.print();
}// main
/**
* Wette.
* @author André Schulz
* @version 1.0
*/
private class Wette
{
private String spielerName;
private String schneckenName;
private double wetteinsatz;
/**
* Konstruktor erstellt eine neue Wette.
* @param schneckenName Name der Schnecke auf die gesetzt werden soll.
* @param wetteinsatz der Wetteinsatz für die Wette
* @param spielerName der Name des Spielers
*/
public Wette(String schneckenName, double wetteinsatz, String spielerName)
{
if (wetteinsatz < 0)
{
throw new IllegalArgumentException("betAmount must be >=0!");
}
this.spielerName = spielerName;
this.schneckenName = schneckenName;
this.wetteinsatz = wetteinsatz;
}// Wette
public String toString()
{
return this.spielerName + ":" + this.wetteinsatz + "@" + this.schneckenName;
}
/**
* Gibt den Namen des Spielers dieser Wette zurück.
* @return Name des Spielers
*/
public String getSpielername()
{
return spielerName;
}
/**
* Gibt den Namen der Schnecke zurück, auf die gesetzt wurde.
* @return Name der Schnecke
*/
public String getSchneckenname()
{
return schneckenName;
}
/**
* Gibt den Wetteinsatz zurück.
* @return Wetteinsatz
*/
public double getWetteinsatz()
{
return wetteinsatz;
}
}// class Wette
}// class Wettbuero
Wettbuero_2.java (verbesserte Version)
package Schneckenrennen;
import java.util.ArrayList;
import java.util.Collections;
/**
* Wettbüro (verbesserte Version)
* @author André Schulz
* @version 2.0
*/
public class Wettbuero_2
{
private Rennen rennen;
private ArrayList<Spieler> spieler;
private ArrayList<Wette> wetten;
private double faktor;
private Rennschnecke gewinner;
/**
* Konstruktor für ein Wettbüro.
* @param rennen das Rennen, welches dieses Wettbüro betreuen soll
* @param faktor der Faktor, welcher bei gewinnen ausgezahlt wird
* @throws IllegalArgumentException wenn versucht wird einen negativen Wetteinsatz zu verwenden
*/
public Wettbuero_2(Rennen rennen, double faktor)
{
// wenn der Wetteinsatz negativ sein sollte => Fehler
// (Zusatzpunkt 2)
if (faktor < 0)
{
throw new IllegalArgumentException("Es dürfen keine Negativen Wetten abgeschlossen werden!");
}
this.rennen = rennen;
this.faktor = faktor;
this.spieler = new ArrayList<Spieler>();
this.wetten = new ArrayList<Wette>();
}// Wettbuero_2
/**
* Fügt dem Wettbüro einen neuen Spieler hinzu.
* @param spielerName der Name des Spielers
*/
public Spieler addSpieler(String spielerName)
{
// neunen Spieler erstellen
Spieler spieler = new Spieler(spielerName);
// wenn der Spieler noch nicht vorhanden ist => hinzufügen
if (!this.spieler.contains(spieler))
{
this.spieler.add(spieler);
}
return spieler;
}// addSpieler
/**
* Fügt eine Wette hinzu.
* @param schneckenName der Name der Schnecke, auf die gesetzt werden soll
* @param wetteinsatz der Wetteinsatz aud die Schnecke
* @param spielerName der Name des Spielers
*/
public void addWette(String schneckenName, double wetteinsatz, Spieler spieler)
{
for (Rennschnecke snail : this.rennen.getSchnecken())
{
if (snail.getName().equals(schneckenName))
{
wetten.add(new Wette(snail, wetteinsatz, spieler));
return;
}// if
}// for
throw new IllegalArgumentException("Eine Schnecke mit dem Namen '" + schneckenName + "' gibts in dem Rennen '" + this.rennen.getName() + " nicht!");
}// addWette
/**
* Führt das Rennen durch.
*/
public void rennenDurchfuehren()
{
this.rennen.durchfuehren();
this.gewinner = this.rennen.getGewinner();
}
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("Rennen:\n");
sb.append(this.rennen);
sb.append("Wetten:\n");
if (wetten.size() > 0)
{
for (Wette bet : this.wetten)
{
sb.append(bet);
sb.append("\n");
}// for
}
else
{
sb.append("(keine)");
}
return sb.toString();
}// toString
/**
* Methode wertet alle Wetten aus.
*/
public void wettenAuswerten()
{
for (Wette wette : this.wetten)
{
wette.setzeGewinn(this.gewinner, this.faktor);
}
}// wettenAuswerten
/**
* Main-Mthode zum Testen.
* @param args (none)
*/
public static void main(String[] args)
{
// rennen erstellen
Rennen race = new Rennen("Testrennen", 100000);
// Schnecken hinzufügen
race.addRennschnecke(new Rennschnecke("andre", "Mensch", 100));
race.addRennschnecke(new Rennschnecke("klaus", "Mensch", 90));
race.addRennschnecke(new Rennschnecke("hans", "Mensch", 75));
// Wettbüro erstellen
Wettbuero_2 wettbuero = new Wettbuero_2(race, 1.5);
// Spieler erstellen
Spieler spielerAndre = wettbuero.addSpieler("andre");
Spieler spielerHans = wettbuero.addSpieler("hans");
// wetten setzen
wettbuero.addWette("andre", 100, spielerAndre);
wettbuero.addWette("hans", 100, spielerHans);
wettbuero.addWette("andre", 10, spielerHans);
// Wettbüro ausgeben (vor dem Lauf)
System.out.println(wettbuero);
// Rennen durchführen udn auswerten
wettbuero.rennenDurchfuehren();
wettbuero.wettenAuswerten();
// Wettbüro ausgeben (nach dem Lauf)
System.out.println(wettbuero);
// zeigt die einzelnen Spieler
System.out.println("Spielerübersicht:");
wettbuero.zeigeSpieler();
}// main
/**
* Methode gibt alle Spieler mit ihren jeweiligen Wetten übersichtlich aus.
*/
public void zeigeSpieler()
{
// sortieren aller Wetten (nach Spielername)
Collections.sort(this.wetten);
String oldSpielerName = "";
double wetteinsatz = 0;// Gesamtwetteinsatz eines Spielers
double wettgewinn = 0;// Gesamtwettgewinn eines Spielers
System.out.println("Spieler\tSchnecke\tEinsatz\tGewinn\tSaldo");
System.out.println("================================================");
for (Wette wette : this.wetten)
{
if (wette.spieler.name == oldSpielerName)
{
System.out.println("\t" + wette.schnecke.getRasse() + "." + wette.schnecke.getName() + "\t" + wette.wetteinsatz + "\t" + wette.wettgewinn + "\t" + (wette.wettgewinn - wette.wetteinsatz));
wetteinsatz += wette.wetteinsatz;
wettgewinn += wette.wettgewinn;
}
else
{
if (oldSpielerName != "")
{
System.out.println("\t\t\t------------------------");
System.out.println("\t\t\t" + wetteinsatz + "\t" + wettgewinn + "\t" + (wettgewinn - wetteinsatz));
}// if
System.out.println(wette.spieler.name);
System.out.println("\t" + wette.schnecke.getRasse() + "." + wette.schnecke.getName() + "\t" + wette.wetteinsatz + "\t" + wette.wettgewinn + "\t" + (wette.wettgewinn - wette.wetteinsatz));
oldSpielerName = wette.spieler.name;
wetteinsatz = wette.wetteinsatz;
wettgewinn = wette.wettgewinn;
}// else
}// for
if (oldSpielerName != "")
{
System.out.println("\t\t\t------------------------");
System.out.println("\t\t\t" + wetteinsatz + "\t" + wettgewinn + "\t" + (wettgewinn - wetteinsatz));
}// if
}// zeigeSpieler
/**
* Eine Wette.
*/
private class Wette implements Comparable<Wette>
{
private Spieler spieler;
private Rennschnecke schnecke;
private double wetteinsatz;
private double wettgewinn;
/**
* Konstruktor für wetten.
* @param schnecke die Schnecke
* @param wetteinsatz der Wetteinsatz
* @param spieler der Spieler der wettet
*/
public Wette(Rennschnecke schnecke, double wetteinsatz, Spieler spieler)
{
if (wetteinsatz < 0)
{
throw new IllegalArgumentException("Wetteinsatz muss >=0 sein!");
}
this.spieler = spieler;
this.schnecke = schnecke;
this.wetteinsatz = wetteinsatz;
this.wettgewinn = -1;
}// Wette
/**
* Methode setzt in Abhängigkeit vom Gewinner den Wettgewinn.
* @param gewinner die Schnecke, welce das Rennen gewonnen hat
* @param faktor der Gewinnfaktor
*/
public void setzeGewinn(Rennschnecke gewinner, double faktor)
{
if (this.schnecke.equals(gewinner))
{
// auf Gewinner gesetzt => Wettgewinn setzen
this.wettgewinn = this.wetteinsatz * faktor;
}
else
{
// auf andere Schnecke gesetzt => kein Gewinn
this.wettgewinn = 0;
}
}// setzeGewinn
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append(this.spieler);
sb.append(":");
sb.append(this.wetteinsatz);
sb.append("@");
sb.append(this.schnecke);
if (this.wettgewinn != -1)
{
sb.append("->");
sb.append(this.wettgewinn);
}
return sb.toString();
}// toString
@Override
public int compareTo(Wette other)
{
return this.spieler.name.compareTo(other.spieler.name);
}
}// class Bet
/**
* Ein Spieler welcher Wetten tätigt.
* @author André Schulz
* @version 1.0
*/
public class Spieler
{
private String name;
public Spieler(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}
public String toString()
{
return name;
}
}// calss Spieler
}// class Wettbuero_2