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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user