Spezifische bzw Generische Simulation

forsti222

Mitglied
Hey Leute hätte 2 Anliegen an euch :) hab eine Aufgabe auf der Uni und hab mal teil 1 erledigt, da würde ich um Verbesserungen bitten :)

Java:
package uebung9;
/**
 * Institute for Pervasive Computing, JKU Linz, 2012
 * 
 * @author Sascha Maschek
 */

import java.util.Random;

public class Environment {

	// matrix representing all simulation cells
	private Plant[][] plants;
	// matrix width
	private int width;
	// matrix height
	private int height;

	/**
	 * constructor.
	 */
	public Environment(int width, int height) {
		this.width = width;
		this.height = height;
		this.plants = new Plant[width][height];
	}

	/**
	 * iterates over all plants stored in the matrix and updates them.
	 */
	public void update() {
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (plants[x][y] != null) {
					plants[x][y].update();
				}
			}
		}
	}

	/**
	 * width getter.
	 * 
	 * @return width of matrix
	 */
	public int getWidth() {
		return width;
	}

	/**
	 * height getter.
	 * 
	 * @return height of matrix
	 */
	public int getHeight() {
		return height;
	}

	/**
	 * adds a plant to the simulation. position is implicitly stored in plant
	 * object.
	 * 
	 * @param p
	 *            plant to be put into the simulation environment
	 * @return true if insert was a success, otherwise false
	 */
	public boolean addPlant(Plant p) {
		boolean success = false;
		int x = p.getPos().x;
		int y = p.getPos().y;

		if (x >= 0 && x < width && y >= 0 && y < height) {
			if (plants[x][y] == null) {
				plants[x][y] = p;
				success = true;
			}
		}

		return success;
	}

	/**
	 * remove a plant from the simulation.
	 * 
	 * @param p
	 *            plant to be removed from the simulation environment
	 */
	public void removePlant(Plant p) {
		plants[p.getPos().x][p.getPos().y] = null;
	}

	/**
	 * determines the number of plants of a specific type within a specific
	 * range of the origin plant.
	 * 
	 * @param origin
	 *            the originator of the determination method call
	 * @param range
	 *            max. distance to origin plant
	 * @param plantTypeId
	 *            plant type to be searched
	 * @return number of plants determined
	 */
	public int getNumPlantsInRange(Plant origin, int range, int plantTypeId) {

		int result = 0;
		int pX = Math.max(0, origin.getPos().x);
		int pY = Math.max(0, origin.getPos().y);

		for (int y = pY - range; y < pY + range; y++) {
			for (int x = pX - range; x < pX + range; x++) {
				// check for matrix borders
				if (x >= 0 && x < width && y >= 0 && y < height) {
					// check for circular range
					if (plants[x][y] != null
							&& origin.getPos().distance(plants[x][y].getPos()) <= range) {
						// check for plant type match
						if (plantTypeId == plants[x][y].getTypeId()) {
							result++;
						}
					}
				}
			}
		}

		return result;
	}

	/**
	 * whenever a plant is going to spawn, it will call the seed method of the
	 * environment object. this method will produce a clone of the original
	 * plant and put it into an environment cell within the radius of the
	 * origins max. seed distance.
	 * 
	 * @param origin
	 *            spawning plant
	 * @param maxDistance
	 *            max. distance to origin plant
	 */
	public void seed(Plant origin, int maxDistance) {
		Random rand = new Random(System.nanoTime());
		int dX = rand.nextInt(maxDistance) + 1;
		if (rand.nextBoolean()) {
			dX *= -1;
		}
		int dY = rand.nextInt(maxDistance) + 1;
		if (rand.nextBoolean()) {
			dY *= -1;
		}
		int x = origin.getPos().x + dX;
		int y = origin.getPos().y + dY;

		Plant plant = origin.clone();
		plant.setPos(x, y);
		if (plant != null) {
			addPlant(plant);
		}
	}

	/**
	 * render-method.
	 * 
	 * @return string representation of the environment
	 */
	public String toString() {
		String s = "";

		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				if (plants[x][y] != null) {
					s += plants[x][y].toString();
				} else {
					s += " ";
				}
			}
			s += "\n";
		}

		return s;
	}

}
Java:
package uebung9;

/**
 * Institute for Pervasive Computing, JKU Linz, 2012
 * 
 * @author Sascha Maschek
 */

import java.io.IOException;
import java.util.Random;

public class Simulation {

	public static void main(String[] args) {

		// simulation environment
		Environment env = new Environment(10, 5);

		// seed rand with system time
		Random rand = new Random(System.nanoTime());

		// populate environment with 10 plants
		for (int i = 0; i < 10; i++) {
			// get random coordinates
			int x = rand.nextInt(env.getWidth());
			int y = rand.nextInt(env.getHeight());

			Plant p = null;
			if (i % 2 == 0) {
				// 5 flowers
				p = new Flower(env, x, y);
			} else {
				// 5 trees
				p = new Tree(env, x, y);
			}

			// put plant into environment object
			env.addPlant(p);
		}

		// begin of simulation
		int key = 0;
		try {
			key = System.in.read();
			// main loop
			while (key != 113) { // q ... quit
				// render environment to standard output device
				System.out.println(env.toString());
				// update environment and all plants in each iteration
				env.update();
				key=0;
				// wait for enter to be pressed before next iteration
				key = System.in.read(); // new line
				//key = System.in.read();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
Java:
package uebung9;

public class Flower extends Plant {
	public Flower(Environment environment, int posX, int posY){
		super(environment, posX, posY);
		this.TypeId = 0;
		this.MaxSize = 30;
		this.MaxGrowthRate = 5;
		this.MaxSeedDistance = 3;
		this.RenderChar = '*';
		} 
	public int getTypeId() {
		return TypeId;
	}

	/**
	 * TODO: implement this method in all subclasses.
	 */
	public int getMaxSize() {
		return MaxSize;
	}

	public int getMaxGrowthRate() {
		return MaxGrowthRate;
	}


	public int getMaxSeedDistance() {
		return MaxSeedDistance;
	}


	public char getRenderChar() {
		return RenderChar;
	}


	
	public void update() {
		Flower flower = new Flower(super.environment,super.getPos().x,super.getPos().y);
		if(environment.getNumPlantsInRange(flower,6,0)<=16 || environment.getNumPlantsInRange(flower,this.MaxSeedDistance,1)>=3) {
			environment.seed(flower, this.MaxSeedDistance);
		}
		else if(environment.getNumPlantsInRange(flower,this.MaxSeedDistance,1)>=10) {
			super.die();
		}
		super.grow();
		if(size>this.MaxSize) {
			super.die();
		}
	}


	public Plant clone() {
		Flower flower = new Flower(super.environment,super.getPos().x,super.getPos().y);
		return flower;
	}

}
Java:
package uebung9;

/**
 * Institute for Pervasive Computing, JKU Linz, 2012
 * 
 * @author Sascha Maschek
 */

import java.awt.Point;
import java.util.Random;

public abstract class Plant {

	// position of plant in environment
	protected Point pos;
	// simulation environment
	protected Environment environment;
	// current size of plant (increased by grow-method)
	protected int size;
	
	int TypeId;
	int MaxSize;
	int MaxGrowthRate;
	int MaxSeedDistance;
	char RenderChar;
	
	/**
	 * constructor
	 */
	public Plant(Environment environment, int posX, int posY) {
		this.pos = new Point(posX, posY);
		this.environment = environment;
		this.size = 0;
	}
	
	/**
	 * position getter.
	 * 
	 * @return position stored in a point object
	 */
	public Point getPos() {
		return pos;
	}

	/**
	 * position setter.
	 * 
	 * param x x-coordinate
	 * param y y-coordinate
	 */
	public void setPos(int x, int y) {
		pos.x = x;
		pos.y = y;
	}

	/**
	 * render-method.
	 * 
	 * @return string representation of the plant
	 */
	public String toString() {
		return String.valueOf(getRenderChar());
	}

	/**
	 * increases the current size of the plant by a value between
	 * 1 and max. growth rate.
	 */
	protected void grow() {
		Random rand = new Random(System.nanoTime());
		size += rand.nextInt(getMaxGrowthRate()) + 1;
	}

	/**
	 * seeds a clone of the plant in the simulation environment
	 * within the radius of the max. seed distance.
	 */
	protected void spawn() {
		environment.seed(this, getMaxSeedDistance());
	}

	/**
	 * removes the plant from the simulation environment.
	 */
	protected void die() {
		environment.removePlant(this);
	}

	/**
	 * TODO: implement this method in all subclasses.
	 */
	abstract public int getTypeId();

	/**
	 * TODO: implement this method in all subclasses.
	 */
	abstract public int getMaxSize();

	/**
	 * TODO: implement this method in all subclasses.
	 */
	abstract public int getMaxGrowthRate();

	/**
	 * TODO: implement this method in all subclasses.
	 */
	abstract public int getMaxSeedDistance();

	/**
	 * TODO: implement this method in all subclasses.
	 */
	abstract public char getRenderChar();

	/**
	 * TODO: implement this method in all subclasses.
	 */
	abstract public void update();

	/**
	 * TODO: implement this method in all subclasses.
	 */
	abstract public Plant clone();
}
Java:
package uebung9;

/**
 * Institute for Pervasive Computing, JKU Linz, 2012
 * 
 * @author Sascha Maschek
 */

import java.awt.Point;
import java.util.Random;

public abstract class Plant {

	// position of plant in environment
	protected Point pos;
	// simulation environment
	protected Environment environment;
	// current size of plant (increased by grow-method)
	protected int size;
	
	int TypeId;
	int MaxSize;
	int MaxGrowthRate;
	int MaxSeedDistance;
	char RenderChar;
	
	/**
	 * constructor
	 */
	public Plant(Environment environment, int posX, int posY) {
		this.pos = new Point(posX, posY);
		this.environment = environment;
		this.size = 0;
	}
	
	/**
	 * position getter.
	 * 
	 * @return position stored in a point object
	 */
	public Point getPos() {
		return pos;
	}

	/**
	 * position setter.
	 * 
	 * param x x-coordinate
	 * param y y-coordinate
	 */
	public void setPos(int x, int y) {
		pos.x = x;
		pos.y = y;
	}

	/**
	 * render-method.
	 * 
	 * @return string representation of the plant
	 */
	public String toString() {
		return String.valueOf(getRenderChar());
	}

	/**
	 * increases the current size of the plant by a value between
	 * 1 and max. growth rate.
	 */
	protected void grow() {
		Random rand = new Random(System.nanoTime());
		size += rand.nextInt(getMaxGrowthRate()) + 1;
	}

	/**
	 * seeds a clone of the plant in the simulation environment
	 * within the radius of the max. seed distance.
	 */
	protected void spawn() {
		environment.seed(this, getMaxSeedDistance());
	}

	/**
	 * removes the plant from the simulation environment.
	 */
	protected void die() {
		environment.removePlant(this);
	}

	/**
	 * TODO: implement this method in all subclasses.
	 */
	abstract public int getTypeId();

	/**
	 * TODO: implement this method in all subclasses.
	 */
	abstract public int getMaxSize();

	/**
	 * TODO: implement this method in all subclasses.
	 */
	abstract public int getMaxGrowthRate();

	/**
	 * TODO: implement this method in all subclasses.
	 */
	abstract public int getMaxSeedDistance();

	/**
	 * TODO: implement this method in all subclasses.
	 */
	abstract public char getRenderChar();

	/**
	 * TODO: implement this method in all subclasses.
	 */
	abstract public void update();

	/**
	 * TODO: implement this method in all subclasses.
	 */
	abstract public Plant clone();
}

Die 2. Aufgabe ist, dass das ganze zu einer Generischen Sumulation wird. Dazu soll ich die Klasse GenericPlant erstellen. Das ganze kein Problem, aber jetzt stell ich mir die Frage, wie mache ich es, dass ich flexibel die Regeln festlegen kann, die ich zurzeit abprüfe unter der "update" funktion. das ganze soll man einfach eingeben können. Ich habe mir schon überlegt einen Array zu initialiseren aber das funktioniert nicht so ganz.
hat da wer eine Idee für micht?

lg danke vielmals!
 
Hi,
da würde ich um Verbesserungen bitten :)
Was für Verbesserung würdest du denn gerne hören? Codequalität? Logik?
Also zur Codequalität kann ich sagen, dass es ziemlich gut aussieht. Das was du ändern kannst, sind eher Kleinigkeiten, wie z.B. in der Klasse Plant (die hast du übrigens zwei mal gepostet. Ich glaube du wolltest den Tree posten :)) hast du 5 Variablen (TypeId, MaxSize, MaxGrowthRate, MaxSeedDistance, RenderChar), die die default-Sichtbarkeit zugewießen bekommen haben. Diese würde ich entweder protected machen, oder private und mit Getter- und Setter-Methoden arbeiten.
Wenn du die Variablen protected machst, würde ich dir empfehlen, die Getter-Methoden nicht abstract zu machen. So musst du diese in jeder - von dieser Klasse abgeleiteten - Klasse die Methoden neu implementieren. Wenn eine Klasse in dieser Methode etwas anderes machen soll, kannst du diese Methode immer noch überschreiben.

Die 2. Aufgabe ist, dass das ganze zu einer Generischen Sumulation wird. Dazu soll ich die Klasse GenericPlant erstellen. Das ganze kein Problem, aber jetzt stell ich mir die Frage, wie mache ich es, dass ich flexibel die Regeln festlegen kann, die ich zurzeit abprüfe unter der "update" funktion. das ganze soll man einfach eingeben können. Ich habe mir schon überlegt einen Array zu initialiseren aber das funktioniert nicht so ganz.
hat da wer eine Idee für micht?
Bei der zweiten Aufgabe verstehe ich diesen Satz "das ganze soll man einfach eingeben können" nicht. Was soll man ganz einfach eingeben können? Und wo?

Gruß

Fabio
 
Zurück