import java.util.ArrayList; import java.util.List; /** * Diese Klasse ist das Board von eimem spieler und enthält alle logischen operationen. * Sprich ist das Backend Board. * * @author Peer Ole Wachtel, Florian Alexy und Florian Hantzschel */ public class Board { /** * Alle bisher empfangenen HitResponsen */ private List hits; /** * Alle Schiffe des Semesters */ private List ships; /** * Die größe des Spielfeldes */ private final int size; /** * Erstellt ein neues Board. * setzt die übergebene Spielfeldgröße. * Erstellt die Liste aller Schiffe des Semesters * @param size Die größe des Spielfeldes * @author Peer Ole Wachtel, Florian Alexy und Florian Hantzschel */ public Board(int size) { this.size = size; this.ships = new ArrayList<>(); this.hits = new ArrayList<>(); this.createShip(size - 13); } /** * Nimmt einen punkt entgegen und Gibt einen HitResponse zurück. * @param point auf den geschossen wurde * @return * @author Peer Ole Wachtel */ public synchronized HitResponse hit (Point point){ HitResponse response = new HitResponse(HitResponseType.MISS,point); for (int i = 0; i < this.ships.size(); i++) { HitResponseType type = this.ships.get(i).shootOnShip(point); if ( type == HitResponseType.SUNK) { for (int ii = 0; ii < this.ships.size(); ii++) { if (!this.ships.get(ii).isSunk()) { response.setType(type); this.addHits(response); return response; } } response.setType(HitResponseType.VICTORY); this.addHits(response); return response; } else if (type == HitResponseType.HIT) { response.setType(type); this.addHits(response); return response; } } this.addHits(response); return response; } /** * finds adjacened hit responses and sets their type to SUNK if they are currently HIT * this makes it so that all the points of the ship are marked as SUNK, not just the final hit * @param p the Point from which to propate the SUNK type * @author Luca Conte */ private void propagateSunk(Point p) { HitResponse hit = this.getHitResponseOnPoint(p); if (hit == null || hit.getType() != HitResponseType.HIT) return; hit.setType(HitResponseType.SUNK); propagateSunk(new Point(p.getX() + 1, p.getY())); propagateSunk(new Point(p.getX() - 1, p.getY())); propagateSunk(new Point(p.getX(), p.getY() + 1)); propagateSunk(new Point(p.getX(), p.getY() - 1)); } /** * creates all the ships on a board given a certain semester * @param semester the semester to be played in * @author Peer Ole Wachtel */ private void createShip(int semester){ List shipData = Ship.semeterList.get(semester-1); for (int i = 0; i < shipData.size(); i++) { this.ships.add(new Ship(shipData.get(i).size(), shipData.get(i).name())); } } /** * returns a list of all the Ships on the board * @return a list of all the Ships on the board * @author Peer Ole Wachtel */ public List getShips() { return ships; } /** * adds a HitResponse to the list of Hits on the board * If a hit response already exists on the same position, the hit response will not be added * If the hit response is of type `HitResponseType.SUNK` it will propagate this hit response type * to all adjacened hit responses with type HIT using `propagateSunk`. * @param hitResponse the HitResponse to be added * @return true when the hit response was added, otherwise false * @author Peer Ole Wachtel, Luca Conte */ public synchronized boolean addHits(HitResponse hitResponse) { if (this.getHitResponseOnPoint(hitResponse.getPoint()) == null){ this.hits.add(hitResponse); //Propagate sunk for display purposes if (hitResponse.getType() == HitResponseType.SUNK) { hitResponse.setType(HitResponseType.HIT); propagateSunk(hitResponse.getPoint()); } return true; } return false; } /** * @param point the position to get the hit response from * @return the hit response at the position `point` * @author Peer Ole Wachtel */ public synchronized HitResponse getHitResponseOnPoint(Point point) { for (int i = 0; i < this.hits.size(); i++){ if (this.hits.get(i).getPoint().equals(point)){ return this.hits.get(i); } } return null; } /** * returns the size of the board * @return the size of the board * @author Florian Alexy, Florian Hantzschel */ public int getSize() { return this.size; } }