diff --git a/README b/README
index ac49080..36370fb 100644
--- a/README
+++ b/README
@@ -12,4 +12,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see
\ No newline at end of file
+ along with this program. If not, see
+
+ Commenting and JavaDocs completed by Riley McGee for McMaster Universities
+ Software Engineering 3I03 Course.
\ No newline at end of file
diff --git a/src/eu/janinko/games/backgammon/Board.java b/src/eu/janinko/games/backgammon/Board.java
index 83bf991..da72949 100644
--- a/src/eu/janinko/games/backgammon/Board.java
+++ b/src/eu/janinko/games/backgammon/Board.java
@@ -1,195 +1,392 @@
package eu.janinko.games.backgammon;
-import java.util.Arrays;
-import java.util.HashMap;
-
import eu.janinko.games.backgammon.Stone.Color;
+/**
+ * Backgammon game board class
+ */
public class Board {
+ // Number of each color removed from play
private int homeWhite;
private int homeBlack;
+ // Number of each color blotted
private int barWhite;
private int barBlack;
+ // Number of stones at a given position
private int[] stoneCounts;
+ // Color of point ownership at a given position
private Stone.Color[] stoneColors;
-
- public Board(){
+
+ /**
+ * Creats a Board instance for a standard game of Backgammon
+ */
+ public Board() {
init();
}
-
- public void init(){
+
+ /**
+ * Initializes a game of Backgammon
+ */
+ public void init() {
+ // No stones have been removed from play
homeWhite = 0;
homeBlack = 0;
+ // No stones begin blotted
barWhite = 0;
barBlack = 0;
+ // Clean boards state
stoneCounts = new int[24];
stoneColors = new Stone.Color[24];
- for(int i=0; i<24; i++){
+
+ // Set up an empty board
+ for (int i = 0; i < 24; i++) {
stoneColors[i] = Stone.Color.NONE;
}
- stoneCounts[0] = 2; stoneColors[0] = Stone.Color.WHITE;
- stoneCounts[11] = 5; stoneColors[11] = Stone.Color.WHITE;
- stoneCounts[16] = 5; stoneColors[16] = Stone.Color.WHITE;
- stoneCounts[18] = 3; stoneColors[18] = Stone.Color.WHITE;
- stoneCounts[23] = 2; stoneColors[23] = Stone.Color.BLACK;
- stoneCounts[12] = 5; stoneColors[12] = Stone.Color.BLACK;
- stoneCounts[7] = 5; stoneColors[7] = Stone.Color.BLACK;
- stoneCounts[5] = 3; stoneColors[5] = Stone.Color.BLACK;
+
+ // Initialize a standard game of Backgammon
+ stoneCounts[0] = 2;
+ stoneColors[0] = Stone.Color.WHITE;
+ stoneCounts[11] = 5;
+ stoneColors[11] = Stone.Color.WHITE;
+ stoneCounts[16] = 5;
+ stoneColors[16] = Stone.Color.WHITE;
+ stoneCounts[18] = 3;
+ stoneColors[18] = Stone.Color.WHITE;
+ stoneCounts[23] = 2;
+ stoneColors[23] = Stone.Color.BLACK;
+ stoneCounts[12] = 5;
+ stoneColors[12] = Stone.Color.BLACK;
+ stoneCounts[7] = 5;
+ stoneColors[7] = Stone.Color.BLACK;
+ stoneCounts[5] = 3;
+ stoneColors[5] = Stone.Color.BLACK;
}
+ /**
+ * Fetch the number of stones at a position
+ *
+ * @param i
+ * - Position being checked
+ * @return Number of stones at position i
+ */
public int getStoneCount(int i) {
- if(i < 0 || i > 24) return 0;
-
+ // If i is not a possible position no stones can exist on it
+ if (i < 0 || i > 24) {
+ return 0;
+ }
+
return stoneCounts[i];
}
+ /**
+ * Get a stone reference at position i
+ *
+ * @param i
+ * - Position a stone is being fetched from
+ * @return Stone reference at position i
+ */
public Stone getStone(int i) {
- if(i < 0 || i > 24) return Stone.NONE;
-
- switch(stoneColors[i]){
- case WHITE: return Stone.WHITE;
- case BLACK: return Stone.BLACK;
- default: return Stone.NONE;
+ if (i < 0 || i > 24)
+ return Stone.NONE;
+
+ switch (stoneColors[i]) {
+ case WHITE:
+ return Stone.WHITE;
+ case BLACK:
+ return Stone.BLACK;
+ default:
+ return Stone.NONE;
}
}
+ /**
+ * Fetches the number of blotted stones for player 'color'
+ *
+ * @param color
+ * - Color associated with blotted stones being checked
+ * @return Number of stones blotted that are of color 'color'
+ */
public int getBarCount(Color color) {
- switch(color){
- case WHITE: return barWhite;
- case BLACK: return barBlack;
- default: return 0;
+ // Check the color and return its associated number of blotted stones
+ switch (color) {
+ case WHITE:
+ return barWhite;
+ case BLACK:
+ return barBlack;
+ default:
+ return 0;
}
}
- public boolean canMove(int from, int count){
- if(from < 0 || from > 24) return false;
-
- if(stoneCounts[from] == 0) return false;
+ /**
+ * Checks if a specified move is leagal in the game of backgammon in term of
+ * the board state
+ *
+ * @param from
+ * - Position of a stone being moved
+ * @param count
+ * - Number of positions being moved away from 'from'
+ * @return If the Move is legal to move a piece in 'from' 'count' positions
+ * away
+ */
+ public boolean canMove(int from, int count) {
+ // If from is not a bopard position the move is illegal
+ if (from < 0 || from > 24) {
+ return false;
+ }
+
+ // If there are no stones at from to move the move is illegal
+ if (stoneCounts[from] == 0) {
+ return false;
+ }
+ // Calculate the position of the target location
Stone.Color who = stoneColors[from];
int target;
- if(who == Stone.Color.WHITE){
- if(barWhite > 0) return false;
+ if (who == Stone.Color.WHITE) {
+ // If a blot is inplace no other moves may be done
+ if (barWhite > 0) {
+ return false;
+ }
+ // White moves in the positive direction
target = from + count;
- }else{
- if(barBlack > 0) return false;
+ } else {
+ // If a blot is inplace no other moves may be done
+ if (barBlack > 0) {
+ return false;
+ }
+ // Black moves in negative direction
target = from - count;
}
- if(target > 23 || target < 0){
- return hasAllInBase(who,from);
+
+ // If the request is a move off the board, only allow the move if all
+ // stones are in base
+ if (target > 23 || target < 0) {
+ return hasAllInBase(who, from);
}
+
+ // Check if the taget position can be moved to
Stone.Color tarwho = stoneColors[target];
- if(tarwho == who || tarwho == Stone.Color.NONE){
+ if (tarwho == who || tarwho == Stone.Color.NONE) {
return true;
- }else{
+ } else {
+ // Check if a blot is possible
return stoneCounts[target] == 1;
}
}
-
- public boolean canPut(Stone.Color color, int number){
- switch(color){
+
+ /**
+ * Checks if a stone can be put back into play from being blotted
+ *
+ * @param color
+ * - Color of stone returning to play
+ * @param number
+ * - Position in enemy home where the stone is to be put
+ * @return If the a blotted stone of color 'color' can be be put in position
+ * 'number'
+ */
+ public boolean canPut(Stone.Color color, int number) {
+ switch (color) {
case WHITE:
- if(barWhite == 0) return false;
- if(stoneColors[number-1] == Stone.Color.BLACK) return false;
+ // If white has no blotted stones the play is illegal
+ if (barWhite == 0)
+ return false;
+ // If the opponent has a made then the play cannot be done
+ if (stoneColors[number - 1] == Stone.Color.BLACK)
+ return false;
break;
case BLACK:
- if(barBlack == 0) return false;
- if(stoneColors[24-number] == Stone.Color.WHITE) return false;
+ // If black has no blotted stones the play is illegal
+ if (barBlack == 0)
+ return false;
+ // If the opponent has a made then the play cannot be done
+ if (stoneColors[24 - number] == Stone.Color.WHITE)
+ return false;
break;
- default: return false;
+ default:
+ return false;
}
+ // The play is legal
return true;
}
-
- public boolean hasAllInBase(Stone.Color color, int except){
+
+ /**
+ * Checks if a the player 'color' has all of its stones in a base
+ *
+ * @param color - Color of stones being check if they are all in home
+ * @param except - If a position should be ignored for the check
+ * @return If all stones of color 'color' are in base, excluding except
+ */
+ public boolean hasAllInBase(Stone.Color color, int except) {
+ // Bounds for all positions that are not in colors base
int f;
int t;
- switch(color){
+
+ // Set bounds based on Color
+ switch (color) {
case WHITE:
- if(barWhite > 0) return false;
- f=0; t=18;
+ // If white has unhandled blots at least one stone is not in base
+ if (barWhite > 0)
+ return false;
+ // White Base is positions 24-19
+ f = 0;
+ t = 18;
break;
case BLACK:
- if(barBlack > 0) return false;
- f=6; t=24;
+ // If black has unhandled blots at least one stone is not in base
+ if (barBlack > 0)
+ return false;
+ // Black Base is positions 0-5
+ f = 6;
+ t = 24;
break;
- default: return false;
+ default:
+ // If the color is NONE, there is no representative base, return
+ // false
+ return false;
}
-
- for(int i=f; i < t; i++){
- if(stoneColors[i] == color && (i != except || stoneCounts[i] > 1)){
+
+ // If the positions representing not the colors base have a stone of
+ // color 'color' then not all stones are in the base
+ for (int i = f; i < t; i++) {
+ // Except allows for testing of no remaining moves, if all but i are
+ // in base, and i is an invalid move return true to notify
+ if (stoneColors[i] == color && (i != except || stoneCounts[i] > 1)) {
return false;
}
}
return true;
}
-
- public void move(int from, int count) throws WrongMoveException{
- if(!canMove(from,count)) throw new WrongMoveException();
- if(stoneColors[from] == Stone.Color.WHITE){
+
+ /**
+ * Attempts to move a stone in position 'from' 'count' positions closer to home
+ * @param from - Position from which the stone is being moved
+ * @param count - Distance the stone is being moved
+ * @throws WrongMoveException - The requested move is Illegal
+ */
+ public void move(int from, int count) throws WrongMoveException {
+ //Validate the move is legal
+ if (!canMove(from, count))
+ throw new WrongMoveException();
+
+ //Handle each stone collor individually
+ if (stoneColors[from] == Stone.Color.WHITE) {
+ //White moves towards 24
int target = from + count;
- if(target > 23){
+
+ if (target > 23) {
+ //Remove the stone from play
homeWhite++;
- }else if(stoneColors[target] == Stone.Color.BLACK){
+ } else if (stoneColors[target] == Stone.Color.BLACK) {
+ //Blot the target position
removeStone(target);
barBlack++;
- addStone(target,Stone.Color.WHITE);
- }else{
- addStone(target,Stone.Color.WHITE);
+ addStone(target, Stone.Color.WHITE);
+ } else {
+ //Simply move the stone
+ addStone(target, Stone.Color.WHITE);
}
- }else{
+ } else {
+ //Black moves towards 0
int target = from - count;
- if(target < 0){
+ if (target < 0) {
+ //Remove the stone from play
homeBlack++;
- }else if(stoneColors[target] == Stone.Color.WHITE){
+ } else if (stoneColors[target] == Stone.Color.WHITE) {
+ //Blot the target position
removeStone(target);
barWhite++;
- addStone(target,Stone.Color.BLACK);
- }else{
- addStone(target,Stone.Color.BLACK);
+ addStone(target, Stone.Color.BLACK);
+ } else {
+ //Simply move the stone
+ addStone(target, Stone.Color.BLACK);
}
}
+ //Update the moved stones origin
removeStone(from);
}
-
- public void put(Stone.Color color, int number) throws WrongMoveException{
- if(!canPut(color,number)) throw new WrongMoveException();
-
- switch(color){
+
+ /**
+ * Attempts to place a blotted stone from the bar of color 'color' in the enemies base at position 'number'
+ * @param color - Color of the stone being put into play
+ * @param number - Position in the enemeies base where the stone is to be placed
+ * @throws WrongMoveException - Illegal Backgammon move was requested
+ */
+ public void put(Stone.Color color, int number) throws WrongMoveException {
+ //Validates the move is legal
+ if (!canPut(color, number))
+ throw new WrongMoveException();
+
+ //Updates the colors stones on the bar and places the stone
+ switch (color) {
case WHITE:
barWhite--;
- addStone(number-1,color);
+ addStone(number - 1, color);
break;
case BLACK:
barBlack--;
- addStone(24-number,color);
+ addStone(24 - number, color);
break;
- }
+ }
}
+ /**
+ * Removes a stone from position 'from'
+ *
+ * @param from
+ * - Position a stone is being moved 'from'
+ */
private void removeStone(int from) {
- if(stoneCounts[from] <= 0)
+ // Verifiy a stone exists at from
+ if (stoneCounts[from] <= 0) {
throw new IllegalArgumentException("Removing stone from zero at " + from);
+ }
+ // Update references to number of stones at from
stoneCounts[from]--;
- if(stoneCounts[from] == 0){
+
+ // Update control of position stone was at
+ if (stoneCounts[from] == 0) {
stoneColors[from] = Stone.Color.NONE;
}
}
+ /**
+ * Adds a stone to position 'to' of color 'color'
+ *
+ * @param to
+ * - Position a stone is being added to
+ * @param color
+ * - Color of the stone being moved
+ */
private void addStone(int to, Stone.Color color) {
- if(stoneColors[to] != Stone.Color.NONE && stoneColors[to] != color)
+ // If the ownership of to is not the same as color the move is no
+ // allowed
+ if (stoneColors[to] != Stone.Color.NONE && stoneColors[to] != color) {
throw new IllegalArgumentException("Adding wrong color of stone to " + to);
+ }
+ // Update the stone count at to
stoneCounts[to]++;
- if(stoneColors[to] == Stone.Color.NONE){
+ // Update the ownership of position to
+ if (stoneColors[to] == Stone.Color.NONE) {
stoneColors[to] = color;
}
}
+ /**
+ * Fetches the number of stones in a colors corresponding home
+ *
+ * @param color
+ * - Color of Stones Home
+ * @return Number of stones in the home corresponding to color
+ */
public int getHome(Color color) {
- switch(color){
- case WHITE: return homeWhite;
- case BLACK: return homeBlack;
- default: return 0;
+ switch (color) {
+ case WHITE:
+ return homeWhite;
+ case BLACK:
+ return homeBlack;
+ default:
+ return 0;
}
}
diff --git a/src/eu/janinko/games/backgammon/Dices.java b/src/eu/janinko/games/backgammon/Dices.java
deleted file mode 100644
index 3a34fc4..0000000
--- a/src/eu/janinko/games/backgammon/Dices.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package eu.janinko.games.backgammon;
-
-import java.util.Random;
-
-public class Dices {
- private int diceOne;
- private int diceTwo;
-
- private int diceOneUses;
- private int diceTwoUses;
-
- private Random generator;
-
- public Dices(){
- generator = new Random();
- }
-
- public Dices(Dices d) {
- diceOne = d.diceOne;
- diceTwo = d.diceTwo;
- diceOneUses = d.diceOneUses;
- diceTwoUses = d.diceTwoUses;
- generator = new Random();
- }
-
- public void roll(){
- diceOne = generator.nextInt(6) + 1;
- diceTwo = generator.nextInt(6) + 1;
- if(diceOne == diceTwo){
- diceOneUses = diceTwoUses = 2;
- }else{
- diceOneUses = diceTwoUses = 1;
- }
- }
-
- public boolean isOnDice(int number){
- if(diceOneUses > 0 && diceOne == number) return true;
- if(diceTwoUses > 0 && diceTwo == number) return true;
- return false;
- }
-
- public void rollDifferent(){
- do{
- diceOne = generator.nextInt(6) + 1;
- diceTwo = generator.nextInt(6) + 1;
- }while(diceOne == diceTwo);
- diceOneUses = diceTwoUses = 1;
- }
-
- public void takeDice(int number){
- if(diceOneUses > 0 && diceOne == number){
- diceOneUses--;
- }else if(diceTwoUses > 0 && diceTwo == number){
- diceTwoUses--;
- }else{
- throw new IllegalArgumentException("Trying to take invalid dice " + number);
- }
- }
-
- public int takeDiceOne(){
- if(diceOneUses == 0) return 0;
- diceOneUses--;
- return diceOne;
- }
-
- public int takeDiceTwo(){
- if(diceTwoUses == 0) return 0;
- diceTwoUses--;
- return diceTwo;
- }
-
- public boolean isRolled(){
- return diceOneUses > 0 || diceTwoUses > 0;
- }
-
- public int getDiceOne(){
- return diceOne;
- }
-
- public int getDiceTwo(){
- return diceTwo;
- }
-
-}
diff --git a/src/eu/janinko/games/backgammon/Game.java b/src/eu/janinko/games/backgammon/Game.java
index 1c8aa5e..305033e 100644
--- a/src/eu/janinko/games/backgammon/Game.java
+++ b/src/eu/janinko/games/backgammon/Game.java
@@ -1,94 +1,204 @@
package eu.janinko.games.backgammon;
-import java.util.Random;
-
+/**
+ * Class controlling turn advancements in Backgammon and player control
+ */
public class Game {
- Random generator;
- Board board;
- Stone.Color player;
+ // Board instance tied to this Game
+ private Board board;
+ // player represents the current turn in the game, Black or White
+ private Stone.Color player;
+ // Dice to be rolled determining player moves availiable
+ private GameDice dice;
- Dices dices;
-
- public Game(){
- generator = new Random();
+ /**
+ * Construct a Game Instance
+ */
+ public Game() {
board = new Board();
player = Stone.Color.NONE;
- dices = new Dices();
+ dice = new GameDice();
}
-
- public void roll(){
- if(player == Stone.Color.NONE){
- dices.rollDifferent();
- }else{
- dices.roll();
+
+ /**
+ * Roll the Game Dice
+ *
+ *
If the game has yet to start the roll will assign the starting player
+ * roll() is to be called again to start the turn
+ * If the game has begun the turn will switch and the roll will be used
+ * for moving the player
+ *
+ */
+ public void roll() {
+ if (player == Stone.Color.NONE) {
+ // If the player is None the roll determines the first turn
+ // A different roll is used to enforce one player starts the game
+ dice.rollDifferent();
+ } else {
+ // Regular turn roll
+ dice.roll();
}
-
- switch(player){
+
+ switch (player) {
case WHITE:
+ // Change the turn to Black from White
player = Stone.Color.BLACK;
break;
case BLACK:
+ // Change the turn to White from Black
player = Stone.Color.WHITE;
break;
case NONE:
- if(dices.getDiceOne() > dices.getDiceTwo()){
+ // Roll for starting player
+ // Dice one represents whites roll and dice two represents blacks
+ // roll
+ if (dice.getDiceOne() > dice.getDiceTwo()) {
+ // White begins for having a higher roll
player = Stone.Color.WHITE;
- }else{
+ } else {
+ // Black begins for having a higher roll
player = Stone.Color.BLACK;
}
break;
}
}
-
- public boolean canMove(int from, int count){
- if(!dices.isRolled()) return false;
- if(!dices.isOnDice(count)) return false;
- if(!board.canMove(from, count)) return false;
- if(board.getStone(from).color() != player) return false;
-
+ /**
+ * Checks if a stone can be moved from the position 'from' to the position
+ * 'count' steps towards player home.
+ *
+ * @param from
+ * - Starting position of the stone being moved
+ * @param count
+ * - Positions being moved
+ * @return If a stone at from can move count distance away legally
+ */
+ private boolean canMove(int from, int count) {
+ // Validate the dice states allow for the move to occur
+ if (!dice.isRolled() || !dice.isOnDice(count)) {
+ return false;
+ }
+ // Validate the movement satisfies the rules of the board
+ if (!board.canMove(from, count)) {
+ return false;
+ }
+ // Validate the player color is representative of the stone being moved
+ if (board.getStone(from).getColor() != player) {
+ return false;
+ }
+ // A stone at position from, can move count spaces
return true;
}
-
- public void move(int from, int count) throws WrongMoveException{
- if(!canMove(from,count)) throw new WrongMoveException();
- board.move(from,count);
- dices.takeDice(count);
+
+ /**
+ * Attempts to move a stone from position 'from' count distance away
+ *
+ * @param from
+ * - Position of stone being moved
+ * @param count
+ * - Distance stone is being moved away from 'from'
+ * @throws WrongMoveException
+ * - The specified action is illegal
+ */
+ public void move(int from, int count) throws WrongMoveException {
+ // Verify the move is legal
+ if (!canMove(from, count))
+ throw new WrongMoveException();
+ // Move the stone on the board and update the dice usability
+ board.move(from, count);
+ dice.takeDice(count);
}
-
- public boolean canPut(int number){
- if(!dices.isRolled()) return false;
- if(!dices.isOnDice(number)) return false;
- if(!board.canPut(player, number)) return false;
-
+
+ /**
+ * Verifies if the player can take a blotted stone and place it in the
+ * enimies home
+ *
+ * @param number
+ * - position in enemies home where the blotted stone will go
+ * @return - If a blotted stone can be placed in the enemies home at
+ * position number
+ */
+ private boolean canPut(int number) {
+ // Validate the dice states are correct for the number
+ if (!dice.isRolled() || !dice.isOnDice(number))
+ return false;
+ //Validate a blotted stone can be put in position number
+ if (!board.canPut(player, number))
+ return false;
+
return true;
}
-
- public void put(int number) throws WrongMoveException{
- if(!canPut(number)) throw new WrongMoveException();
- board.put(player,number);
- dices.takeDice(number);
+
+ /**
+ * Attempts to put a blotted stone belinging to player in the enmeies home
+ * in position 'number'
+ *
+ * @param number
+ * - position in enemies home
+ * @throws WrongMoveException
+ * - Illegal move in backgammon, or no blotted stones exist
+ */
+ public void put(int number) throws WrongMoveException {
+ // Verify that the stone can be put at position number
+ if (!canPut(number))
+ throw new WrongMoveException();
+ // Place the stone and update the dice moves availiable
+ board.put(player, number);
+ dice.takeDice(number);
}
-
- public Board getBoard(){
+
+ /**
+ * @return - Board instance linked to this
+ */
+ public Board getBoard() {
return board;
}
-
- public Stone.Color getPlayer(){
+
+ /**
+ * @return The current players turn
+ */
+ public Stone.Color getPlayer() {
return player;
}
-
- public ShowOnlyDices getDice(){
- return new ShowOnlyDices(dices);
+
+ /**
+ * @return The game dice linked to this game, with control abstracted
+ */
+ public ShowOnlyGameDice getDice() {
+ return new ShowOnlyGameDice(dice);
}
-
- public boolean isEnded(){
+
+ /**
+ * Checks if the game has ended or is inprogress
+ *
+ * @return False - The game is in progress
+ * True - The game has concluded
+ */
+ public boolean isEnded() {
return board.getHome(Stone.Color.WHITE) == 15 || board.getHome(Stone.Color.BLACK) == 15;
}
-
- public Stone.Color winner(){
- if(!isEnded()) return Stone.Color.NONE;
- if(board.getHome(Stone.Color.WHITE) == 15) return Stone.Color.WHITE;
+
+ /**
+ * Returns the player color of the winner for the current game instance
+ *
+ * @return Stone.Color.NONE - The game is in progress, no player
+ * has won
+ * Stone.Color.WHITE - The game has concluded, White has
+ * won
+ * Stone.Color.BLACK - The game has concluded, Black has
+ * won
+ * @see Stone.Color
+ */
+ public Stone.Color winner() {
+ //Verify the game has ended
+ if (!isEnded()){
+ return Stone.Color.NONE;
+ }
+ //If White has won all of its stones will be home
+ // else Black has won
+ if (board.getHome(Stone.Color.WHITE) == 15){
+ return Stone.Color.WHITE;
+ }
return Stone.Color.BLACK;
}
}
diff --git a/src/eu/janinko/games/backgammon/GameDice.java b/src/eu/janinko/games/backgammon/GameDice.java
new file mode 100644
index 0000000..d9edfc7
--- /dev/null
+++ b/src/eu/janinko/games/backgammon/GameDice.java
@@ -0,0 +1,169 @@
+package eu.janinko.games.backgammon;
+
+import java.util.Random;
+
+/**
+ * Object representing the dice pair used in Backgammon and the use of each
+ * roll.
+ */
+public class GameDice {
+ // Dice used in each Backgammon turn roll value
+ private int diceOne;
+ private int diceTwo;
+
+ // Remaining plays for each Dice (2,1, or 0)
+ private int diceOneUses;
+ private int diceTwoUses;
+
+ // Random number generator used to model a 6 sided dice roll
+ private Random generator;
+
+ /**
+ * Create an instance of a Backgammon game dice pair
+ */
+ public GameDice() {
+ // Create the Random number generator used to roll dice
+ generator = new Random();
+ }
+
+ /**
+ * Method to roll the dice to new values, resetting use limit for each dice
+ * appropriately
+ */
+ public void roll() {
+ // Roll dice and set their values to the roll value
+ // Dice can take on a value of [1,6]
+ diceOne = generator.nextInt(6) + 1;
+ diceTwo = generator.nextInt(6) + 1;
+
+ if (diceOne == diceTwo) {
+ // When doubles are rolled each dice is used twice
+ diceOneUses = diceTwoUses = 2;
+ } else {
+ // When the dice are distinct each dice is used once
+ diceOneUses = diceTwoUses = 1;
+ }
+ }
+
+ /**
+ * Check if a specified number has been rolled.
+ *
+ * @param number
+ * Value under check.
+ * @return If number can be used as a roll value.
+ */
+ public boolean isOnDice(int number) {
+ // If number is the value of dice one or dice two and it has moves
+ // remaining return true
+ if (diceOneUses > 0 && diceOne == number) {
+ return true;
+ } else if (diceTwoUses > 0 && diceTwo == number) {
+ return true;
+ } else {
+ // The number is not represented for use
+ return false;
+ }
+ }
+
+ /**
+ * Forces the dice roll to be distinct values
+ */
+ public void rollDifferent() {
+ // Until the values of both dice are distinct reroll the dice
+ do {
+ diceOne = generator.nextInt(6) + 1;
+ diceTwo = generator.nextInt(6) + 1;
+ } while (diceOne == diceTwo);
+ // Since the dice are distinct set each dices use limit to 1
+ diceOneUses = diceTwoUses = 1;
+ }
+
+ /**
+ * Request to use number, and update dice states
+ *
+ * @param number
+ * Value being checked against dice
+ * @throws IllegalArgumentException number cannot be used
+ */
+ public void takeDice(int number) {
+ if (diceOneUses > 0 && diceOne == number) {
+ // Dice One is used
+ diceOneUses--;
+ } else if (diceTwoUses > 0 && diceTwo == number) {
+ // Dice Two is used
+ diceTwoUses--;
+ } else {
+ // number may not be requested for use
+ throw new IllegalArgumentException("Trying to take invalid dice " + number);
+ }
+ }
+
+ /**
+ * Controls the movement available by the rolled value of dice one
+ *
+ * @return
+ *
+ * 0 - The dice one cannot be used further
+ *
+ *
+ * [1,6] - The value of Dice one, Dice one may be used one less time
+ *
+ */
+ public int takeDiceOne() {
+ // Check if dice one moves have been claimed
+ if (diceOneUses == 0)
+ return 0;
+ // Represent dice one as used once and return the value dice one rolled
+ diceOneUses--;
+ return diceOne;
+ }
+
+ /**
+ * Controls the movement available by the rolled value of dice two
+ *
+ * @return
+ *
+ * 0 - The dice two cannot be used further
+ *
+ *
+ * [1,6] - The value of Dice two, Dice two may be used one less time
+ *
+ */
+ public int takeDiceTwo() {
+ // Check if dice two moves have been claimed
+ if (diceTwoUses == 0)
+ return 0;
+ // Represent dice two as used once and return the value dice two rolled
+ diceTwoUses--;
+ return diceTwo;
+ }
+
+ /**
+ * Returns if remaining dice values that must move a stone exist
+ *
+ * @return Are there any unclaimed moves for the current roll
+ */
+ public boolean isRolled() {
+ // If dice uses exceed zero, moves have been unclaimed
+ return diceOneUses > 0 || diceTwoUses > 0;
+ }
+
+ /**
+ * Fetch the value of Dice One
+ *
+ * @return [1-6] value of Dice One
+ */
+ public int getDiceOne() {
+ return diceOne;
+ }
+
+ /**
+ * Fetch the value of Dice Two
+ *
+ * @return [1-6] value of Dice Two
+ */
+ public int getDiceTwo() {
+ return diceTwo;
+ }
+
+}
diff --git a/src/eu/janinko/games/backgammon/Player.java b/src/eu/janinko/games/backgammon/Player.java
deleted file mode 100644
index a7b27c8..0000000
--- a/src/eu/janinko/games/backgammon/Player.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package eu.janinko.games.backgammon;
-
-public interface Player {
-
-}
diff --git a/src/eu/janinko/games/backgammon/ShowOnlyDices.java b/src/eu/janinko/games/backgammon/ShowOnlyDices.java
deleted file mode 100644
index 07c180e..0000000
--- a/src/eu/janinko/games/backgammon/ShowOnlyDices.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package eu.janinko.games.backgammon;
-
-public class ShowOnlyDices{
-
- Dices dices;
-
- public ShowOnlyDices(Dices d){
- dices = d;
- }
-
- public boolean isOnDice(int number) {
- return dices.isOnDice(number);
- }
-
- public boolean isRolled() {
- return dices.isRolled();
- }
-
- public int getDiceOne() {
- return dices.getDiceOne();
- }
-
- public int getDiceTwo() {
- return dices.getDiceTwo();
- }
-
-}
diff --git a/src/eu/janinko/games/backgammon/ShowOnlyGameDice.java b/src/eu/janinko/games/backgammon/ShowOnlyGameDice.java
new file mode 100644
index 0000000..ad6618e
--- /dev/null
+++ b/src/eu/janinko/games/backgammon/ShowOnlyGameDice.java
@@ -0,0 +1,54 @@
+package eu.janinko.games.backgammon;
+
+/**
+ * Class to abstract Dice details to just their roll values
+ */
+public class ShowOnlyGameDice {
+ // Game Dice being abstracted
+ private GameDice gameDice;
+
+ /**
+ * Instantiate a ShowOnlyGameDice instance referencing the dice values of d
+ *
+ * @param d
+ * GameDice being referenced
+ */
+ public ShowOnlyGameDice(GameDice d) {
+ gameDice = d;
+ }
+
+ /**
+ * Checks if number is on the dice rolled
+ *
+ * @param number
+ * - Value being checked against roll
+ * @return Is number represented by the dice
+ */
+ public boolean isOnDice(int number) {
+ return gameDice.isOnDice(number);
+ }
+
+ /**
+ * Checks if a turn with respect to the game dice has completed.
+ *
+ * @return Have the dice been used.
+ */
+ public boolean isRolled() {
+ return gameDice.isRolled();
+ }
+
+ /**
+ * @return Roll value of dice one
+ */
+ public int getDiceOne() {
+ return gameDice.getDiceOne();
+ }
+
+ /**
+ * @return Roll value of dice two
+ */
+ public int getDiceTwo() {
+ return gameDice.getDiceTwo();
+ }
+
+}
diff --git a/src/eu/janinko/games/backgammon/Stone.java b/src/eu/janinko/games/backgammon/Stone.java
index 484fd02..a51c475 100644
--- a/src/eu/janinko/games/backgammon/Stone.java
+++ b/src/eu/janinko/games/backgammon/Stone.java
@@ -1,42 +1,63 @@
package eu.janinko.games.backgammon;
-import eu.janinko.games.backgammon.Stone.Color;
-
+/**
+ * Model of a Stone for the game of Backgammon
+ *
+ * To Use:
+ * Utilize the Stone object references Stone.WHITE, Stone.BLACK, & Stone.NONE to
+ * represent White, Black, and no reference stones respectively
+ *
+ */
public class Stone {
+ /**
+ * Stone Color representation for a game of Backgammon
+ *
+ * As in the classic game of Backgammon stones are in colors WHITE or BLACK,
+ * there Color of NONE represents no color
+ *
+ */
public enum Color {
- WHITE,
- BLACK,
- NONE
+ WHITE, BLACK, NONE
}
+
+ // Stone references to be used throughout the application
public static Stone WHITE = new Stone(Color.WHITE);
public static Stone BLACK = new Stone(Color.BLACK);
public static Stone NONE = new Stone(Color.NONE);
-
+
+ // Color of the Stone
private Color color;
-
-
- public Stone(Color color) {
- this.color = color;
- }
- public Stone(boolean color) {
- this.color = (color?Color.WHITE:Color.BLACK);
- }
-
- public Stone() {
- this.color = Color.NONE;
+ /**
+ * Constructor for a Stone instance
+ *
+ * @param color
+ * The Color associated with the Stone
+ * @see Color
+ */
+ private Stone(Color color) {
+ if (color == null) {
+ // null is represented by a non-existing piece or NONE
+ this.color = Color.NONE;
+ } else {
+ // Set the color of this to the requested color
+ this.color = color;
+ }
}
+ /**
+ * Fetches the color of the Stone
+ *
+ * @return Color enumeration value for the stones color
+ * @see Color
+ */
public Color getColor() {
return color;
}
- public void setColor(Color color) {
- this.color = color;
- }
-
@Override
public int hashCode() {
+ // Calculates a hash code value specific to each Stone using a low prime
final int prime = 31;
int result = 1;
result = prime * result + ((color == null) ? 0 : color.hashCode());
@@ -45,32 +66,50 @@ public int hashCode() {
@Override
public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
+ // If the object is null or not a stone, obj is not equivalent to this
+ if (obj == null || !(obj instanceof eu.janinko.games.backgammon.Stone))
return false;
+ // Else compare the Stones by color,
+ // if they match the stones are considered equivalent
Stone other = (Stone) obj;
if (color != other.color)
return false;
return true;
}
+ /**
+ * Provides the string representation of a Stone instance as an ASCII
+ * character representation.
+ *
+ * @return
+ *
+ * " " - The Stone instance does not represent a playable piece.
+ *
+ *
+ * "O" - The Stone instance represents a White piece.
+ *
+ *
+ * "#" - The Stone instance represents a Black piece.
+ *
+ *
+ * "$" - Stone Error, instance not instantiated or color is null
+ *
+ */
@Override
public String toString() {
- switch(color){
- case NONE: return " ";
- case WHITE: return "O";
- case BLACK: return "#";
- default: return "$";
+ switch (color) {
+ case NONE:
+ // The stone represents a placeholder
+ return " ";
+ case WHITE:
+ // The stone represents a white piece
+ return "O";
+ case BLACK:
+ // The stone represents a black piece
+ return "#";
+ default:
+ // The stone is null, this state should be unreachable
+ return "$";
}
}
-
- public Color color() {
- return color;
- }
-
-
-
}
diff --git a/src/eu/janinko/games/backgammon/WrongMoveException.java b/src/eu/janinko/games/backgammon/WrongMoveException.java
index 40eb8b7..2da5ce4 100644
--- a/src/eu/janinko/games/backgammon/WrongMoveException.java
+++ b/src/eu/janinko/games/backgammon/WrongMoveException.java
@@ -1,14 +1,21 @@
package eu.janinko.games.backgammon;
+/**
+ * Exception Class for invalid Backgammon movements.
+ *
+ * @see Exception
+ */
public class WrongMoveException extends Exception {
-
+
+ /**
+ * Exception for requesting invalid moves in Backgammon. For criteria of
+ * when this exception is used see the Backgammon rules.
+ */
public WrongMoveException() {
super("Wrong move!");
}
- /**
- *
- */
- private static final long serialVersionUID = 8184331891011138632L;
+ // Unique ID corresponding to this exception type
+ private static final long serialVersionUID = 8184331891011138632L;
}