From 7b70666332d3a52588c115243ef6bf29e17bf8d5 Mon Sep 17 00:00:00 2001 From: "Hanno Fleischer hanno.fleischer@unibw.de" <96438401+fletch13@users.noreply.github.com> Date: Wed, 2 Oct 2024 14:50:14 +0200 Subject: [PATCH] added the solution for exercise 8 for the client added the checkMapToLoad() in EditorState.java so if the Player tries to load a map it will be checked if the placement is correct. --- .../battleship/game/client/EditorState.java | 55 +++++++++++++++++-- .../pp/battleship/model/dto/ShipMapDTO.java | 14 +++++ 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/game/client/EditorState.java b/Projekte/battleship/model/src/main/java/pp/battleship/game/client/EditorState.java index 3e5b837e..27058c03 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/game/client/EditorState.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/game/client/EditorState.java @@ -16,8 +16,10 @@ import java.io.File; import java.io.IOException; import java.lang.System.Logger.Level; +import java.util.Arrays; import static pp.battleship.Resources.lookup; +import static pp.battleship.game.client.ClientGameLogic.LOGGER; import static pp.battleship.model.Battleship.Status.INVALID_PREVIEW; import static pp.battleship.model.Battleship.Status.NORMAL; import static pp.battleship.model.Battleship.Status.VALID_PREVIEW; @@ -56,7 +58,7 @@ public boolean showEditor() { */ @Override public void movePreview(IntPoint pos) { - ClientGameLogic.LOGGER.log(Level.DEBUG, "move preview to {0}", pos); //NON-NLS + LOGGER.log(Level.DEBUG, "move preview to {0}", pos); //NON-NLS if (preview == null || !ownMap().isValid(pos)) return; preview.moveTo(pos); setPreviewStatus(preview); @@ -71,7 +73,7 @@ public void movePreview(IntPoint pos) { */ @Override public void clickOwnMap(IntPoint pos) { - ClientGameLogic.LOGGER.log(Level.DEBUG, "click at {0} in own map", pos); //NON-NLS + LOGGER.log(Level.DEBUG, "click at {0} in own map", pos); //NON-NLS if (!ownMap().isValid(pos)) return; if (preview == null) modifyShip(pos); @@ -125,7 +127,7 @@ private void placeShip(IntPoint cursor) { */ @Override public void clickHarbor(IntPoint pos) { - ClientGameLogic.LOGGER.log(Level.DEBUG, "click at {0} in harbor", pos); //NON-NLS + LOGGER.log(Level.DEBUG, "click at {0} in harbor", pos); //NON-NLS if (!harbor().isValid(pos)) return; final Battleship shipAtCursor = harbor().findShipAt(pos); if (preview != null) { @@ -152,7 +154,7 @@ else if (shipAtCursor != null) { */ @Override public void rotateShip() { - ClientGameLogic.LOGGER.log(Level.DEBUG, "pushed rotate"); //NON-NLS + LOGGER.log(Level.DEBUG, "pushed rotate"); //NON-NLS if (preview == null) return; preview.rotated(); ownMap().remove(preview); @@ -238,6 +240,9 @@ public void loadMap(File file) throws IOException { final ShipMapDTO dto = ShipMapDTO.loadFrom(file); if (!dto.fits(logic.getDetails())) throw new IOException(lookup("map.doesnt.fit")); + else if (!checkMapToLoad(dto)) { + throw new IOException(lookup("ships.dont.fit.the.map")); + } ownMap().clear(); dto.getShips().forEach(ownMap()::add); harbor().clear(); @@ -245,6 +250,48 @@ public void loadMap(File file) throws IOException { selectedInHarbor = null; } + private boolean checkMapToLoad(ShipMapDTO dto) { + int mapWidth = dto.getWidth(); + int mapHeight = dto.getHeight(); + + // check if ship is out of bounds + for (int i = 0; i < dto.getShips().size(); i++) { + Battleship battleship = dto.getShips().get(i); + if (battleship.getMaxX() >= mapWidth || battleship.getMinX() < 0 || battleship.getMaxY() >= mapHeight || battleship.getMinY() < 0) { + LOGGER.log(Level.ERROR, "Ship is out of bounds ({0})", battleship.toString()); + return false; + } + } + + // check if ships overlap + int[][] tempMap = new int[mapWidth][mapHeight]; + for (int[] row : tempMap) + Arrays.fill(row, 0); + dto.getShips().forEach(s -> { + int deltaX = s.getMaxX() - s.getMinX(); + int deltaY = s.getMaxY() - s.getMinY(); + int lastX = s.getX(); + int lastY = s.getY(); + tempMap[lastX][lastY] += 1; + for (int i = 0; i < deltaX - 1; i++) + for (int j = 0; j < deltaY - 1; j++) { + tempMap[lastX + (deltaX / Math.abs(deltaX))][lastY + (deltaY / Math.abs(deltaY))] += 1; + lastX = lastX + (deltaX / Math.abs(deltaX)); + lastY = lastY + (deltaY / Math.abs(deltaY)); + } + }); + for (int[] row : tempMap) { + for (int cell : row) { + if (cell > 1) { + LOGGER.log(Level.ERROR, "There are multiple ships on one position"); + return false; + } + } + } + + return true; + } + /** * Checks if the player's own map may be loaded from a file. * diff --git a/Projekte/battleship/model/src/main/java/pp/battleship/model/dto/ShipMapDTO.java b/Projekte/battleship/model/src/main/java/pp/battleship/model/dto/ShipMapDTO.java index 9d53146c..76507830 100644 --- a/Projekte/battleship/model/src/main/java/pp/battleship/model/dto/ShipMapDTO.java +++ b/Projekte/battleship/model/src/main/java/pp/battleship/model/dto/ShipMapDTO.java @@ -82,6 +82,20 @@ public List getShips() { return ships.stream().map(BattleshipDTO::toBattleship).toList(); } + /** + * This method returns the width of the DTO. + * + * @return the width of the DTO + */ + public int getWidth() {return width;} + + /** + * Returns the height of the DTO. + * + * @return the height of the DTO. + */ + public int getHeight() {return height;} + /** * Saves the current ShipMapDTO to a file in JSON format. *