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.
This commit is contained in:
Hanno Fleischer hanno.fleischer@unibw.de
2024-10-02 14:50:14 +02:00
parent 1bac56c92c
commit 7b70666332
2 changed files with 65 additions and 4 deletions

View File

@@ -16,8 +16,10 @@
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.System.Logger.Level; import java.lang.System.Logger.Level;
import java.util.Arrays;
import static pp.battleship.Resources.lookup; 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.INVALID_PREVIEW;
import static pp.battleship.model.Battleship.Status.NORMAL; import static pp.battleship.model.Battleship.Status.NORMAL;
import static pp.battleship.model.Battleship.Status.VALID_PREVIEW; import static pp.battleship.model.Battleship.Status.VALID_PREVIEW;
@@ -56,7 +58,7 @@ public boolean showEditor() {
*/ */
@Override @Override
public void movePreview(IntPoint pos) { 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; if (preview == null || !ownMap().isValid(pos)) return;
preview.moveTo(pos); preview.moveTo(pos);
setPreviewStatus(preview); setPreviewStatus(preview);
@@ -71,7 +73,7 @@ public void movePreview(IntPoint pos) {
*/ */
@Override @Override
public void clickOwnMap(IntPoint pos) { 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 (!ownMap().isValid(pos)) return;
if (preview == null) if (preview == null)
modifyShip(pos); modifyShip(pos);
@@ -125,7 +127,7 @@ private void placeShip(IntPoint cursor) {
*/ */
@Override @Override
public void clickHarbor(IntPoint pos) { 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; if (!harbor().isValid(pos)) return;
final Battleship shipAtCursor = harbor().findShipAt(pos); final Battleship shipAtCursor = harbor().findShipAt(pos);
if (preview != null) { if (preview != null) {
@@ -152,7 +154,7 @@ else if (shipAtCursor != null) {
*/ */
@Override @Override
public void rotateShip() { public void rotateShip() {
ClientGameLogic.LOGGER.log(Level.DEBUG, "pushed rotate"); //NON-NLS LOGGER.log(Level.DEBUG, "pushed rotate"); //NON-NLS
if (preview == null) return; if (preview == null) return;
preview.rotated(); preview.rotated();
ownMap().remove(preview); ownMap().remove(preview);
@@ -238,6 +240,9 @@ public void loadMap(File file) throws IOException {
final ShipMapDTO dto = ShipMapDTO.loadFrom(file); final ShipMapDTO dto = ShipMapDTO.loadFrom(file);
if (!dto.fits(logic.getDetails())) if (!dto.fits(logic.getDetails()))
throw new IOException(lookup("map.doesnt.fit")); throw new IOException(lookup("map.doesnt.fit"));
else if (!checkMapToLoad(dto)) {
throw new IOException(lookup("ships.dont.fit.the.map"));
}
ownMap().clear(); ownMap().clear();
dto.getShips().forEach(ownMap()::add); dto.getShips().forEach(ownMap()::add);
harbor().clear(); harbor().clear();
@@ -245,6 +250,48 @@ public void loadMap(File file) throws IOException {
selectedInHarbor = null; 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. * Checks if the player's own map may be loaded from a file.
* *

View File

@@ -82,6 +82,20 @@ public List<Battleship> getShips() {
return ships.stream().map(BattleshipDTO::toBattleship).toList(); 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. * Saves the current ShipMapDTO to a file in JSON format.
* *