diff --git a/overview.html b/overview.html
new file mode 100644
index 0000000..4d014f1
--- /dev/null
+++ b/overview.html
@@ -0,0 +1,7 @@
+
+
+
+
+BattleShip package
+
+
\ No newline at end of file
diff --git a/src/battleship/Main.java b/src/battleship/Main.java
index 0e963d4..76f53b6 100644
--- a/src/battleship/Main.java
+++ b/src/battleship/Main.java
@@ -6,8 +6,8 @@ import battleship.model.player.Human;
import battleship.model.player.Player;
import battleship.model.player.Random;
import battleship.utils.Pair;
-import battleship.view.AbstractView;
import battleship.view.Terminal;
+import battleship.view.View;
import battleship.view.Window;
import java.lang.reflect.InvocationTargetException;
@@ -15,9 +15,13 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.NoSuchElementException;
+/**
+ * Main class
+ * Given arguments are importants, please give attention to {@link Main#parseArgs(String[])} about this
+ */
public class Main {
- public static AbstractView view;
+ public static View view;
public static Game game;
public static void main(String[] args) {
@@ -36,6 +40,20 @@ public class Main {
game.Play(view);
}
+ /**
+ * Read and parse launch arguments.
+ * launch arguments need to follow this syntax:
+ * {@code [nogui]}
+ * <arg> -> mandatory parameter
+ * [arg] -> optional parameter
+ * player_instance values are: "Human" or "Random"
+ * nogui to launch the game in terminal or nothing to launch in graphical interface
+ * @param args launch arguments
+ * @throws NoSuchMethodException reflect exception
+ * @throws IllegalAccessException reflect exception
+ * @throws InvocationTargetException reflect exception
+ * @throws InstantiationException reflect exception
+ */
private static void parseArgs(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Player[] players = new Player[2];
ArrayList>> playerClass = new ArrayList<>(2);
diff --git a/src/battleship/control/package-info.java b/src/battleship/control/package-info.java
new file mode 100644
index 0000000..c1cc5f0
--- /dev/null
+++ b/src/battleship/control/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Contains keyboard and mouse listeners
+ */
+package battleship.control;
\ No newline at end of file
diff --git a/src/battleship/model/Game.java b/src/battleship/model/Game.java
index 810bc8e..0690e78 100644
--- a/src/battleship/model/Game.java
+++ b/src/battleship/model/Game.java
@@ -3,8 +3,11 @@ package battleship.model;
import battleship.model.player.Player;
import battleship.utils.Pair;
import battleship.utils.Triplet;
-import battleship.view.AbstractView;
+import battleship.view.View;
+/**
+ * Main game class
+ */
public class Game {
public Player[] players;
@@ -17,7 +20,6 @@ public class Game {
players[1].setId(2);
}
-
public Player getCurrentPlayer(){
return this.currentPlayer;
}
@@ -34,6 +36,9 @@ public class Game {
currentPlayer = getOtherPlayer();
}
+ /**
+ * Update ship to know if they're drowned
+ */
public void checkDrownedShips(){
Player otherPlayer = getOtherPlayer();
for(Ship ship : otherPlayer.getShips()){
@@ -42,6 +47,9 @@ public class Game {
}
}
+ /**
+ * @return player 1 if player 2' ships are drowned, or player 2 if player1' ships are drowned, null otherwise
+ */
public Player getWinner(){
Ship remainingShip = players[0].getShips().parallelStream().filter(ship -> !ship.isDrown()).findFirst().orElse(null);
if(remainingShip == null)
@@ -52,6 +60,11 @@ public class Game {
return null;
}
+
+ /**
+ * Play the selected move from current player in grid
+ * @param move selected player move
+ */
public void move(Pair move){
boolean bool = false;
Player otherPlayer = getOtherPlayer();
@@ -68,7 +81,11 @@ public class Game {
currentPlayer.addMove(new Triplet<>(move, bool));
}
- public void Play(AbstractView view) {
+ /**
+ * game loop
+ * @param view can be {@link battleship.view.Terminal} or {@link battleship.view.Window}
+ */
+ public void Play(View view) {
try {
view.setShips(players[0]);
view.setShips(players[1]);
diff --git a/src/battleship/model/package-info.java b/src/battleship/model/package-info.java
new file mode 100644
index 0000000..ddd86bc
--- /dev/null
+++ b/src/battleship/model/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Contains all main Game classes
+ */
+package battleship.model;
\ No newline at end of file
diff --git a/src/battleship/model/player/package-info.java b/src/battleship/model/player/package-info.java
new file mode 100644
index 0000000..1ff58cc
--- /dev/null
+++ b/src/battleship/model/player/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Contains all players classes instances and theirs super classes and interface
+ */
+package battleship.model.player;
\ No newline at end of file
diff --git a/src/battleship/package-info.java b/src/battleship/package-info.java
new file mode 100644
index 0000000..e8d3bd2
--- /dev/null
+++ b/src/battleship/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Contains Main Class
+ */
+package battleship;
\ No newline at end of file
diff --git a/src/battleship/utils/Pair.java b/src/battleship/utils/Pair.java
index 7f1e7f5..16de05f 100644
--- a/src/battleship/utils/Pair.java
+++ b/src/battleship/utils/Pair.java
@@ -3,7 +3,7 @@ package battleship.utils;
import java.util.Objects;
/**
- * tuple containing 2 unknown type elements
+ * tuple containing 2 generic type elements
*
* @param left
* @param right
diff --git a/src/battleship/utils/Triplet.java b/src/battleship/utils/Triplet.java
index a24f088..961a335 100644
--- a/src/battleship/utils/Triplet.java
+++ b/src/battleship/utils/Triplet.java
@@ -3,10 +3,11 @@ package battleship.utils;
import java.util.Objects;
/**
- * tuple containing 2 unknown type elements
+ * tuple containing 3 generic type elements
*
* @param left
- * @param right
+ * @param middle
+ * @param right
*/
public class Triplet {
diff --git a/src/battleship/utils/package-info.java b/src/battleship/utils/package-info.java
new file mode 100644
index 0000000..abd472d
--- /dev/null
+++ b/src/battleship/utils/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Utility classes
+ */
+package battleship.utils;
\ No newline at end of file
diff --git a/src/battleship/view/AbstractView.java b/src/battleship/view/AbstractView.java
index 2da045d..766be35 100644
--- a/src/battleship/view/AbstractView.java
+++ b/src/battleship/view/AbstractView.java
@@ -9,18 +9,26 @@ import battleship.utils.Triplet;
import java.util.ArrayList;
+/**
+ * Abstract view class
+ * @see View
+ * @see Window
+ * @see Terminal
+ */
public abstract class AbstractView implements View {
-
protected Game game;
public AbstractView(Game game) {
this.game = game;
}
+ /**
+ * Used during debugging, used in terminal to display grids too
+ * @return all player grids
+ */
@Override
public String toString() {
- // String chain = "A vous de joueur "+game.currentPlayer.toString()+ "\n+ - - - - - - - - - - +\n";
String chain = "";
for(int u = 0; u < 2; ++u) {
Player player = game.players[u];
@@ -63,6 +71,10 @@ public abstract class AbstractView implements View {
return chain;
}
+ /**
+ *
+ * @return {@code true} if {@link Ship#getFullCoords()} contains {@code boardsCoords}, {@code false} otherwise
+ */
private boolean isShipPosition(Ship ship, Pair boardsCoords) {
for(Pair coords : ship.getFullCoords()) {
if(boardsCoords.equals(coords))
@@ -71,6 +83,12 @@ public abstract class AbstractView implements View {
return false;
}
+ /**
+ * ask player for keyboard input and parse it into one of {@link Direction} value
+ * @return Direction depending of player input
+ * @throws InterruptedException see {@link Window#getDirectionFromChar()}
+ * @see Window#getDirectionFromChar()
+ */
protected Direction getDirectionFromChar() throws InterruptedException {
String dir;
while (true) {
@@ -84,21 +102,37 @@ public abstract class AbstractView implements View {
}
}
+ /**
+ * ask player for keyboard input and return result
+ * @return String given by player
+ * @throws InterruptedException see {@link Window#getKeyInput()}
+ */
protected abstract String getKeyInput() throws InterruptedException;
+ /**
+ * Display a text above the grid on {@link Window}, simply print text on {@link Terminal}
+ * @param s text to display
+ * @see Window#setUpperText(String)
+ * @see Terminal#setUpperText(String)
+ */
protected abstract void setUpperText(String s);
+ /**
+ * used if {@code player} instance of {@link battleship.model.player.Computer}
+ * @param player player we ask to set position of its ships
+ * @throws InterruptedException see {@link Window#setShips(Player)}
+ */
@Override
public void setShips(Player player) throws InterruptedException {
player.placeShips();
}
/**
- *
* @param other other than the current player
- * @param ship check if this ship at this position is touch
+ * @param ship check if this ship at this position has been hit
* @param pair coords
* @return 1 if ship fully drowned, 2 if only damaged, 0 if not
+ * @see
*/
private int isPositionDrowned(Player other, Ship ship, Pair pair) {
if(ship.isDrown())
@@ -106,6 +140,11 @@ public abstract class AbstractView implements View {
return isPositionDrowned(other, pair);
}
+ /**
+ * @param other other than the current player
+ * @param pair coords to check
+ * @return 2 if player already played here, 0 otherwise
+ */
private int isPositionDrowned(Player other, Pair pair) {
for(Triplet move : other.getMoves()) {
if(pair.getLeft().equals(move.getLeft()) && pair.getRight().equals(move.getMiddle())) {
@@ -115,12 +154,33 @@ public abstract class AbstractView implements View {
return 0;
}
+ /**
+ * used by {@link battleship.model.player.Computer} player to play a move in the grid depending of its algorithm
+ * @param player {@link battleship.model.Game#currentPlayer}
+ * @return a couple ({@link Pair} containing the x and y coordinate (left side store Y and right side X)
+ * @throws InterruptedException see {@link Window#chooseMove(Player)}
+ */
@Override
public Pair chooseMove(Player player) throws InterruptedException {
return player.chooseMove();
}
+ /**
+ * ask {@code player} for mouse input
+ * @param player {@link Game#currentPlayer}
+ * @return coordinate of {@code player} opponent grid
+ * @see Window#mouseInput(Player)
+ * @throws InterruptedException see {@link Window#mouseInput(Player)}
+ */
protected abstract Pair mouseInput(Player player) throws InterruptedException;
+ /**
+ * ask {@link Game#currentPlayer} for keyboard input
+ * @return String given by player
+ * @throws InterruptedException see {@link Window#keyboardInput()}
+ * @see Window#keyboardInput()
+ * @see Terminal#keyboardInput()
+ * @see Terminal#keyboardInputInteger()
+ */
protected abstract String keyboardInput() throws InterruptedException;
}
diff --git a/src/battleship/view/Terminal.java b/src/battleship/view/Terminal.java
index 899c284..c200b3d 100644
--- a/src/battleship/view/Terminal.java
+++ b/src/battleship/view/Terminal.java
@@ -10,6 +10,11 @@ import battleship.utils.Pair;
import java.util.Scanner;
+/**
+ * Terminal view, instanced if argument 2 equals to "nogui"
+ * @see View
+ * @see AbstractView
+ */
public class Terminal extends AbstractView {
public static Scanner scanner = null;
@@ -22,16 +27,28 @@ public class Terminal extends AbstractView {
keyboardComponent = new TerminalKeyboardListener(scanner);
}
+ /**
+ * @return given string in terminal
+ */
@Override
protected String getKeyInput() {
return scanner.next().toUpperCase();
}
+ /**
+ * print string
+ * @param s text to display
+ */
@Override
protected void setUpperText(String s) {
System.out.println(s);
}
+ /**
+ * Ask {@code player} to set position of its ships
+ * @param player player we ask to set position of its ships
+ * @throws InterruptedException see {@link AbstractView#getDirectionFromChar()}
+ */
@Override
public void setShips(Player player) throws InterruptedException {
setUpperText("Joueur " + player.getId() + ", placez vos navires");
@@ -69,11 +86,22 @@ public class Terminal extends AbstractView {
}
}
+ /**
+ * print board in terminal
+ */
@Override
public void displayBoard() {
System.out.println(this);
}
+ /**
+ * ask player to choose a coords on its opponent grid, call {@link AbstractView#chooseMove(Player)} if instance of
+ * player is {@link battleship.model.player.Computer}
+ * if {@code player} isn't {@link Human} instance
+ * @param player {@link battleship.model.Game#currentPlayer}
+ * @return a element containing the x and y coordinate (left side store Y and right side X)
+ * @throws InterruptedException see {@link AbstractView#chooseMove(Player)}
+ */
@Override
public Pair chooseMove(Player player) throws InterruptedException {
if(player instanceof Human) {
@@ -97,20 +125,38 @@ public class Terminal extends AbstractView {
}
+ /**
+ * Never call in Terminal
+ * @param player {@link Game#currentPlayer}
+ * @return {@code null}
+ */
@Override
protected Pair mouseInput(Player player) {
return null;
}
+ /**
+ * @see TerminalKeyboardListener#keyboardInput()
+ * @return given string in terminal
+ */
@Override
protected String keyboardInput() {
return keyboardComponent.keyboardInput();
}
+ /**
+ * @see Terminal#keyboardInput()
+ * @return convert string from keyboardInput() and convert it into an integer
+ * @throws NumberFormatException if given string can't be parse into an integer
+ */
protected int keyboardInputInteger() throws NumberFormatException {
return Integer.parseInt(keyboardComponent.keyboardInput());
}
+ /**
+ * print grid, winner player and close scanner, game automatically close after this
+ * @param winner the winner of the game.
+ */
@Override
public void displayWinner(Player winner) {
displayBoard();
diff --git a/src/battleship/view/View.java b/src/battleship/view/View.java
index 232cc86..39d8851 100644
--- a/src/battleship/view/View.java
+++ b/src/battleship/view/View.java
@@ -3,15 +3,44 @@ package battleship.view;
import battleship.model.player.Player;
import battleship.utils.Pair;
+/**
+ * View interface, used as an API
+ * This model (interface(s) -> abstract class(es) -> concrete classes) prevent hard code.
+ * This is the only object which interact with other object
+ * Allows an outside person easily change the code or add a view easily without modifying existing classes
+ * @see AbstractView
+ * @see Terminal
+ * @see Window
+ */
public interface View {
int[] shipsSize = { 5, 4, 3, 3, 2};
+ /**
+ * Ask {@code player} to set position of its ships
+ * @param player player instance we ask
+ * @throws InterruptedException see {@link Window#setShips(Player)}
+ */
void setShips(Player player) throws InterruptedException;
+ /**
+ * Display all grids
+ */
void displayBoard();
+ /**
+ * ask the player the choose a position on its opponent grid
+ * @param player {@link battleship.model.Game#currentPlayer}
+ * @return a element containing the x and y coordinate (left side store Y and right side X)
+ * @throws InterruptedException see {@link Window#chooseMove(Player)}
+ */
Pair chooseMove(Player player) throws InterruptedException;
+ /**
+ * Display the winner of the game and then close the game
+ * @param winner the winner of the game.
+ * @see Window#displayWinner(Player)
+ * @see Terminal#displayWinner(Player)
+ */
void displayWinner(Player winner);
}
diff --git a/src/battleship/view/Window.java b/src/battleship/view/Window.java
index c86d601..5febc70 100644
--- a/src/battleship/view/Window.java
+++ b/src/battleship/view/Window.java
@@ -15,11 +15,22 @@ import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.geom.RoundRectangle2D;
+/**
+ * Window view, instanced if argument 2 equals to "nogui"
+ * @see View
+ * @see AbstractView
+ */
public class Window extends AbstractView {
final JFrame frame;
+ /**
+ * grids height, do no represent frame size
+ */
public final int height = 600;
+ /**
+ * grids width, do no represent frame size
+ */
public final int width = 1200;
private final WindowMouseListener mouseComponent;
private final WindowKeyboardListener keyboardComponent;
@@ -46,11 +57,20 @@ public class Window extends AbstractView {
return keyboardInput();
}
+ /**
+ * Display a text above the grid
+ * @param s text to display
+ */
@Override
protected void setUpperText(String s) {
upperTitle = s;
}
+ /**
+ * Ask {@code player} to set position of its ships
+ * @param player player we ask
+ * @throws InterruptedException see {@link Window#mouseInput(Player)} and {@link Window#getDirectionFromChar()}
+ */
@Override
public void setShips(Player player) throws InterruptedException {
if(player instanceof Human) {
@@ -80,6 +100,11 @@ public class Window extends AbstractView {
}
}
+ /**
+ * ask {@link Game#currentPlayer} for keyboard input
+ * @return String given by player
+ * @throws InterruptedException throw if this Thread is interrupted while {@link Thread#sleep(long) sleeping}
+ */
@Override
protected String keyboardInput() throws InterruptedException {
keyboardComponent.requestInput = true;
@@ -94,6 +119,12 @@ public class Window extends AbstractView {
}
}
+ /**
+ * ask {@code player} for mouse input
+ * @param player {@link Game#currentPlayer}
+ * @return coordinate of {@code player} opponent grid
+ * @throws InterruptedException throw if this Thread is interrupted while {@link Thread#sleep(long) sleeping}
+ */
@Override
protected Pair mouseInput(Player player) throws InterruptedException {
mouseComponent.requestInput = true;
@@ -105,7 +136,6 @@ public class Window extends AbstractView {
mouseComponent.playerIdLastInput = 0;
Pair value = mouseComponent.lastInput;
mouseComponent.lastInput = null;
- System.out.println(value);
return value;
} else {
openDialog("Vous avez cliquer sur une zone de jeu qui n'est pas la votre");
@@ -116,21 +146,40 @@ public class Window extends AbstractView {
}
}
+ /**
+ * Open a window with {@code message} as content and with a "OK" button
+ * @param message message to display
+ * @param exitOnClose {@code true} if when user close this window, the program exit, {@code false} otherwise
+ */
public void openDialog(String message, boolean exitOnClose) {
JOptionPane.showMessageDialog(frame, message);
if(exitOnClose)
System.exit(0);
}
+ /**
+ * Open a window with {@code message} as content and with a "OK" button
+ * @param message message to display
+ * @see Window#openDialog(String, boolean)
+ */
public void openDialog(String message) {
openDialog(message, false);
}
+ /**
+ * refresh windows to display updated content
+ */
@Override
public void displayBoard() {
frame.paintComponents(frame.getGraphics());
}
+ /**
+ * ask player to choose a position in its opponent grid
+ * @param player {@link battleship.model.Game#currentPlayer}
+ * @return a couple ({@link Pair} containing the x and y coordinate (left side store Y and right side X)
+ * @throws InterruptedException see {@link Window#mouseInput(Player)}
+ */
@Override
public Pair chooseMove(Player player) throws InterruptedException {
setUpperText("Joueur " + player.getId() + " cliquer sur l'emplacement ou vous souhaitez tirer");
@@ -150,11 +199,19 @@ public class Window extends AbstractView {
}
+ /**
+ * open a dialog to display the winner and exit the program when window is closed
+ * @param winner the winner of the game.
+ */
@Override
public void displayWinner(Player winner) {
openDialog("Le joueur " + winner.getId() + " a gagné(e)", true);
}
+ /**
+ * Panel where we paint the board
+ * @see JPanel
+ */
class Draw extends JPanel {
private final Window window;
@@ -240,11 +297,8 @@ public class Window extends AbstractView {
g2d.rotate(Math.toRadians(45), x1 + initialWidth - 9, y1 - 9);
g2d.fill(cross2);
g2d.rotate(Math.toRadians(-45), x1 + initialWidth - 9, y1 - 9);
-
-
}
}
- System.out.println(window);
}
}
}
diff --git a/src/battleship/view/package-info.java b/src/battleship/view/package-info.java
new file mode 100644
index 0000000..b104f2e
--- /dev/null
+++ b/src/battleship/view/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Contains terminal and windows view classes and theirs super class and interface
+ */
+package battleship.view;
\ No newline at end of file