OOP Bauernhofsimulator

24

Mitglied
Guten Abend,

da ich hier neu bin, zunächst einige Infos zu mir. Mein Name ist Michael, studiere BWL und belege den OOP Kurs als Wahlfach. Meine bisherigen Programmiererfahrungen beschränken sich auf ein wenig Php (Homepage + Shop).

Unsere Aufgabe ist hier zu finden

http://www.vsp.tu-berlin.de/fileadmin/a0533/uploads/lehre/LV/WS1011/L023/Hausaufgabe_Objektorientiertes_Programmieren_fuer_Ingenieure_WS_10.pdf

Mir ist nicht ganz klar, was die einzelnen Klasen enthalten sollen.

Mein bisheriges Ergebnis lautet (Klasse Schweine lasse ich weg, ist ja analog zu Rinder):

Klasse Rinder
  • abstract
  • implementiert Interface Ageable
  • scopes sind protected
  • Methode:diverse Getter, passedAway(können sterben)

Klasse Kuh
  • erbt von Rinder
  • implementier Interface Ageable
  • scopes sind protected
  • Methode: getBaby(kann Kinder bekommen)
Java:
	public double getSchwangerschaftsWkt() {
		Random schwangerSchaftsWkt = new Random();
		return (schwangerSchaftsWkt.nextDouble());
	}
	public Kalb getBaby(double a){ // innerhalb der Simulation, wird jeden Monat SchwangerschaftsWkt erzeugt
		if (this.getAge()>=3 && a<=0.02 ){
			return (new Kalb(0));
		}
		else{
			return null;
		}
	}
Klasse Kalb
erbt von Rinder
implementiert Interface Ageable
scopes sind protected
Methoden:growUp (Kalb wird ab 3 zur Kuh)
Java:
	public Kuh growUp(){
			return (new Kuh(this.getAge())); // erzeuge neue Kuh, die Alter vom Kalb bekommt
	}
Klasse Simulator
  • implementiert Interface Comparator
  • scopes sind private
  • Methode:simulate (Bauernhof simulieren), addKuh (Kuh zu der SImulation hinzufügen) , printResult (Ergebnisse, in der Form "in Jahr 1 ist das passiert(Tot?, Baby?)" Ausgabe abhängig vom Komparator)
Java:
	public void addKuh(int alterKuh){
		kuhListe.add(new Kuh(alterKuh)); // füge Kuh zur Liste kuhListe hinzu
	}

	public void simulate(int month){
			for (int ii = 1 ; ii < month ; ii++){           
                       // ................... fehlt noch einiges

			}
	}
        public String printResult(){
              return ....;
       }
Klasse Hauptprogramm
  • Hier soll die eigentlich Bedienung stattfinden
  • enthält die main-Methode
Java:
package Ha;
public class Hauptprogramm {

	
	public static void main(String[] args) {
		Simulator sim = new Simulator();
		sim.addKuh(7);
		sim.addKuh(4);
		sim.addKuh(27);
		sim.simulate(70);
		sim.erg();
	}
}

Tja und das war es irgendwie schon (bis auf die Schweine, Sau, Ferkel und div Comparatoren Klassen). Vielleicht findet sich ja jemand, der mir bei folgenden Fragen helfen kann.
  • Kann mir jemand eine ungefähre Bauanleitung (inhaltlich) für mein Problem geben (natürlich kein Code!)
  • Brauche ich noch weitere Klassen (Bauernhof?)?
  • Wann und wie verwende ich die ArrayListen?
  • Konkret zu den ArrayListen..
Angenommen ich habe folgendes:
Java:
for (Kuh kuh : kuhListe){
		kuh.increaseAge();
		if (kuh.passedAway()){
			kuhListe.remove(kuh);//entferne die Kuh, wenn gestorben, aus der Liste
		}
	}
wie schaffe ich es, das Objekt zu entfernen ohne, dass ich eine Exception bekomme. Die Exception besagte stets, dass ich während des Iterierens versuche eine Element zu entfernen. Dass das nicht geht, leuchtet mir ein, aber wie löse ich das sonst?

Vielen Dank im Voraus, :toll:

Gruß Michael
 
M

maki

Gast
Anstatt der for-each Schleife nimmst du eine for Schleife und einen Iterator, letzterer bietet remove() methode.
 

24

Mitglied
Hi Maki,

danke für deine Antwort. Mit dem Iterator habe ich bereits versucht gehabt (hätte ich auch schreiben können :oops: ). Das Löschen hat tatsächlich problemlos funktioniert.
Bei Verwendung des Iterators trat allerdings das Problem auf, dass sobald alle Kühe tot sind it.hasNext() false zurückliefert und die ganze Simulation abschmiert, obwohl sich die Kälber ja noch entwickeln können. Vermutlich liegt es einfach an meiner saudummen Umsetzung des Simulators.

Vielleicht kann mir jemand noch versuchen zu erklären, wie ich in etwa vorgehen muss.
 

24

Mitglied
Ach eine konkretere Frage in bezug auf die getBaby()Methode der Kuh habe ich noch. Wie realisiere ich es, dass erst nach 9 Monaten ein neues Kalb returned wird?
 

Cola_Colin

Top Contributor
Bei Verwendung des Iterators trat allerdings das Problem auf, dass sobald alle Kühe tot sind it.hasNext() false zurückliefert und die ganze Simulation abschmiert, obwohl sich die Kälber ja noch entwickeln können. Vermutlich liegt es einfach an meiner saudummen Umsetzung des Simulators.

Wenn hasNext false liefert sollte man für gewöhnlich die Schleife abbrechen ?!



--------
Mal eine Variante, die bei jedem Aufruf entweder das Baby in der Kuh älter werden lässt, um es dann nach 9 Aufrufen(=Monaten) zurückzuliefern oder eben bei einer nicht schwangeren Kuh zu 2% Die Schwangerschaft beginnt.

Java:
// Ich gehe mal davon aus, dass du getBaby() einmal monatlich auf jeder Kuh aufrufst.

private boolean pregnant = false;

private int monthOfPregnancy = 0;

public Kalb getBaby() {
	Kalb result = null;

	if (!pregnant) {
		if (this.getAge() >= 3 && Math.random() <= 0.02) {														 //Math.random ersetzt getSchwangerschaftsWkt()
														 //Eventuell die 0.02 als Konstante an anderer Stelle definieren.
			pregnant = true;
			monthOfPregnancy = 1;
		}
	} else {
		monthOfPregnancy++;
		if (monthOfPregnancy > 8) {
			result = new Kalb(0);
			pregnant = false;
		}
	}

	return result;
}

Als kurze Bauanleitung:

Dein Simulator hat eine Liste aller Tiere.
Alle Tiere basieren auf der abstrakten Klasse Animal, die Grundeigenschaften wie Alter, Gewicht, etc. pp. bestimmt. Auch die Sterblichkeit zählt dazu. Der Teil, der die Wahrscheinlichkeit berechnet wird wohl erstmal Abstrakt. Ebenso gibt es eine abstrakte Methode getBaby(), die für die Erzeugung von Nachwuchs verantwortlich ist.

Nun gibt es die Klasse Kuh und die Klasse Schwein. Kälber und Ferkel würde ich nur als Sonderfälle betrachten, die anhand des Alters bestimmt werden. Soll am Ende gezählt werden, wieviele Ferkel existieren, so werden eben alle Tiere durchlaufen, und alle die der Klasse Schwein angehören auf das Alter 1 überprüft. Man könnte auch über eine Methode hasReachedAdulthood() in der Basisklasse animal nachdenken. Anhand dieser würde man dann immer wenn benötigt bestimmen, ob es noch ein Jungtier oder schon ein erwachsenes Tier ist.

Die Simulation durchläuft dann jeweils alle Tiere, fragt Babys ab und lässt die Tiere sterben.
 

24

Mitglied
Hi vielen Dank für die Hilfe,

die Aufgabe ist nun mittlerweile gelöst und alles klappt hervorragend ;)

Das Problem mit der Exception, die beim Löschvorgang während des Iterierens ausgelöst wird, habe ich mit
Java:
for (k = 0 ; k < tierListe.size() ; k ++ ){
     Tier tier = tierListe.get(k);
....
}
wegbekommen.
 

crush2k

Mitglied
Hallo ich sitze auch an dieser Aufgabe und habe ein Problem bei der Sortierung. Ich würde gerne nach Alter sortieren lassen.

Habe ein comparator Interface erstellt was so ausschaut:

Java:
 import java.util.Comparator;

public class AgeComparator implements Comparator<Rind> {
	
	
	public int compare(Rind k1, Rind k2){
	Integer kuh1 = k1.getAlter();
	Integer kuh2 = k2.getAlter();
	return kuh1.compareTo(kuh2);
	}
}

Dann bin ich in die Klasse bauernhof wo die ganzen Liste definiert wurden und habe das eingefügt:

Java:
 System.out.println("******************************");
		System.out.println("sortiert:");
		System.out.println("*******************************");
		 for(Rind r: Kuehe){ 
		     Collections.sort(Kuehe, new AgeComparator());
		      System.out.println(r);

weiter oben steht das (nur Ausschnitt):

Java:
	// Start der Simulation bei Monat 0
	private int monat = 0;
	
	// Erstellen von Lsiten für die einzelnen Tiere
	List <Rind> Kuehe = new ArrayList <Rind> ();
	List <Rind> NeueKuehe = new ArrayList <Rind> ();
	List <Rind> ToteKuehe = new ArrayList <Rind> ();

Wenn ich das Programm ausführe erhalte ich das:

Java:
******************************
sortiert:
*******************************
Bauernhof.Kuh@6ca1c
Bauernhof.Kuh@1bf216a
Bauernhof.Kuh@12ac982
Bauernhof.Kuh@1389e4
Bauernhof.Kuh@c20e24
Bauernhof.Kuh@2e7263
Bauernhof.Kuh@157f0dc

Hab ich was vergessen ? Kann mir wer vielelicht einen guten Link geben wo es verständlich erklärt wird?

Danke schon mal
 

crush2k

Mitglied
Hallo danke schon mal für die Hilfe. habe in der Rind-Klasse eine toString Methode eingefügt und erhalte nun das:

Java:
******************************
sortiert:
*******************************
Lola(212)
Mariella(10)
Alma(11)
Olivia(13)
Ronja(14)
Judith(41)
Alica(59)
Noemi(61)
Jasmina(73)
Liliana(75)
Madita(87)
Alina(99)
Carmen(129)
Veronika(175)
Lola(212)

Das ist aber irgendwie noch nicht ganz richtig. Brauch ich da nicht noch eine compareTo Methode in der Rind-Klasse ?

greetz
 

Landei

Top Contributor
Erst sortieren, dann ausgeben:
Java:
Collections.sort(Kuehe, new AgeComparator());
for(Rind r: Kuehe){ 
       System.out.println(r);
}

Tja, eine Kuh macht Muh, und viele Kühe machen Mühe....

Übrigens solltest du Variablen (wie Kuehe) klein schreiben.
 

crush2k

Mitglied
Ohja was für ein Fehler. Kann ich analog bei Gewicht und Namen vorgehen wobei ich ja dann die toString Methode ändern müsste oder?

Danke
 

Landei

Top Contributor
Du kannst nur eine [c]toString()[/c]-Methode für eine Klasse haben. Üblich ist, dort alle wichtigen Eigenschaften aufzulisten, also "Lola(3 Jahre, 180 kg, ...)". Du kannst natürlich andere Methoden implementieren, etwa [c]nameMitGewicht()[/c], die "Lola(180kg)" zurückgibt. Dann ruffst du nicht mehr [c]System.out.println(kuh);[/c] sondern eben [c]System.out.println(kuh.nameMitGewicht());[/c] auf. Einen "eingebauten automatischen Aufruf" gibt es nur für [c]toString()[/c],
 

crush2k

Mitglied
Hallo iche nochmal,

ich habe jetzt Comparatoren für Alter und Gewicht erstellt. Jedoch kann die Sortierung nur einzeln vornehmen also separat Rind und separat Schwein. Gibt es eine Möglichkeit die Sortierung für beide Objekte durchzuführen ?


Beides kann ich ja nicht in die for each Schleife packen oder ?
Java:
  Collections.sort(kuehe new AlterComparator());
		     for(Rind r: kuehe){ 
		      System.out.println(r); 
			 }
 

timbeau

Gesperrter Benutzer
Wenn beide von der gleichen Oberklasse erben kannst du sie auch beide in eine Liste packen.

Ich hoffe ich hab dich richtig verstanden :
Java:
class schwein extends Vererbung {

	public schwein(int kg){
		art = "Schwein";
		gewicht = kg;
	}

}

class kuh extends Vererbung {
	kuh (int kg){
		art = "kuh";
		gewicht = kg;
	}

	@Override
	public String toString(){
		super.toString();
		System.out.println("Muh macht die Kuh");
		return "";
	}
}

Der Test:
Java:
	@Test
	public void ouput(){
		kuh kuh = new kuh(500);
		schwein schwein = new schwein(150);
		List<Vererbung> tiere = new ArrayList<Vererbung>();
		tiere.add(kuh);
		tiere.add(schwein);
		for (Vererbung vererbung : tiere) {
			vererbung.toString();
		}
	}

Ergibt:
Java:
kuh
500
Muh macht die Kuh
Schwein
150
 

Pw

Neues Mitglied
Hallo,

sorry erstmal dafür dass ich dieses alte Thema wieder ausgrabe, aber auch ich sitze jetzt an dieser Aufgabe. Ich bin nicht sonderlich gut in Javaprogrammierung aber nach anfänglichen Rückschlägen habe ich es jetzt zumindest schonmal hinbekommen dass Namen, Alter und Gewicht ausgegeben werden und Schweine (diesmal sind es Schweine und Schafe, siehe dazu: http://www.vsp.tu-berlin.de/fileadm...12/L023/ex/2011-12-15_hausaufgabe_ws_2011.pdf) sterben können.

Jetzt hänge ich aber leider dabei fest, dass keine neuen Ferkel geboren werden. Da muss irgendwas an der Übergabe nicht so richtig klappen. Auch die Sortierung will noch nicht so ganz wie sie soll. Vielleicht könntet ihr mal über meinen Quelltext schauen und mir ein paar Hinweise geben wie ich dieses Problem lösen kann.

Meine Klassen:

Main:
Java:
public class Main{

public static void main(String[] args){
	

	Simulator sim = new Simulator(20,3);
	sim.run();
	}
}

Simulator:
Java:
import java.util.*;
public class Simulator {
final int start = 0;
private int yrs;
private int pNom;
List<Schwein> SchweinList = new ArrayList<Schwein>();
List<Schwein> AddedSchweine = new ArrayList<Schwein>();
List<Schwein> RemovedSchweine = new ArrayList<Schwein>();
//List<Schwein> AgeSchweine = new ArrayList<Schwein>();
	

Simulator(int yrs,int pNom){
	this.yrs=yrs;
	this.pNom=pNom;
		
	}
	
public void run(){
	for (int j=0; j<pNom;j ++){
		SchweinList.add(new Sau());

	}
	
	for (int i = 0; i<=yrs;i++){
		System.out.println((i+".Monat")+","+SchweinList.size()+" Schweine");
		
		System.out.println(SchweinList);
		oneMonthForward();
		
	}

}
private void oneMonthForward(){
	RemovedSchweine.clear();
	AddedSchweine.clear();
//	AgeSchweine.clear();
	
	for (Schwein p: SchweinList){
		p.OneMonthForward();
		
//		if (p.getFerkel() != null) AddedSchweine.add(((Ferkel) p).getFerkel());
//		if (p.growUp() != null) AddedSchweine.add(((Sau) p).growUp());
		if (p.getTot()) RemovedSchweine.add(p);
		p.getAge();
		p.getGewicht();
		
		
	}
	SchweinList.removeAll(RemovedSchweine);
	SchweinList.addAll(AddedSchweine);
	
	
}
}

Bauernhof:
Java:
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;

public class Bauernhof {
	
	

    
    // Erstellen von Lsiten für die einzelnen Tiere
    ArrayList <Schwein> schweine = new ArrayList <Schwein> ();
    HashMap <String,Schwein> schweineByName = new HashMap<String,Schwein>();
    
    public void addSchwein (Schwein p){
    	this.schweine.add(p);
    	this.schweineByName.put(p.getName(), p);
    }
    
    public void printSchweineByName (String name) {
    	System.out.println("====================");
    	System.out.println(this.schweineByName.get(name));
    	
    }
    
    public void printSchweineSortedByAge(){
    	System.out.println("====================");
    	Schwein.setComparator(new AgeComparator());
    	Collections.sort(this.schweine);
    	for (Schwein schwein : this.schweine){
    		System.out.println(schwein);
    	}
    	
    }
    
    public void printSchweineSortedByName(){
    	System.out.println("===================");
    	Schwein.setComparator(new NameComparator());
    	Collections.sort(this.schweine);
    	for (Schwein schwein : this.schweine){
    		System.out.println(schwein);
    	}

    
}
 

 
}

Schwein:
Java:
import java.util.Comparator;


import femaleNameGenerator.FemaleName;


public abstract class Schwein implements Comparable<Schwein>{
	private static Comparator<Schwein> comp;
	public int age;
	public String name;
	double gewicht;
	double personalRandom;
	double p;
	boolean tot=false;



	

		public Schwein(String name, int age, double gewicht){
			this.name=FemaleName.getRandomName();
			this.age=age;
			this.gewicht=gewicht;
			this.personalRandom=Math.random();
		}				

		
		Schwein(){
			this.age=0;
			this.name=FemaleName.getRandomName();
			this.gewicht=getGewicht();
			this.personalRandom=Math.random();
			
		}
		
		
		

	public int getAge() {
		return this.age;
	}


	public String getName() {
		return this.name;
	}
	
	
	
	public static void setComparator(Comparator<Schwein> c){
		comp=c;
	}
	
	public int compareTo(Schwein k){
		return comp.compare(this,  k);
	}
	
		
	
	public double getGewicht(){	
		this.gewicht=(1+0.25*personalRandom)*(0.0078*Math.pow(age,5)-0.33*Math.pow(age,4)+5.3*Math.pow(age,3)-41*Math.pow(age,2)+150*age+2.4);
		return this.gewicht;
	}
	
	public boolean getTot(){
		
		p=(Math.pow(age,2)*Math.sqrt(Math.pow(age,3))/100000);
		
		if (p>personalRandom)
		tot=true;
		return tot;
	}

	
	public  String toString(){
		return(name+", "+age+", "+gewicht+", "+tot+"" );
	}
	
	
	
	
	abstract public boolean getFerkel();

	public void OneMonthForward(){
		age++;
	}
}

Sau: (Hier steckt das Problem)

Java:
public class Sau extends Schwein {

	double a;
	
	 public Sau(String name, int age, double gewicht) {
		super( name, age, gewicht);

	}
	 
	 
	public Sau() {
		super();		
	}
	
	private boolean pregnant = false;


	 
	public boolean getFerkel() { 

	 
       if (pregnant==false&&Math.random() <= 1) {
	        	
	            pregnant = true;
	            
	            
	            a=(36*(Math.exp(-0.5*Math.pow((4*Math.random()-2),2))))/Math.PI;
	            	int l=(int) a;
	            		for (int i=1;i==l; i++){
	            			return new Ferkel(name,age,gewicht);  //berechnet Anzahl Ferkel
	            		}
	            pregnant = false;
	            
	            }
	    }
}

Ferkel:

Java:
public class Ferkel extends Schwein {
	
	
	
    public Ferkel(String name, int age, double gewicht) {
		super(name, age, gewicht);

	}

	@Override
	public boolean getFerkel() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public int compareTo(Schwein k) {
		// TODO Auto-generated method stub
		return 0;
	}

}

Dann habe ich noch einen Name und einen Age-Comparator in zwei unterschiedlichen Klassen.
Ich hoffe ihr könnt mir helfen.
Vielen Dank!
 

Landei

Top Contributor
Was soll die komische Formel? Die Schleife sollte jedenfalls so aussehen: [c]for (int i=1;i<=l; i++){[/c] (übrigens ist l wegen der Verwechslungsgefahr mit 1 ein furchtbarer Variablen-Name). Du solltest entweder lernen, wie man einen Debugger benutzt (ist weder Hexenwerk noch Raketentechnik) oder dir zur Fehlersuche wenigstens mit [c]System.out.println[/c] interessante Werte (wie a) ausgeben lassen.
 

Neue Themen


Oben