From b2d5edaa4360b715841f58190a933da6fd827ea4 Mon Sep 17 00:00:00 2001 From: Julija Date: Tue, 27 Dec 2022 17:59:30 +0100 Subject: [PATCH] FileMenager, Statistics, Map --- ...radle__org_openjfx_javafx_base_mac_17.xml} | 4 +- ...e__org_openjfx_javafx_controls_mac_17.xml} | 4 +- ...radle__org_openjfx_javafx_fxml_mac_17.xml} | 4 +- ...e__org_openjfx_javafx_graphics_mac_17.xml} | 4 +- .../main/java/agh/ics/oop/FileMenager.java | 42 +++++++++ oolab/src/main/java/agh/ics/oop/GlobMap.java | 24 +++-- oolab/src/main/java/agh/ics/oop/HellMap.java | 13 ++- oolab/src/main/java/agh/ics/oop/IMapType.java | 29 ------ oolab/src/main/java/agh/ics/oop/Map.java | 52 +++++++++-- .../java/agh/ics/oop/SimulationEngine.java | 89 +++++++++++++++++++ .../src/main/java/agh/ics/oop/Statistics.java | 69 ++++++++++++-- oolab/src/main/java/agh/ics/oop/Vector2d.java | 8 +- 12 files changed, 268 insertions(+), 74 deletions(-) rename .idea/libraries/{Gradle__org_openjfx_javafx_base_win_17.xml => Gradle__org_openjfx_javafx_base_mac_17.xml} (69%) rename .idea/libraries/{Gradle__org_openjfx_javafx_controls_win_17.xml => Gradle__org_openjfx_javafx_controls_mac_17.xml} (68%) rename .idea/libraries/{Gradle__org_openjfx_javafx_fxml_win_17.xml => Gradle__org_openjfx_javafx_fxml_mac_17.xml} (69%) rename .idea/libraries/{Gradle__org_openjfx_javafx_graphics_win_17.xml => Gradle__org_openjfx_javafx_graphics_mac_17.xml} (68%) create mode 100644 oolab/src/main/java/agh/ics/oop/FileMenager.java diff --git a/.idea/libraries/Gradle__org_openjfx_javafx_base_win_17.xml b/.idea/libraries/Gradle__org_openjfx_javafx_base_mac_17.xml similarity index 69% rename from .idea/libraries/Gradle__org_openjfx_javafx_base_win_17.xml rename to .idea/libraries/Gradle__org_openjfx_javafx_base_mac_17.xml index 460d4db..79881c8 100644 --- a/.idea/libraries/Gradle__org_openjfx_javafx_base_win_17.xml +++ b/.idea/libraries/Gradle__org_openjfx_javafx_base_mac_17.xml @@ -1,7 +1,7 @@ - + - + diff --git a/.idea/libraries/Gradle__org_openjfx_javafx_controls_win_17.xml b/.idea/libraries/Gradle__org_openjfx_javafx_controls_mac_17.xml similarity index 68% rename from .idea/libraries/Gradle__org_openjfx_javafx_controls_win_17.xml rename to .idea/libraries/Gradle__org_openjfx_javafx_controls_mac_17.xml index c50f1b2..14e30cf 100644 --- a/.idea/libraries/Gradle__org_openjfx_javafx_controls_win_17.xml +++ b/.idea/libraries/Gradle__org_openjfx_javafx_controls_mac_17.xml @@ -1,7 +1,7 @@ - + - + diff --git a/.idea/libraries/Gradle__org_openjfx_javafx_fxml_win_17.xml b/.idea/libraries/Gradle__org_openjfx_javafx_fxml_mac_17.xml similarity index 69% rename from .idea/libraries/Gradle__org_openjfx_javafx_fxml_win_17.xml rename to .idea/libraries/Gradle__org_openjfx_javafx_fxml_mac_17.xml index 24ab318..08d2126 100644 --- a/.idea/libraries/Gradle__org_openjfx_javafx_fxml_win_17.xml +++ b/.idea/libraries/Gradle__org_openjfx_javafx_fxml_mac_17.xml @@ -1,7 +1,7 @@ - + - + diff --git a/.idea/libraries/Gradle__org_openjfx_javafx_graphics_win_17.xml b/.idea/libraries/Gradle__org_openjfx_javafx_graphics_mac_17.xml similarity index 68% rename from .idea/libraries/Gradle__org_openjfx_javafx_graphics_win_17.xml rename to .idea/libraries/Gradle__org_openjfx_javafx_graphics_mac_17.xml index b719c2e..6c9dfb8 100644 --- a/.idea/libraries/Gradle__org_openjfx_javafx_graphics_win_17.xml +++ b/.idea/libraries/Gradle__org_openjfx_javafx_graphics_mac_17.xml @@ -1,7 +1,7 @@ - + - + diff --git a/oolab/src/main/java/agh/ics/oop/FileMenager.java b/oolab/src/main/java/agh/ics/oop/FileMenager.java new file mode 100644 index 0000000..863e910 --- /dev/null +++ b/oolab/src/main/java/agh/ics/oop/FileMenager.java @@ -0,0 +1,42 @@ +package agh.ics.oop; + +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Arrays; + +public record FileMenager(String filename) { + + public FileMenager(String filename){ + this.filename = filename; + try (PrintWriter output = new PrintWriter(new FileWriter(filename))) { + output.println("AllAnimals, AllPlants, FreeSpots, MostPopularGenotype, AverageEnergyAlive, AverageEnergyDead"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void dayStats(Object[] statistics){ + String data = Arrays.toString(statistics); + data = data.substring(0, data.length() - 1); + + StringBuilder stringBuilder = new StringBuilder(); //takie cuś do łączenia stringów + + for (int i = 0; i < data.length(); i++ ){ + char curr = data.charAt(i); + if (curr != ' '){ + stringBuilder.append(curr); + } + } + + try (PrintWriter output = new PrintWriter(new FileWriter(filename, true))){ + output.println(stringBuilder); + } + catch (IOException exception){ + exception.printStackTrace(); + } + + } + + +} diff --git a/oolab/src/main/java/agh/ics/oop/GlobMap.java b/oolab/src/main/java/agh/ics/oop/GlobMap.java index 67a6b51..0e23be7 100644 --- a/oolab/src/main/java/agh/ics/oop/GlobMap.java +++ b/oolab/src/main/java/agh/ics/oop/GlobMap.java @@ -13,16 +13,12 @@ public void moveOnMap(Animal animal, SimulationVar var, Map map){ //jeśli zwierzę może się poruszyć if (animal.energy - 1 >= 0){ - changeAnimalPosition(animal, var); //zmiana pozycji - animalDinnerAndBreeding(animal, var, map);//obiad i dzieci - animal.age += 1; - var.getGardener().seedGrass(var, map); - - + changeAnimalPosition(animal, var, map); //zmiana pozycji } else{ animal.diedDate = animal.age; - //dodajemy zwierzaka do listy zmarłych zwierząt + map.setDiedAnimals(map.getDiedAnimals() + 1); + map.addToDiedList(animal); } @@ -30,7 +26,7 @@ public void moveOnMap(Animal animal, SimulationVar var, Map map){ } - protected void changeAnimalPosition(Animal animal, SimulationVar var){ + protected void changeAnimalPosition(Animal animal, SimulationVar var, Map map){ Direction[] genes = animal.genes; int currGeneIdx = animal.activeGeneIx; int mapHeight = var.getMapHeight(); @@ -41,9 +37,6 @@ protected void changeAnimalPosition(Animal animal, SimulationVar var){ Vector2d posAfterMovement = animal.position.add(vectorToMove); - // jeśli zwierzątko będzie na samym krańcu mapy, a będzie miało iść na skos, to jednocześnie wyjdzie na równik - // i na biegun, więc nie wiem, co wtedy mamy robić - napisałam wersję z odwrotnym kierunkiem - // wtedy można usunąć te warunki i po prostu sprawdzac tylko ten z y if (posAfterMovement.y < 0 || posAfterMovement.y >= mapHeight){ animal.orientation = animal.orientation.opposite(animal.orientation); posAfterMovement = animal.position; @@ -51,14 +44,19 @@ protected void changeAnimalPosition(Animal animal, SimulationVar var){ //czy równik else if (posAfterMovement.x >= mapWidth || posAfterMovement.x < 0){ if (posAfterMovement.x >= mapWidth){ - posAfterMovement.x = 0; + Vector2d vector = new Vector2d(0, posAfterMovement.y); + posAfterMovement = vector; + } else{ - posAfterMovement.x = mapWidth - 1; + Vector2d vector = new Vector2d(mapWidth - 1, posAfterMovement.y); + posAfterMovement = vector; } } + map.setAnimalsOnField(animal.getPosition(), posAfterMovement); animal.changePosition(posAfterMovement); + } } diff --git a/oolab/src/main/java/agh/ics/oop/HellMap.java b/oolab/src/main/java/agh/ics/oop/HellMap.java index 2a5f5f3..d86c06d 100644 --- a/oolab/src/main/java/agh/ics/oop/HellMap.java +++ b/oolab/src/main/java/agh/ics/oop/HellMap.java @@ -14,16 +14,12 @@ public void moveOnMap(Animal animal, SimulationVar var, Map map){ //jeśli zwierzę może się poruszyć if (animal.energy - 1 >= 0){ - changeAnimalPosition(animal, var); //zmiana pozycji - animalDinnerAndBreeding(animal, var, map);//obiad i dzieci - animal.age += 1; - var.getGardener().seedGrass(var, map); - - + changeAnimalPosition(animal, var, map); //zmiana pozycji } else{ animal.diedDate = animal.age; - //dodajemy zwierzaka do listy zmarłych zwierząt + map.setDiedAnimals(map.getDiedAnimals() + 1); + map.addToDiedList(animal); } @@ -31,7 +27,7 @@ public void moveOnMap(Animal animal, SimulationVar var, Map map){ } - protected void changeAnimalPosition(Animal animal, SimulationVar var){ + protected void changeAnimalPosition(Animal animal, SimulationVar var, Map map){ Direction[] genes = animal.genes; int currGeneIdx = animal.activeGeneIx; int mapHeight = var.getMapHeight(); @@ -46,6 +42,7 @@ protected void changeAnimalPosition(Animal animal, SimulationVar var){ if (animal.energy - var.getMinEnergyForCopulation() >= 0) { animal.energy -= var.getMinEnergyForCopulation(); Random generator = new Random(); + map.setAnimalsOnField(animal.getPosition(), posAfterMovement); animal.changePosition(new Vector2d(generator.nextInt(mapWidth), generator.nextInt(mapHeight))); } diff --git a/oolab/src/main/java/agh/ics/oop/IMapType.java b/oolab/src/main/java/agh/ics/oop/IMapType.java index 08810ad..48c27ab 100644 --- a/oolab/src/main/java/agh/ics/oop/IMapType.java +++ b/oolab/src/main/java/agh/ics/oop/IMapType.java @@ -6,33 +6,4 @@ public interface IMapType { void moveOnMap(Animal animal, SimulationVar var, Map map); - default void animalDinnerAndBreeding(Animal animal, SimulationVar var, Map map) { - - ArrayList possibleMatch = new ArrayList<>(); - possibleMatch.add(animal); - //allAnimals = listaZeZwierzaczkami - //for (animall : allAnimals){ -// if (animal.position == animall.position){ -// possibleMatch.add(animall); -// } - //} - - if (possibleMatch.size() != 1) { - possibleMatch.sort(Comparator.comparingInt(el -> -el.energy).thenComparingInt(el -> -el.age).thenComparingInt(el -> -el.children)); - } - Animal winner = possibleMatch.get(0); - - if (map.isGrassThere(winner.position)) { - winner.energy += var.getGrassEnergyProfit(); - } - - winner.energy += var.getGrassEnergyProfit(); - Animal secondWinner = possibleMatch.get(1); - if (winner.energy >= var.getMinEnergyForCopulation() && secondWinner.energy >= var.getMinEnergyForCopulation()) { - Animal baby = new Animal(var, winner, secondWinner); - // tu trzeba zmienić ten fragment bo zmieniliśmy tę metodę - //map.placeAnimalOnMap(winner.getPosition(), baby); - } - - } } diff --git a/oolab/src/main/java/agh/ics/oop/Map.java b/oolab/src/main/java/agh/ics/oop/Map.java index f12d965..ac3ffec 100644 --- a/oolab/src/main/java/agh/ics/oop/Map.java +++ b/oolab/src/main/java/agh/ics/oop/Map.java @@ -2,20 +2,26 @@ import java.lang.reflect.Array; import java.util.ArrayList; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; public class Map { private HashMap grassOnField = new HashMap<>(); - private ArrayList animalsOnField=new ArrayList<>(); + private int diedAnimals = 0; + private ArrayList animalsOnField=new ArrayList<>(); //wszystkie zwierzątka na mapie private HashMap numberOfAnimalsOnField = new HashMap<>(); //pamietac zeby przy move zmieniac wartosc w tej hashmapie + private ArrayList diedAnimalsOnMap = new ArrayList<>(); private int height; private int width; + private IMapType map; + private int howManyGrasses = 0; //Big Bang public Map(SimulationVar var) { height=var.getMapHeight(); width= var.getMapWidth(); + map = var.getMapType(); for (int i=0;i animalsOnSpot(Vector2d spot){ + protected void setAnimalsOnField(Vector2d oldSpot, Vector2d newSpot){ + numberOfAnimalsOnField.put(oldSpot, numberOfAnimalsOnField.get(oldSpot) - 1); //usuwamy ze starego miejsca + numberOfAnimalsOnField.put(newSpot, numberOfAnimalsOnField.get(newSpot) + 1); //dodajemy do nowego miejsca + } - return null; + protected void removeAnimal(Animal animal){ + animalsOnField.remove(animal); //usunięcie z listy zwierząt + numberOfAnimalsOnField.put(animal.getPosition(), numberOfAnimalsOnField.get(animal.getPosition()) - 1); //dekrementowanie liczby zwierząt na tym polu } - protected int howManyAnimalsOnSpot(Vector2d spot){ - return 0; + protected int howManyAnimalsOnSpot(Vector2d spot){ //zwraca liczbę zwierzątek na danych polu + return numberOfAnimalsOnField.get(spot); + + } + + protected ArrayList getAnimalsOnField(){ + return this.animalsOnField; } protected boolean isGrassThere(Vector2d spot){ return grassOnField.containsKey(spot); } + protected int getDiedAnimals(){ + return diedAnimals; + } + + protected void setDiedAnimals(int n){ + diedAnimals = n; + } + + protected HashMap getAnimalsOnEachSpot(){ + return numberOfAnimalsOnField; + } + + protected ArrayList getDiedAnimalsOnMap(){ + return diedAnimalsOnMap; + } + + protected void addToDiedList(Animal animal){ + diedAnimalsOnMap.add(animal); + } + + protected void removeGrass(Grass grass){ + grassOnField.remove(grassOnField.get(grass).getPosition(), grass); + } + + + } \ No newline at end of file diff --git a/oolab/src/main/java/agh/ics/oop/SimulationEngine.java b/oolab/src/main/java/agh/ics/oop/SimulationEngine.java index dc9fdc3..6a21666 100644 --- a/oolab/src/main/java/agh/ics/oop/SimulationEngine.java +++ b/oolab/src/main/java/agh/ics/oop/SimulationEngine.java @@ -1,9 +1,98 @@ package agh.ics.oop; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Vector; + public class SimulationEngine implements ISimulationEngine{ SimulationVar variables; + private Map map; + private int howManyDays = 0; + private Statistics stats; + + + + public SimulationEngine(Map map, SimulationVar variables){ + this.map = map; + this.variables = variables; + } + + public void dayRitual(IMapType mapType, Map map){ + howManyDays += 1; + //korowód + int diedToday = 0; + for (Animal animal: map.getAnimalsOnField()){ + if (animal.diedDate != 0){ + diedToday += 1; + map.removeAnimal(animal); + } + } + map.setDiedAnimals(map.getDiedAnimals() + diedToday); //łączna liczba zmarłych zwierzątek + + + //poruszamy wszystkie zwierzątka + for (Animal animal:map.getAnimalsOnField()){ + mapType.moveOnMap(animal, variables, map); + } + + ArrayList animals = map.getAnimalsOnField(); + animals.sort(Comparator.comparingInt(el -> el.position.x).thenComparingInt(el -> el.position.y)); + Vector2d lastVector = new Vector2d(10^9, 10^9); + + //jedzonko i rozmnażanie + for (Animal animal: map.getAnimalsOnField()){ + if (animal.getPosition() != lastVector){ //jeśli wektor zwierzątka nie jest identyczny do ostatniego -> aby nie sprawdzac kilka razy tej samej pozycji zwierząt + lastVector = animal.getPosition(); + if (map.howManyAnimalsOnSpot(animal.getPosition())!= 1){ //jeśli jest wiecej niż 1 zwierze na danym polu + + int howManyOnThisSpot = map.howManyAnimalsOnSpot(animal.getPosition()); + ArrayList possibleMatch = new ArrayList<>(); + for(int i = 0; i < howManyOnThisSpot; i++){ + possibleMatch.add(animals.get(i)); + } + possibleMatch.sort(Comparator.comparingInt(el -> -el.energy).thenComparingInt(el -> -el.age).thenComparingInt(el -> -el.children)); + + Animal winner = possibleMatch.get(0); //wygrał trawkę + + if (map.isGrassThere(winner.position)) { + winner.energy += variables.getGrassEnergyProfit(); + winner.grassEaten += 1; + map.removeGrass(new Grass(winner.position)); + } + + Animal secondWinner = possibleMatch.get(1); //ma szansę na dzieciątko z winnerem + if (winner.energy >= variables.getMinEnergyForCopulation() && secondWinner.energy >= variables.getMinEnergyForCopulation()) { + Animal baby = new Animal(variables, winner, secondWinner); //nowe bobo + map.placeAnimalOnMap(baby); //umieszczamy na mapie + + } + } + } + + } + + //zasianie roślin + variables.getGardener().seedGrass(variables, map); + + + } + + protected int getDays(){ + return howManyDays; + } + @Override public void run() { + Object[] statistics = new Object[]{ + stats.getAmountOfAnimals(map), + stats.getAmountOfGrass(variables, this), + stats.freeSpots(map, variables), + stats.theMostCommonGenotype(map), + stats.averageEnergyAlive(map), + stats.averageEnergyDead(map) + + }; } } diff --git a/oolab/src/main/java/agh/ics/oop/Statistics.java b/oolab/src/main/java/agh/ics/oop/Statistics.java index 7768e9a..b9955a0 100644 --- a/oolab/src/main/java/agh/ics/oop/Statistics.java +++ b/oolab/src/main/java/agh/ics/oop/Statistics.java @@ -1,8 +1,6 @@ package agh.ics.oop; -import java.util.HashMap; -import java.util.SortedMap; -import java.util.TreeMap; +import java.util.*; public class Statistics { private int amountOfGrass; @@ -22,8 +20,67 @@ public HashMap getDiedAnimals() { return diedAnimals; } - public int getAmountOfAnimals(){ - //oblicz ile było wszystkich zwierzaków w danej symulacji - return 0; + public int getAmountOfAnimals(Map map){ //liczba wszystkich zwierząt na mapie + return map.getDiedAnimals() + map.getAnimalsOnField().size(); } + + //liczba wszystkich roślin (tutaj chyba trzeba jakoś mądrzej, żeby nie przekazywać engine) + public int getAmountOfGrass(SimulationVar var, SimulationEngine engine){ + return var.getGrassSpawnedEveryday() * engine.getDays(); + } + + //liczba wolnych pól + public int freeSpots(Map map, SimulationVar var){ + int allSpots = var.getMapHeight() * var.getMapHeight(); + int busySpots = map.getAnimalsOnEachSpot().size(); + return allSpots - busySpots; + } + + //najpopularniejszy genotyp + public Direction[] theMostCommonGenotype(Map map){ + int maxi = 1; + Direction[] popular = new Direction[]{}; + + HashMap genotypes = new HashMap(); + ArrayList animals = map.getAnimalsOnField(); + + for (Animal animal: animals){ + if (genotypes.containsKey(animal.genes)){ + int count = genotypes.get(animal.genes); + genotypes.put(animal.genes, count + 1); + if (count + 1 > maxi){ + maxi = count + 1; + popular = animal.genes; + } + } + else{ + genotypes.put(animal.genes, 1); + } + } + + return popular; + + + } + + //średnia energia żyjących zwierząt + public int averageEnergyAlive(Map map){ + int sum = 0; + for(Animal animal : map.getAnimalsOnField()){ + sum += animal.energy; + } + + return sum / map.getAnimalsOnField().size(); + } + + //średnia długość życia nieżyjących zwierząt + public int averageEnergyDead(Map map){ + int sum = 0; + for (Animal animal : map.getDiedAnimalsOnMap()){ + sum += animal.energy; + } + return sum / map.getDiedAnimalsOnMap().size(); + } + + } diff --git a/oolab/src/main/java/agh/ics/oop/Vector2d.java b/oolab/src/main/java/agh/ics/oop/Vector2d.java index aadcb85..6cbc246 100644 --- a/oolab/src/main/java/agh/ics/oop/Vector2d.java +++ b/oolab/src/main/java/agh/ics/oop/Vector2d.java @@ -3,17 +3,14 @@ import java.util.Objects; public class Vector2d{ - public int x; - public int y; + public final int x; + public final int y; public Vector2d (int x, int y){ this.x=x; this.y=y; } - public Vector2d(Vector2d position) { - } - public String toString() { return "(%d, %d)".formatted(x, y); @@ -59,5 +56,6 @@ public boolean equals(Object obj) { public int hashCode() { return Objects.hash(x, y); } + }