Aufgabe 8.

edited class EditorState and ServerGameLogic
 to check for invalid maps in which ships overlap or are out of the map boundries for clientside and serverside
This commit is contained in:
Lukas Bauer
2024-10-02 18:24:27 +02:00
parent 93ade34282
commit 42b442e937
4 changed files with 104 additions and 10 deletions

View File

@@ -8,10 +8,12 @@
package pp.battleship.game.client;
import pp.battleship.message.client.ClientMessage;
import pp.battleship.message.client.MapMessage;
import pp.battleship.message.server.EffectMessage;
import pp.battleship.message.server.GameDetails;
import pp.battleship.message.server.ServerInterpreter;
import pp.battleship.message.server.StartBattleMessage;
import pp.battleship.model.Battleship;
import pp.battleship.model.IntPoint;
import pp.battleship.model.ShipMap;
import pp.battleship.model.dto.ShipMapDTO;

View File

@@ -16,6 +16,7 @@
import java.io.File;
import java.io.IOException;
import java.lang.System.Logger.Level;
import java.util.List;
import static pp.battleship.Resources.lookup;
import static pp.battleship.model.Battleship.Status.INVALID_PREVIEW;
@@ -111,8 +112,7 @@ private void placeShip(IntPoint cursor) {
harbor().remove(selectedInHarbor);
preview = null;
selectedInHarbor = null;
}
else {
} else {
preview.setStatus(INVALID_PREVIEW);
ownMap().add(preview);
}
@@ -135,8 +135,7 @@ public void clickHarbor(IntPoint pos) {
harbor().add(selectedInHarbor);
preview = null;
selectedInHarbor = null;
}
else if (shipAtCursor != null) {
} else if (shipAtCursor != null) {
selectedInHarbor = shipAtCursor;
selectedInHarbor.setStatus(VALID_PREVIEW);
harbor().remove(selectedInHarbor);
@@ -238,6 +237,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"));
if(!validMap(dto)){
throw new IOException(lookup("map is invalid"));
}
ownMap().clear();
dto.getShips().forEach(ownMap()::add);
harbor().clear();
@@ -264,4 +266,36 @@ public boolean mayLoadMap() {
public boolean maySaveMap() {
return harbor().getItems().isEmpty();
}
private boolean validMap(ShipMapDTO dto) {
return inBoundsClient(dto) && overLapClient(dto);
}
private boolean overLapClient(ShipMapDTO dto) {
List<Battleship> battleshipList = dto.getShips();
for (int i = 0; i < battleshipList.size(); i++) {
Battleship ship1 = battleshipList.get(i);
for (int j = i + 1; j < battleshipList.size(); j++) {
Battleship ship2 = battleshipList.get(j);
if (ship1.collidesWith(ship2)) {
return false;
}
}
}
return true;
}
private boolean inBoundsClient(ShipMapDTO dto) {
int widht = dto.getWidth();
int height = dto.getHeight();
for (int i = 0; i < dto.getShips().size(); i++) {
Battleship localShip = dto.getShips().get(i);
if (!(localShip.getMaxX() < widht && localShip.getMaxY() < height && localShip.getMinY() >= 0 && localShip.getMinX() >= 0)) {
return false;
}
}
return true;
}
}

View File

@@ -54,6 +54,7 @@ public ServerGameLogic(ServerSender serverSender, BattleshipConfig config) {
* Returns the state of the game.
*/
ServerState getState() {
return state;
}
@@ -146,6 +147,58 @@ public void received(MapMessage msg, int from) {
playerReady(getPlayerById(from), msg.getShips());
}
/**
* Checks if the map is Valid in terms of boundries and overlaps
*
* @param msg the received MapMessage
* @param id the ID of the sender client
* @return
*/
private boolean validMap(MapMessage msg, int id) {
return inBounds(msg, id) && overLap(msg);
}
/**
* Checks if the Ships overLap
*
* @param msg the received MapMessage
* @return
*/
private boolean overLap(MapMessage msg) {
List<Battleship> battleshipList = msg.getShips();
for (int i = 0; i < battleshipList.size(); i++) {
Battleship ship1 = battleshipList.get(i);
for (int j = i + 1; j < battleshipList.size(); j++) {
Battleship ship2 = battleshipList.get(j);
if (ship1.collidesWith(ship2)) {
return false;
}
}
}
return true;
}
/**
* Checks if the Ship is placed in Bounds with the Map
*
* @param msg the received MapMessage
* @param id the ID of the sender client
* @return
*/
private boolean inBounds(MapMessage msg, int id) {
int widht = getPlayerById(id).getMap().getWidth();
int height = getPlayerById(id).getMap().getHeight();
for (int i = 0; i < msg.getShips().size(); i++) {
Battleship localShip = msg.getShips().get(i);
if (!(localShip.getMaxX() < widht && localShip.getMaxY() < height && localShip.getMinY() >= 0 && localShip.getMinX() >= 0)) {
return false;
}
}
return true;
}
/**
* Handles the reception of a ShootMessage.
*
@@ -195,8 +248,7 @@ void shoot(Player p, IntPoint pos) {
send(activePlayer, EffectMessage.miss(true, pos));
send(otherPlayer, EffectMessage.miss(false, pos));
activePlayer = otherPlayer;
}
else {
} else {
// shot hit a ship
selectedShip.hit(pos);
if (otherPlayer.getMap().getRemainingShips().isEmpty()) {
@@ -204,13 +256,11 @@ void shoot(Player p, IntPoint pos) {
send(activePlayer, EffectMessage.won(pos, selectedShip));
send(otherPlayer, EffectMessage.lost(pos, selectedShip, activePlayer.getMap().getRemainingShips()));
setState(ServerState.GAME_OVER);
}
else if (selectedShip.isDestroyed()) {
} else if (selectedShip.isDestroyed()) {
// ship has been destroyed, but game is not yet over
send(activePlayer, EffectMessage.shipDestroyed(true, pos, selectedShip));
send(otherPlayer, EffectMessage.shipDestroyed(false, pos, selectedShip));
}
else {
} else {
// ship has been hit, but it hasn't been destroyed
send(activePlayer, EffectMessage.hit(true, pos));
send(otherPlayer, EffectMessage.hit(false, pos));

View File

@@ -73,6 +73,14 @@ public boolean fits(GameDetails details) {
return true;
}
public int getHeight() {
return height;
}
public int getWidth() {
return width;
}
/**
* Returns the ships stored in this DTO.
*