From 5e7d100b276efee039895c18b301926265af0a87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Lys=C3=A9n?= Date: Thu, 16 Oct 2025 12:13:53 +0200 Subject: [PATCH 01/31] Commit init --- src/main/java/World.java | 71 ++++++++++++++++++++++++++++++++++++ src/test/java/WorldTest.java | 14 +++++++ 2 files changed, 85 insertions(+) create mode 100644 src/main/java/World.java create mode 100644 src/test/java/WorldTest.java diff --git a/src/main/java/World.java b/src/main/java/World.java new file mode 100644 index 0000000..5e5b319 --- /dev/null +++ b/src/main/java/World.java @@ -0,0 +1,71 @@ +import java.util.HashMap; +import java.util.Random; +import java.util.LinkedList; +public class World { + // Används för att printa mappen. + private String[][] map = { + {"@","@","@","@","@","@","@","@","@","@","@"}, + {"@","X","|"," ", "|", " ","|"," ","|"," ","@"}, + {"@"," ","|"," ", "|", " ","|"," ","|"," ","@"}, + {"@"," ","|"," ", "|", " ","|"," ","|"," ","@"}, + {"@"," ","|"," ", "|", " ","|"," ","|"," ","@"}, + {"@"," ","|"," ", "|", " ","|"," ","|"," ","@"}, + {"@","@","@","@","@","@","@","@","@","@","@"} + }; + HashMap tileMap = new HashMap<>(); + private LinkedList entityList = new LinkedList<>(); + public Entity addEntityToList(Entity e) { + entityList.add(e); + } + + public void addTile(Tile tile, int xCoordinate, int yCoordinate) { + int key = xCoordinate * 10 + yCoordinate; + tileMap.put(key, tile); + } + + /* + M in array is monster + C in array is chest + X in array is player. + */ + public void printMap() { + for (int i = 0; i < map.length; i++) { + for (int j = 0; j < map[i].length; j++) { + System.out.print(map[i][j]); + } + } + } + + public String[][] getMap() { + return map; + } + + public LinkedList getEntityList() { + return entityList; + } + + public Tile getTileAtPosition(int xCoordinate, int yCoordinate) { + int tileKey = xCoordinate * 10 + yCoordinate; + return tileMap.get(tileKey); + } + + public Entity getEntityAtPosition(int xCoordinate, int yCoordinate) { + if (!entityList.isEmpty()) { + for (int i = 0; i < entityList.size(); i++) { + int xEntityCord = entityList.get(i).getX(); + int yEntityCord = entityList.get(i).getY(); + if (xCoordinate == xEntityCord && yCoordinate == yEntityCord) { + return entityList.get(i); + } + } + } + return null; + } + public void changePosition(Object Character, int xCoordinate, int yCoordinate) { + if (Character instanceof Player) { + map[(xCoordinate * 2) + 1][yCoordinate + 1] = "X"; + } else if (Character instanceof Enemy) { + map[(xCoordinate * 2) + 1][yCoordinate + 1] = "M"; + } + } +} diff --git a/src/test/java/WorldTest.java b/src/test/java/WorldTest.java new file mode 100644 index 0000000..aef7e6f --- /dev/null +++ b/src/test/java/WorldTest.java @@ -0,0 +1,14 @@ +import static org.junit.jupiter.api.Assertions.*; +class WorldTest { + @Test + void addTileToMapTest() { + World test = new World(); + Tile tile new Tile(); + int xCoordinate = 1; + int yCoordinate = 1; + test.addTile(tile, xCoordinate, yCoordinate); + Tile tileTest = test.getTileAtPosition(1, 1); + assertEquals(tile, tileTest); + } + +} \ No newline at end of file -- 2.39.5 From a36b5923ae4635bc81ab96c34af477434c1d0e4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Lys=C3=A9n?= Date: Fri, 17 Oct 2025 00:40:13 +0200 Subject: [PATCH 02/31] Commit init --- src/main/java/Tile.java | 20 ++++++++++++++ src/main/java/World.java | 52 +++++++++++++++++++++--------------- src/test/java/TileTest.java | 27 +++++++++++++++++++ src/test/java/WorldTest.java | 29 ++++++++++++++++++-- 4 files changed, 104 insertions(+), 24 deletions(-) create mode 100644 src/main/java/Tile.java create mode 100644 src/test/java/TileTest.java diff --git a/src/main/java/Tile.java b/src/main/java/Tile.java new file mode 100644 index 0000000..9c72e70 --- /dev/null +++ b/src/main/java/Tile.java @@ -0,0 +1,20 @@ + +public class Tile { + private String tileName; + private int staminaCost; + private String tilePrintString; + public Tile(String tileName, int staminaCost, String tilePrintString) { + this.tileName = tileName; + this.staminaCost = staminaCost; + this.tilePrintString = tilePrintString; + } + public String getName() { + return tileName; + } + public int getStaminaCost() { + return staminaCost; + } + public String getTilePrintString() { + return tilePrintString; + } +} diff --git a/src/main/java/World.java b/src/main/java/World.java index 5e5b319..2f8f468 100644 --- a/src/main/java/World.java +++ b/src/main/java/World.java @@ -1,6 +1,7 @@ +import java.util.ArrayList; import java.util.HashMap; +import java.util.Map; import java.util.Random; -import java.util.LinkedList; public class World { // Används för att printa mappen. private String[][] map = { @@ -13,21 +14,33 @@ public class World { {"@","@","@","@","@","@","@","@","@","@","@"} }; HashMap tileMap = new HashMap<>(); - private LinkedList entityList = new LinkedList<>(); - public Entity addEntityToList(Entity e) { - entityList.add(e); + private HashMap entityMap = new HashMap<>(); + public final int TILE_SIZE = 25; + + public void addEntityToMap(Entity e) { + entityMap.put(e, e.getPosition()); + } + + public World() { + autoGenerateTiles(); + } + + private void autoGenerateTiles() { + Random rand = new Random(); + for (int i = 0; i < TILE_SIZE; i++) { + int x = rand.nextInt(4); + } } public void addTile(Tile tile, int xCoordinate, int yCoordinate) { int key = xCoordinate * 10 + yCoordinate; tileMap.put(key, tile); } - /* M in array is monster C in array is chest X in array is player. - */ + */ public void printMap() { for (int i = 0; i < map.length; i++) { for (int j = 0; j < map[i].length; j++) { @@ -40,8 +53,8 @@ public class World { return map; } - public LinkedList getEntityList() { - return entityList; + public HashMap getEntityList() { + return entityMap; } public Tile getTileAtPosition(int xCoordinate, int yCoordinate) { @@ -49,23 +62,18 @@ public class World { return tileMap.get(tileKey); } - public Entity getEntityAtPosition(int xCoordinate, int yCoordinate) { - if (!entityList.isEmpty()) { - for (int i = 0; i < entityList.size(); i++) { - int xEntityCord = entityList.get(i).getX(); - int yEntityCord = entityList.get(i).getY(); - if (xCoordinate == xEntityCord && yCoordinate == yEntityCord) { - return entityList.get(i); - } + public Entity getEntityAtPosition(Position position) { + for (HashMap.Entry entry : entityMap.entrySet()) { + Position pos = entry.getValue(); + Entity e = entry.getKey(); + if (pos.equals(position)) { + return e; } } return null; } - public void changePosition(Object Character, int xCoordinate, int yCoordinate) { - if (Character instanceof Player) { - map[(xCoordinate * 2) + 1][yCoordinate + 1] = "X"; - } else if (Character instanceof Enemy) { - map[(xCoordinate * 2) + 1][yCoordinate + 1] = "M"; - } + + public void changePosition(Entity Character, Position newPosition) { + entityMap.put(Character, newPosition); } } diff --git a/src/test/java/TileTest.java b/src/test/java/TileTest.java new file mode 100644 index 0000000..7834d42 --- /dev/null +++ b/src/test/java/TileTest.java @@ -0,0 +1,27 @@ +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +class TileTest { + private final String TILE_NAME = "Name test"; + private final int STAMINA_COST = 1; + private final String PRINT_STRING = "Mountain test"; + @Test + void getTileNameTest() { + Tile tileTest = new Tile(TILE_NAME, STAMINA_COST, PRINT_STRING); + String tileNameTwo = tileTest.getName(); + assertEquals(TILE_NAME, tileNameTwo); + } + @Test + void getStaminaCostTest() { + Tile tileTest = new Tile(TILE_NAME, STAMINA_COST, PRINT_STRING); + assertEquals(STAMINA_COST, tileTest.getStaminaCost()); + } + @Test + void printTileStringTest() { + Tile tileTest = new Tile(TILE_NAME, STAMINA_COST, PRINT_STRING); + assertEquals(PRINT_STRING, tileTest.getTilePrintString()); + } +} \ No newline at end of file diff --git a/src/test/java/WorldTest.java b/src/test/java/WorldTest.java index aef7e6f..ed86580 100644 --- a/src/test/java/WorldTest.java +++ b/src/test/java/WorldTest.java @@ -1,14 +1,39 @@ + +import org.junit.jupiter.api.Test; + +import java.util.HashMap; + import static org.junit.jupiter.api.Assertions.*; class WorldTest { + final int TILE_SIZE = 25; @Test void addTileToMapTest() { World test = new World(); - Tile tile new Tile(); + Tile tile = new Tile("test", 3, "test"); int xCoordinate = 1; int yCoordinate = 1; test.addTile(tile, xCoordinate, yCoordinate); Tile tileTest = test.getTileAtPosition(1, 1); assertEquals(tile, tileTest); } - + @Test + void addEntityToMapTest() { + World test = new World(); + Entity character = new Player("Name"); + character.setPosition(new Position(2, 2)); + test.addEntityToMap(character); + } + @Test + void randomTileGeneratorTest() { + World test = new World(); + HashMap tileMap = new HashMap<>(); + int tileSize = tileMap.size(); + assertEquals(TILE_SIZE, tileSize); + } + @Test + void getTileAtPositionTest() { + World test = new World(); + HashMap tileMap = new HashMap<>(); + } + } \ No newline at end of file -- 2.39.5 From b8fc93a1bfd106cf0669204e87a1695701bce862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Lys=C3=A9n?= Date: Fri, 17 Oct 2025 02:39:17 +0200 Subject: [PATCH 03/31] Commit init --- src/main/java/MapGenerator.java | 46 +++++++++++++++++ src/main/java/World.java | 78 ++++++++++++++++++----------- src/test/java/MapGeneratorTest.java | 33 ++++++++++++ src/test/java/WorldTest.java | 41 +++++++-------- 4 files changed, 148 insertions(+), 50 deletions(-) create mode 100644 src/main/java/MapGenerator.java create mode 100644 src/test/java/MapGeneratorTest.java diff --git a/src/main/java/MapGenerator.java b/src/main/java/MapGenerator.java new file mode 100644 index 0000000..aecb71d --- /dev/null +++ b/src/main/java/MapGenerator.java @@ -0,0 +1,46 @@ +import java.util.Random; +public class MapGenerator { + private int x; + private int y; + private World gameWorld; + + public MapGenerator(int x, int y) { + this.x = x; + this.y = y; + if (x <= 0 || y <= 0) { + throw new IllegalArgumentException("X and Y coordinates must be positive"); + } + this.gameWorld = new World(x, y); + } + + public void randomWorldGeneration() { + Random rand = new Random(); + for (int i = 0; i < x; i++) { + for (int j = 0; j < y; j++) { + int tileDice = rand.nextInt(4); + if (tileDice == 0) { + Tile newTile = new Tile("Mountain", 3, "Future development"); + gameWorld.addTile(newTile, new Position(i, j)); + } else if (tileDice == 1) { + Tile newTile = new Tile("plain", 1, "Future development"); + gameWorld.addTile(newTile, new Position(i, j)); + } else if (tileDice == 2) { + Tile newTile = new Tile("Lava", 2, "Future development"); + gameWorld.addTile(newTile, new Position(i, j)); + } else if (tileDice == 3) { + Tile newTile = new Tile("Water", 4, "Future development"); + gameWorld.addTile(newTile, new Position(i, j)); + } + } + } + } + + public void addTile(String name, int staminaCost, String description, Position position) { + Tile newTile = new Tile(name, staminaCost, description); + gameWorld.addTile(newTile, position); + } + + public World getWorld() { + return gameWorld; + } +} diff --git a/src/main/java/World.java b/src/main/java/World.java index 2f8f468..6695488 100644 --- a/src/main/java/World.java +++ b/src/main/java/World.java @@ -3,38 +3,54 @@ import java.util.HashMap; import java.util.Map; import java.util.Random; public class World { - // Används för att printa mappen. - private String[][] map = { - {"@","@","@","@","@","@","@","@","@","@","@"}, - {"@","X","|"," ", "|", " ","|"," ","|"," ","@"}, - {"@"," ","|"," ", "|", " ","|"," ","|"," ","@"}, - {"@"," ","|"," ", "|", " ","|"," ","|"," ","@"}, - {"@"," ","|"," ", "|", " ","|"," ","|"," ","@"}, - {"@"," ","|"," ", "|", " ","|"," ","|"," ","@"}, - {"@","@","@","@","@","@","@","@","@","@","@"} - }; - HashMap tileMap = new HashMap<>(); + + private HashMap tileMap = new HashMap<>(); private HashMap entityMap = new HashMap<>(); - public final int TILE_SIZE = 25; + private String[][] map; + + public World(int x, int y) { + this.map = new String[(x * 2) + 1][y + 2]; + addWorldToMap(); + } + + private void addWorldToMap() { + for (int i = 0; i < map.length; i++) { + for (int j = 0; j < map[i].length; j++) { + if (i == 0 || j == 0 || i == map.length || j == map[j].length) { + map[i][j] = "@"; + } else if (j % 2 == 1) { + map[i][j] = " "; + } else { + map[i][j] = "|"; + } + } + } + } + + public void printWorld() { + for (Entity e : entityMap.keySet()) { + Position pos = entityMap.get(e); + if (e instanceof Player) { + map[pos.x()][pos.y()] = "X"; + } /* else if (e instanceof Monster) { + map[pos.x()][pos.y()] = "M"; + */ + } + for (int i = 0; i < map.length; i++) { + System.out.println(); + for (int j = 0; j < map[i].length; j++) { + System.out.print(map[i][j]); + } + } + } + + public void addEntityToMap(Entity e) { entityMap.put(e, e.getPosition()); } - - public World() { - autoGenerateTiles(); - } - - private void autoGenerateTiles() { - Random rand = new Random(); - for (int i = 0; i < TILE_SIZE; i++) { - int x = rand.nextInt(4); - } - } - - public void addTile(Tile tile, int xCoordinate, int yCoordinate) { - int key = xCoordinate * 10 + yCoordinate; - tileMap.put(key, tile); + public void addTile(Tile tile, Position pos) { + tileMap.put(pos, tile); } /* M in array is monster @@ -56,10 +72,12 @@ public class World { public HashMap getEntityList() { return entityMap; } + public HashMap getTileMap() { + return tileMap; + } - public Tile getTileAtPosition(int xCoordinate, int yCoordinate) { - int tileKey = xCoordinate * 10 + yCoordinate; - return tileMap.get(tileKey); + public Tile getTileAtPosition(Position pos) { + return tileMap.get(pos); } public Entity getEntityAtPosition(Position position) { diff --git a/src/test/java/MapGeneratorTest.java b/src/test/java/MapGeneratorTest.java new file mode 100644 index 0000000..51989f1 --- /dev/null +++ b/src/test/java/MapGeneratorTest.java @@ -0,0 +1,33 @@ +import org.junit.jupiter.api.Test; + +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.*; + +class MapGeneratorTest { + private final int X_FIVE = 5; + private final int Y_FIVE = 5; + @Test + void mapBeingGeneratedTest() { + MapGenerator mapGenerate = new MapGenerator(X_FIVE, Y_FIVE); + mapGenerate.randomWorldGeneration(); + World world = mapGenerate.getWorld(); + HashMap map = world.getTileMap(); + assertEquals(map.size(), X_FIVE * Y_FIVE); + } + // Valid klass + @Test + void addTileAtPositionTest() { + MapGenerator mapGenerate = new MapGenerator(X_FIVE, Y_FIVE); + mapGenerate.addTile("Test", 10, "test description", new Position(2, 2)); + World testWorld = mapGenerate.getWorld(); + assertTrue(testWorld.getTileAtPosition(new Position(2, 2)) instanceof Tile); + assertFalse(testWorld.getTileAtPosition(new Position(2, 1)) instanceof Tile); + } + // Invalid klass + @Test + void negativeCoordinatesTest() { + assertThrows(IllegalArgumentException.class, () -> new MapGenerator(-1, 5)); + assertThrows(IllegalArgumentException.class, () -> new MapGenerator(5, 0)); + } +} \ No newline at end of file diff --git a/src/test/java/WorldTest.java b/src/test/java/WorldTest.java index ed86580..d1f0a69 100644 --- a/src/test/java/WorldTest.java +++ b/src/test/java/WorldTest.java @@ -5,35 +5,36 @@ import java.util.HashMap; import static org.junit.jupiter.api.Assertions.*; class WorldTest { - final int TILE_SIZE = 25; - @Test - void addTileToMapTest() { - World test = new World(); - Tile tile = new Tile("test", 3, "test"); - int xCoordinate = 1; - int yCoordinate = 1; - test.addTile(tile, xCoordinate, yCoordinate); - Tile tileTest = test.getTileAtPosition(1, 1); - assertEquals(tile, tileTest); - } @Test void addEntityToMapTest() { - World test = new World(); + World test = new World(5, 5); Entity character = new Player("Name"); character.setPosition(new Position(2, 2)); test.addEntityToMap(character); } @Test - void randomTileGeneratorTest() { - World test = new World(); + void getTileAtPositionTest() { + World test = new World(5, 5); HashMap tileMap = new HashMap<>(); - int tileSize = tileMap.size(); - assertEquals(TILE_SIZE, tileSize); } @Test - void getTileAtPositionTest() { - World test = new World(); - HashMap tileMap = new HashMap<>(); + void worldCreationTest() { + World test = new World(5, 5); + String[][] mapTest = test.getMap(); + int counter = 0; + for (int i = 0; i < mapTest.length; i++) { + for (int j = 0; j < mapTest[i].length; j++) { + counter += 1; + } + } + assertEquals(counter, 5 * 5); + } + @Test + void mapCreationTest() { + World test = new World(5, 5); + String[][] mapTest = test.getMap(); + assertEquals(mapTest[1][1], " "); + assertEquals(mapTest[1][2], "|"); + assertEquals(mapTest[0][0], "@"); } - } \ No newline at end of file -- 2.39.5 From 5fbe61d42782fc9ee1f2d867509f9ca539349ec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Lys=C3=A9n?= Date: Fri, 24 Oct 2025 10:19:36 +0200 Subject: [PATCH 04/31] Commit init --- src/main/java/Tile.java | 13 ++++++++----- src/test/java/TileTest.java | 17 ++++++++++++----- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/main/java/Tile.java b/src/main/java/Tile.java index 9c72e70..4fe4df8 100644 --- a/src/main/java/Tile.java +++ b/src/main/java/Tile.java @@ -2,11 +2,14 @@ public class Tile { private String tileName; private int staminaCost; - private String tilePrintString; - public Tile(String tileName, int staminaCost, String tilePrintString) { + private String tileID; + public Tile(String tileName, int staminaCost, String tileID) { this.tileName = tileName; this.staminaCost = staminaCost; - this.tilePrintString = tilePrintString; + this.tileID = tileID; + } + public void setStaminaCost(int newStaminaCost) { + staminaCost = newStaminaCost; } public String getName() { return tileName; @@ -14,7 +17,7 @@ public class Tile { public int getStaminaCost() { return staminaCost; } - public String getTilePrintString() { - return tilePrintString; + public String getTileID() { + return tileID; } } diff --git a/src/test/java/TileTest.java b/src/test/java/TileTest.java index 7834d42..5adba16 100644 --- a/src/test/java/TileTest.java +++ b/src/test/java/TileTest.java @@ -7,21 +7,28 @@ import static org.junit.jupiter.api.Assertions.*; class TileTest { private final String TILE_NAME = "Name test"; private final int STAMINA_COST = 1; - private final String PRINT_STRING = "Mountain test"; + private final String ID_STRING = "Mountain test"; @Test void getTileNameTest() { - Tile tileTest = new Tile(TILE_NAME, STAMINA_COST, PRINT_STRING); + Tile tileTest = new Tile(TILE_NAME, STAMINA_COST, ID_STRING); String tileNameTwo = tileTest.getName(); assertEquals(TILE_NAME, tileNameTwo); } @Test void getStaminaCostTest() { - Tile tileTest = new Tile(TILE_NAME, STAMINA_COST, PRINT_STRING); + Tile tileTest = new Tile(TILE_NAME, STAMINA_COST, ID_STRING); assertEquals(STAMINA_COST, tileTest.getStaminaCost()); } @Test void printTileStringTest() { - Tile tileTest = new Tile(TILE_NAME, STAMINA_COST, PRINT_STRING); - assertEquals(PRINT_STRING, tileTest.getTilePrintString()); + Tile tileTest = new Tile(TILE_NAME, STAMINA_COST, ID_STRING); + assertEquals(ID_STRING, tileTest.getTileID()); + } + @Test + void setStaminaCostTest() { + Tile tileTest = new Tile(TILE_NAME, STAMINA_COST, ID_STRING); + tileTest.setStaminaCost(10); + int newStaminaCost = tileTest.getStaminaCost(); + assertEquals(10, newStaminaCost); } } \ No newline at end of file -- 2.39.5 From 588f4715f68d6bf9bc2d925ae919255fdeec4658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Lys=C3=A9n?= Date: Fri, 24 Oct 2025 10:21:55 +0200 Subject: [PATCH 05/31] Commit init --- .idea/.name | 1 + 1 file changed, 1 insertion(+) create mode 100644 .idea/.name diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..7e25fbe --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +World.java \ No newline at end of file -- 2.39.5 From abc209d313ea670ee5f32bcb7af85d9592e512b1 Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Mon, 27 Oct 2025 14:25:29 +0100 Subject: [PATCH 06/31] =?UTF-8?q?Skrivit=20tre=20tester,=20kanske=20f?= =?UTF-8?q?=C3=B6r=20m=C3=A5nga=20p=C3=A5=20samma=20g=C3=A5ng=20men=20jag?= =?UTF-8?q?=20ville=20skriva=20dom=20medans=20dom=20var=20f=C3=A4rska=20i?= =?UTF-8?q?=20huvudet.=20Tv=C3=A5=20av=20dom=20=C3=A4r=20v=C3=A4ldigt=20sn?= =?UTF-8?q?arlika=20varandra=20och=20testar=20'isAlive'-egenskapen=20fr?= =?UTF-8?q?=C3=A5n=20tv=C3=A5=20olika=20h=C3=A5ll.=20Har=20mycket=20att=20?= =?UTF-8?q?g=C3=B6ra=20med=20sj=C3=A4lva=20monsterklasserna,=20planerar=20?= =?UTF-8?q?att=20ta=20bort=20character=20helt=20och=20=C3=A4ven=20g=C3=B6r?= =?UTF-8?q?a=20'Monster'=20mycket=20mindre=20genom=20att=20flytta=20ner=20?= =?UTF-8?q?mycket=20information=20till=20dom=20konkreta=20implementationer?= =?UTF-8?q?na.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Attack.java | 2 ++ src/main/java/Biomes.java | 2 +- src/main/java/Character.java | 19 ++++-------- src/main/java/Monster.java | 24 ++++++++++---- src/test/java/MonsterTest.java | 57 +++++++++++++--------------------- 5 files changed, 48 insertions(+), 56 deletions(-) diff --git a/src/main/java/Attack.java b/src/main/java/Attack.java index a292f3e..1b4a263 100644 --- a/src/main/java/Attack.java +++ b/src/main/java/Attack.java @@ -19,4 +19,6 @@ public abstract class Attack { this.energyCost = energyCost; this.damage = damage; } + + public abstract boolean perform(Character target); } diff --git a/src/main/java/Biomes.java b/src/main/java/Biomes.java index 3c61251..49fdd1c 100644 --- a/src/main/java/Biomes.java +++ b/src/main/java/Biomes.java @@ -1,3 +1,3 @@ public enum Biomes { GRASSLAND, MOUNTAIN, COAST, FOREST //Är inte fäst vid dessa -} +} \ No newline at end of file diff --git a/src/main/java/Character.java b/src/main/java/Character.java index 80387ef..0927cb2 100644 --- a/src/main/java/Character.java +++ b/src/main/java/Character.java @@ -1,20 +1,17 @@ -//Vill inte göra så mycket med den här klassen, då jag vill påverka implementeringen av Player så lite som möjligt +import Entity.Position; + public abstract class Character { private static final double DEFAULT_HEALTH = 50d; - private static final double DEFAULT_LEVEL = 1.0; - private static final double DEFAULT_ENERGY = 50d; //Detta borde kanske egentligen beräknas och sättas automatiskt genom en algoritm som tar health och level i beaktskap?? Eller något sådant - private static final Position DEFAULT_POSITION = new Position(0,0); //Är detta en bra idé?? Mest för att kunna ha defaultkonstruktor + private static final double DEFAULT_ENERGY = 20d; + private static final Position DEFAULT_POSITION = new Position(0,0); - // Borde jag bara sätta allt till default direkt här???? private double health; - private double level; private double energy; //Borde kanske beräknas genom en algoritm istället för att kunna sättas i konstruktorn... Så det alltid blir balanserat private Position position; // Hur många varianter på konstruktorn behövs? public Character() { this.health = DEFAULT_HEALTH; - this.level = DEFAULT_LEVEL; this.energy = DEFAULT_ENERGY; this.position = DEFAULT_POSITION; } @@ -24,22 +21,18 @@ public abstract class Character { // Just denna variant är bara för testning i min implementation av Monster public Character(Position position) { this.health = DEFAULT_HEALTH; - this.level = DEFAULT_LEVEL; this.energy = DEFAULT_ENERGY; this.position = position; } - public Character(double health, double level, double energy, Position position) { + public Character(double health, double energy, Position position) { this.health = health; - this.level = level; this.energy = energy; this.position = position; } //Returnerar true om attacken gick igenom, annars false - //Tänker att positionen som skickas in är karaktärens egna - //Kommer antagligen behöva diverse hjälpmetoder i implementeringen då det är många krav som måste uppfyllas för att attacken ska gå igenom - abstract boolean attack(Position position, Character character); + abstract boolean attack(Character character); public double getHealth() { return health; diff --git a/src/main/java/Monster.java b/src/main/java/Monster.java index a9b3efc..039a608 100644 --- a/src/main/java/Monster.java +++ b/src/main/java/Monster.java @@ -1,18 +1,30 @@ import Entity.Position; - import java.util.*; -public abstract class Monster extends Character{ +public abstract class Monster { - private final List habitat = new ArrayList<>(); + private static final double DEFAULT_HEALTH = 50d; + private static final double DEFAULT_ENERGY = 20d; + private static final Position DEFAULT_POSITION = new Position(0,0); + private static final List DEFAULT_HABITAT = Arrays.asList(Biomes.GRASSLAND, Biomes.MOUNTAIN, Biomes.COAST, Biomes.FOREST); + + private double health; + private double energy; //Borde kanske beräknas genom en algoritm istället för att kunna sättas i konstruktorn... Så det alltid blir balanserat + private Position position; + private List habitat; public Monster() { - habitat.addAll(Arrays.asList(Biomes.GRASSLAND, Biomes.MOUNTAIN, Biomes.COAST, Biomes.FOREST)); + this.health = DEFAULT_HEALTH; + this.energy = DEFAULT_ENERGY; + this.position = DEFAULT_POSITION; + this.habitat.addAll(DEFAULT_HABITAT); } public Monster(Position position) { - super(position); - habitat.addAll(Arrays.asList(Biomes.GRASSLAND, Biomes.MOUNTAIN, Biomes.COAST, Biomes.FOREST)); + this-health = DEFAULT_HEALTH; + this.energy = DEFAULT_ENERGY; + this.position = position; + this.habitat.addAll(DEFAULT_HABITAT); } public Monster(double health, double level, double energy, Position position) { diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index cc75cd4..abb6e21 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -1,50 +1,35 @@ -import static org.junit.jupiter.api.Assertions.*; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.*; +import static org.hamcrest.MatcherAssert.*; +import static org.hamcrest.Matchers.*; +import static org.mockito.Mockito.mock; +import Entity.Player; public class MonsterTest { - @Test - void monster_cannot_attack_when_dead() { - /* - Monster someMonster = new Monster(); - someMonster.setHealth(-5d); - Assert(false, someMonster.attack(someMonster.getPosition(), character)); - */ + private Shade defaultShade; + private Player defaultPlayer = mock(Player.class); + + @BeforeEach + void reset() { + defaultShade = new Shade(); //Återställer alla värden till default } @Test - void monster_cannot_be_attacked_when_dead() { - /* - Monster attackingMonster = new Monster(); - Monster deadMonster = new Monster(); - deadMonster.setHealth(-4d); - Assert(false, attackingMonster.attack(attackingMonster.getPosition(), deadMonster)); - */ + void monster_cannot_act_after_death() { + defaultShade.setHealth(0); + assertThat(false, anyOf(defaultShade.moveTo(0, 1), defaultShade.attack(Attacks.CHILL, defaultPlayer))); } @Test - void monster_cannot_attack_character_at_different_position() { - /* - Monster monsterAtOnePosition = new Monster(new Position(0,0)); - Monster monsterAtDifferentPosition = new Monster(new Position(1,1)); - Assert(false, monsterAtOnePosition.attack(monsterAtOnePosition.getPosition(), monsterAtDifferentPosition); - */ + void reaching_zero_health_triggers_death() { + defaultShade.setHealth(0); + assertThat(true, is(defaultShade.isAlive())); } @Test - void monster_is_instantiated_correctly_from_default_constructor() { - /* - AssertAll???? - */ - } - - @Test - void monster_is_instantiated_correctly_from_position_only_constructor() { - - } - - @Test - void monster_is_instantiated_correctly_from_full_constructor() { - + void monster_cannot_regain_health_after_death() { + defaultShade.setHealth(0); + defaultShade.setHealth(10d); + assertThat(defaultShade.getHealth(), equalTo(0)); } } -- 2.39.5 From 5788f4210a4b66ebba08d57d892dc884cc88e39c Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Mon, 27 Oct 2025 15:24:50 +0100 Subject: [PATCH 07/31] =?UTF-8?q?Ett=20f=C3=B6rsta=20utkast=20av=20den=20n?= =?UTF-8?q?ya=20'Monster'-klassen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Monster.java | 59 ++++++++++++++++++---------------- src/main/java/Shade.java | 12 +++++++ src/test/java/MonsterTest.java | 9 +++--- 3 files changed, 48 insertions(+), 32 deletions(-) create mode 100644 src/main/java/Shade.java diff --git a/src/main/java/Monster.java b/src/main/java/Monster.java index 039a608..d62f10d 100644 --- a/src/main/java/Monster.java +++ b/src/main/java/Monster.java @@ -2,43 +2,46 @@ import Entity.Position; import java.util.*; public abstract class Monster { + public static final Position DEFAULT_POSITION = new Position(0,0); - private static final double DEFAULT_HEALTH = 50d; - private static final double DEFAULT_ENERGY = 20d; - private static final Position DEFAULT_POSITION = new Position(0,0); - private static final List DEFAULT_HABITAT = Arrays.asList(Biomes.GRASSLAND, Biomes.MOUNTAIN, Biomes.COAST, Biomes.FOREST); - - private double health; - private double energy; //Borde kanske beräknas genom en algoritm istället för att kunna sättas i konstruktorn... Så det alltid blir balanserat + private int health; + private int energy; //Borde kanske beräknas genom en algoritm istället för att kunna sättas i konstruktorn... Så det alltid blir balanserat private Position position; - private List habitat; + private boolean isAlive; - public Monster() { - this.health = DEFAULT_HEALTH; - this.energy = DEFAULT_ENERGY; - this.position = DEFAULT_POSITION; - this.habitat.addAll(DEFAULT_HABITAT); - } - - public Monster(Position position) { - this-health = DEFAULT_HEALTH; - this.energy = DEFAULT_ENERGY; + public Monster(int health, int energy, Position position) { + this.health = health; + this.energy = energy; this.position = position; - this.habitat.addAll(DEFAULT_HABITAT); + + isAlive = true; } - public Monster(double health, double level, double energy, Position position) { - super(health, level, energy, position); - habitat.addAll(Arrays.asList(Biomes.GRASSLAND, Biomes.MOUNTAIN, Biomes.COAST, Biomes.FOREST)); + public void kill() { + health = 0; + isAlive = false; } - public Monster(double health, double level, double energy, Position position, List habitat) { - super(health, level, energy, position); - this.habitat.addAll(habitat); + public int getHealth() { + return health; } - //Är detta bra??? Med unmodifiableList dvs - public List getHabitat() { - return Collections.unmodifiableList(habitat); + public int getEnergy() { + return energy; } + + public Position getPosition() { + return position; + } + + abstract void heal(); + + abstract void takeDamage(); + + abstract void recharge(); + + abstract void move(); + + abstract void moveTo(Position position); + } diff --git a/src/main/java/Shade.java b/src/main/java/Shade.java new file mode 100644 index 0000000..bf2ba33 --- /dev/null +++ b/src/main/java/Shade.java @@ -0,0 +1,12 @@ +import Entity.Position; +import java.util.*; + +public class Shade extends Monster { + public static final int MAX_HEALTH = 20; + public static final int MAX_ENERGY = 14; + public static final List habitat = Collections.unmodifiableList(Arrays.asList(Biomes.COAST, Biomes.FOREST, Biomes.GRASSLAND, Biomes.MOUNTAIN)); + + public Shade() { + + } +} diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index abb6e21..f5d1392 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -1,3 +1,4 @@ +import Entity.Position; import org.junit.jupiter.api.*; import static org.hamcrest.MatcherAssert.*; import static org.hamcrest.Matchers.*; @@ -16,8 +17,8 @@ public class MonsterTest { @Test void monster_cannot_act_after_death() { - defaultShade.setHealth(0); - assertThat(false, anyOf(defaultShade.moveTo(0, 1), defaultShade.attack(Attacks.CHILL, defaultPlayer))); + defaultShade.kill(); + assertThat(false, anyOf(defaultShade.moveTo(new Position(0, 1)), defaultShade.attack(Attacks.CHILL, defaultPlayer))); } @Test @@ -28,8 +29,8 @@ public class MonsterTest { @Test void monster_cannot_regain_health_after_death() { - defaultShade.setHealth(0); - defaultShade.setHealth(10d); + defaultShade.kill(); + defaultShade.setHealth(10); assertThat(defaultShade.getHealth(), equalTo(0)); } } -- 2.39.5 From b633427e8eda712073712b14e32ec0bf3b5e3730 Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Mon, 27 Oct 2025 17:49:36 +0100 Subject: [PATCH 08/31] =?UTF-8?q?Tv=C3=A5=20nedre=20testerna=20g=C3=A5r=20?= =?UTF-8?q?igenom?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- src/main/java/Attack.java | 24 ------------ src/main/java/Character.java | 68 ---------------------------------- src/main/java/Monster.java | 12 ++++-- src/main/java/Shade.java | 29 ++++++++++++++- src/test/java/MonsterTest.java | 21 +++++++---- 6 files changed, 50 insertions(+), 106 deletions(-) delete mode 100644 src/main/java/Attack.java delete mode 100644 src/main/java/Character.java diff --git a/pom.xml b/pom.xml index a427f23..4954a6f 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ org.mockito mockito-core - 5.12.0 + 5.20.0 test diff --git a/src/main/java/Attack.java b/src/main/java/Attack.java deleted file mode 100644 index 1b4a263..0000000 --- a/src/main/java/Attack.java +++ /dev/null @@ -1,24 +0,0 @@ -public abstract class Attack { - //Namnet och bägge dessa siffror är helt lösryckta - private static final String DEFAULT_NAME = "DEFAULT_NAME"; - private static final double DEFAULT_ENERGY_COST = 5d; - private static final double DEFAULT_DAMAGE = 5d; - - private String name; - private double energyCost; - private double damage; - - public Attack() { - name = DEFAULT_NAME; - energyCost = DEFAULT_ENERGY_COST; - damage = DEFAULT_DAMAGE; - } - - public Attack(String name, double energyCost, double damage) { - this.name = name; - this.energyCost = energyCost; - this.damage = damage; - } - - public abstract boolean perform(Character target); -} diff --git a/src/main/java/Character.java b/src/main/java/Character.java deleted file mode 100644 index 0927cb2..0000000 --- a/src/main/java/Character.java +++ /dev/null @@ -1,68 +0,0 @@ -import Entity.Position; - -public abstract class Character { - private static final double DEFAULT_HEALTH = 50d; - private static final double DEFAULT_ENERGY = 20d; - private static final Position DEFAULT_POSITION = new Position(0,0); - - private double health; - private double energy; //Borde kanske beräknas genom en algoritm istället för att kunna sättas i konstruktorn... Så det alltid blir balanserat - private Position position; - - // Hur många varianter på konstruktorn behövs? - public Character() { - this.health = DEFAULT_HEALTH; - this.energy = DEFAULT_ENERGY; - this.position = DEFAULT_POSITION; - } - - // Jag antar att den som instansierar massa monster i världen ansvarar - // för att kolla att "position" har ett tillåtet värde. - // Just denna variant är bara för testning i min implementation av Monster - public Character(Position position) { - this.health = DEFAULT_HEALTH; - this.energy = DEFAULT_ENERGY; - this.position = position; - } - - public Character(double health, double energy, Position position) { - this.health = health; - this.energy = energy; - this.position = position; - } - - //Returnerar true om attacken gick igenom, annars false - abstract boolean attack(Character character); - - public double getHealth() { - return health; - } - - public void setHealth(int newHealth) { - health = newHealth; - } - - public double getLevel() { - return level; - } - - public void setLevel(int newLevel) { - level = newLevel; - } - - public double getEnergy() { - return energy; - } - - public void setEnergy(double newEnergy) { - energy = newEnergy; - } - - public Position getPosition() { - return position; - } - - public void setPosition(Position newPosition) { - position = newPosition; - } -} diff --git a/src/main/java/Monster.java b/src/main/java/Monster.java index d62f10d..dfeebb5 100644 --- a/src/main/java/Monster.java +++ b/src/main/java/Monster.java @@ -4,10 +4,10 @@ import java.util.*; public abstract class Monster { public static final Position DEFAULT_POSITION = new Position(0,0); - private int health; - private int energy; //Borde kanske beräknas genom en algoritm istället för att kunna sättas i konstruktorn... Så det alltid blir balanserat - private Position position; - private boolean isAlive; + protected int health; + protected int energy; //Borde kanske beräknas genom en algoritm istället för att kunna sättas i konstruktorn... Så det alltid blir balanserat + protected Position position; + protected boolean isAlive; public Monster(int health, int energy, Position position) { this.health = health; @@ -34,6 +34,10 @@ public abstract class Monster { return position; } + public boolean isAlive() { + return isAlive; + } + abstract void heal(); abstract void takeDamage(); diff --git a/src/main/java/Shade.java b/src/main/java/Shade.java index bf2ba33..4033aa0 100644 --- a/src/main/java/Shade.java +++ b/src/main/java/Shade.java @@ -2,11 +2,36 @@ import Entity.Position; import java.util.*; public class Shade extends Monster { - public static final int MAX_HEALTH = 20; - public static final int MAX_ENERGY = 14; public static final List habitat = Collections.unmodifiableList(Arrays.asList(Biomes.COAST, Biomes.FOREST, Biomes.GRASSLAND, Biomes.MOUNTAIN)); + private static final int MAX_HEALTH = 20; + private static final int MAX_ENERGY = 14; + + + public Shade() { + super(MAX_HEALTH, MAX_ENERGY, Monster.DEFAULT_POSITION); + } + + public void heal() { + if (isAlive()) { + health += 2; + } + } + + public void takeDamage() { + + } + + public void recharge() { + + } + + public void move() { + + } + + public void moveTo(Position position) { } } diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index f5d1392..e1df421 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -1,9 +1,16 @@ -import Entity.Position; +import Action.*; +import Character.*; +import Combat.*; +import Entity.*; +import Inventory.*; +import Job.*; +import Shared.*; + import org.junit.jupiter.api.*; import static org.hamcrest.MatcherAssert.*; import static org.hamcrest.Matchers.*; import static org.mockito.Mockito.mock; -import Entity.Player; + public class MonsterTest { @@ -15,22 +22,22 @@ public class MonsterTest { defaultShade = new Shade(); //Återställer alla värden till default } - @Test + /*@Test void monster_cannot_act_after_death() { defaultShade.kill(); assertThat(false, anyOf(defaultShade.moveTo(new Position(0, 1)), defaultShade.attack(Attacks.CHILL, defaultPlayer))); - } + }*/ @Test void reaching_zero_health_triggers_death() { - defaultShade.setHealth(0); - assertThat(true, is(defaultShade.isAlive())); + defaultShade.kill(); + assertThat(false, equalTo(defaultShade.isAlive())); } @Test void monster_cannot_regain_health_after_death() { defaultShade.kill(); - defaultShade.setHealth(10); + defaultShade.heal(); assertThat(defaultShade.getHealth(), equalTo(0)); } } -- 2.39.5 From 556dcf4160371e230be868fb7b0098ef19c96330 Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Mon, 27 Oct 2025 22:43:54 +0100 Subject: [PATCH 09/31] =?UTF-8?q?Har=20lagt=20till=20Exceptions,=20kan=20v?= =?UTF-8?q?ara=20ett=20misstag...=20Tre=20nya=20klasser=20som=20f=C3=B6rs?= =?UTF-8?q?=C3=B6ker=20modellera=20n=C3=A5gon=20typ=20av=20handling=20p?= =?UTF-8?q?=C3=A5=20olika=20s=C3=A4tt,=20dom=20kommer=20inte=20=C3=B6verle?= =?UTF-8?q?va=20l=C3=A4nge.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 3 ++- src/main/java/Action.java | 11 +++++++++++ src/main/java/Actions.java | 9 +++++++++ src/main/java/Healing.java | 8 ++++++++ src/main/java/Monster.java | 3 ++- src/main/java/Shade.java | 34 +++++++++++++++++++++++++++------- src/test/java/MonsterTest.java | 6 +++--- 7 files changed, 62 insertions(+), 12 deletions(-) create mode 100644 src/main/java/Action.java create mode 100644 src/main/java/Actions.java create mode 100644 src/main/java/Healing.java diff --git a/pom.xml b/pom.xml index 4954a6f..f3d4870 100644 --- a/pom.xml +++ b/pom.xml @@ -13,6 +13,7 @@ 23 UTF-8 + org.junit.jupiter @@ -33,5 +34,5 @@ test + - \ No newline at end of file diff --git a/src/main/java/Action.java b/src/main/java/Action.java new file mode 100644 index 0000000..669c418 --- /dev/null +++ b/src/main/java/Action.java @@ -0,0 +1,11 @@ +public abstract class Action { + private int cost; + + public Action(int cost) { + + } + + public int getCost() { + return cost; + } +} diff --git a/src/main/java/Actions.java b/src/main/java/Actions.java new file mode 100644 index 0000000..fe79c49 --- /dev/null +++ b/src/main/java/Actions.java @@ -0,0 +1,9 @@ +public enum Actions { + HEAL(2); + + private final int cost; + + Actions(int cost) { + this.cost = cost; + } +} diff --git a/src/main/java/Healing.java b/src/main/java/Healing.java new file mode 100644 index 0000000..eeafe15 --- /dev/null +++ b/src/main/java/Healing.java @@ -0,0 +1,8 @@ +public class Healing extends Action { + private int healthRegenerated; + + public Healing() { + super(2); + + } +} diff --git a/src/main/java/Monster.java b/src/main/java/Monster.java index dfeebb5..926ed03 100644 --- a/src/main/java/Monster.java +++ b/src/main/java/Monster.java @@ -19,6 +19,7 @@ public abstract class Monster { public void kill() { health = 0; + energy = 0; isAlive = false; } @@ -40,7 +41,7 @@ public abstract class Monster { abstract void heal(); - abstract void takeDamage(); + abstract void takeDamage(int amount); abstract void recharge(); diff --git a/src/main/java/Shade.java b/src/main/java/Shade.java index 4033aa0..b6c7bf1 100644 --- a/src/main/java/Shade.java +++ b/src/main/java/Shade.java @@ -3,24 +3,38 @@ import java.util.*; public class Shade extends Monster { public static final List habitat = Collections.unmodifiableList(Arrays.asList(Biomes.COAST, Biomes.FOREST, Biomes.GRASSLAND, Biomes.MOUNTAIN)); + public static final int MAX_HEALTH = 20; + public static final int MAX_ENERGY = 14; - private static final int MAX_HEALTH = 20; - private static final int MAX_ENERGY = 14; - - + private static final int HEALTH_PER_HEAL = 2; + private static final int ENERGY_COST_PER_HEAL = 1; public Shade() { super(MAX_HEALTH, MAX_ENERGY, Monster.DEFAULT_POSITION); } public void heal() { - if (isAlive()) { - health += 2; + if (!isAlive) { + throw new IllegalStateException("This shade is dead"); + } + if (health < MAX_HEALTH) { + health += HEALTH_PER_HEAL; + energy -= ENERGY_COST_PER_HEAL; + enforceHealthMaximum(); } } - public void takeDamage() { + public void takeDamage(int amount) { + if (amount < 0) { + throw new IllegalArgumentException("'amount' must be a positive integer"); + } + if (health - amount <= 0) { + kill(); + } + else { + health =- amount; + } } public void recharge() { @@ -34,4 +48,10 @@ public class Shade extends Monster { public void moveTo(Position position) { } + + private void enforceHealthMaximum() { + if (health > MAX_HEALTH) { + health = MAX_HEALTH; + } + } } diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index e1df421..2fe10fb 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -9,6 +9,7 @@ import Shared.*; import org.junit.jupiter.api.*; import static org.hamcrest.MatcherAssert.*; import static org.hamcrest.Matchers.*; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; @@ -30,14 +31,13 @@ public class MonsterTest { @Test void reaching_zero_health_triggers_death() { - defaultShade.kill(); + defaultShade.takeDamage(Shade.MAX_HEALTH); assertThat(false, equalTo(defaultShade.isAlive())); } @Test void monster_cannot_regain_health_after_death() { defaultShade.kill(); - defaultShade.heal(); - assertThat(defaultShade.getHealth(), equalTo(0)); + assertThrows(IllegalStateException.class, () -> defaultShade.heal()); } } -- 2.39.5 From 7d67c7db649ad758d1d115d1639a7e58eff58ffb Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Mon, 27 Oct 2025 23:10:50 +0100 Subject: [PATCH 10/31] =?UTF-8?q?monster=5Fcannot=5Fact=5Fafter=5Fdeath()?= =?UTF-8?q?=20g=C3=A5r=20igenom?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Attacks.java | 11 +++++++++++ src/main/java/CanMove.java | 8 ++++++++ src/main/java/Monster.java | 15 +++++++-------- src/main/java/MovementPatterns.java | 9 +++++++++ src/main/java/Shade.java | 22 +++++++++++++++------- src/test/java/MonsterTest.java | 8 ++++---- 6 files changed, 54 insertions(+), 19 deletions(-) create mode 100644 src/main/java/Attacks.java create mode 100644 src/main/java/CanMove.java create mode 100644 src/main/java/MovementPatterns.java diff --git a/src/main/java/Attacks.java b/src/main/java/Attacks.java new file mode 100644 index 0000000..68af640 --- /dev/null +++ b/src/main/java/Attacks.java @@ -0,0 +1,11 @@ +public enum Attacks { + CHILL(3, 2); + + private int damage; + private int cost; + + Attacks(int damage, int cost) { + this.damage = damage; + this.cost = cost; + } +} diff --git a/src/main/java/CanMove.java b/src/main/java/CanMove.java new file mode 100644 index 0000000..ec5139a --- /dev/null +++ b/src/main/java/CanMove.java @@ -0,0 +1,8 @@ +import Entity.Position; +//Är detta ett ok namn? +public interface CanMove { + + abstract boolean move(); + + abstract boolean moveTo(Position position); +} diff --git a/src/main/java/Monster.java b/src/main/java/Monster.java index 926ed03..80e3769 100644 --- a/src/main/java/Monster.java +++ b/src/main/java/Monster.java @@ -1,7 +1,6 @@ -import Entity.Position; -import java.util.*; +import Entity.*; -public abstract class Monster { +public abstract class Monster implements CanMove { public static final Position DEFAULT_POSITION = new Position(0,0); protected int health; @@ -39,14 +38,14 @@ public abstract class Monster { return isAlive; } + public boolean isDead() { + return !isAlive; + } + abstract void heal(); abstract void takeDamage(int amount); - abstract void recharge(); - - abstract void move(); - - abstract void moveTo(Position position); + abstract boolean performAttack(Attacks attack, Player player); } diff --git a/src/main/java/MovementPatterns.java b/src/main/java/MovementPatterns.java new file mode 100644 index 0000000..3db6174 --- /dev/null +++ b/src/main/java/MovementPatterns.java @@ -0,0 +1,9 @@ +public enum MovementPatterns { + ONE_STEP_DIAGONALLY(1); + + private int cost; + + MovementPatterns(int cost) { + this.cost = cost; + } +} diff --git a/src/main/java/Shade.java b/src/main/java/Shade.java index b6c7bf1..a731764 100644 --- a/src/main/java/Shade.java +++ b/src/main/java/Shade.java @@ -1,7 +1,8 @@ +import Entity.Player; import Entity.Position; import java.util.*; -public class Shade extends Monster { +public class Shade extends Monster implements CanMove { public static final List habitat = Collections.unmodifiableList(Arrays.asList(Biomes.COAST, Biomes.FOREST, Biomes.GRASSLAND, Biomes.MOUNTAIN)); public static final int MAX_HEALTH = 20; public static final int MAX_ENERGY = 14; @@ -14,7 +15,7 @@ public class Shade extends Monster { } public void heal() { - if (!isAlive) { + if (isDead()) { throw new IllegalStateException("This shade is dead"); } if (health < MAX_HEALTH) { @@ -28,7 +29,6 @@ public class Shade extends Monster { if (amount < 0) { throw new IllegalArgumentException("'amount' must be a positive integer"); } - if (health - amount <= 0) { kill(); } @@ -37,16 +37,24 @@ public class Shade extends Monster { } } - public void recharge() { + public boolean performAttack(Attacks attack, Player player) { + if (isDead()) { + return false; + } + return true; } - public void move() { - + public boolean move() { + return false; } - public void moveTo(Position position) { + public boolean moveTo(Position position) { + if (isDead()) { + return false; + } + return true; } private void enforceHealthMaximum() { diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index 2fe10fb..1199f5d 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -23,11 +23,11 @@ public class MonsterTest { defaultShade = new Shade(); //Återställer alla värden till default } - /*@Test + @Test void monster_cannot_act_after_death() { defaultShade.kill(); - assertThat(false, anyOf(defaultShade.moveTo(new Position(0, 1)), defaultShade.attack(Attacks.CHILL, defaultPlayer))); - }*/ + assertThat(false, anyOf(is(defaultShade.moveTo(new Position(0, 1))), is(defaultShade.performAttack(Attacks.CHILL, defaultPlayer)))); + } @Test void reaching_zero_health_triggers_death() { @@ -36,7 +36,7 @@ public class MonsterTest { } @Test - void monster_cannot_regain_health_after_death() { + void monster_cannot_heal_after_death() { defaultShade.kill(); assertThrows(IllegalStateException.class, () -> defaultShade.heal()); } -- 2.39.5 From d06e3fcc8d99a7021bc67415ef534226e03788e2 Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Mon, 27 Oct 2025 23:48:36 +0100 Subject: [PATCH 11/31] =?UTF-8?q?F=C3=B6rs=C3=B6ker=20skapa=20n=C3=A5got?= =?UTF-8?q?=20sorts=20Action-interface,=20g=C3=A5r=20s=C3=A5d=C3=A4r=20och?= =?UTF-8?q?=20k=C3=A4nner=20att=20jag=20kanske=20borde=20strunta=20i=20det?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Action.java | 8 +++++--- src/main/java/Actions.java | 9 --------- src/main/java/AttackAction.java | 2 ++ src/main/java/CanAttack.java | 5 +++++ src/main/java/HealAction.java | 18 ++++++++++++++++++ src/main/java/Healing.java | 8 -------- src/main/java/Monster.java | 2 -- src/main/java/Shade.java | 2 +- src/test/java/MonsterTest.java | 3 ++- 9 files changed, 33 insertions(+), 24 deletions(-) delete mode 100644 src/main/java/Actions.java create mode 100644 src/main/java/AttackAction.java create mode 100644 src/main/java/CanAttack.java create mode 100644 src/main/java/HealAction.java delete mode 100644 src/main/java/Healing.java diff --git a/src/main/java/Action.java b/src/main/java/Action.java index 669c418..7f2e999 100644 --- a/src/main/java/Action.java +++ b/src/main/java/Action.java @@ -1,11 +1,13 @@ public abstract class Action { - private int cost; - - public Action(int cost) { + private final int cost; + Action(int cost) { + this.cost = cost; } public int getCost() { return cost; } + + abstract boolean performAction(); } diff --git a/src/main/java/Actions.java b/src/main/java/Actions.java deleted file mode 100644 index fe79c49..0000000 --- a/src/main/java/Actions.java +++ /dev/null @@ -1,9 +0,0 @@ -public enum Actions { - HEAL(2); - - private final int cost; - - Actions(int cost) { - this.cost = cost; - } -} diff --git a/src/main/java/AttackAction.java b/src/main/java/AttackAction.java new file mode 100644 index 0000000..9af9bf3 --- /dev/null +++ b/src/main/java/AttackAction.java @@ -0,0 +1,2 @@ +public class AttackAction extends Action { +} diff --git a/src/main/java/CanAttack.java b/src/main/java/CanAttack.java new file mode 100644 index 0000000..f77f37b --- /dev/null +++ b/src/main/java/CanAttack.java @@ -0,0 +1,5 @@ +import Entity.Player; + +public interface CanAttack { + abstract boolean performAttack(Attacks attack, Player player); +} diff --git a/src/main/java/HealAction.java b/src/main/java/HealAction.java new file mode 100644 index 0000000..e7fb19b --- /dev/null +++ b/src/main/java/HealAction.java @@ -0,0 +1,18 @@ +public class HealAction extends Action { + private static final int DEFAULT_HEALTH_RECHARGE = 5; + + private int healthGain; + + public HealAction(int cost, int healthGain) { + super(cost); + this.healthGain = healthGain; + } + + public int getHealthGain() { + return healthGain; + } + + public boolean performAction(Monster monster) { + + } +} diff --git a/src/main/java/Healing.java b/src/main/java/Healing.java deleted file mode 100644 index eeafe15..0000000 --- a/src/main/java/Healing.java +++ /dev/null @@ -1,8 +0,0 @@ -public class Healing extends Action { - private int healthRegenerated; - - public Healing() { - super(2); - - } -} diff --git a/src/main/java/Monster.java b/src/main/java/Monster.java index 80e3769..0c27e77 100644 --- a/src/main/java/Monster.java +++ b/src/main/java/Monster.java @@ -46,6 +46,4 @@ public abstract class Monster implements CanMove { abstract void takeDamage(int amount); - abstract boolean performAttack(Attacks attack, Player player); - } diff --git a/src/main/java/Shade.java b/src/main/java/Shade.java index a731764..bc15d95 100644 --- a/src/main/java/Shade.java +++ b/src/main/java/Shade.java @@ -2,7 +2,7 @@ import Entity.Player; import Entity.Position; import java.util.*; -public class Shade extends Monster implements CanMove { +public class Shade extends Monster implements CanMove, CanAttack { public static final List habitat = Collections.unmodifiableList(Arrays.asList(Biomes.COAST, Biomes.FOREST, Biomes.GRASSLAND, Biomes.MOUNTAIN)); public static final int MAX_HEALTH = 20; public static final int MAX_ENERGY = 14; diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index 1199f5d..ce5f409 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -26,7 +26,8 @@ public class MonsterTest { @Test void monster_cannot_act_after_death() { defaultShade.kill(); - assertThat(false, anyOf(is(defaultShade.moveTo(new Position(0, 1))), is(defaultShade.performAttack(Attacks.CHILL, defaultPlayer)))); + assertThat(false, anyOf(is(defaultShade.moveTo(new Position(0, 1))), + is(defaultShade.performAttack(Attacks.CHILL, defaultPlayer)))); } @Test -- 2.39.5 From e4a90efa0853283b73cfa70ac9cd4c117e540644 Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Tue, 28 Oct 2025 00:14:29 +0100 Subject: [PATCH 12/31] Skrivit testet 'method_move_places_monster_in_legal_position()' --- src/main/java/Action.java | 13 ------------- src/main/java/AttackAction.java | 2 -- src/main/java/HealAction.java | 18 ------------------ src/main/java/MovementPatterns.java | 11 +++++++++++ src/test/java/MonsterTest.java | 29 ++++++++++++++++++++++++++--- 5 files changed, 37 insertions(+), 36 deletions(-) delete mode 100644 src/main/java/Action.java delete mode 100644 src/main/java/AttackAction.java delete mode 100644 src/main/java/HealAction.java diff --git a/src/main/java/Action.java b/src/main/java/Action.java deleted file mode 100644 index 7f2e999..0000000 --- a/src/main/java/Action.java +++ /dev/null @@ -1,13 +0,0 @@ -public abstract class Action { - private final int cost; - - Action(int cost) { - this.cost = cost; - } - - public int getCost() { - return cost; - } - - abstract boolean performAction(); -} diff --git a/src/main/java/AttackAction.java b/src/main/java/AttackAction.java deleted file mode 100644 index 9af9bf3..0000000 --- a/src/main/java/AttackAction.java +++ /dev/null @@ -1,2 +0,0 @@ -public class AttackAction extends Action { -} diff --git a/src/main/java/HealAction.java b/src/main/java/HealAction.java deleted file mode 100644 index e7fb19b..0000000 --- a/src/main/java/HealAction.java +++ /dev/null @@ -1,18 +0,0 @@ -public class HealAction extends Action { - private static final int DEFAULT_HEALTH_RECHARGE = 5; - - private int healthGain; - - public HealAction(int cost, int healthGain) { - super(cost); - this.healthGain = healthGain; - } - - public int getHealthGain() { - return healthGain; - } - - public boolean performAction(Monster monster) { - - } -} diff --git a/src/main/java/MovementPatterns.java b/src/main/java/MovementPatterns.java index 3db6174..32e057b 100644 --- a/src/main/java/MovementPatterns.java +++ b/src/main/java/MovementPatterns.java @@ -1,3 +1,6 @@ +import Entity.Position; +import java.util.*; + public enum MovementPatterns { ONE_STEP_DIAGONALLY(1); @@ -6,4 +9,12 @@ public enum MovementPatterns { MovementPatterns(int cost) { this.cost = cost; } + + public List getLegalDestinations(Position position) { + List legalDestinations = new ArrayList<>(); + + switch { + case + } + } } diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index ce5f409..9b1489b 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -7,6 +7,9 @@ import Job.*; import Shared.*; import org.junit.jupiter.api.*; + +import java.util.*; + import static org.hamcrest.MatcherAssert.*; import static org.hamcrest.Matchers.*; import static org.junit.jupiter.api.Assertions.*; @@ -24,10 +27,15 @@ public class MonsterTest { } @Test - void monster_cannot_act_after_death() { + void monster_cannot_move_after_death() { defaultShade.kill(); - assertThat(false, anyOf(is(defaultShade.moveTo(new Position(0, 1))), - is(defaultShade.performAttack(Attacks.CHILL, defaultPlayer)))); + assertThat(false, equalTo(defaultShade.moveTo(new Position(0, 1)))); + } + + @Test + void monster_cannot_attack_after_death() { + defaultShade.kill(); + assertThat(false, equalTo(defaultShade.performAttack(Attacks.CHILL, defaultPlayer))); } @Test @@ -41,4 +49,19 @@ public class MonsterTest { defaultShade.kill(); assertThrows(IllegalStateException.class, () -> defaultShade.heal()); } + + @Test + void method_move_places_monster_in_legal_position() { + Position startingPosition = defaultShade.getPosition(); + List legalDestinations = new ArrayList<>(); + List moves = defaultShade.MOVES; + + for (MovementPatterns move : moves) { + legalDestinations.addAll(move.getLegalDestinations(startingPosition)); + } + + defaultShade.move(); + + assertThat(legalDestinations, hasItem(defaultShade.getPosition())); + } } -- 2.39.5 From 6f94d1510c164bd66a15caf115e58e51776ca6df Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Tue, 28 Oct 2025 01:02:31 +0100 Subject: [PATCH 13/31] =?UTF-8?q?'method=5Fmove=5Fplaces=5Fmonster=5Fin=5F?= =?UTF-8?q?legal=5Fposition()'=20g=C3=A5r=20igenom=20skrivit=20namnet=20p?= =?UTF-8?q?=C3=A5=20n=C3=A4sta=20test=20'monster=5Fcannot=5Fdo=5Fanything?= =?UTF-8?q?=5Fwhen=5Fout=5Fof=5Fenergy()'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/MovementPatterns.java | 21 +++++++++++++++------ src/main/java/Shade.java | 22 ++++++++++++++++++++-- src/test/java/MonsterTest.java | 9 +++++++-- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/main/java/MovementPatterns.java b/src/main/java/MovementPatterns.java index 32e057b..571c94a 100644 --- a/src/main/java/MovementPatterns.java +++ b/src/main/java/MovementPatterns.java @@ -2,19 +2,28 @@ import Entity.Position; import java.util.*; public enum MovementPatterns { - ONE_STEP_DIAGONALLY(1); + ONE_DIAGONAL_STEP(1, 1); - private int cost; + public int cost; + private int id; - MovementPatterns(int cost) { + MovementPatterns(int cost, int id) { this.cost = cost; + this.id = id; } - public List getLegalDestinations(Position position) { + public List findLegalDestinations(Position position) { List legalDestinations = new ArrayList<>(); - switch { - case + switch(id) { + case 1: + int x = position.x(); + int y = position.y(); + legalDestinations.addAll(Arrays.asList(new Position(x - 1, y + 1), new Position(x + 1, y + 1), + new Position(x - 1, y - 1), new Position(x + 1, y - 1))); + break; } + + return legalDestinations; } } diff --git a/src/main/java/Shade.java b/src/main/java/Shade.java index bc15d95..ff186de 100644 --- a/src/main/java/Shade.java +++ b/src/main/java/Shade.java @@ -3,15 +3,20 @@ import Entity.Position; import java.util.*; public class Shade extends Monster implements CanMove, CanAttack { - public static final List habitat = Collections.unmodifiableList(Arrays.asList(Biomes.COAST, Biomes.FOREST, Biomes.GRASSLAND, Biomes.MOUNTAIN)); + public static final List HABITAT = Collections.unmodifiableList(Arrays.asList(Biomes.COAST, Biomes.FOREST, Biomes.GRASSLAND, Biomes.MOUNTAIN)); + public static final List MOVES = Collections.unmodifiableList(Arrays.asList(MovementPatterns.ONE_DIAGONAL_STEP)); public static final int MAX_HEALTH = 20; public static final int MAX_ENERGY = 14; private static final int HEALTH_PER_HEAL = 2; private static final int ENERGY_COST_PER_HEAL = 1; + private Random random = new Random(); + private List validDestinations = new ArrayList<>(); + public Shade() { super(MAX_HEALTH, MAX_ENERGY, Monster.DEFAULT_POSITION); + updateDestinations(position); } public void heal() { @@ -46,7 +51,13 @@ public class Shade extends Monster implements CanMove, CanAttack { } public boolean move() { - return false; + if (isDead()) { + return false; + } + position = validDestinations.get(random.nextInt(validDestinations.size())); + updateDestinations(position); + + return true; } public boolean moveTo(Position position) { @@ -62,4 +73,11 @@ public class Shade extends Monster implements CanMove, CanAttack { health = MAX_HEALTH; } } + + private void updateDestinations(Position position) { + validDestinations.clear(); + for (MovementPatterns move : MOVES) { + validDestinations.addAll(move.findLegalDestinations(position)); + } + } } diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index 9b1489b..2285fcb 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -50,6 +50,7 @@ public class MonsterTest { assertThrows(IllegalStateException.class, () -> defaultShade.heal()); } + //Är denna för lång? @Test void method_move_places_monster_in_legal_position() { Position startingPosition = defaultShade.getPosition(); @@ -57,11 +58,15 @@ public class MonsterTest { List moves = defaultShade.MOVES; for (MovementPatterns move : moves) { - legalDestinations.addAll(move.getLegalDestinations(startingPosition)); + legalDestinations.addAll(move.findLegalDestinations(startingPosition)); } defaultShade.move(); - assertThat(legalDestinations, hasItem(defaultShade.getPosition())); } + + @Test + void monster_cannot_do_anything_when_out_of_energy() { + + } } -- 2.39.5 From af4a7d422d6a7a942cd2ab7629cda1bad5c50ce0 Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Tue, 28 Oct 2025 01:20:25 +0100 Subject: [PATCH 14/31] =?UTF-8?q?skrivit=20fler=20testmetodnamn=20samt=20n?= =?UTF-8?q?amngett=20tv=C3=A5=20nya=20monsterklasser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Bäckahäst.java | 2 ++ src/main/java/Troll.java | 2 ++ src/test/java/MonsterTest.java | 15 +++++++++++++++ 3 files changed, 19 insertions(+) create mode 100644 src/main/java/Bäckahäst.java create mode 100644 src/main/java/Troll.java diff --git a/src/main/java/Bäckahäst.java b/src/main/java/Bäckahäst.java new file mode 100644 index 0000000..ea1294d --- /dev/null +++ b/src/main/java/Bäckahäst.java @@ -0,0 +1,2 @@ +public class Bäckahäst extends Monster implements CanMove, CanAttack { +} diff --git a/src/main/java/Troll.java b/src/main/java/Troll.java new file mode 100644 index 0000000..2272aa9 --- /dev/null +++ b/src/main/java/Troll.java @@ -0,0 +1,2 @@ +public class Troll extends Monster implements CanMove, CanAttack { +} diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index 2285fcb..9c25ca5 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -69,4 +69,19 @@ public class MonsterTest { void monster_cannot_do_anything_when_out_of_energy() { } + + @Test + void only_moves_within_energy_budget_are_performed() { + + } + + @Test + void move_to_invalid_destination_is_rejected() { + + } + + @Test + void use_of_attack_not_in_arsenal_is_rejected() { + + } } -- 2.39.5 From 1dbfdb9e9f695162f342567e50d283b44085f8b0 Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Tue, 28 Oct 2025 01:39:54 +0100 Subject: [PATCH 15/31] =?UTF-8?q?Skrivit=20koden=20f=C3=B6r=20'void=20shad?= =?UTF-8?q?e=5Fwont=5Fmove=5Fto=5Fsame=5Fposition=5Fas=5Fplayer()'=20samt?= =?UTF-8?q?=20gjort=20tillf=C3=A4lliga=20=C3=A4ndringar=20i=20'Troll'=20oc?= =?UTF-8?q?h=20'Nixie'=20f=C3=B6r=20att=20f=C3=A5=20koden=20att=20kompiler?= =?UTF-8?q?a?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Bäckahäst.java | 2 -- src/main/java/Nixie.java | 6 ++++++ src/main/java/Troll.java | 6 +++++- src/test/java/MonsterTest.java | 9 ++++++++- 4 files changed, 19 insertions(+), 4 deletions(-) delete mode 100644 src/main/java/Bäckahäst.java create mode 100644 src/main/java/Nixie.java diff --git a/src/main/java/Bäckahäst.java b/src/main/java/Bäckahäst.java deleted file mode 100644 index ea1294d..0000000 --- a/src/main/java/Bäckahäst.java +++ /dev/null @@ -1,2 +0,0 @@ -public class Bäckahäst extends Monster implements CanMove, CanAttack { -} diff --git a/src/main/java/Nixie.java b/src/main/java/Nixie.java new file mode 100644 index 0000000..e6af177 --- /dev/null +++ b/src/main/java/Nixie.java @@ -0,0 +1,6 @@ +public abstract class Nixie extends Monster implements CanMove, CanAttack { + + public Nixie() { + super(0,0,Monster.DEFAULT_POSITION); + } +} diff --git a/src/main/java/Troll.java b/src/main/java/Troll.java index 2272aa9..4404bf1 100644 --- a/src/main/java/Troll.java +++ b/src/main/java/Troll.java @@ -1,2 +1,6 @@ -public class Troll extends Monster implements CanMove, CanAttack { +public abstract class Troll extends Monster implements CanMove, CanAttack { + + public Troll() { + super(0,0,Monster.DEFAULT_POSITION); + } } diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index 9c25ca5..3d64e2c 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -13,7 +13,7 @@ import java.util.*; import static org.hamcrest.MatcherAssert.*; import static org.hamcrest.Matchers.*; import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.*; public class MonsterTest { @@ -65,6 +65,13 @@ public class MonsterTest { assertThat(legalDestinations, hasItem(defaultShade.getPosition())); } + @Test + void shade_wont_move_to_same_position_as_player() { + Position destination = new Position(1, 1); + when(defaultPlayer.getPosition()).thenReturn(destination); + assertThat(defaultShade.moveTo(destination), equalTo(false)); + } + @Test void monster_cannot_do_anything_when_out_of_energy() { -- 2.39.5 From 16ad80aed2295dda502743ceb258e81d4249d8d8 Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Tue, 28 Oct 2025 01:39:54 +0100 Subject: [PATCH 16/31] =?UTF-8?q?Skrivit=20koden=20f=C3=B6r=20'void=20shad?= =?UTF-8?q?e=5Fwont=5Fmove=5Fto=5Fsame=5Fposition=5Fas=5Fplayer()'=20samt?= =?UTF-8?q?=20gjort=20tillf=C3=A4lliga=20=C3=A4ndringar=20i=20'Troll'=20oc?= =?UTF-8?q?h=20'Nixie'=20f=C3=B6r=20att=20f=C3=A5=20koden=20att=20kompiler?= =?UTF-8?q?a.=20Skapat=20ett=20eget=20paket=20'Monster'=20dit=20jag=20flyt?= =?UTF-8?q?tat=20allt.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Bäckahäst.java | 2 -- src/main/java/{ => Monster}/Attacks.java | 2 ++ src/main/java/{ => Monster}/Biomes.java | 2 ++ src/main/java/{ => Monster}/CanAttack.java | 2 ++ src/main/java/{ => Monster}/CanMove.java | 2 ++ src/main/java/{ => Monster}/Monster.java | 2 ++ .../java/{ => Monster}/MovementPatterns.java | 2 ++ src/main/java/Monster/Nixie.java | 8 ++++++++ src/main/java/{ => Monster}/Shade.java | 2 ++ src/main/java/Monster/Troll.java | 8 ++++++++ src/main/java/Troll.java | 2 -- src/test/java/MonsterTest.java | 18 +++++++++++------- 12 files changed, 41 insertions(+), 11 deletions(-) delete mode 100644 src/main/java/Bäckahäst.java rename src/main/java/{ => Monster}/Attacks.java (91%) rename src/main/java/{ => Monster}/Biomes.java (82%) rename src/main/java/{ => Monster}/CanAttack.java (87%) rename src/main/java/{ => Monster}/CanMove.java (89%) rename src/main/java/{ => Monster}/Monster.java (98%) rename src/main/java/{ => Monster}/MovementPatterns.java (97%) create mode 100644 src/main/java/Monster/Nixie.java rename src/main/java/{ => Monster}/Shade.java (99%) create mode 100644 src/main/java/Monster/Troll.java delete mode 100644 src/main/java/Troll.java diff --git a/src/main/java/Bäckahäst.java b/src/main/java/Bäckahäst.java deleted file mode 100644 index ea1294d..0000000 --- a/src/main/java/Bäckahäst.java +++ /dev/null @@ -1,2 +0,0 @@ -public class Bäckahäst extends Monster implements CanMove, CanAttack { -} diff --git a/src/main/java/Attacks.java b/src/main/java/Monster/Attacks.java similarity index 91% rename from src/main/java/Attacks.java rename to src/main/java/Monster/Attacks.java index 68af640..15344a1 100644 --- a/src/main/java/Attacks.java +++ b/src/main/java/Monster/Attacks.java @@ -1,3 +1,5 @@ +package Monster; + public enum Attacks { CHILL(3, 2); diff --git a/src/main/java/Biomes.java b/src/main/java/Monster/Biomes.java similarity index 82% rename from src/main/java/Biomes.java rename to src/main/java/Monster/Biomes.java index 49fdd1c..aeb46e3 100644 --- a/src/main/java/Biomes.java +++ b/src/main/java/Monster/Biomes.java @@ -1,3 +1,5 @@ +package Monster; + public enum Biomes { GRASSLAND, MOUNTAIN, COAST, FOREST //Är inte fäst vid dessa } \ No newline at end of file diff --git a/src/main/java/CanAttack.java b/src/main/java/Monster/CanAttack.java similarity index 87% rename from src/main/java/CanAttack.java rename to src/main/java/Monster/CanAttack.java index f77f37b..76f92e5 100644 --- a/src/main/java/CanAttack.java +++ b/src/main/java/Monster/CanAttack.java @@ -1,3 +1,5 @@ +package Monster; + import Entity.Player; public interface CanAttack { diff --git a/src/main/java/CanMove.java b/src/main/java/Monster/CanMove.java similarity index 89% rename from src/main/java/CanMove.java rename to src/main/java/Monster/CanMove.java index ec5139a..875f162 100644 --- a/src/main/java/CanMove.java +++ b/src/main/java/Monster/CanMove.java @@ -1,3 +1,5 @@ +package Monster; + import Entity.Position; //Är detta ett ok namn? public interface CanMove { diff --git a/src/main/java/Monster.java b/src/main/java/Monster/Monster.java similarity index 98% rename from src/main/java/Monster.java rename to src/main/java/Monster/Monster.java index 0c27e77..3220a65 100644 --- a/src/main/java/Monster.java +++ b/src/main/java/Monster/Monster.java @@ -1,3 +1,5 @@ +package Monster; + import Entity.*; public abstract class Monster implements CanMove { diff --git a/src/main/java/MovementPatterns.java b/src/main/java/Monster/MovementPatterns.java similarity index 97% rename from src/main/java/MovementPatterns.java rename to src/main/java/Monster/MovementPatterns.java index 571c94a..2164831 100644 --- a/src/main/java/MovementPatterns.java +++ b/src/main/java/Monster/MovementPatterns.java @@ -1,3 +1,5 @@ +package Monster; + import Entity.Position; import java.util.*; diff --git a/src/main/java/Monster/Nixie.java b/src/main/java/Monster/Nixie.java new file mode 100644 index 0000000..488034c --- /dev/null +++ b/src/main/java/Monster/Nixie.java @@ -0,0 +1,8 @@ +package Monster; + +public abstract class Nixie extends Monster implements CanMove, CanAttack { + + public Nixie() { + super(0,0,Monster.DEFAULT_POSITION); + } +} diff --git a/src/main/java/Shade.java b/src/main/java/Monster/Shade.java similarity index 99% rename from src/main/java/Shade.java rename to src/main/java/Monster/Shade.java index ff186de..4a1a194 100644 --- a/src/main/java/Shade.java +++ b/src/main/java/Monster/Shade.java @@ -1,3 +1,5 @@ +package Monster; + import Entity.Player; import Entity.Position; import java.util.*; diff --git a/src/main/java/Monster/Troll.java b/src/main/java/Monster/Troll.java new file mode 100644 index 0000000..d08fe11 --- /dev/null +++ b/src/main/java/Monster/Troll.java @@ -0,0 +1,8 @@ +package Monster; + +public abstract class Troll extends Monster implements CanMove, CanAttack { + + public Troll() { + super(0,0,Monster.DEFAULT_POSITION); + } +} diff --git a/src/main/java/Troll.java b/src/main/java/Troll.java deleted file mode 100644 index 2272aa9..0000000 --- a/src/main/java/Troll.java +++ /dev/null @@ -1,2 +0,0 @@ -public class Troll extends Monster implements CanMove, CanAttack { -} diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index 9c25ca5..1e9ca6b 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -1,10 +1,7 @@ -import Action.*; -import Character.*; -import Combat.*; import Entity.*; -import Inventory.*; -import Job.*; -import Shared.*; +import Monster.Attacks; +import Monster.MovementPatterns; +import Monster.Shade; import org.junit.jupiter.api.*; @@ -13,7 +10,7 @@ import java.util.*; import static org.hamcrest.MatcherAssert.*; import static org.hamcrest.Matchers.*; import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.*; public class MonsterTest { @@ -65,6 +62,13 @@ public class MonsterTest { assertThat(legalDestinations, hasItem(defaultShade.getPosition())); } + @Test + void shade_wont_move_to_same_position_as_player() { + Position destination = new Position(1, 1); + when(defaultPlayer.getPosition()).thenReturn(destination); + assertThat(defaultShade.moveTo(destination), equalTo(false)); + } + @Test void monster_cannot_do_anything_when_out_of_energy() { -- 2.39.5 From 667998337e45b239499ba2b8173d8a3aaf697c6e Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Tue, 28 Oct 2025 14:06:56 +0100 Subject: [PATCH 17/31] =?UTF-8?q?'shade=5Fwont=5Fmove=5Fto=5Fsame=5Fpositi?= =?UTF-8?q?on=5Fas=5Fplayer()'=20g=C3=A5r=20igenom.=20Har=20skrivit=20gans?= =?UTF-8?q?ka=20mycket=20kod,=20bl.a.=20har=20jag=20gjort=20mycket=20?= =?UTF-8?q?=C3=A4ndringar=20i=20World-grenens=20klasser=20s=C3=A5=20att=20?= =?UTF-8?q?gr=C3=A4nsnittet=20till=20mina=20klasser=20fungerar.=20Dom=20be?= =?UTF-8?q?h=C3=B6vdes=20f=C3=B6r=20att=20jag=20ska=20kunna=20skriva=20int?= =?UTF-8?q?ressanta=20tester.=20Jag=20=C3=A4r=20n=C3=B6jd=20med=20det=20ny?= =?UTF-8?q?a=20testet=20i=20det=20avseende=20att=20det=20g=C3=A5r=20igenom?= =?UTF-8?q?=20(ett=20mirakel!!),=20men=20jag=20vet=20att=20jag=20nog=20int?= =?UTF-8?q?e=20anv=C3=A4nder=20mocks=20p=C3=A5=20det=20mest=20effektiva/ko?= =?UTF-8?q?rrekta=20s=C3=A4ttet.=20Jag=20vet=20inte=20i=20hur=20stor=20uts?= =?UTF-8?q?tr=C3=A4ckning=20man=20kan=20skapa=20lager=20av=20mocks.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/Monster/CanMove.java | 4 +-- src/main/java/Monster/Shade.java | 30 ++++++++++++++++++--- src/main/java/Nixie.java | 6 ----- src/main/java/{ => World}/MapGenerator.java | 17 +++++++----- src/main/java/{ => World}/Tile.java | 14 ++++++---- src/main/java/{ => World}/World.java | 28 ++++++++++++++++--- src/test/java/MapGeneratorTest.java | 7 ++++- src/test/java/MonsterTest.java | 18 ++++++++----- src/test/java/TileTest.java | 21 +++++++-------- src/test/java/WorldTest.java | 3 +++ 11 files changed, 104 insertions(+), 46 deletions(-) delete mode 100644 src/main/java/Nixie.java rename src/main/java/{ => World}/MapGenerator.java (67%) rename src/main/java/{ => World}/Tile.java (64%) rename src/main/java/{ => World}/World.java (78%) diff --git a/README.md b/README.md index cccb987..4457fb8 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ The player object is a representation of the user and it's agency in the game wo -- Warrior -- Mage - Spells -- World generation +- World.World generation -- Terrain types - Loot - Equipment diff --git a/src/main/java/Monster/CanMove.java b/src/main/java/Monster/CanMove.java index 875f162..7c78fbd 100644 --- a/src/main/java/Monster/CanMove.java +++ b/src/main/java/Monster/CanMove.java @@ -1,10 +1,10 @@ package Monster; - +import World.*; import Entity.Position; //Är detta ett ok namn? public interface CanMove { abstract boolean move(); - abstract boolean moveTo(Position position); + abstract boolean moveTo(Position position, World world); } diff --git a/src/main/java/Monster/Shade.java b/src/main/java/Monster/Shade.java index 4a1a194..6efcd33 100644 --- a/src/main/java/Monster/Shade.java +++ b/src/main/java/Monster/Shade.java @@ -1,7 +1,6 @@ package Monster; - -import Entity.Player; -import Entity.Position; +import Entity.*; +import World.*; import java.util.*; public class Shade extends Monster implements CanMove, CanAttack { @@ -62,11 +61,24 @@ public class Shade extends Monster implements CanMove, CanAttack { return true; } - public boolean moveTo(Position position) { + public boolean moveTo(Position position, World world) { if (isDead()) { return false; } + int x = position.x(); + int y = position.y(); + int worldSize = world.getMap().length; + + if (x >= worldSize || y >= worldSize || x < 0 || y < 0) { + return false; + } + if (playerIsAtPosition(position, world)) { + return false; + } + + this.position = position; + updateDestinations(this.position); return true; } @@ -82,4 +94,14 @@ public class Shade extends Monster implements CanMove, CanAttack { validDestinations.addAll(move.findLegalDestinations(position)); } } + + private boolean playerIsAtPosition(Position position, World world) { + List entitiesAtPosition = world.getPositionEntityMap().get(position); + for (Entity entity : entitiesAtPosition) { + if (entity instanceof Player) { + return true; + } + } + return false; + } } diff --git a/src/main/java/Nixie.java b/src/main/java/Nixie.java deleted file mode 100644 index e6af177..0000000 --- a/src/main/java/Nixie.java +++ /dev/null @@ -1,6 +0,0 @@ -public abstract class Nixie extends Monster implements CanMove, CanAttack { - - public Nixie() { - super(0,0,Monster.DEFAULT_POSITION); - } -} diff --git a/src/main/java/MapGenerator.java b/src/main/java/World/MapGenerator.java similarity index 67% rename from src/main/java/MapGenerator.java rename to src/main/java/World/MapGenerator.java index aecb71d..f9f21ca 100644 --- a/src/main/java/MapGenerator.java +++ b/src/main/java/World/MapGenerator.java @@ -1,4 +1,9 @@ +package World; + import java.util.Random; +import Entity.*; +import Monster.Biomes; + public class MapGenerator { private int x; private int y; @@ -19,24 +24,24 @@ public class MapGenerator { for (int j = 0; j < y; j++) { int tileDice = rand.nextInt(4); if (tileDice == 0) { - Tile newTile = new Tile("Mountain", 3, "Future development"); + Tile newTile = new Tile(Biomes.FOREST, 3, "Future development"); gameWorld.addTile(newTile, new Position(i, j)); } else if (tileDice == 1) { - Tile newTile = new Tile("plain", 1, "Future development"); + Tile newTile = new Tile(Biomes.GRASSLAND, 1, "Future development"); gameWorld.addTile(newTile, new Position(i, j)); } else if (tileDice == 2) { - Tile newTile = new Tile("Lava", 2, "Future development"); + Tile newTile = new Tile(Biomes.MOUNTAIN, 2, "Future development"); gameWorld.addTile(newTile, new Position(i, j)); } else if (tileDice == 3) { - Tile newTile = new Tile("Water", 4, "Future development"); + Tile newTile = new Tile(Biomes.COAST, 4, "Future development"); gameWorld.addTile(newTile, new Position(i, j)); } } } } - public void addTile(String name, int staminaCost, String description, Position position) { - Tile newTile = new Tile(name, staminaCost, description); + public void addTile(Biomes biome, int staminaCost, String description, Position position) { + Tile newTile = new Tile(biome, staminaCost, description); gameWorld.addTile(newTile, position); } diff --git a/src/main/java/Tile.java b/src/main/java/World/Tile.java similarity index 64% rename from src/main/java/Tile.java rename to src/main/java/World/Tile.java index 4fe4df8..58aed8e 100644 --- a/src/main/java/Tile.java +++ b/src/main/java/World/Tile.java @@ -1,18 +1,22 @@ +package World; + +import Monster.Biomes; public class Tile { - private String tileName; + private Biomes biome; private int staminaCost; private String tileID; - public Tile(String tileName, int staminaCost, String tileID) { - this.tileName = tileName; + + public Tile(Biomes biome, int staminaCost, String tileID) { + this.biome = biome; this.staminaCost = staminaCost; this.tileID = tileID; } public void setStaminaCost(int newStaminaCost) { staminaCost = newStaminaCost; } - public String getName() { - return tileName; + public Biomes getBiome() { + return biome; } public int getStaminaCost() { return staminaCost; diff --git a/src/main/java/World.java b/src/main/java/World/World.java similarity index 78% rename from src/main/java/World.java rename to src/main/java/World/World.java index 6695488..c631517 100644 --- a/src/main/java/World.java +++ b/src/main/java/World/World.java @@ -1,7 +1,8 @@ -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.Random; +package World; + +import Entity.*; +import java.util.*; + public class World { private HashMap tileMap = new HashMap<>(); @@ -91,6 +92,25 @@ public class World { return null; } + //Har inte testat denna så den kanske inte alls funkar + private Map> invertEntityMap() { + Map> entitysByPosition = new HashMap<>(); + + for (Position position : entityMap.values()) { + entitysByPosition.put(position, new ArrayList<>()); + } + + for (Entity entity : entityMap.keySet()) { + Position position = entityMap.get(entity); + entitysByPosition.get(position).add(entity); + } + return entitysByPosition; + } + + public Map> getPositionEntityMap() { + return invertEntityMap(); + } + public void changePosition(Entity Character, Position newPosition) { entityMap.put(Character, newPosition); } diff --git a/src/test/java/MapGeneratorTest.java b/src/test/java/MapGeneratorTest.java index 51989f1..c6ef57b 100644 --- a/src/test/java/MapGeneratorTest.java +++ b/src/test/java/MapGeneratorTest.java @@ -1,3 +1,8 @@ +import Monster.Biomes; +import World.MapGenerator; +import World.Tile; +import World.World; +import Entity.*; import org.junit.jupiter.api.Test; import java.util.HashMap; @@ -19,7 +24,7 @@ class MapGeneratorTest { @Test void addTileAtPositionTest() { MapGenerator mapGenerate = new MapGenerator(X_FIVE, Y_FIVE); - mapGenerate.addTile("Test", 10, "test description", new Position(2, 2)); + mapGenerate.addTile(Biomes.MOUNTAIN, 10, "test description", new Position(2, 2)); World testWorld = mapGenerate.getWorld(); assertTrue(testWorld.getTileAtPosition(new Position(2, 2)) instanceof Tile); assertFalse(testWorld.getTileAtPosition(new Position(2, 1)) instanceof Tile); diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index 1e9ca6b..a5361bc 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -1,8 +1,6 @@ import Entity.*; -import Monster.Attacks; -import Monster.MovementPatterns; -import Monster.Shade; - +import Monster.*; +import World.*; import org.junit.jupiter.api.*; import java.util.*; @@ -17,6 +15,8 @@ public class MonsterTest { private Shade defaultShade; private Player defaultPlayer = mock(Player.class); + private World defaultWorld = mock(World.class); + private MapGenerator worldGenerator = new MapGenerator(4, 4); @BeforeEach void reset() { @@ -26,7 +26,7 @@ public class MonsterTest { @Test void monster_cannot_move_after_death() { defaultShade.kill(); - assertThat(false, equalTo(defaultShade.moveTo(new Position(0, 1)))); + assertThat(false, equalTo(defaultShade.moveTo(new Position(0, 1), defaultWorld))); } @Test @@ -62,11 +62,17 @@ public class MonsterTest { assertThat(legalDestinations, hasItem(defaultShade.getPosition())); } + //Borde nog ha mer mocks här men tycker det är svårt med flera lager av dom... @Test void shade_wont_move_to_same_position_as_player() { + worldGenerator.randomWorldGeneration(); + World world = worldGenerator.getWorld(); + Position destination = new Position(1, 1); when(defaultPlayer.getPosition()).thenReturn(destination); - assertThat(defaultShade.moveTo(destination), equalTo(false)); + world.addEntityToMap(defaultPlayer); + + assertThat(defaultShade.moveTo(destination, world), equalTo(false)); } @Test diff --git a/src/test/java/TileTest.java b/src/test/java/TileTest.java index 5adba16..c053d0a 100644 --- a/src/test/java/TileTest.java +++ b/src/test/java/TileTest.java @@ -1,32 +1,31 @@ +import Monster.*; +import World.Tile; import org.junit.jupiter.api.Test; -import java.util.ArrayList; -import java.util.List; - import static org.junit.jupiter.api.Assertions.*; class TileTest { - private final String TILE_NAME = "Name test"; + private final Biomes BIOME = Biomes.MOUNTAIN; private final int STAMINA_COST = 1; private final String ID_STRING = "Mountain test"; @Test - void getTileNameTest() { - Tile tileTest = new Tile(TILE_NAME, STAMINA_COST, ID_STRING); - String tileNameTwo = tileTest.getName(); - assertEquals(TILE_NAME, tileNameTwo); + void getBiomeTest() { + Tile tileTest = new Tile(BIOME, STAMINA_COST, ID_STRING); + Biomes tileNameTwo = tileTest.getBiome(); + assertEquals(BIOME, tileNameTwo); } @Test void getStaminaCostTest() { - Tile tileTest = new Tile(TILE_NAME, STAMINA_COST, ID_STRING); + Tile tileTest = new Tile(BIOME, STAMINA_COST, ID_STRING); assertEquals(STAMINA_COST, tileTest.getStaminaCost()); } @Test void printTileStringTest() { - Tile tileTest = new Tile(TILE_NAME, STAMINA_COST, ID_STRING); + Tile tileTest = new Tile(BIOME, STAMINA_COST, ID_STRING); assertEquals(ID_STRING, tileTest.getTileID()); } @Test void setStaminaCostTest() { - Tile tileTest = new Tile(TILE_NAME, STAMINA_COST, ID_STRING); + Tile tileTest = new Tile(BIOME, STAMINA_COST, ID_STRING); tileTest.setStaminaCost(10); int newStaminaCost = tileTest.getStaminaCost(); assertEquals(10, newStaminaCost); diff --git a/src/test/java/WorldTest.java b/src/test/java/WorldTest.java index d1f0a69..9ca607b 100644 --- a/src/test/java/WorldTest.java +++ b/src/test/java/WorldTest.java @@ -1,5 +1,8 @@ +import World.Tile; +import World.World; import org.junit.jupiter.api.Test; +import Entity.*; import java.util.HashMap; -- 2.39.5 From d914885d67ab5a7d73baeac005c434aec01f3c20 Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Tue, 28 Oct 2025 16:42:02 +0100 Subject: [PATCH 18/31] =?UTF-8?q?Delat=20upp=20f=C3=B6rra=20testet=20till?= =?UTF-8?q?=20tv=C3=A5=20olika.=20Ska=20nu=20g=C3=B6ra=20ett=20andra=20f?= =?UTF-8?q?=C3=B6rs=C3=B6k=20att=20skapa=20funktionalitet=20f=C3=B6r=20mov?= =?UTF-8?q?e-metoderna=20att=20kolla=20s=C3=A5=20monstret=20hamnar=20inom?= =?UTF-8?q?=20v=C3=A4rldens=20r=C3=A4ckvidd.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Monster/CanMove.java | 2 +- src/main/java/Monster/Monster.java | 2 +- src/main/java/Monster/Shade.java | 17 +++++++++++++++-- src/main/java/World/World.java | 12 ++++++++++++ src/test/java/MonsterTest.java | 27 ++++++++++++++++++++++----- 5 files changed, 51 insertions(+), 9 deletions(-) diff --git a/src/main/java/Monster/CanMove.java b/src/main/java/Monster/CanMove.java index 7c78fbd..40802b6 100644 --- a/src/main/java/Monster/CanMove.java +++ b/src/main/java/Monster/CanMove.java @@ -4,7 +4,7 @@ import Entity.Position; //Är detta ett ok namn? public interface CanMove { - abstract boolean move(); + abstract boolean move(World world); abstract boolean moveTo(Position position, World world); } diff --git a/src/main/java/Monster/Monster.java b/src/main/java/Monster/Monster.java index 3220a65..595106b 100644 --- a/src/main/java/Monster/Monster.java +++ b/src/main/java/Monster/Monster.java @@ -3,7 +3,7 @@ package Monster; import Entity.*; public abstract class Monster implements CanMove { - public static final Position DEFAULT_POSITION = new Position(0,0); + public static final Position DEFAULT_POSITION = new Position(1,1); protected int health; protected int energy; //Borde kanske beräknas genom en algoritm istället för att kunna sättas i konstruktorn... Så det alltid blir balanserat diff --git a/src/main/java/Monster/Shade.java b/src/main/java/Monster/Shade.java index 6efcd33..b703431 100644 --- a/src/main/java/Monster/Shade.java +++ b/src/main/java/Monster/Shade.java @@ -2,6 +2,7 @@ package Monster; import Entity.*; import World.*; import java.util.*; +import static java.util.Objects.*; public class Shade extends Monster implements CanMove, CanAttack { public static final List HABITAT = Collections.unmodifiableList(Arrays.asList(Biomes.COAST, Biomes.FOREST, Biomes.GRASSLAND, Biomes.MOUNTAIN)); @@ -51,10 +52,15 @@ public class Shade extends Monster implements CanMove, CanAttack { return true; } - public boolean move() { + public boolean move(World world) { if (isDead()) { return false; } + for (Position destination : validDestinations) { + if (playerIsAtPosition(this.position, world)) { + validDestinations.remove(destination); + } + } position = validDestinations.get(random.nextInt(validDestinations.size())); updateDestinations(position); @@ -70,7 +76,7 @@ public class Shade extends Monster implements CanMove, CanAttack { int y = position.y(); int worldSize = world.getMap().length; - if (x >= worldSize || y >= worldSize || x < 0 || y < 0) { + if (x >= worldSize || y >= worldSize || x < 1 || y < 1) { return false; } if (playerIsAtPosition(position, world)) { @@ -97,6 +103,9 @@ public class Shade extends Monster implements CanMove, CanAttack { private boolean playerIsAtPosition(Position position, World world) { List entitiesAtPosition = world.getPositionEntityMap().get(position); + if (isNull(entitiesAtPosition)) { + return false; + } for (Entity entity : entitiesAtPosition) { if (entity instanceof Player) { return true; @@ -104,4 +113,8 @@ public class Shade extends Monster implements CanMove, CanAttack { } return false; } + + private boolean noPlayerIsAtPosition(Position position, World world) { + return !playerIsAtPosition(position, world); + } } diff --git a/src/main/java/World/World.java b/src/main/java/World/World.java index c631517..0edacab 100644 --- a/src/main/java/World/World.java +++ b/src/main/java/World/World.java @@ -8,10 +8,14 @@ public class World { private HashMap tileMap = new HashMap<>(); private HashMap entityMap = new HashMap<>(); private String[][] map; + private int width; + private int height; public World(int x, int y) { this.map = new String[(x * 2) + 1][y + 2]; addWorldToMap(); + width = x; + height = y; } private void addWorldToMap() { @@ -111,6 +115,14 @@ public class World { return invertEntityMap(); } + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + public void changePosition(Entity Character, Position newPosition) { entityMap.put(Character, newPosition); } diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index a5361bc..c262f56 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -16,7 +16,7 @@ public class MonsterTest { private Shade defaultShade; private Player defaultPlayer = mock(Player.class); private World defaultWorld = mock(World.class); - private MapGenerator worldGenerator = new MapGenerator(4, 4); + private MapGenerator worldGenerator = new MapGenerator(5, 5); @BeforeEach void reset() { @@ -26,7 +26,7 @@ public class MonsterTest { @Test void monster_cannot_move_after_death() { defaultShade.kill(); - assertThat(false, equalTo(defaultShade.moveTo(new Position(0, 1), defaultWorld))); + assertThat(false, equalTo(defaultShade.moveTo(new Position(1, 2), defaultWorld))); } @Test @@ -58,23 +58,40 @@ public class MonsterTest { legalDestinations.addAll(move.findLegalDestinations(startingPosition)); } - defaultShade.move(); + defaultShade.move(defaultWorld); assertThat(legalDestinations, hasItem(defaultShade.getPosition())); } //Borde nog ha mer mocks här men tycker det är svårt med flera lager av dom... @Test - void shade_wont_move_to_same_position_as_player() { + void method_move_to_wont_move_shade_to_same_position_as_player() { worldGenerator.randomWorldGeneration(); World world = worldGenerator.getWorld(); - Position destination = new Position(1, 1); + Position destination = new Position(2, 2); when(defaultPlayer.getPosition()).thenReturn(destination); world.addEntityToMap(defaultPlayer); assertThat(defaultShade.moveTo(destination, world), equalTo(false)); } + void method_move_wont_move_shade_to_same_position_as_player() { + worldGenerator.randomWorldGeneration(); + World world = worldGenerator.getWorld(); + + Position destination = new Position(2, 2); + when(defaultPlayer.getPosition()).thenReturn(destination); + world.addEntityToMap(defaultPlayer); + + defaultShade.move(world); + assertThat(defaultShade.getPosition(), not(defaultPlayer.getPosition())); + } + + @Test + void method_move_places_monster_within_bounds() { + + } + @Test void monster_cannot_do_anything_when_out_of_energy() { -- 2.39.5 From 1430e0877750b210ccde947375671b92f900441f Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Tue, 28 Oct 2025 18:40:55 +0100 Subject: [PATCH 19/31] =?UTF-8?q?F=C3=A5r=20inte=20senaste=20testet=20att?= =?UTF-8?q?=20fungera.=20N=C3=A5got=20i=20logiken=20h=C3=A5ller=20inte,=20?= =?UTF-8?q?men=20det=20=C3=A4r=20s=C3=A5=20mycket=20jobb=20s=C3=A5=20jag?= =?UTF-8?q?=20vill=20=C3=A4nd=C3=A5=20spara=20det=20innan=20jag=20tar=20bo?= =?UTF-8?q?rt=20det.=20Jag=20kommer=20inte=20l=C3=A4gga=20mer=20tid=20p?= =?UTF-8?q?=C3=A5=20det=20h=C3=A4r=20d=C3=A5=20felet=20kan=20ligga=20b?= =?UTF-8?q?=C3=A5de=20i=20logiken=20f=C3=B6r=20min=20kod,=20men=20det=20ka?= =?UTF-8?q?n=20=C3=A4ven=20bero=20p=C3=A5=20n=C3=A5got=20i=20World.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Monster/Attacks.java | 2 +- src/main/java/Monster/CanMove.java | 2 +- src/main/java/Monster/MovementPatterns.java | 4 +- src/main/java/Monster/Shade.java | 49 ++++++++++++--------- src/test/java/MonsterTest.java | 36 ++++++++++----- 5 files changed, 59 insertions(+), 34 deletions(-) diff --git a/src/main/java/Monster/Attacks.java b/src/main/java/Monster/Attacks.java index 15344a1..c8ab2da 100644 --- a/src/main/java/Monster/Attacks.java +++ b/src/main/java/Monster/Attacks.java @@ -1,7 +1,7 @@ package Monster; public enum Attacks { - CHILL(3, 2); + CHILL(3, 2), STOMP(7, 5); private int damage; private int cost; diff --git a/src/main/java/Monster/CanMove.java b/src/main/java/Monster/CanMove.java index 40802b6..c9a8dd6 100644 --- a/src/main/java/Monster/CanMove.java +++ b/src/main/java/Monster/CanMove.java @@ -6,5 +6,5 @@ public interface CanMove { abstract boolean move(World world); - abstract boolean moveTo(Position position, World world); + abstract boolean moveTo(Position destination, World world); } diff --git a/src/main/java/Monster/MovementPatterns.java b/src/main/java/Monster/MovementPatterns.java index 2164831..48408c9 100644 --- a/src/main/java/Monster/MovementPatterns.java +++ b/src/main/java/Monster/MovementPatterns.java @@ -14,8 +14,8 @@ public enum MovementPatterns { this.id = id; } - public List findLegalDestinations(Position position) { - List legalDestinations = new ArrayList<>(); + public Set findLegalDestinations(Position position) { + Set legalDestinations = new HashSet<>(); switch(id) { case 1: diff --git a/src/main/java/Monster/Shade.java b/src/main/java/Monster/Shade.java index b703431..d30d5bd 100644 --- a/src/main/java/Monster/Shade.java +++ b/src/main/java/Monster/Shade.java @@ -18,7 +18,6 @@ public class Shade extends Monster implements CanMove, CanAttack { public Shade() { super(MAX_HEALTH, MAX_ENERGY, Monster.DEFAULT_POSITION); - updateDestinations(position); } public void heal() { @@ -56,35 +55,25 @@ public class Shade extends Monster implements CanMove, CanAttack { if (isDead()) { return false; } - for (Position destination : validDestinations) { - if (playerIsAtPosition(this.position, world)) { - validDestinations.remove(destination); - } - } + updateDestinations(position, world); position = validDestinations.get(random.nextInt(validDestinations.size())); - updateDestinations(position); - + updateDestinations(position, world); return true; } - public boolean moveTo(Position position, World world) { + public boolean moveTo(Position destination, World world) { if (isDead()) { return false; } - - int x = position.x(); - int y = position.y(); - int worldSize = world.getMap().length; - - if (x >= worldSize || y >= worldSize || x < 1 || y < 1) { + if (positionIsOutOfBounds(destination, world)) { return false; } - if (playerIsAtPosition(position, world)) { + if (playerIsAtPosition(destination, world)) { return false; } - this.position = position; - updateDestinations(this.position); + position = destination; + updateDestinations(position, world); return true; } @@ -94,10 +83,15 @@ public class Shade extends Monster implements CanMove, CanAttack { } } - private void updateDestinations(Position position) { + private void updateDestinations(Position position, World world) { validDestinations.clear(); for (MovementPatterns move : MOVES) { - validDestinations.addAll(move.findLegalDestinations(position)); + Set destinations = move.findLegalDestinations(position); + for (Position destination : destinations) { + if (noPlayerIsAtPosition(destination, world) && positionIsInBounds(destination, world)) { + validDestinations.add(destination); + } + } } } @@ -117,4 +111,19 @@ public class Shade extends Monster implements CanMove, CanAttack { private boolean noPlayerIsAtPosition(Position position, World world) { return !playerIsAtPosition(position, world); } + + private boolean positionIsInBounds(Position position, World world) { + int upperX = world.getWidth(); + int lowerX = 1; + int upperY = world.getHeight(); + int lowerY = 1; + int x = position.x(); + int y = position.y(); + + return x > upperX || x < lowerX || y > upperY || y < lowerY; + } + + private boolean positionIsOutOfBounds(Position position, World world) { + return !positionIsInBounds(position, world); + } } diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index c262f56..08a2288 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -1,6 +1,7 @@ import Entity.*; import Monster.*; import World.*; +import org.hamcrest.core.AllOf; import org.junit.jupiter.api.*; import java.util.*; @@ -14,10 +15,11 @@ import static org.mockito.Mockito.*; public class MonsterTest { private Shade defaultShade; - private Player defaultPlayer = mock(Player.class); - private World defaultWorld = mock(World.class); private MapGenerator worldGenerator = new MapGenerator(5, 5); + private Player mockPlayer = mock(Player.class); + private World mockWorld = mock(World.class); + @BeforeEach void reset() { defaultShade = new Shade(); //Återställer alla värden till default @@ -26,13 +28,13 @@ public class MonsterTest { @Test void monster_cannot_move_after_death() { defaultShade.kill(); - assertThat(false, equalTo(defaultShade.moveTo(new Position(1, 2), defaultWorld))); + assertThat(false, equalTo(defaultShade.moveTo(new Position(1, 2), mockWorld))); } @Test void monster_cannot_attack_after_death() { defaultShade.kill(); - assertThat(false, equalTo(defaultShade.performAttack(Attacks.CHILL, defaultPlayer))); + assertThat(false, equalTo(defaultShade.performAttack(Attacks.CHILL, mockPlayer))); } @Test @@ -58,7 +60,7 @@ public class MonsterTest { legalDestinations.addAll(move.findLegalDestinations(startingPosition)); } - defaultShade.move(defaultWorld); + defaultShade.move(mockWorld); assertThat(legalDestinations, hasItem(defaultShade.getPosition())); } @@ -69,27 +71,39 @@ public class MonsterTest { World world = worldGenerator.getWorld(); Position destination = new Position(2, 2); - when(defaultPlayer.getPosition()).thenReturn(destination); - world.addEntityToMap(defaultPlayer); + when(mockPlayer.getPosition()).thenReturn(destination); + world.addEntityToMap(mockPlayer); assertThat(defaultShade.moveTo(destination, world), equalTo(false)); } + @Test void method_move_wont_move_shade_to_same_position_as_player() { worldGenerator.randomWorldGeneration(); World world = worldGenerator.getWorld(); Position destination = new Position(2, 2); - when(defaultPlayer.getPosition()).thenReturn(destination); - world.addEntityToMap(defaultPlayer); + when(mockPlayer.getPosition()).thenReturn(destination); + world.addEntityToMap(mockPlayer); defaultShade.move(world); - assertThat(defaultShade.getPosition(), not(defaultPlayer.getPosition())); + assertThat(defaultShade.getPosition(), not(mockPlayer.getPosition())); } + //Flera assertThat i samma. Farligt???? @Test void method_move_places_monster_within_bounds() { + worldGenerator.randomWorldGeneration(); + World world = worldGenerator.getWorld(); + /*when(mockWorld.getWidth()).thenReturn(5); + when(mockWorld.getHeight()).thenReturn(5);*/ + defaultShade.move(world); + int newX = defaultShade.getPosition().x(); + int newY = defaultShade.getPosition().y(); + + boolean positionCheck = newX > 0 ; + assertThat(true, equalTo(positionCheck)); } @Test @@ -111,4 +125,6 @@ public class MonsterTest { void use_of_attack_not_in_arsenal_is_rejected() { } + + } -- 2.39.5 From 7b74c0392073b7d6aa3fe66d706942a4c6c9f828 Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Tue, 28 Oct 2025 19:21:18 +0100 Subject: [PATCH 20/31] =?UTF-8?q?Skapat=20och=20f=C3=A5tt=20igenom=20test?= =?UTF-8?q?=20som=20kontrollerar=20att=20monster=20inte=20kan=20utf=C3=B6r?= =?UTF-8?q?a=20n=C3=A5gra=20handlingar=20om=20dom=20har=20slut=20p=C3=A5?= =?UTF-8?q?=20energi.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Monster/Attacks.java | 4 +- src/main/java/Monster/Monster.java | 6 +- src/main/java/Monster/MovementPatterns.java | 9 ++- src/main/java/Monster/Shade.java | 88 +++++++++++++-------- src/test/java/MonsterTest.java | 38 ++++----- 5 files changed, 81 insertions(+), 64 deletions(-) diff --git a/src/main/java/Monster/Attacks.java b/src/main/java/Monster/Attacks.java index c8ab2da..6abda4a 100644 --- a/src/main/java/Monster/Attacks.java +++ b/src/main/java/Monster/Attacks.java @@ -3,8 +3,8 @@ package Monster; public enum Attacks { CHILL(3, 2), STOMP(7, 5); - private int damage; - private int cost; + public int damage; + public int cost; Attacks(int damage, int cost) { this.damage = damage; diff --git a/src/main/java/Monster/Monster.java b/src/main/java/Monster/Monster.java index 595106b..7b1384a 100644 --- a/src/main/java/Monster/Monster.java +++ b/src/main/java/Monster/Monster.java @@ -4,6 +4,8 @@ import Entity.*; public abstract class Monster implements CanMove { public static final Position DEFAULT_POSITION = new Position(1,1); + public static final int MIN_HEALTH = 0; + public static final int MIN_ENERGY = 0; protected int health; protected int energy; //Borde kanske beräknas genom en algoritm istället för att kunna sättas i konstruktorn... Så det alltid blir balanserat @@ -44,8 +46,8 @@ public abstract class Monster implements CanMove { return !isAlive; } - abstract void heal(); + abstract boolean heal(); - abstract void takeDamage(int amount); + abstract boolean takeDamage(int amount); } diff --git a/src/main/java/Monster/MovementPatterns.java b/src/main/java/Monster/MovementPatterns.java index 48408c9..b2e1d04 100644 --- a/src/main/java/Monster/MovementPatterns.java +++ b/src/main/java/Monster/MovementPatterns.java @@ -4,7 +4,7 @@ import Entity.Position; import java.util.*; public enum MovementPatterns { - ONE_DIAGONAL_STEP(1, 1); + ONE_DIAGONAL_STEP(1, 1), TWO_STEPS_IN_STRAIGHT_LINE(2, 2); public int cost; private int id; @@ -16,14 +16,17 @@ public enum MovementPatterns { public Set findLegalDestinations(Position position) { Set legalDestinations = new HashSet<>(); + int x = position.x(); + int y = position.y(); switch(id) { case 1: - int x = position.x(); - int y = position.y(); legalDestinations.addAll(Arrays.asList(new Position(x - 1, y + 1), new Position(x + 1, y + 1), new Position(x - 1, y - 1), new Position(x + 1, y - 1))); break; + case 2: + legalDestinations.addAll(Arrays.asList(new Position(x, y + 2), new Position(x, y - 2), + new Position(x + 2, y), new Position(x - 2, y))); } return legalDestinations; diff --git a/src/main/java/Monster/Shade.java b/src/main/java/Monster/Shade.java index d30d5bd..80ab863 100644 --- a/src/main/java/Monster/Shade.java +++ b/src/main/java/Monster/Shade.java @@ -20,26 +20,44 @@ public class Shade extends Monster implements CanMove, CanAttack { super(MAX_HEALTH, MAX_ENERGY, Monster.DEFAULT_POSITION); } - public void heal() { - if (isDead()) { - throw new IllegalStateException("This shade is dead"); - } - if (health < MAX_HEALTH) { - health += HEALTH_PER_HEAL; - energy -= ENERGY_COST_PER_HEAL; - enforceHealthMaximum(); - } + public Shade(int health, int energy, Position position) { + super(health, energy, position); + enforceHealthValueBoundries(); + enforceEnergyValueBoundries(); } - public void takeDamage(int amount) { + public boolean heal() { + if (isDead()) { + return false; + } + if (health == MIN_HEALTH) { + return false; + } + if (health == MAX_HEALTH) { + return false; + } + if (energy < ENERGY_COST_PER_HEAL) { + return false; + } + + health += HEALTH_PER_HEAL; + energy -= ENERGY_COST_PER_HEAL; + enforceHealthValueBoundries(); + + return true; + } + + public boolean takeDamage(int amount) { if (amount < 0) { - throw new IllegalArgumentException("'amount' must be a positive integer"); + return false; } if (health - amount <= 0) { kill(); + return true; } else { health =- amount; + return true; } } @@ -47,6 +65,9 @@ public class Shade extends Monster implements CanMove, CanAttack { if (isDead()) { return false; } + if (attack.cost > energy) { + return false; + } return true; } @@ -56,6 +77,9 @@ public class Shade extends Monster implements CanMove, CanAttack { return false; } updateDestinations(position, world); + if (validDestinations.isEmpty()) { + return false; + } position = validDestinations.get(random.nextInt(validDestinations.size())); updateDestinations(position, world); return true; @@ -65,9 +89,6 @@ public class Shade extends Monster implements CanMove, CanAttack { if (isDead()) { return false; } - if (positionIsOutOfBounds(destination, world)) { - return false; - } if (playerIsAtPosition(destination, world)) { return false; } @@ -77,19 +98,33 @@ public class Shade extends Monster implements CanMove, CanAttack { return true; } - private void enforceHealthMaximum() { + private void enforceHealthValueBoundries() { if (health > MAX_HEALTH) { health = MAX_HEALTH; } + else if (health <= MIN_HEALTH) { + health = 1; + } + } + + private void enforceEnergyValueBoundries() { + if (energy > MAX_ENERGY) { + energy = MAX_ENERGY; + } + else if (energy < MIN_ENERGY) { + energy = MIN_ENERGY; + } } private void updateDestinations(Position position, World world) { validDestinations.clear(); for (MovementPatterns move : MOVES) { - Set destinations = move.findLegalDestinations(position); - for (Position destination : destinations) { - if (noPlayerIsAtPosition(destination, world) && positionIsInBounds(destination, world)) { - validDestinations.add(destination); + if (move.cost <= energy) { + Set destinations = move.findLegalDestinations(position); + for (Position destination : destinations) { + if (noPlayerIsAtPosition(destination, world)) { + validDestinations.add(destination); + } } } } @@ -111,19 +146,4 @@ public class Shade extends Monster implements CanMove, CanAttack { private boolean noPlayerIsAtPosition(Position position, World world) { return !playerIsAtPosition(position, world); } - - private boolean positionIsInBounds(Position position, World world) { - int upperX = world.getWidth(); - int lowerX = 1; - int upperY = world.getHeight(); - int lowerY = 1; - int x = position.x(); - int y = position.y(); - - return x > upperX || x < lowerX || y > upperY || y < lowerY; - } - - private boolean positionIsOutOfBounds(Position position, World world) { - return !positionIsInBounds(position, world); - } } diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index 08a2288..d070f89 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -46,7 +46,7 @@ public class MonsterTest { @Test void monster_cannot_heal_after_death() { defaultShade.kill(); - assertThrows(IllegalStateException.class, () -> defaultShade.heal()); + assertThat(false, equalTo(defaultShade.heal())); } //Är denna för lång? @@ -90,36 +90,28 @@ public class MonsterTest { assertThat(defaultShade.getPosition(), not(mockPlayer.getPosition())); } - //Flera assertThat i samma. Farligt???? @Test - void method_move_places_monster_within_bounds() { - worldGenerator.randomWorldGeneration(); - World world = worldGenerator.getWorld(); - /*when(mockWorld.getWidth()).thenReturn(5); - when(mockWorld.getHeight()).thenReturn(5);*/ - - defaultShade.move(world); - int newX = defaultShade.getPosition().x(); - int newY = defaultShade.getPosition().y(); - - boolean positionCheck = newX > 0 ; - assertThat(true, equalTo(positionCheck)); + void monster_cannot_heal_when_out_of_energy() { + Shade shade = new Shade(Shade.MAX_HEALTH, Shade.MIN_ENERGY, Shade.DEFAULT_POSITION); + assertThat(shade.heal(), equalTo(false)); } @Test - void monster_cannot_do_anything_when_out_of_energy() { - + void monster_cannot_move_to_when_out_of_energy() { + Shade shade = new Shade(Shade.MAX_HEALTH, Shade.MIN_ENERGY, Shade.DEFAULT_POSITION); + assertThat(shade.move(mockWorld), equalTo(false)); } @Test + void monster_cannot_attack_when_out_of_energy() { + Shade shade = new Shade(Shade.MAX_HEALTH, Shade.MIN_ENERGY, Shade.DEFAULT_POSITION); + assertThat(shade.performAttack(Attacks.CHILL, mockPlayer), equalTo(false)); + } + + /*@Test void only_moves_within_energy_budget_are_performed() { - - } - - @Test - void move_to_invalid_destination_is_rejected() { - - } + Troll troll = new Troll(Troll.MAX_HEALTH) + }*/ @Test void use_of_attack_not_in_arsenal_is_rejected() { -- 2.39.5 From 3281bb8b9b64ad7c1892c899fc621b76f74441b5 Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Tue, 28 Oct 2025 21:57:35 +0100 Subject: [PATCH 21/31] =?UTF-8?q?Ett=20f=C3=B6rsta=20utkast=20av=20Troll?= =?UTF-8?q?=20s=C3=A5=20att=20testet=20'only=5Fmoves=5Fwithin=5Fenergy=5Fb?= =?UTF-8?q?udget=5Fare=5Fperformed()'=20kan=20k=C3=B6ras=20(och=20g=C3=A5?= =?UTF-8?q?=20igenom!)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Monster/MovementPatterns.java | 4 +- src/main/java/Monster/Shade.java | 4 +- src/main/java/Monster/Troll.java | 150 +++++++++++++++++++- src/test/java/MonsterTest.java | 11 +- 4 files changed, 159 insertions(+), 10 deletions(-) diff --git a/src/main/java/Monster/MovementPatterns.java b/src/main/java/Monster/MovementPatterns.java index b2e1d04..e4f8ea6 100644 --- a/src/main/java/Monster/MovementPatterns.java +++ b/src/main/java/Monster/MovementPatterns.java @@ -14,8 +14,8 @@ public enum MovementPatterns { this.id = id; } - public Set findLegalDestinations(Position position) { - Set legalDestinations = new HashSet<>(); + public List findLegalDestinations(Position position) { + List legalDestinations = new ArrayList<>(); int x = position.x(); int y = position.y(); diff --git a/src/main/java/Monster/Shade.java b/src/main/java/Monster/Shade.java index 80ab863..7874bdf 100644 --- a/src/main/java/Monster/Shade.java +++ b/src/main/java/Monster/Shade.java @@ -17,7 +17,7 @@ public class Shade extends Monster implements CanMove, CanAttack { private List validDestinations = new ArrayList<>(); public Shade() { - super(MAX_HEALTH, MAX_ENERGY, Monster.DEFAULT_POSITION); + super(MAX_HEALTH, MAX_ENERGY, DEFAULT_POSITION); } public Shade(int health, int energy, Position position) { @@ -120,7 +120,7 @@ public class Shade extends Monster implements CanMove, CanAttack { validDestinations.clear(); for (MovementPatterns move : MOVES) { if (move.cost <= energy) { - Set destinations = move.findLegalDestinations(position); + List destinations = move.findLegalDestinations(position); for (Position destination : destinations) { if (noPlayerIsAtPosition(destination, world)) { validDestinations.add(destination); diff --git a/src/main/java/Monster/Troll.java b/src/main/java/Monster/Troll.java index d08fe11..c824b5e 100644 --- a/src/main/java/Monster/Troll.java +++ b/src/main/java/Monster/Troll.java @@ -1,8 +1,154 @@ package Monster; -public abstract class Troll extends Monster implements CanMove, CanAttack { +import Entity.Entity; +import Entity.Player; +import Entity.Position; +import World.World; + +import java.util.*; + +import static java.util.Objects.isNull; + +public class Troll extends Monster implements CanMove, CanAttack { + public static final List HABITAT = Collections.unmodifiableList(Arrays.asList(Biomes.FOREST, Biomes.MOUNTAIN)); + public static final List MOVES = Collections.unmodifiableList(Arrays.asList(MovementPatterns.ONE_DIAGONAL_STEP, MovementPatterns.TWO_STEPS_IN_STRAIGHT_LINE)); + public static final int MAX_HEALTH = 80; + public static final int MAX_ENERGY = 100; + + private static final int HEALTH_PER_HEAL = 6; + private static final int ENERGY_COST_PER_HEAL = 3; + + private Random random = new Random(); + private List validDestinations = new ArrayList<>(); public Troll() { - super(0,0,Monster.DEFAULT_POSITION); + super(MAX_HEALTH, MAX_ENERGY, DEFAULT_POSITION); + } + + public Troll(int health, int energy, Position position) { + super(health, energy, position); + enforceHealthValueBoundries(); + enforceEnergyValueBoundries(); + } + + public boolean heal() { + if (isDead()) { + return false; + } + if (health == MIN_HEALTH) { + return false; + } + if (health == MAX_HEALTH) { + return false; + } + if (energy < ENERGY_COST_PER_HEAL) { + return false; + } + + health += HEALTH_PER_HEAL; + energy -= ENERGY_COST_PER_HEAL; + enforceHealthValueBoundries(); + + return true; + } + + public boolean takeDamage(int amount) { + if (amount < 0) { + return false; + } + if (health - amount <= 0) { + kill(); + return true; + } + else { + health =- amount; + return true; + } + } + + public boolean performAttack(Attacks attack, Player player) { + if (isDead()) { + return false; + } + if (attack.cost > energy) { + return false; + } + + return true; + } + + public boolean move(World world) { + if (isDead()) { + return false; + } + updateDestinations(position, world); + if (validDestinations.isEmpty()) { + return false; + } + position = validDestinations.get(random.nextInt(validDestinations.size())); + updateDestinations(position, world); + return true; + } + + public boolean moveTo(Position destination, World world) { + if (isDead()) { + return false; + } + if (playerIsAtPosition(destination, world)) { + return false; + } + + position = destination; + updateDestinations(position, world); + return true; + } + + private void updateDestinations(Position position, World world) { + validDestinations.clear(); + for (MovementPatterns move : MOVES) { + if (move.cost <= energy) { + List destinations = move.findLegalDestinations(position); + for (Position destination : destinations) { + if (noPlayerIsAtPosition(destination, world)) { + validDestinations.add(destination); + } + } + } + } + } + + private boolean playerIsAtPosition(Position position, World world) { + List entitiesAtPosition = world.getPositionEntityMap().get(position); + if (isNull(entitiesAtPosition)) { + return false; + } + for (Entity entity : entitiesAtPosition) { + if (entity instanceof Player) { + return true; + } + } + return false; + } + + private boolean noPlayerIsAtPosition(Position position, World world) { + return !playerIsAtPosition(position, world); + } + + private void enforceHealthValueBoundries() { + if (health > MAX_HEALTH) { + health = MAX_HEALTH; + } + else if (health <= MIN_HEALTH) { + health = 1; + } + } + + private void enforceEnergyValueBoundries() { + if (energy > MAX_ENERGY) { + energy = MAX_ENERGY; + } + else if (energy < MIN_ENERGY) { + energy = MIN_ENERGY; + } } } diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index d070f89..2051e18 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -108,14 +108,17 @@ public class MonsterTest { assertThat(shade.performAttack(Attacks.CHILL, mockPlayer), equalTo(false)); } - /*@Test + @Test void only_moves_within_energy_budget_are_performed() { - Troll troll = new Troll(Troll.MAX_HEALTH) - }*/ + Troll troll = new Troll(Troll.MAX_HEALTH, 1, Troll.DEFAULT_POSITION); + List movesWithinBudget = MovementPatterns.ONE_DIAGONAL_STEP.findLegalDestinations(troll.getPosition()); + troll.move(mockWorld); + + assertThat(movesWithinBudget, hasItem(troll.getPosition())); + } @Test void use_of_attack_not_in_arsenal_is_rejected() { - } -- 2.39.5 From e255957532a18e7d4249d7547c6eeaf503c70f68 Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Tue, 28 Oct 2025 22:10:56 +0100 Subject: [PATCH 22/31] =?UTF-8?q?Dubblerat=20dom=20tester=20som=20=C3=A4r?= =?UTF-8?q?=20relevanta=20f=C3=B6r=20b=C3=A5de=20Troll=20och=20Shade=20f?= =?UTF-8?q?=C3=B6r=20att=20verifiera=20att=20logiken=20=C3=A4r=20densamma?= =?UTF-8?q?=20f=C3=B6r=20b=C3=A4gge.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/MonsterTest.java | 83 ++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 14 deletions(-) diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index 2051e18..e1f7762 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -1,20 +1,19 @@ import Entity.*; import Monster.*; import World.*; -import org.hamcrest.core.AllOf; import org.junit.jupiter.api.*; import java.util.*; import static org.hamcrest.MatcherAssert.*; import static org.hamcrest.Matchers.*; -import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; public class MonsterTest { private Shade defaultShade; + private Troll defaultTroll; private MapGenerator worldGenerator = new MapGenerator(5, 5); private Player mockPlayer = mock(Player.class); @@ -22,36 +21,60 @@ public class MonsterTest { @BeforeEach void reset() { - defaultShade = new Shade(); //Återställer alla värden till default + defaultShade = new Shade(); + defaultTroll = new Troll(); } @Test - void monster_cannot_move_after_death() { + void shade_cannot_move_after_death() { defaultShade.kill(); assertThat(false, equalTo(defaultShade.moveTo(new Position(1, 2), mockWorld))); } @Test - void monster_cannot_attack_after_death() { + void troll_cannot_move_after_death() { + defaultTroll.kill(); + assertThat(false, equalTo(defaultTroll.moveTo(new Position(1, 2), mockWorld))); + } + + @Test + void shade_cannot_attack_after_death() { defaultShade.kill(); assertThat(false, equalTo(defaultShade.performAttack(Attacks.CHILL, mockPlayer))); } @Test - void reaching_zero_health_triggers_death() { + void troll_cannot_attack_after_death() { + defaultTroll.kill(); + assertThat(false, equalTo(defaultTroll.performAttack(Attacks.STOMP, mockPlayer))); + } + + @Test + void reaching_zero_health_triggers_shade_to_die() { defaultShade.takeDamage(Shade.MAX_HEALTH); assertThat(false, equalTo(defaultShade.isAlive())); } @Test - void monster_cannot_heal_after_death() { + void reaching_zero_health_triggers_troll_to_die() { + defaultTroll.takeDamage(Troll.MAX_HEALTH); + assertThat(false, equalTo(defaultTroll.isAlive())); + } + + @Test + void shade_cannot_heal_after_death() { defaultShade.kill(); assertThat(false, equalTo(defaultShade.heal())); } - //Är denna för lång? @Test - void method_move_places_monster_in_legal_position() { + void troll_cannot_heal_after_death() { + defaultTroll.kill(); + assertThat(false, equalTo(defaultTroll.heal())); + } + + @Test + void method_move_places_shade_in_legal_position() { Position startingPosition = defaultShade.getPosition(); List legalDestinations = new ArrayList<>(); List moves = defaultShade.MOVES; @@ -64,9 +87,22 @@ public class MonsterTest { assertThat(legalDestinations, hasItem(defaultShade.getPosition())); } - //Borde nog ha mer mocks här men tycker det är svårt med flera lager av dom... @Test - void method_move_to_wont_move_shade_to_same_position_as_player() { + void method_move_places_troll_in_legal_position() { + Position startingPosition = defaultTroll.getPosition(); + List legalDestinations = new ArrayList<>(); + List moves = defaultTroll.MOVES; + + for (MovementPatterns move : moves) { + legalDestinations.addAll(move.findLegalDestinations(startingPosition)); + } + + defaultTroll.move(mockWorld); + assertThat(legalDestinations, hasItem(defaultTroll.getPosition())); + } + + @Test + void method_moveTo_wont_move_shade_to_same_position_as_player() { worldGenerator.randomWorldGeneration(); World world = worldGenerator.getWorld(); @@ -77,6 +113,7 @@ public class MonsterTest { assertThat(defaultShade.moveTo(destination, world), equalTo(false)); } + @Test void method_move_wont_move_shade_to_same_position_as_player() { worldGenerator.randomWorldGeneration(); @@ -91,23 +128,41 @@ public class MonsterTest { } @Test - void monster_cannot_heal_when_out_of_energy() { + void shade_cannot_heal_when_out_of_energy() { Shade shade = new Shade(Shade.MAX_HEALTH, Shade.MIN_ENERGY, Shade.DEFAULT_POSITION); assertThat(shade.heal(), equalTo(false)); } @Test - void monster_cannot_move_to_when_out_of_energy() { + void troll_cannot_heal_when_out_of_energy() { + Troll troll = new Troll(Troll.MAX_HEALTH, Troll.MIN_ENERGY, Troll.DEFAULT_POSITION); + assertThat(troll.heal(), equalTo(false)); + } + + @Test + void shade_cannot_move_when_out_of_energy() { Shade shade = new Shade(Shade.MAX_HEALTH, Shade.MIN_ENERGY, Shade.DEFAULT_POSITION); assertThat(shade.move(mockWorld), equalTo(false)); } @Test - void monster_cannot_attack_when_out_of_energy() { + void troll_cannot_move_when_out_of_energy() { + Troll troll = new Troll(Troll.MAX_HEALTH, Troll.MIN_ENERGY, Troll.DEFAULT_POSITION); + assertThat(troll.move(mockWorld), equalTo(false)); + } + + @Test + void shade_cannot_attack_when_out_of_energy() { Shade shade = new Shade(Shade.MAX_HEALTH, Shade.MIN_ENERGY, Shade.DEFAULT_POSITION); assertThat(shade.performAttack(Attacks.CHILL, mockPlayer), equalTo(false)); } + @Test + void troll_cannot_attack_when_out_of_energy() { + Troll troll = new Troll(Troll.MAX_HEALTH, Troll.MIN_ENERGY, Troll.DEFAULT_POSITION); + assertThat(troll.performAttack(Attacks.STOMP, mockPlayer), equalTo(false)); + } + @Test void only_moves_within_energy_budget_are_performed() { Troll troll = new Troll(Troll.MAX_HEALTH, 1, Troll.DEFAULT_POSITION); -- 2.39.5 From 11278cf052dc76b34832f372ac7cc5b77118f37f Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Tue, 28 Oct 2025 22:26:11 +0100 Subject: [PATCH 23/31] =?UTF-8?q?Grundl=C3=A4ggande=20tester=20f=C3=B6r=20?= =?UTF-8?q?performAttack=20implementerade=20f=C3=B6r=20b=C3=A5de=20Troll?= =?UTF-8?q?=20och=20Shade?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Monster/Shade.java | 10 +++++++++- src/main/java/Monster/Troll.java | 10 +++++++++- src/test/java/MonsterTest.java | 17 ++++++++++++++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/main/java/Monster/Shade.java b/src/main/java/Monster/Shade.java index 7874bdf..43d95cf 100644 --- a/src/main/java/Monster/Shade.java +++ b/src/main/java/Monster/Shade.java @@ -7,6 +7,7 @@ import static java.util.Objects.*; public class Shade extends Monster implements CanMove, CanAttack { public static final List HABITAT = Collections.unmodifiableList(Arrays.asList(Biomes.COAST, Biomes.FOREST, Biomes.GRASSLAND, Biomes.MOUNTAIN)); public static final List MOVES = Collections.unmodifiableList(Arrays.asList(MovementPatterns.ONE_DIAGONAL_STEP)); + public static final List ATTACKS = Collections.unmodifiableList(Arrays.asList(Attacks.CHILL)); public static final int MAX_HEALTH = 20; public static final int MAX_ENERGY = 14; @@ -68,7 +69,10 @@ public class Shade extends Monster implements CanMove, CanAttack { if (attack.cost > energy) { return false; } - + if (attackIsNotInArsenal(attack)) { + return false; + } + player.setHealth(player.getHealth() - attack.cost); return true; } @@ -146,4 +150,8 @@ public class Shade extends Monster implements CanMove, CanAttack { private boolean noPlayerIsAtPosition(Position position, World world) { return !playerIsAtPosition(position, world); } + + private boolean attackIsNotInArsenal(Attacks attack) { + return !ATTACKS.contains(attack); + } } diff --git a/src/main/java/Monster/Troll.java b/src/main/java/Monster/Troll.java index c824b5e..853e5cb 100644 --- a/src/main/java/Monster/Troll.java +++ b/src/main/java/Monster/Troll.java @@ -12,6 +12,7 @@ import static java.util.Objects.isNull; public class Troll extends Monster implements CanMove, CanAttack { public static final List HABITAT = Collections.unmodifiableList(Arrays.asList(Biomes.FOREST, Biomes.MOUNTAIN)); public static final List MOVES = Collections.unmodifiableList(Arrays.asList(MovementPatterns.ONE_DIAGONAL_STEP, MovementPatterns.TWO_STEPS_IN_STRAIGHT_LINE)); + public static final List ATTACKS = Collections.unmodifiableList(Arrays.asList(Attacks.STOMP)); public static final int MAX_HEALTH = 80; public static final int MAX_ENERGY = 100; @@ -73,7 +74,10 @@ public class Troll extends Monster implements CanMove, CanAttack { if (attack.cost > energy) { return false; } - + if (attackIsNotInArsenal(attack)) { + return false; + } + player.setHealth(player.getHealth() - attack.cost); return true; } @@ -151,4 +155,8 @@ public class Troll extends Monster implements CanMove, CanAttack { energy = MIN_ENERGY; } } + + private boolean attackIsNotInArsenal(Attacks attack) { + return !ATTACKS.contains(attack); + } } diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index e1f7762..df69333 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -173,8 +173,23 @@ public class MonsterTest { } @Test - void use_of_attack_not_in_arsenal_is_rejected() { + void attack_rejected_when_not_in_arsenal_troll() { + assertThat(false, equalTo(defaultTroll.performAttack(Attacks.CHILL, mockPlayer))); } + @Test + void attack_rejected_when_not_in_arsenal_shade() { + assertThat(false, equalTo(defaultShade.performAttack(Attacks.STOMP, mockPlayer))); + } + + @Test + void troll_can_attack_player() { + assertThat(true, equalTo(defaultTroll.performAttack(Attacks.STOMP, mockPlayer))); + } + + @Test + void shade_can_attack_player() { + assertThat(true, equalTo(defaultShade.performAttack(Attacks.CHILL, mockPlayer))); + } } -- 2.39.5 From c526a364a0857ad5e653c591245b941adcff6412 Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Tue, 28 Oct 2025 22:34:50 +0100 Subject: [PATCH 24/31] =?UTF-8?q?Skrivit=20'troll=5Fwont=5Fmove=5Fto=5Ftil?= =?UTF-8?q?e=5Fwith=5Fwrong=5Fbiome()'.=20H=C3=A4r=20=C3=A4r=20det=20lager?= =?UTF-8?q?=20av=20mocks,=20och=20jag=20=C3=A4r=20lite=20os=C3=A4ker=20p?= =?UTF-8?q?=C3=A5=20hur=20det=20fungerar.=20Det=20kan=20bli=20s=C3=A5=20at?= =?UTF-8?q?t=20jag=20m=C3=A5ste=20ta=20bort=20testet.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/MonsterTest.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index df69333..54de04b 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -18,6 +18,7 @@ public class MonsterTest { private Player mockPlayer = mock(Player.class); private World mockWorld = mock(World.class); + private Tile mockTile = mock(Tile.class); @BeforeEach void reset() { @@ -192,4 +193,13 @@ public class MonsterTest { assertThat(true, equalTo(defaultShade.performAttack(Attacks.CHILL, mockPlayer))); } + @Test + void troll_wont_move_to_tile_with_wrong_biome() { + Position destination = new Position(1, 3); + when(mockTile.getBiome()).thenReturn(Biomes.COAST); + when(mockWorld.getTileAtPosition(destination)).thenReturn(mockTile); + + assertThat(false, equalTo(defaultTroll.moveTo(destination, mockWorld))); + } + } -- 2.39.5 From 8f4f2c71453fe6eeb47e2d381f646efc28f52334 Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Tue, 28 Oct 2025 22:51:38 +0100 Subject: [PATCH 25/31] =?UTF-8?q?'troll=5Fwont=5Fmove=5Fto=5Ftile=5Fwith?= =?UTF-8?q?=5Fwrong=5Fbiome()'=20g=C3=A5r=20igenom!!=20Ska=20skriva=20dess?= =?UTF-8?q?=20inverterade=20test=20h=C3=A4rn=C3=A4st=20f=C3=B6r=20att=20s?= =?UTF-8?q?=C3=A4kerst=C3=A4lla=20att=20inget=20fuffens=20sker...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Monster/Troll.java | 7 +++++++ src/test/java/MonsterTest.java | 9 ++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/Monster/Troll.java b/src/main/java/Monster/Troll.java index 853e5cb..4339a0c 100644 --- a/src/main/java/Monster/Troll.java +++ b/src/main/java/Monster/Troll.java @@ -101,6 +101,9 @@ public class Troll extends Monster implements CanMove, CanAttack { if (playerIsAtPosition(destination, world)) { return false; } + if (tileHasWrongHabitat(position, world)) { + return false; + } position = destination; updateDestinations(position, world); @@ -159,4 +162,8 @@ public class Troll extends Monster implements CanMove, CanAttack { private boolean attackIsNotInArsenal(Attacks attack) { return !ATTACKS.contains(attack); } + + private boolean tileHasWrongHabitat(Position position, World world) { + return !HABITAT.contains(world.getTileAtPosition(position).getBiome()); + } } diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index 54de04b..03396c0 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -195,11 +195,14 @@ public class MonsterTest { @Test void troll_wont_move_to_tile_with_wrong_biome() { - Position destination = new Position(1, 3); when(mockTile.getBiome()).thenReturn(Biomes.COAST); - when(mockWorld.getTileAtPosition(destination)).thenReturn(mockTile); + Position destination = new Position(1, 3); - assertThat(false, equalTo(defaultTroll.moveTo(destination, mockWorld))); + worldGenerator.randomWorldGeneration(); + World world = worldGenerator.getWorld(); + world.addTile(mockTile, destination); + + assertThat(defaultTroll.moveTo(destination, world), equalTo(false)); } } -- 2.39.5 From 63b737d1c59e63c457d6014d6a6f29ee095027f2 Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Tue, 28 Oct 2025 22:58:42 +0100 Subject: [PATCH 26/31] =?UTF-8?q?B=C3=A5da=20varianterna=20p=C3=A5=20habit?= =?UTF-8?q?attestet=20g=C3=A5r=20igenom,=20och=20jag=20har=20=C3=A4ven=20o?= =?UTF-8?q?rdnat=20vad=20jag=20hoppas=20var=20det=20sista=20av=20flera=20l?= =?UTF-8?q?ogiska=20fel=20i=20dom=20aktuella=20metoderna=20i=20'Troll'.=20?= =?UTF-8?q?Tagit=20bort=20'Nixie'=20d=C3=A5=20jag=20inte=20hunnit=20f?= =?UTF-8?q?=C3=A4rdigst=C3=A4lla=20den.=20Prelimin=C3=A4rt=20=C3=A4r=20det?= =?UTF-8?q?ta=20den=20slutgiltiga=20versionen=20av=20min=20kod,=20men=20vi?= =?UTF-8?q?=20f=C3=A5r=20v=C3=A4ll=20se...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Monster/Nixie.java | 8 -------- src/main/java/Monster/Troll.java | 2 +- src/test/java/MonsterTest.java | 12 ++++++++++++ 3 files changed, 13 insertions(+), 9 deletions(-) delete mode 100644 src/main/java/Monster/Nixie.java diff --git a/src/main/java/Monster/Nixie.java b/src/main/java/Monster/Nixie.java deleted file mode 100644 index 488034c..0000000 --- a/src/main/java/Monster/Nixie.java +++ /dev/null @@ -1,8 +0,0 @@ -package Monster; - -public abstract class Nixie extends Monster implements CanMove, CanAttack { - - public Nixie() { - super(0,0,Monster.DEFAULT_POSITION); - } -} diff --git a/src/main/java/Monster/Troll.java b/src/main/java/Monster/Troll.java index 4339a0c..d3a2de1 100644 --- a/src/main/java/Monster/Troll.java +++ b/src/main/java/Monster/Troll.java @@ -101,7 +101,7 @@ public class Troll extends Monster implements CanMove, CanAttack { if (playerIsAtPosition(destination, world)) { return false; } - if (tileHasWrongHabitat(position, world)) { + if (tileHasWrongHabitat(destination, world)) { return false; } diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index 03396c0..c4d3b80 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -205,4 +205,16 @@ public class MonsterTest { assertThat(defaultTroll.moveTo(destination, world), equalTo(false)); } + @Test + void troll_can_move_to_tile_within_its_habitat() { + when(mockTile.getBiome()).thenReturn(Biomes.FOREST); + Position destination = new Position(1, 3); + + worldGenerator.randomWorldGeneration(); + World world = worldGenerator.getWorld(); + world.addTile(mockTile, destination); + + assertThat(defaultTroll.moveTo(destination, world), equalTo(true)); + } + } -- 2.39.5 From 446997ddbf78bb4be3f77bcf01464391c9412efa Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Wed, 29 Oct 2025 14:12:19 +0100 Subject: [PATCH 27/31] Bugg i Trolls moveTo fixad! --- src/main/java/Monster/Troll.java | 3 --- src/test/java/MonsterTest.java | 1 - 2 files changed, 4 deletions(-) diff --git a/src/main/java/Monster/Troll.java b/src/main/java/Monster/Troll.java index d3a2de1..5ff411e 100644 --- a/src/main/java/Monster/Troll.java +++ b/src/main/java/Monster/Troll.java @@ -98,9 +98,6 @@ public class Troll extends Monster implements CanMove, CanAttack { if (isDead()) { return false; } - if (playerIsAtPosition(destination, world)) { - return false; - } if (tileHasWrongHabitat(destination, world)) { return false; } diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index c4d3b80..8baa1ed 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -9,7 +9,6 @@ import static org.hamcrest.MatcherAssert.*; import static org.hamcrest.Matchers.*; import static org.mockito.Mockito.*; - public class MonsterTest { private Shade defaultShade; -- 2.39.5 From bfeb33c4ea429449be05fd6e6af941fe4dfd9c67 Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Wed, 29 Oct 2025 14:12:19 +0100 Subject: [PATCH 28/31] Bugg i Trolls moveTo fixad! --- src/main/java/Monster/Shade.java | 10 +++++--- src/main/java/Monster/Troll.java | 43 +++++++++++++------------------- src/test/java/MonsterTest.java | 1 - 3 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/main/java/Monster/Shade.java b/src/main/java/Monster/Shade.java index 43d95cf..cfcb6cc 100644 --- a/src/main/java/Monster/Shade.java +++ b/src/main/java/Monster/Shade.java @@ -77,10 +77,11 @@ public class Shade extends Monster implements CanMove, CanAttack { } public boolean move(World world) { + updateDestinations(position, world); + if (isDead()) { return false; } - updateDestinations(position, world); if (validDestinations.isEmpty()) { return false; } @@ -90,15 +91,18 @@ public class Shade extends Monster implements CanMove, CanAttack { } public boolean moveTo(Position destination, World world) { + updateDestinations(position, world); + if (isDead()) { return false; } if (playerIsAtPosition(destination, world)) { return false; } - + if (validDestinations.isEmpty()) { + return false; + } position = destination; - updateDestinations(position, world); return true; } diff --git a/src/main/java/Monster/Troll.java b/src/main/java/Monster/Troll.java index d3a2de1..82623df 100644 --- a/src/main/java/Monster/Troll.java +++ b/src/main/java/Monster/Troll.java @@ -3,7 +3,7 @@ package Monster; import Entity.Entity; import Entity.Player; import Entity.Position; -import World.World; +import World.*; import java.util.*; @@ -82,10 +82,11 @@ public class Troll extends Monster implements CanMove, CanAttack { } public boolean move(World world) { + updateDestinations(position, world); + if (isDead()) { return false; } - updateDestinations(position, world); if (validDestinations.isEmpty()) { return false; } @@ -95,18 +96,18 @@ public class Troll extends Monster implements CanMove, CanAttack { } public boolean moveTo(Position destination, World world) { + updateDestinations(position, world); + if (isDead()) { return false; } - if (playerIsAtPosition(destination, world)) { - return false; - } if (tileHasWrongHabitat(destination, world)) { return false; } - + if (validDestinations.isEmpty()) { + return false; + } position = destination; - updateDestinations(position, world); return true; } @@ -116,7 +117,7 @@ public class Troll extends Monster implements CanMove, CanAttack { if (move.cost <= energy) { List destinations = move.findLegalDestinations(position); for (Position destination : destinations) { - if (noPlayerIsAtPosition(destination, world)) { + if (tileHasWrongHabitat(destination, world)) { validDestinations.add(destination); } } @@ -124,22 +125,6 @@ public class Troll extends Monster implements CanMove, CanAttack { } } - private boolean playerIsAtPosition(Position position, World world) { - List entitiesAtPosition = world.getPositionEntityMap().get(position); - if (isNull(entitiesAtPosition)) { - return false; - } - for (Entity entity : entitiesAtPosition) { - if (entity instanceof Player) { - return true; - } - } - return false; - } - - private boolean noPlayerIsAtPosition(Position position, World world) { - return !playerIsAtPosition(position, world); - } private void enforceHealthValueBoundries() { if (health > MAX_HEALTH) { @@ -164,6 +149,14 @@ public class Troll extends Monster implements CanMove, CanAttack { } private boolean tileHasWrongHabitat(Position position, World world) { - return !HABITAT.contains(world.getTileAtPosition(position).getBiome()); + Tile destinationTile = world.getTileAtPosition(position); + if (Objects.isNull(destinationTile)) { + return false; + } + boolean hasWrongBiome = !HABITAT.contains(destinationTile.getBiome()); + if (Objects.isNull(hasWrongBiome)) { + return false; + } + return hasWrongBiome; } } diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index c4d3b80..8baa1ed 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -9,7 +9,6 @@ import static org.hamcrest.MatcherAssert.*; import static org.hamcrest.Matchers.*; import static org.mockito.Mockito.*; - public class MonsterTest { private Shade defaultShade; -- 2.39.5 From 68080cd15a1944ca0dfd88008424e0aadc500796 Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Wed, 29 Oct 2025 14:58:30 +0100 Subject: [PATCH 29/31] =?UTF-8?q?Nu=20=C3=A4r=20allt=20bra!!!=20:)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/Monster/Shade.java | 1 - src/main/java/Monster/Troll.java | 7 +------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/main/java/Monster/Shade.java b/src/main/java/Monster/Shade.java index cfcb6cc..51c376c 100644 --- a/src/main/java/Monster/Shade.java +++ b/src/main/java/Monster/Shade.java @@ -86,7 +86,6 @@ public class Shade extends Monster implements CanMove, CanAttack { return false; } position = validDestinations.get(random.nextInt(validDestinations.size())); - updateDestinations(position, world); return true; } diff --git a/src/main/java/Monster/Troll.java b/src/main/java/Monster/Troll.java index 82623df..4489103 100644 --- a/src/main/java/Monster/Troll.java +++ b/src/main/java/Monster/Troll.java @@ -91,7 +91,6 @@ public class Troll extends Monster implements CanMove, CanAttack { return false; } position = validDestinations.get(random.nextInt(validDestinations.size())); - updateDestinations(position, world); return true; } @@ -116,11 +115,7 @@ public class Troll extends Monster implements CanMove, CanAttack { for (MovementPatterns move : MOVES) { if (move.cost <= energy) { List destinations = move.findLegalDestinations(position); - for (Position destination : destinations) { - if (tileHasWrongHabitat(destination, world)) { - validDestinations.add(destination); - } - } + validDestinations.addAll(destinations); } } } -- 2.39.5 From ec9de940191f107cf28896f1a783d66c474965e8 Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Wed, 29 Oct 2025 15:44:25 +0100 Subject: [PATCH 30/31] Beslutstabellstesterna har implementerats. --- src/test/java/MonsterTest.java | 65 ++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index 8baa1ed..7818cbd 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -13,6 +13,7 @@ public class MonsterTest { private Shade defaultShade; private Troll defaultTroll; + private Position defaultDestination = new Position(2, 2); private MapGenerator worldGenerator = new MapGenerator(5, 5); private Player mockPlayer = mock(Player.class); @@ -28,13 +29,13 @@ public class MonsterTest { @Test void shade_cannot_move_after_death() { defaultShade.kill(); - assertThat(false, equalTo(defaultShade.moveTo(new Position(1, 2), mockWorld))); + assertThat(false, equalTo(defaultShade.moveTo(defaultDestination, mockWorld))); } @Test void troll_cannot_move_after_death() { defaultTroll.kill(); - assertThat(false, equalTo(defaultTroll.moveTo(new Position(1, 2), mockWorld))); + assertThat(false, equalTo(defaultTroll.moveTo(defaultDestination, mockWorld))); } @Test @@ -216,4 +217,64 @@ public class MonsterTest { assertThat(defaultTroll.moveTo(destination, world), equalTo(true)); } + // HÄR BÖRJAR BESLUTSTABELLSTESTERNA + + @Test + void decision_table_t1() { + defaultTroll.kill(); + assertThat(defaultTroll.moveTo(defaultDestination, mockWorld), equalTo(false)); + } + + @Test + void decision_table_t2() { + Monster shade = new Shade(Shade.MAX_HEALTH, 0, Shade.DEFAULT_POSITION); + assertThat(shade.moveTo(defaultDestination, mockWorld), equalTo(false)); + } + + @Test + void decision_table_t3() { + worldGenerator.randomWorldGeneration(); + World world = worldGenerator.getWorld(); + + when(mockPlayer.getPosition()).thenReturn(defaultDestination); + world.addEntityToMap(mockPlayer); + + assertThat(defaultShade.moveTo(defaultDestination, world), equalTo(false)); + } + + @Test + void decision_table_t4() { + worldGenerator.randomWorldGeneration(); + World world = worldGenerator.getWorld(); + + when(mockPlayer.getPosition()).thenReturn(new Position(6, 8)); + world.addEntityToMap(mockPlayer); + + assertThat(defaultShade.moveTo(defaultDestination, world), equalTo(true)); + } + + @Test + void decision_table_t5() { + when(mockTile.getBiome()).thenReturn(Biomes.COAST); + Position destination = new Position(1, 3); + + worldGenerator.randomWorldGeneration(); + World world = worldGenerator.getWorld(); + world.addTile(mockTile, destination); + + assertThat(defaultTroll.moveTo(destination, world), equalTo(false)); + } + + @Test + void decision_table_t6() { + when(mockTile.getBiome()).thenReturn(Biomes.FOREST); + Position destination = new Position(1, 3); + + worldGenerator.randomWorldGeneration(); + World world = worldGenerator.getWorld(); + world.addTile(mockTile, destination); + + assertThat(defaultTroll.moveTo(destination, world), equalTo(true)); + } + } -- 2.39.5 From ec17ff8dd3ecc84d52ab38ab8b0c0fc9285ef504 Mon Sep 17 00:00:00 2001 From: Aster000000 Date: Wed, 29 Oct 2025 23:33:17 +0100 Subject: [PATCH 31/31] =?UTF-8?q?=C3=96kat=20test-coverage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/MonsterTest.java | 51 ++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/src/test/java/MonsterTest.java b/src/test/java/MonsterTest.java index 7818cbd..6acf0bb 100644 --- a/src/test/java/MonsterTest.java +++ b/src/test/java/MonsterTest.java @@ -217,6 +217,46 @@ public class MonsterTest { assertThat(defaultTroll.moveTo(destination, world), equalTo(true)); } + @Test + void get_health_returns_correct_value() { + defaultShade = new Shade(8, Shade.MAX_ENERGY, Shade.DEFAULT_POSITION); + assertThat(defaultShade.getHealth(), equalTo(8)); + } + + @Test + void get_energy_returns_correct_value() { + defaultShade = new Shade(Shade.MAX_HEALTH, 10, Shade.DEFAULT_POSITION); + assertThat(defaultShade.getEnergy(), equalTo(10)); + } + + @Test + void shade_can_heal() { + defaultShade = new Shade(8, Shade.MAX_ENERGY, Shade.DEFAULT_POSITION); + assertThat(defaultShade.heal(), equalTo(true)); + } + + @Test + void troll_can_heal() { + defaultTroll = new Troll(8, Troll.MAX_ENERGY, Troll.DEFAULT_POSITION); + assertThat(defaultTroll.heal(), equalTo(true)); + } + + @Test + void shade_can_take_damage() { + assertThat(defaultShade.takeDamage(5), equalTo(true)); + } + + @Test + void troll_can_take_damage() { + assertThat(defaultTroll.takeDamage(5), equalTo(true)); + } + + @Test + void troll_wont_heal_when_it_doesnt_have_enough_energy() { + defaultTroll = new Troll(8, 2, Troll.DEFAULT_POSITION); + assertThat(defaultTroll.heal(), equalTo(false)); + } + // HÄR BÖRJAR BESLUTSTABELLSTESTERNA @Test @@ -256,25 +296,24 @@ public class MonsterTest { @Test void decision_table_t5() { when(mockTile.getBiome()).thenReturn(Biomes.COAST); - Position destination = new Position(1, 3); worldGenerator.randomWorldGeneration(); World world = worldGenerator.getWorld(); - world.addTile(mockTile, destination); + world.addTile(mockTile, defaultDestination); - assertThat(defaultTroll.moveTo(destination, world), equalTo(false)); + assertThat(defaultTroll.moveTo(defaultDestination, world), equalTo(false)); } @Test void decision_table_t6() { when(mockTile.getBiome()).thenReturn(Biomes.FOREST); - Position destination = new Position(1, 3); + when(mockPlayer.getPosition()).thenReturn(defaultDestination); worldGenerator.randomWorldGeneration(); World world = worldGenerator.getWorld(); - world.addTile(mockTile, destination); + world.addTile(mockTile, defaultDestination); - assertThat(defaultTroll.moveTo(destination, world), equalTo(true)); + assertThat(defaultTroll.moveTo(defaultDestination, world), equalTo(true)); } } -- 2.39.5