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; }