diff --git a/src/Board.java b/src/Board.java index 1b7095b..0587b0c 100644 --- a/src/Board.java +++ b/src/Board.java @@ -61,6 +61,10 @@ public class Board { 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 + */ private void createShip(int semester){ List shipData = Ship.semeterList.get(semester -1); for (int i = 0; i < shipData.size(); i++) { @@ -68,10 +72,22 @@ public class Board { } } + /** + * @return a list of all the Ships on the board + */ 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 + * + */ public synchronized boolean addHits(HitResponse hitResponse) { if (this.getHitResponseOnPoint(hitResponse.getPoint()) == null){ this.hits.add(hitResponse); @@ -87,6 +103,10 @@ public class Board { return false; } + /** + * @param point the position to get the hit response from + * @return the hit response at the position `point` + */ public synchronized HitResponse getHitResponseOnPoint(Point point) { for (int i = 0; i < this.hits.size(); i++){ if (this.hits.get(i).getPoint().equals(point)){ @@ -96,6 +116,9 @@ public class Board { return null; } + /** + * @return the size of the board + */ public int getSize() { return this.size; } diff --git a/src/HumanPlayer.java b/src/HumanPlayer.java index 4dfdbe1..6f00dbe 100644 --- a/src/HumanPlayer.java +++ b/src/HumanPlayer.java @@ -1,7 +1,14 @@ public class HumanPlayer extends LocalPlayer { + /** + * shoots a shot onto the provided point on the enemy board + * if it is not the players turn, this method does nothing. + * @param point the location to be shot + * @author Luca Conte + */ @Override public void shoot(Point point) { + if (!this.myTurn) return; this.myTurn = false; enemy.receiveShoot(point); } diff --git a/src/LocalPlayer.java b/src/LocalPlayer.java index af66e53..4da86a6 100644 --- a/src/LocalPlayer.java +++ b/src/LocalPlayer.java @@ -8,6 +8,11 @@ public class LocalPlayer extends Player { this.myCoin = random.nextBoolean(); } + /** + * receives a shot onto a point from the enemy + * @param point the location to be shot + * @author Luca Conte, Peer Ole Wachtel + */ @Override public synchronized void receiveShoot(Point point) { if (!this.enemy.myTurn) return; @@ -29,6 +34,11 @@ public class LocalPlayer extends Player { GameController.getMainFrame().refreshGameBoard(); } + /** + * receives a hit response from the enemy as a response to a receiveShoot call + * @param hitResponse the hitresponse + * @author Peer Ole Wachtel + */ @Override public synchronized void receiveHit(HitResponse hitResponse) { enemy.board.addHits(hitResponse); @@ -40,6 +50,13 @@ public class LocalPlayer extends Player { GameController.getMainFrame().refreshGameBoard(); } + /** + * receives the enemies coin toss result + * this method does nothing if the player has already received the enemies coin + * it will also call `determineCoinToss` + * @param coin the coin of the enemy player + * @author Luca Conte + */ @Override public synchronized void receiveCoin(boolean coin) { if (!this.hasReceivedCoin) { @@ -57,6 +74,10 @@ public class LocalPlayer extends Player { return; } + /** + * marks the player as ready, if all ships have been placed + * @author Luca Conte + */ @Override public synchronized void ready() { for (Ship ship : this.board.getShips()) { diff --git a/src/OnlinePlayer.java b/src/OnlinePlayer.java index 4f0d56b..2db0a90 100644 --- a/src/OnlinePlayer.java +++ b/src/OnlinePlayer.java @@ -1,9 +1,15 @@ -public abstract class OnlinePlayer extends Player implements AsyncSocketListener{ +public abstract class OnlinePlayer extends Player implements AsyncSocketListener { protected AsyncSocket socket; protected int wantedBoardSize; protected boolean hasReceivedCoinPackage; + /** + * Constructor + * @param size the size of the board the enemy player wants to play with + * the actual board size will be determined once the semester of the online partner is known + * @param socket an AsyncSocket to communicate with the enemy through + */ public OnlinePlayer(Integer size, AsyncSocket socket) { this.socket = socket; this.wantedBoardSize = size; @@ -25,6 +31,10 @@ public abstract class OnlinePlayer extends Player implements AsyncSocketListener @Override public abstract void receiveCoin(boolean coin); + /** + * closes the socket and does player cleanup work + * @author Luca Conte + */ @Override public void destroy() { super.destroy(); diff --git a/src/OnlinePlayer_1_1_0.java b/src/OnlinePlayer_1_1_0.java index eab7f1e..b401a6e 100644 --- a/src/OnlinePlayer_1_1_0.java +++ b/src/OnlinePlayer_1_1_0.java @@ -6,6 +6,12 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer { } + /** + * receives a message from the AsyncSocket + * implemented according to version 1.1.0 of https://github.com/lgc-4/ProgProjekt-Netzwerkstandard + * @param message the message from the socket + * @author Peer Ole Wachtel, Luca Conte + */ @Override public void receive(String message) { SocketPackage p = new SocketPackage(message); @@ -67,23 +73,44 @@ public class OnlinePlayer_1_1_0 extends OnlinePlayer { } } + /** + * sends introduction package IAM to online partner. + * @author Luca Conte + */ @Override public synchronized void sendIAM() { if (this.enemy == null) throw new RuntimeException("enemy has not yet been defined"); socket.send(new SocketPackage("IAM", GameController.boardSizeToSemester(this.wantedBoardSize) + " " + this.enemy.name)); } + /** + * receives a shot from the enemy and sends it to the online partner + * if it is not the enemies turn, this method does nothing. + * @param point the point to be shot + * @author Peer Ole Wachtel + */ @Override public synchronized void receiveShoot(Point point){ if (!this.enemy.myTurn) return; super.socket.send(new SocketPackage("SHOOT",point.toString())); } + /** + * receives a hitresponse from the enemy player and sends it to the online partner + * @param hitResponse the hitresponse to be sent + * @author Peer Ole Wachtel + */ @Override public synchronized void receiveHit(HitResponse hitResponse) { super.socket.send(new SocketPackage("HIT", hitResponse.toString())); } + /** + * receives the coin toss result from the enemy player and sends it to the online partner + * if this player has already received the enemies coin, this method does nothing. + * @param coin the result of the coin toss + * @author Peer Ole Wachtel, Luca Conte + */ @Override public synchronized void receiveCoin(boolean coin) { if (!this.hasReceivedCoin) { diff --git a/src/Player.java b/src/Player.java index 5ea7ba7..4adf76c 100644 --- a/src/Player.java +++ b/src/Player.java @@ -20,6 +20,11 @@ public abstract class Player { this.gameRunning = false; } + /** + * initialises this players board + * @param size the size of the board to be created + * @author Peer Ole Wachtel + */ public void createBoard(int size) { this.board = new Board(size); } @@ -30,25 +35,54 @@ public abstract class Player { public abstract void shoot(Point point); + /** + * only relevant for AI Players. + * starts the first turn + * @author Luca Conte + */ public void beginTurn() { System.out.println("issa my turn-a"); } + /** + * sets the enemy Player + * @author Peer Ole Wachtel + */ public void setEnemy(Player enemy) { this.enemy = enemy; } + /** + * sets the name of this player + * @param name the name of this player + * @author Luca Conte + */ public void setName(String name) { this.name = name; } + /** + * returns the name of this player + * @return the name of this player + * @author Luca Conte + */ public String getName() { return this.name; } + /** + * returns the board of this player + * @return the board of this player + * @author Lucas Bronson + */ public Board getBoard() { return this.board; } + /** + * marks the player as ready by sending their coin to the enemy player + * calls determineCoinToss if the enemy coin has already been received + * @author Luca Conte + */ public void ready() { this.enemy.receiveCoin(this.myCoin); this.sentCoin = true; @@ -57,6 +91,11 @@ public abstract class Player { } }; + /** + * determines the result of the coin toss + * this method does nothing if either player is not ready yet or has not yet sent their coin + * @author Luca Conte, Peer Ole Wachtel + */ protected void determineCoinToss() { if (!this.sentCoin || this.myCoin == null || !this.hasReceivedCoin || this.enemy.myCoin == null) return; boolean result = this.enemy.myCoin ^ this.myCoin; // XOR @@ -68,16 +107,39 @@ public abstract class Player { GameController.getMainFrame().refreshGameBoard(); } + /** + * receives the coin toss from the enemy player + * @param coin the coin of the enemy player + * @author Peer Ole Wachtel + */ public abstract void receiveCoin(boolean coin); + /** + * returns whether the game this player is in has started, meaning both players are ready and have sent their coins + * @return the game's running state + * @author Luca Conte + */ public boolean isGameRunning() { return this.gameRunning; } + /** + * returns whether this player is ready and has sent their coin to the enemy player + * @return the player's ready state + */ public boolean isReady() { return this.sentCoin; } + /** + * removes connections to the enemy and its board as well as setting myTurn and gameRunning to false + * this stops the AI Players from making more moves and allows the garbage collector to remove the boards + * and players + * + * This method should be called at the end of a game + * + * @author Luca Conte + */ public void destroy() { this.myTurn = false; this.gameRunning = false; diff --git a/src/Point.java b/src/Point.java index d5b06ed..301ec1e 100644 --- a/src/Point.java +++ b/src/Point.java @@ -2,10 +2,26 @@ public class Point { private int x; private int y; + /** + * initialises a point using X and Y coordinates starting at 0 + * @param x the x coordinate of the point starting at 0 + * @param y the y coordinate of the point starting at 0 + */ public Point (int x, int y) { this.setX(x); this.setY(y); } + + /** + * initialises a Point using a coordinate provided in the format of a letter followed by a number + * this coordinate is checked using `isValidSyntax` + * If the coordinate is not in a valid syntax, an `IllegalArgumentException` will be thrown, stating as such + * The number part of the coordinate starts at 1 instead of 0 so for example, the + * string A1 will result in the X and Y coordinates of (0, 0) + * @param str the coordinate in alphanumeric format + * @throws IllegalArgumentException if the coordinate is invalid according to `isValidSyntax` + * @author Peer Ole Wachtel, Luca Conte + */ public Point (String str) { if (Point.isValidSyntax(str)) { this.setX(str.charAt(0)); @@ -15,34 +31,78 @@ public class Point { } } + /** + * returns this point as a string in its alphanumeric format + * @return this point as a string in its alphanumeric format + * @author Luca Conte, Peer Ole Wachtel + */ @Override public String toString() { return (char) ('A' + this.x) + String.valueOf(this.y + 1); } + /** + * returns the X coordinate of the point starting at 0 + * @return the X coordinate of the point starting at 0 + * @author Peer Ole Wachtel + */ public int getX() { return x; } + /** + * returns the Y coordinate of the point starting at 0 + * @return the Y coordinate of the point starting at 0 + * @author Peer Ole Wachtel + */ public int getY() { return y; } + /** + * sets the X coordinate of the point starting at 0 + * @param x the X coordinate of the point starting at 0 + * @author Peer Ole Wachtel + */ public void setX(int x) { this.x = x; } + /** + * sets the Y coordinate of the point starting at 0 + * @param y the Y coordinate of the point starting at 0 + * @author Peer Ole Wachtel + */ public void setY(int y) { this.y = y; } + + /** + * sets the X coordinate of the from its character value in alphanumeric form + * @param c the character to be transformed into + * @author Peer Ole Wachtel + */ public void setX(char c) { this.x = c - 'A'; } + /** + * checks whether a string is a valid alphanumeric point coordinate + * @param str the string to be tested + * @return whether the string is valid according to the regular expression `^[A-Z]\\d+$` + * @author Peer Ole Wachtel + */ public static boolean isValidSyntax(String str) { return str.matches("^[A-Z]\\d+$"); } + /** + * returns whether two points are equal + * two points with equivalent coordinates are considered equal + * @param o the other object/Point to compare this one to + * @return whether the objects are equal + * @author Luca Conte + */ @Override public boolean equals(Object o) { if (this == o) return true; @@ -52,6 +112,13 @@ public class Point { return p.getX() == this.getX() && p.getY() == this.getY(); } + /** + * determines whether two points are neighbours + * points are considered neighbours if their positions are equal or within a difference of 1 on both X and Y axis + * @param other the point to check for neighbourship + * @return whether the points are neighbours + * @author Luca Conte + */ public boolean neighbours(Point other) { if (other == null) return false; return (int)Math.abs(this.getX() - other.getX()) <= 1 && (int)Math.abs(this.getY() - other.getY()) <= 1;