Skip to content

Commit

Permalink
added stats watcher
Browse files Browse the repository at this point in the history
  • Loading branch information
PiotrMakarewicz committed Dec 22, 2020
1 parent 56beeda commit fdac506
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 31 deletions.
10 changes: 5 additions & 5 deletions parameters.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"width": 50,
"height": 50,
"width": 10,
"height": 10,
"jungleRatio": 0.05,
"moveEnergy": 1.0,
"initialEnergy": 100.0,
"plantEnergy": 50.0,
"initialAnimals": 10
"initialEnergy": 50.0,
"plantEnergy": 25.0,
"initialAnimals": 3
}
13 changes: 7 additions & 6 deletions src/sample/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import javafx.stage.Stage;
import simulation.Simulation;
import simulation.SimulationErrorException;
import simulation.StatsWatcher;

public class Main extends Application {

Expand All @@ -18,11 +19,12 @@ public void start(Stage stage) throws Exception{
}

public void displaySimulation(Simulation simulation, Stage stage) throws InterruptedException, SimulationErrorException {
Group root = new Group();
double width = simulation.getWidth()*10;
double height = simulation.getHeight()*10;
Scene simulationScene = new Scene(root, width, height, Color.BLACK);
final Group root = new Group();
final double width = simulation.getWidth()*10;
final double height = simulation.getHeight()*10;
final Scene simulationScene = new Scene(root, width, height, Color.BLACK);

final StatsWatcher statsWatcher = new StatsWatcher(simulation);
final SimulationCanvas canvas = new SimulationCanvas(simulation);

root.getChildren().add(canvas);
Expand All @@ -40,11 +42,10 @@ public void displaySimulation(Simulation simulation, Stage stage) throws Interru
if (isCancelled()) {
break;
}
System.out.println("Simulation");
simulation.simulateOneDay();
System.out.println("CANVAS UPDATE start");
canvas.update();
System.out.println("CANVAS UPDATE done");
statsWatcher.printStats();
Thread.sleep(100);
}
return iterations;
Expand Down
9 changes: 5 additions & 4 deletions src/sample/SimulationCanvas.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,17 @@ public void update(){
drawTile(x,y,terrainTileFactory.getTile(x,y));
else drawTile(x,y,animalTileFactory.getTile(x,y));
}
for (Location location : simulation.animalBoard.getAnimalLocations()){
for (Location location : simulation.plantBoard.getPlantedLocations()){
int x = location.getX();
int y = location.getY();
drawTile(x,y,animalTileFactory.getTile(x,y));
drawTile(x,y,terrainTileFactory.getTile(x,y));
}
for (Location location : simulation.plantBoard.getPlantedLocations()){
for (Location location : simulation.animalBoard.getAnimalLocations()){
int x = location.getX();
int y = location.getY();
drawTile(x,y,terrainTileFactory.getTile(x,y));
drawTile(x,y,animalTileFactory.getTile(x,y));
}

}
private void drawTile(int x, int y, Tile tile){
int tileSize = 10;
Expand Down
9 changes: 7 additions & 2 deletions src/simulation/Animal.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ public class Animal{
private Direction direction;
private double energy;
private Location location;
private List<Animal> children = new ArrayList<>();

Animal(double energy, int birthDay, Location location){

this.birthDay = birthDay;
this.energy = energy;
this.genome = new Genome();
Expand All @@ -23,12 +23,13 @@ public class Animal{
};

Animal(Animal parent1, Animal parent2, int birthDay, Location location){

this.genome = new Genome(parent1.getGenome(), parent2.getGenome());
this.energy = parent1.energy / 4 + parent2.energy / 4;
this.birthDay = birthDay;
this.location = location;
this.direction = Direction.values()[(new Random(System.nanoTime()).nextInt(8))];
parent1.children.add(this);
parent2.children.add(this);
System.out.println("Born "+this.toString()+", child of "+parent1.toString()+" and "+parent2.toString()+", at "+location);
}

Expand Down Expand Up @@ -87,4 +88,8 @@ public String toString() {
return genome.toString() +
"-" + birthDay;
}

public List<Animal> getChildren() {
return children;
}
}
13 changes: 11 additions & 2 deletions src/simulation/AnimalBoard.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@

public class AnimalBoard {
private AbstractMap<Location, List<Animal>> locationAnimalMap = new TreeMap<>();
private List<Animal> deadAnimals = new ArrayList<>();

public List<Animal> getAll(){
public List<Animal> getAllAlive(){
List<Animal> allAnimals = new ArrayList<Animal>();
for (List<Animal> locationAnimals : locationAnimalMap.values()){
allAnimals = Stream.concat(allAnimals.stream(),locationAnimals.stream()).collect(Collectors.toList());
Expand All @@ -29,6 +30,8 @@ public List<Location> locations(){
return locationAnimalMap.keySet().stream().collect(Collectors.toList());
}



public void remove(Animal animal) {
Location locationToRemove = null;
for (Map.Entry<Location, List<Animal>> entry : locationAnimalMap.entrySet()) {
Expand All @@ -44,6 +47,12 @@ public void remove(Animal animal) {
locationAnimalMap.remove(locationToRemove);
}
}

public void markAsDead(Animal animal){
remove(animal);
deadAnimals.add(animal);
}

public boolean noAnimalsAt(int x, int y){
return noAnimalsAt(new Location(x,y));
}
Expand All @@ -67,7 +76,7 @@ public List<Animal> get(int x, int y){

}
public void update(){
List<Animal> animals = this.getAll();
List<Animal> animals = this.getAllAlive();
locationAnimalMap = new TreeMap<>();
for (Animal animal : animals){
if (animal.isAlive()){
Expand Down
33 changes: 25 additions & 8 deletions src/simulation/Genome.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import java.util.*;
import java.util.stream.Collectors;

public class Genome {
public class Genome implements Comparable<Genome>{
private final List<Integer> genes;
Genome(){
Random rng = new Random();
Expand All @@ -15,12 +15,12 @@ public class Genome {
}
} while (! containsAllGenes(genes));
this.genes = genes.stream().sorted().collect(Collectors.toList());
};
}

Genome(Genome g0, Genome g1){
Random rng = new Random(System.nanoTime());
List<Integer> genes = new ArrayList<Integer>();
List<Genome> parentGenomes = new ArrayList<Genome>();
List<Integer> genes = new ArrayList<>();
List<Genome> parentGenomes = new ArrayList<>();
parentGenomes.add(g0);
parentGenomes.add(g1);
int breakpt1 = rng.nextInt(31);
Expand All @@ -33,13 +33,13 @@ public class Genome {
genes.addAll(parentGenomes.get(secondPartFrom).genes.subList(breakpt1,breakpt2));
genes.addAll(parentGenomes.get(thirdPartFrom).genes.subList(breakpt2,32));
this.genes = Genome.addMissingGenes(genes).stream().sorted().collect(Collectors.toList());
};
}

private static List<Integer> addMissingGenes(List<Integer> genes){
while (getMissingGene(genes) != null){
AbstractSet<Integer> occurringGenes = new TreeSet<Integer>();
AbstractSet<Integer> repeatingGenes = new TreeSet<Integer>();
List<Integer> repeatingGeneIndices = new ArrayList<Integer>();
AbstractSet<Integer> occurringGenes = new TreeSet<>();
AbstractSet<Integer> repeatingGenes = new TreeSet<>();
List<Integer> repeatingGeneIndices = new ArrayList<>();
for (Integer gene : genes){
if(occurringGenes.contains(gene)){
repeatingGenes.add(gene);
Expand Down Expand Up @@ -100,4 +100,21 @@ public String toString(){
}
return sb.toString();
}

public boolean equals(Genome g){
return this.hashCode() == g.hashCode();
}

public int hashCode(){
int hash = 0;
int multiplier = 1;
for (int gene : genes){
hash += multiplier*gene;
}
return hash;
}

public int compareTo(Genome g){
return this.hashCode()-g.hashCode();
}
}
3 changes: 2 additions & 1 deletion src/simulation/PlantBoard.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ public void plant(int x, int y){
plant(new Location(x,y));
}
public void plant(Location location){
getPlantedSpots().put(location,1);
if (!isPlanted(location))
getPlantedSpots().put(location,1);
}
public void unplant(Location location) throws UnplantingUnplantedLocationException{
if (! isPlanted(location)){
Expand Down
7 changes: 4 additions & 3 deletions src/simulation/Simulation.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ private void addPlants(){
boolean plantedOutsideJungle = false;
while (!plantedInJungle || !plantedOutsideJungle){
Location location = Location.getRandom(width,height);
if(jungle.contains(location) && !plantedInJungle && animalBoard.noAnimalsAt(location)){
if(jungle.contains(location) && !plantedInJungle){
plantBoard.plant(location);
System.out.println("Added in-jungle plant at "+location.toString());
plantedInJungle = true;
}
else if(!jungle.contains(location) && !plantedOutsideJungle && animalBoard.noAnimalsAt(location)){
else if(!jungle.contains(location) && !plantedOutsideJungle){
plantBoard.plant(location);
System.out.println("Added outside-jungle plant at "+location.toString());
plantedOutsideJungle = true;
Expand All @@ -59,10 +59,11 @@ else if(!jungle.contains(location) && !plantedOutsideJungle && animalBoard.noAni

private void moveAnimals() throws AnimalStateException {
previousAnimalLocations = animalBoard.getAnimalLocations();
for (Animal animal : animalBoard.getAll()) {
for (Animal animal : animalBoard.getAllAlive()) {
animal.setEnergy(animal.getEnergy()-moveEnergy);
if (animal.getEnergy() < 0) {
animal.die(currentDay);
animalBoard.markAsDead(animal);
} else {
System.out.println("Moving "+animal.toString()+" from " + animal.getLocation() +" to "+toBoardLimits(animal.getLocation().stepTo(animal.getDirection())));
animal.shift();
Expand Down
60 changes: 60 additions & 0 deletions src/simulation/StatsWatcher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package simulation;

import java.sql.SQLOutput;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;

public class StatsWatcher {
private final Simulation simulation;
public StatsWatcher(Simulation s){
this.simulation = s;
}
public int getAliveAnimalsNum(){
return simulation.animalBoard.getAllAlive().size();
}
public int getPlantsNum(){
return simulation.plantBoard.getPlantedLocations().size();
}
public double getAverageEnergy(){
List<Animal> animals = simulation.animalBoard.getAllAlive();
double totalEnergy = animals.stream().map(Animal::getEnergy).reduce(0.0, Double::sum);
return totalEnergy/animals.size();
}
public Genome getDominatingGenome(){
Map<Genome,Integer> occurrences = new TreeMap<>();
for (Animal animal : simulation.animalBoard.getAllAlive()){
Genome genome = animal.getGenome();
if (!occurrences.containsKey(genome)){
occurrences.put(genome,1);
}
else occurrences.put(genome,occurrences.get(genome)+1);
}
return occurrences.keySet().stream().max(Comparator.comparingInt(occurrences::get)).get();
}
public double getAverageChildrenNumber(){
return simulation.animalBoard.getAllAlive().stream()
.map(a -> a.getChildren().size())
.reduce(0,Integer::sum)
.doubleValue()
/simulation.animalBoard.getAllAlive().size();
}
public List<Animal> getAnimalsWithDominatingGenome(){
return simulation.animalBoard.getAllAlive().stream()
.filter(a -> a.getGenome().equals(getDominatingGenome()))
.collect(Collectors.toList());
}

public void printStats(){
System.out.println("\nSimulation "+ simulation.name+" statistics:");
System.out.println("=======================================");
System.out.println("Alive animals: " +getAliveAnimalsNum());
System.out.println("Plants: "+getPlantsNum());
System.out.println("Average energy: "+getAverageEnergy());
System.out.println("Dominating genome: "+getDominatingGenome());
System.out.println("Average children number:"+getAverageChildrenNumber());
System.out.println("Animals with dominating genome: "+getAnimalsWithDominatingGenome());
}
}

0 comments on commit fdac506

Please sign in to comment.