From 2c0629666cba8b1364294915679dd1f54f720c5a Mon Sep 17 00:00:00 2001 From: Kamil Rudny <134285490+krudny@users.noreply.github.com> Date: Thu, 7 Dec 2023 20:48:27 +0100 Subject: [PATCH 1/3] Added exceptions --- .../main/java/agh/ics/oop/OptionsParser.java | 2 ++ .../src/main/java/agh/ics/oop/Simulation.java | 8 ++++-- oolab/src/main/java/agh/ics/oop/World.java | 17 +++++++++---- .../agh/ics/oop/model/AbstractWorldMap.java | 7 +++--- .../PositionAlreadyOccupiedException.java | 7 ++++++ .../main/java/agh/ics/oop/model/WorldMap.java | 2 +- .../agh/ics/oop/model/GrassFieldTest.java | 25 ++++++++++++++----- .../agh/ics/oop/model/RectangularMapTest.java | 22 ++++++++-------- 8 files changed, 63 insertions(+), 27 deletions(-) create mode 100644 oolab/src/main/java/agh/ics/oop/model/PositionAlreadyOccupiedException.java diff --git a/oolab/src/main/java/agh/ics/oop/OptionsParser.java b/oolab/src/main/java/agh/ics/oop/OptionsParser.java index b4e6d4e..9bc49a9 100644 --- a/oolab/src/main/java/agh/ics/oop/OptionsParser.java +++ b/oolab/src/main/java/agh/ics/oop/OptionsParser.java @@ -19,6 +19,8 @@ public static List Parser(String[] args) { MoveDirectionList.add(MoveDirection.LEFT); } else if (Objects.equals(args[i], "r")) { MoveDirectionList.add(MoveDirection.RIGHT); + } else { + throw new IllegalArgumentException(args[i] + " " + "is not legal move"); } } return MoveDirectionList; diff --git a/oolab/src/main/java/agh/ics/oop/Simulation.java b/oolab/src/main/java/agh/ics/oop/Simulation.java index 563b2f8..7cdea8b 100644 --- a/oolab/src/main/java/agh/ics/oop/Simulation.java +++ b/oolab/src/main/java/agh/ics/oop/Simulation.java @@ -14,9 +14,13 @@ public Simulation(List positions, List moves, WorldMap this.Map = map; for(Vector2d position : positions) { Animal new_animal = new Animal(position.getX(), position.getY()); - if(map.place(new_animal)) { - Animals.add(new_animal); + try { + map.place(new_animal); + } catch (PositionAlreadyOccupiedException e) { + e.printStackTrace(); } + Animals.add(new_animal); + } } diff --git a/oolab/src/main/java/agh/ics/oop/World.java b/oolab/src/main/java/agh/ics/oop/World.java index d383d44..f58db62 100644 --- a/oolab/src/main/java/agh/ics/oop/World.java +++ b/oolab/src/main/java/agh/ics/oop/World.java @@ -28,13 +28,20 @@ public static void run(List directions) { } } public static void main(String[] args) { + List directions = new ArrayList<>(); + String[] args1 = {"f", "b", "l", "r", "r", "f", "l", "b", "b"}; - List directions = OptionsParser.Parser(args1); - List positions = List.of(new Vector2d(2,2), new Vector2d(3,4), new Vector2d(0,0)); + try { + directions = OptionsParser.Parser(args1); + List positions = List.of(new Vector2d(2,2), new Vector2d(3,4), new Vector2d(0,0)); + GrassField map = new GrassField(10); + Simulation sim = new Simulation(positions, directions, map); + sim.run(); + } catch (IllegalArgumentException e){ + e.printStackTrace(); + } + - GrassField map = new GrassField(10); - Simulation sim = new Simulation(positions, directions, map); - sim.run(); } diff --git a/oolab/src/main/java/agh/ics/oop/model/AbstractWorldMap.java b/oolab/src/main/java/agh/ics/oop/model/AbstractWorldMap.java index 6c08af6..7d1373b 100644 --- a/oolab/src/main/java/agh/ics/oop/model/AbstractWorldMap.java +++ b/oolab/src/main/java/agh/ics/oop/model/AbstractWorldMap.java @@ -13,13 +13,14 @@ public abstract class AbstractWorldMap implements WorldMap { Vector2d MAP_RIGHT_TOP = new Vector2d(0,0); @Override - public boolean place(Animal animal) { + public void place(Animal animal) throws PositionAlreadyOccupiedException{ if (canMoveTo(animal.getPosition())){ animals.put(animal.getPosition(), animal); - return true; + } else { + throw new PositionAlreadyOccupiedException(animal.getPosition()); } - return false; + } @Override diff --git a/oolab/src/main/java/agh/ics/oop/model/PositionAlreadyOccupiedException.java b/oolab/src/main/java/agh/ics/oop/model/PositionAlreadyOccupiedException.java new file mode 100644 index 0000000..03ca2e8 --- /dev/null +++ b/oolab/src/main/java/agh/ics/oop/model/PositionAlreadyOccupiedException.java @@ -0,0 +1,7 @@ +package agh.ics.oop.model; + +public class PositionAlreadyOccupiedException extends Exception { + public PositionAlreadyOccupiedException(Vector2d vec) { + super("Position: " + vec.toString() + "is already occupied"); + } +} diff --git a/oolab/src/main/java/agh/ics/oop/model/WorldMap.java b/oolab/src/main/java/agh/ics/oop/model/WorldMap.java index 7592b70..bccdd79 100644 --- a/oolab/src/main/java/agh/ics/oop/model/WorldMap.java +++ b/oolab/src/main/java/agh/ics/oop/model/WorldMap.java @@ -17,7 +17,7 @@ public interface WorldMap extends MoveValidator { * @param animal The animal to place on the map. * @return True if the animal was placed. The animal cannot be placed if the move is not valid. */ - boolean place(Animal animal); + void place(Animal animal) throws PositionAlreadyOccupiedException; /** * Moves an animal (if it is present on the map) according to specified direction. diff --git a/oolab/src/test/java/agh/ics/oop/model/GrassFieldTest.java b/oolab/src/test/java/agh/ics/oop/model/GrassFieldTest.java index a80f787..74632d6 100644 --- a/oolab/src/test/java/agh/ics/oop/model/GrassFieldTest.java +++ b/oolab/src/test/java/agh/ics/oop/model/GrassFieldTest.java @@ -17,10 +17,15 @@ public void placeTest() { GrassField map = new GrassField(10); Map finalAnimals = map.getAnimals(); - for(Vector2d position : positions) { - map.place(new Animal(position.getX(), position.getY())); + for (Vector2d position : positions) { + try { + map.place(new Animal(position.getX(), position.getY())); + } catch (PositionAlreadyOccupiedException e){ + e.printStackTrace(); + } } + assertTrue(finalAnimals.containsKey(new Vector2d(3,4))); assertTrue(finalAnimals.containsKey(new Vector2d(0,0))); assertTrue(finalAnimals.containsKey(new Vector2d(2,2))); @@ -32,8 +37,12 @@ public void isOccupiedTest() { List positions = List.of(new Vector2d(2,2), new Vector2d(5,7), new Vector2d(-4,0)); GrassField map = new GrassField(10); - for(Vector2d position : positions) { - map.place(new Animal(position.getX(), position.getY())); + for (Vector2d position : positions) { + try { + map.place(new Animal(position.getX(), position.getY())); + } catch (PositionAlreadyOccupiedException e){ + e.printStackTrace(); + } } assertTrue(map.isOccupied(new Vector2d(2,2))); @@ -46,8 +55,12 @@ public void objectAtTest() { List positions = List.of(new Vector2d(2,2)); GrassField map = new GrassField(10); - for(Vector2d position : positions) { - map.place(new Animal(position.getX(), position.getY())); + for (Vector2d position : positions) { + try { + map.place(new Animal(position.getX(), position.getY())); + } catch (PositionAlreadyOccupiedException e){ + e.printStackTrace(); + } } Animal animal = (Animal) map.objectAt(new Vector2d(2,2)); diff --git a/oolab/src/test/java/agh/ics/oop/model/RectangularMapTest.java b/oolab/src/test/java/agh/ics/oop/model/RectangularMapTest.java index 5cecff2..5a10ed9 100644 --- a/oolab/src/test/java/agh/ics/oop/model/RectangularMapTest.java +++ b/oolab/src/test/java/agh/ics/oop/model/RectangularMapTest.java @@ -17,24 +17,26 @@ public void testCanMoveToBasic(){ assertFalse(rectangularMap.canMoveTo(new Vector2d(5,5))); } @Test - public void testPlace(){ - RectangularMap rectangularMap = new RectangularMap(4,4); - assertTrue(rectangularMap.place(ANIMAL1)); - assertTrue(rectangularMap.place(ANIMAL2)); - assertFalse(rectangularMap.place(new Animal())); - } - @Test public void testIsOccupied(){ RectangularMap rectangularMap = new RectangularMap(4,4); - rectangularMap.place(ANIMAL1); - rectangularMap.place(ANIMAL2); + try { + rectangularMap.place(ANIMAL1); + rectangularMap.place(ANIMAL2); + } catch (PositionAlreadyOccupiedException e) { + e.printStackTrace(); + } + assertFalse(rectangularMap.isOccupied(new Vector2d(0,0))); assertTrue(rectangularMap.isOccupied(VEC11)); } @Test public void testObjectAt(){ RectangularMap rectangularMap = new RectangularMap(4,4); - rectangularMap.place(ANIMAL1); + try { + rectangularMap.place(ANIMAL1); + } catch (PositionAlreadyOccupiedException e) { + e.printStackTrace(); + } assertNull(rectangularMap.objectAt(new Vector2d(0, 0))); assertEquals(ANIMAL1, rectangularMap.objectAt(VEC11)); } From cb088a761a920af9ca4be5a7299b6bf223ca62ce Mon Sep 17 00:00:00 2001 From: Kamil Rudny <134285490+krudny@users.noreply.github.com> Date: Thu, 7 Dec 2023 21:06:14 +0100 Subject: [PATCH 2/3] Added boundary --- oolab/src/main/java/agh/ics/oop/Simulation.java | 3 ++- oolab/src/main/java/agh/ics/oop/World.java | 2 +- .../src/main/java/agh/ics/oop/model/AbstractWorldMap.java | 8 ++++++++ oolab/src/main/java/agh/ics/oop/model/Boundary.java | 4 ++++ oolab/src/main/java/agh/ics/oop/model/GrassField.java | 6 ------ .../ics/oop/model/PositionAlreadyOccupiedException.java | 2 +- oolab/src/main/java/agh/ics/oop/model/RectangularMap.java | 4 ---- 7 files changed, 16 insertions(+), 13 deletions(-) create mode 100644 oolab/src/main/java/agh/ics/oop/model/Boundary.java diff --git a/oolab/src/main/java/agh/ics/oop/Simulation.java b/oolab/src/main/java/agh/ics/oop/Simulation.java index 7cdea8b..77987f2 100644 --- a/oolab/src/main/java/agh/ics/oop/Simulation.java +++ b/oolab/src/main/java/agh/ics/oop/Simulation.java @@ -16,10 +16,11 @@ public Simulation(List positions, List moves, WorldMap Animal new_animal = new Animal(position.getX(), position.getY()); try { map.place(new_animal); + Animals.add(new_animal); } catch (PositionAlreadyOccupiedException e) { e.printStackTrace(); } - Animals.add(new_animal); + } diff --git a/oolab/src/main/java/agh/ics/oop/World.java b/oolab/src/main/java/agh/ics/oop/World.java index f58db62..50f135a 100644 --- a/oolab/src/main/java/agh/ics/oop/World.java +++ b/oolab/src/main/java/agh/ics/oop/World.java @@ -30,7 +30,7 @@ public static void run(List directions) { public static void main(String[] args) { List directions = new ArrayList<>(); - String[] args1 = {"f", "b", "l", "r", "r", "f", "l", "b", "b"}; + String[] args1 = {"f", "f","f","f","f","f","f","f","f","f","f","f","f","f","f","f","f","f","f","f","f"}; try { directions = OptionsParser.Parser(args1); List positions = List.of(new Vector2d(2,2), new Vector2d(3,4), new Vector2d(0,0)); diff --git a/oolab/src/main/java/agh/ics/oop/model/AbstractWorldMap.java b/oolab/src/main/java/agh/ics/oop/model/AbstractWorldMap.java index 7d1373b..3fffcab 100644 --- a/oolab/src/main/java/agh/ics/oop/model/AbstractWorldMap.java +++ b/oolab/src/main/java/agh/ics/oop/model/AbstractWorldMap.java @@ -69,4 +69,12 @@ public Map getElements(){ return all_elements; } + + public Boundary getCurrentBounds(){ + return new Boundary(MAP_LEFT_BOTTOM, MAP_RIGHT_TOP); + } + + public String toString() { + return mapVisualizer.draw(getCurrentBounds().MAP_LEFT_BOTTOM(), getCurrentBounds().MAP_RIGHT_TOP()); + } } diff --git a/oolab/src/main/java/agh/ics/oop/model/Boundary.java b/oolab/src/main/java/agh/ics/oop/model/Boundary.java new file mode 100644 index 0000000..8cfba46 --- /dev/null +++ b/oolab/src/main/java/agh/ics/oop/model/Boundary.java @@ -0,0 +1,4 @@ +package agh.ics.oop.model; + +public record Boundary(Vector2d MAP_LEFT_BOTTOM, Vector2d MAP_RIGHT_TOP) { +} diff --git a/oolab/src/main/java/agh/ics/oop/model/GrassField.java b/oolab/src/main/java/agh/ics/oop/model/GrassField.java index 100b0a6..1007451 100644 --- a/oolab/src/main/java/agh/ics/oop/model/GrassField.java +++ b/oolab/src/main/java/agh/ics/oop/model/GrassField.java @@ -29,12 +29,6 @@ public void generatePositions() { grass.put(position, new Grass(position)); } } - @Override - public String toString() { - return mapVisualizer.draw(MAP_LEFT_BOTTOM, MAP_RIGHT_TOP); - } - - @Override public boolean isOccupied(Vector2d position) { return (super.isOccupied(position) || grass.containsKey(position)); diff --git a/oolab/src/main/java/agh/ics/oop/model/PositionAlreadyOccupiedException.java b/oolab/src/main/java/agh/ics/oop/model/PositionAlreadyOccupiedException.java index 03ca2e8..5fc2036 100644 --- a/oolab/src/main/java/agh/ics/oop/model/PositionAlreadyOccupiedException.java +++ b/oolab/src/main/java/agh/ics/oop/model/PositionAlreadyOccupiedException.java @@ -2,6 +2,6 @@ public class PositionAlreadyOccupiedException extends Exception { public PositionAlreadyOccupiedException(Vector2d vec) { - super("Position: " + vec.toString() + "is already occupied"); + super("Position: " + vec.toString() + " is already occupied"); } } diff --git a/oolab/src/main/java/agh/ics/oop/model/RectangularMap.java b/oolab/src/main/java/agh/ics/oop/model/RectangularMap.java index 77b4377..cca8167 100644 --- a/oolab/src/main/java/agh/ics/oop/model/RectangularMap.java +++ b/oolab/src/main/java/agh/ics/oop/model/RectangularMap.java @@ -27,8 +27,4 @@ public Vector2d getMAP_RIGHT_TOP() { public Vector2d getMAP_LEFT_BOTTOM() { return MAP_LEFT_BOTTOM; } - @Override - public String toString(){ - return mapVisualizer.draw(MAP_LEFT_BOTTOM, MAP_RIGHT_TOP); - } } \ No newline at end of file From 7dca7852ff5d108c0fe81e03eed72d38748c7729 Mon Sep 17 00:00:00 2001 From: Kamil Rudny <134285490+krudny@users.noreply.github.com> Date: Thu, 7 Dec 2023 22:38:15 +0100 Subject: [PATCH 3/3] Added observators --- .../src/main/java/agh/ics/oop/Simulation.java | 5 ++-- oolab/src/main/java/agh/ics/oop/World.java | 1 + .../agh/ics/oop/model/AbstractWorldMap.java | 25 +++++++++++++++++++ .../agh/ics/oop/model/ConsoleMapDisplay.java | 16 ++++++++++++ .../agh/ics/oop/model/MapChangeListener.java | 5 ++++ 5 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 oolab/src/main/java/agh/ics/oop/model/ConsoleMapDisplay.java create mode 100644 oolab/src/main/java/agh/ics/oop/model/MapChangeListener.java diff --git a/oolab/src/main/java/agh/ics/oop/Simulation.java b/oolab/src/main/java/agh/ics/oop/Simulation.java index 77987f2..8c4ba9f 100644 --- a/oolab/src/main/java/agh/ics/oop/Simulation.java +++ b/oolab/src/main/java/agh/ics/oop/Simulation.java @@ -27,16 +27,15 @@ public Simulation(List positions, List moves, WorldMap } public void run() { - System.out.println(Map); int animal_count = Animals.size(); int cnt = 0; for(MoveDirection currentMove : Moves) { Animal current_animal = Animals.get(0); Animals.remove(0); - Map.move(current_animal, currentMove); System.out.println("Zwierze " + ((cnt % animal_count) + 1) + " " + current_animal.toString()); - System.out.println(Map); + Map.move(current_animal, currentMove); + cnt += 1; Animals.add(current_animal); } diff --git a/oolab/src/main/java/agh/ics/oop/World.java b/oolab/src/main/java/agh/ics/oop/World.java index 50f135a..4f11d45 100644 --- a/oolab/src/main/java/agh/ics/oop/World.java +++ b/oolab/src/main/java/agh/ics/oop/World.java @@ -35,6 +35,7 @@ public static void main(String[] args) { directions = OptionsParser.Parser(args1); List positions = List.of(new Vector2d(2,2), new Vector2d(3,4), new Vector2d(0,0)); GrassField map = new GrassField(10); + map.addListener(new ConsoleMapDisplay()); Simulation sim = new Simulation(positions, directions, map); sim.run(); } catch (IllegalArgumentException e){ diff --git a/oolab/src/main/java/agh/ics/oop/model/AbstractWorldMap.java b/oolab/src/main/java/agh/ics/oop/model/AbstractWorldMap.java index 3fffcab..de16d73 100644 --- a/oolab/src/main/java/agh/ics/oop/model/AbstractWorldMap.java +++ b/oolab/src/main/java/agh/ics/oop/model/AbstractWorldMap.java @@ -2,6 +2,7 @@ import agh.ics.oop.model.util.MapVisualizer; +import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -12,6 +13,12 @@ public abstract class AbstractWorldMap implements WorldMap { Vector2d MAP_LEFT_BOTTOM = new Vector2d(0,0); Vector2d MAP_RIGHT_TOP = new Vector2d(0,0); + protected ArrayList listeners = new ArrayList<>(); + + public AbstractWorldMap() { + listeners = new ArrayList<>(); + } + @Override public void place(Animal animal) throws PositionAlreadyOccupiedException{ if (canMoveTo(animal.getPosition())){ @@ -50,6 +57,7 @@ public void move(Animal animal, MoveDirection direction) { int y = animal.getPosition().getY(); Vector2d vec = new Vector2d(x, y); calculateMapSize(vec); + mapChanged(animal, position, animal.getPosition()); } } } @@ -77,4 +85,21 @@ public Boundary getCurrentBounds(){ public String toString() { return mapVisualizer.draw(getCurrentBounds().MAP_LEFT_BOTTOM(), getCurrentBounds().MAP_RIGHT_TOP()); } + + public void addListener(MapChangeListener listener) { + listeners.add(listener); + } + + public String mapChanged( Animal animal, Vector2d oldPosition, Vector2d newPosition){ + String result = ""; + if (oldPosition == null){ + result = "New animal placed on the map at " + newPosition.toString(); + } + else{ + result = "Animal moved from " + oldPosition.toString() + " to " + newPosition.toString(); + } + for (MapChangeListener listener : listeners) + listener.mapChanged((WorldMap) this,result); + return result; + } } diff --git a/oolab/src/main/java/agh/ics/oop/model/ConsoleMapDisplay.java b/oolab/src/main/java/agh/ics/oop/model/ConsoleMapDisplay.java new file mode 100644 index 0000000..cb6f393 --- /dev/null +++ b/oolab/src/main/java/agh/ics/oop/model/ConsoleMapDisplay.java @@ -0,0 +1,16 @@ +package agh.ics.oop.model; + +public class ConsoleMapDisplay implements MapChangeListener{ + private int changescount; + + public ConsoleMapDisplay() { + this.changescount = 0; + } + @Override + public void mapChanged(WorldMap worldMap, String message) { + changescount++; + System.out.println(message); + System.out.println(worldMap.toString()); + System.out.println("Number of changes: " + changescount + "\n\n\n"); + } +} diff --git a/oolab/src/main/java/agh/ics/oop/model/MapChangeListener.java b/oolab/src/main/java/agh/ics/oop/model/MapChangeListener.java new file mode 100644 index 0000000..e0215f8 --- /dev/null +++ b/oolab/src/main/java/agh/ics/oop/model/MapChangeListener.java @@ -0,0 +1,5 @@ +package agh.ics.oop.model; + +public interface MapChangeListener { + void mapChanged(WorldMap worldMap, String message); +}