Javakurs/Übungsaufgaben/Rennschnecke/Musterloesung
< Javakurs | Übungsaufgaben | Rennschnecke
Version vom 1. August 2010, 15:23 Uhr von Jörg F (Diskussion | Beiträge) (hat „Javakurs2006/Rennschnecke/Musterloesung“ nach „Javakurs/Übungsaufgaben/Rennschnecke/Musterloesung“ verschoben: wikistruktur)
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 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 = this.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 : this.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 : this.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