diff --git a/oolab/src/main/java/agh/ics/oop/Direction.java b/oolab/src/main/java/agh/ics/oop/Direction.java index ead20a9..26b2c8e 100644 --- a/oolab/src/main/java/agh/ics/oop/Direction.java +++ b/oolab/src/main/java/agh/ics/oop/Direction.java @@ -2,24 +2,24 @@ public enum Direction { NORTH, - EASTNORTH, + NORTHEAST, EAST, - EASTSOUTH, + SOUTHEAST, SOUTH, - WESTSOUTH, + SOUTHWEST, WEST, - WESTNORTH; + NORTHWEST; public Vector2d toUnitVector(){ return switch(this){ case NORTH -> new Vector2d(0,1); - case EASTNORTH -> new Vector2d(1,1); + case NORTHEAST -> new Vector2d(1,1); case EAST -> new Vector2d(1,0); - case EASTSOUTH -> new Vector2d(1,-1); + case SOUTHEAST -> new Vector2d(1,-1); case SOUTH -> new Vector2d(0,-1); - case WESTSOUTH -> new Vector2d(-1,-1); + case SOUTHWEST -> new Vector2d(-1,-1); case WEST -> new Vector2d(-1,0); - case WESTNORTH -> new Vector2d(-1,1); + case NORTHWEST -> new Vector2d(-1,1); default -> null; }; } @@ -27,25 +27,25 @@ public Vector2d toUnitVector(){ public int toNumber(){ return switch(this){ case NORTH -> 0; - case EASTNORTH -> 1; + case NORTHEAST -> 1; case EAST -> 2; - case EASTSOUTH -> 3; + case SOUTHEAST -> 3; case SOUTH -> 4; - case WESTSOUTH -> 5; + case SOUTHWEST -> 5; case WEST -> 6; - case WESTNORTH -> 7; + case NORTHWEST -> 7; }; } public static Direction numberToDirection(int n){ return switch(n%8){ case 0 -> NORTH; - case 1 -> EASTNORTH; + case 1 -> NORTHEAST; case 2 -> EAST; - case 3 -> EASTSOUTH; + case 3 -> SOUTHEAST; case 4 -> SOUTH; - case 5 -> WESTSOUTH; + case 5 -> SOUTHWEST; case 6 -> WEST; - case 7 -> WESTNORTH; + case 7 -> NORTHWEST; default -> NORTH; }; } @@ -59,4 +59,17 @@ public Direction add(Direction d){ int sumInt=this.toNumber()+d.toNumber(); return numberToDirection(sumInt); } + + public Direction opposite(Direction direction){ + return switch(direction){ + case NORTH -> SOUTH; + case NORTHEAST -> SOUTHWEST; + case EAST -> WEST; + case SOUTHEAST -> NORTHWEST; + case SOUTH -> NORTH; + case SOUTHWEST -> NORTHEAST; + case WEST -> EAST; + case NORTHWEST -> SOUTHEAST; + }; + } } diff --git a/oolab/src/main/java/agh/ics/oop/GlobMap.java b/oolab/src/main/java/agh/ics/oop/GlobMap.java index 23b5df1..67a6b51 100644 --- a/oolab/src/main/java/agh/ics/oop/GlobMap.java +++ b/oolab/src/main/java/agh/ics/oop/GlobMap.java @@ -1,6 +1,64 @@ package agh.ics.oop; +import java.util.ArrayList; +import java.util.Comparator; + public class GlobMap implements IMapType{ + @Override + public void moveOnMap(Animal animal, SimulationVar var, Map map){ + + var.getBehaviorModel().geneBehaviour(animal); + + //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); + + + } + else{ + animal.diedDate = animal.age; + //dodajemy zwierzaka do listy zmarłych zwierząt + } + + + + } + + + protected void changeAnimalPosition(Animal animal, SimulationVar var){ + Direction[] genes = animal.genes; + int currGeneIdx = animal.activeGeneIx; + int mapHeight = var.getMapHeight(); + int mapWidth = var.getMapHeight(); + + //o ten wektor się poruszamy + Vector2d vectorToMove = genes[currGeneIdx].toUnitVector(); + 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; + } + //czy równik + else if (posAfterMovement.x >= mapWidth || posAfterMovement.x < 0){ + if (posAfterMovement.x >= mapWidth){ + posAfterMovement.x = 0; + } + else{ + posAfterMovement.x = mapWidth - 1; + } + } + + 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 39be7a8..2a5f5f3 100644 --- a/oolab/src/main/java/agh/ics/oop/HellMap.java +++ b/oolab/src/main/java/agh/ics/oop/HellMap.java @@ -1,5 +1,55 @@ package agh.ics.oop; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Random; + public class HellMap implements IMapType { + + @Override + public void moveOnMap(Animal animal, SimulationVar var, Map map){ + + var.getBehaviorModel().geneBehaviour(animal); + + //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); + + + } + else{ + animal.diedDate = animal.age; + //dodajemy zwierzaka do listy zmarłych zwierząt + } + + + + } + + + protected void changeAnimalPosition(Animal animal, SimulationVar var){ + Direction[] genes = animal.genes; + int currGeneIdx = animal.activeGeneIx; + int mapHeight = var.getMapHeight(); + int mapWidth = var.getMapHeight(); + + //o ten wektor się poruszamy + Vector2d vectorToMove = genes[currGeneIdx].toUnitVector(); + Vector2d posAfterMovement = animal.position.add(vectorToMove); + + + if (posAfterMovement.y < 0 || posAfterMovement.y >= mapHeight || posAfterMovement.x >= mapWidth || posAfterMovement.x < 0) { + if (animal.energy - var.getMinEnergyForCopulation() >= 0) { + animal.energy -= var.getMinEnergyForCopulation(); + Random generator = new Random(); + animal.changePosition(new Vector2d(generator.nextInt(mapWidth), generator.nextInt(mapHeight))); + } + + } + } } + diff --git a/oolab/src/main/java/agh/ics/oop/HijinksBehavior.java b/oolab/src/main/java/agh/ics/oop/HijinksBehavior.java index c54e647..cde0612 100644 --- a/oolab/src/main/java/agh/ics/oop/HijinksBehavior.java +++ b/oolab/src/main/java/agh/ics/oop/HijinksBehavior.java @@ -1,4 +1,24 @@ package agh.ics.oop; +import java.util.Random; + public class HijinksBehavior implements IBehaviorModel{ + + @Override + public void geneBehaviour(Animal animal){ + //losujemy liczbę od 0 do 9 + //w zależności od tego albo porusza się normalnie, albo losujemy + Random generator = new Random(); + if (generator.nextInt(10) < 2){ + animal.activeGeneIx = generator.nextInt(animal.genes.length); + } + else{ + if (animal.activeGeneIx + 1 >= animal.genes.length){ + animal.activeGeneIx = 0; + } + else{ + animal.activeGeneIx += 1; + } + } + } } diff --git a/oolab/src/main/java/agh/ics/oop/IBehaviorModel.java b/oolab/src/main/java/agh/ics/oop/IBehaviorModel.java index c1f5da9..3cd7080 100644 --- a/oolab/src/main/java/agh/ics/oop/IBehaviorModel.java +++ b/oolab/src/main/java/agh/ics/oop/IBehaviorModel.java @@ -1,5 +1,6 @@ package agh.ics.oop; -public interface IBehaviorModel { +public interface IBehaviorModel { + void geneBehaviour(Animal animal); } diff --git a/oolab/src/main/java/agh/ics/oop/IMapType.java b/oolab/src/main/java/agh/ics/oop/IMapType.java index 9d11be7..0ee1cf9 100644 --- a/oolab/src/main/java/agh/ics/oop/IMapType.java +++ b/oolab/src/main/java/agh/ics/oop/IMapType.java @@ -1,4 +1,37 @@ package agh.ics.oop; +import java.util.ArrayList; +import java.util.Comparator; + 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); + map.placeAnimal(winner.position, baby); + } + + } } diff --git a/oolab/src/main/java/agh/ics/oop/PredestinationBehavior.java b/oolab/src/main/java/agh/ics/oop/PredestinationBehavior.java index 7600839..1a49044 100644 --- a/oolab/src/main/java/agh/ics/oop/PredestinationBehavior.java +++ b/oolab/src/main/java/agh/ics/oop/PredestinationBehavior.java @@ -1,4 +1,13 @@ package agh.ics.oop; public class PredestinationBehavior implements IBehaviorModel{ + @Override + public void geneBehaviour(Animal animal){ + if (animal.activeGeneIx + 1 >= animal.genes.length){ + animal.activeGeneIx = 0; + } + else{ + animal.activeGeneIx += 1; + } + } } diff --git a/oolab/src/main/java/agh/ics/oop/Vector2d.java b/oolab/src/main/java/agh/ics/oop/Vector2d.java index 6740949..aadcb85 100644 --- a/oolab/src/main/java/agh/ics/oop/Vector2d.java +++ b/oolab/src/main/java/agh/ics/oop/Vector2d.java @@ -3,8 +3,8 @@ import java.util.Objects; public class Vector2d{ - public final int x; - public final int y; + public int x; + public int y; public Vector2d (int x, int y){ this.x=x;