diff --git a/justcheckers/game/board.py b/justcheckers/game/board.py
index 1dc7955..f5bde17 100644
--- a/justcheckers/game/board.py
+++ b/justcheckers/game/board.py
@@ -17,477 +17,342 @@
# Please share and enjoy!
#
-/**
- * Container for the state of the checker board during a game.
- *
- * The size of the board is defined by the number of squares along one side,
- * since all checker boards are square. The board coordinate system has both
- * horizontal and vertical numeric components ranging from 0 to boardSize-1.
- * Depicted on-screen, the horizontal component extends to the right and the
- * vertical component extends downwards, making the upper left square (0, 0) and
- * the lower right square (boardSize-1, boardSize-1).
- *
- * Navigating through the Board Internally, the checker board is
- * organized as a two-dimensional array. So when iterating through the board,
- * you first specify the vertical component and then the horizontal component.
- * Another way of thinking about is first specifying which row you want to look
- * at from top to bottom. Then you specify how across the row you are looking at
- * from left to right.
- *
- * Players Places The light player (the starting player) starts at the
- * top of the board. The dark player starts at the bottom of the board.
- *
- * @author Dorian Pula
- * @author Ross Etchells
- */
-public class Board {
+from enum import Enum
- /** Constant representing a dark king. */
- public static final int DARK_KING = 4;
- /** Constant representing a dark single man. */
- public static final int DARK_PAWN = 3;
- /** Constant representing an empty space. */
- public static final int EMPTY_SPACE = 0;
- // -- Constants ------------------------------------------------------------
- /**
- * Constant representing an illegal square. That is a white square in
- * checkers.
- */
- public static final int ILLEGAL_SPACE = -1;
- /** Constant representing a light king. */
- public static final int LIGHT_KING = 2;
- /** Constant representing a light single man. */
- public static final int LIGHT_PAWN = 1;
+from justcheckers.game import rules
- // -- Object Fields --------------------------------------------------------
- /** Is the board mirrored or a regular checker board. */
- private final boolean amIMirrored;
- /**
- * Holds the positions of the pieces on the board.
- */
- private final int[][] board;
- /** The size of the board. */
- private final int boardSize;
- /** A reference to the rules being used. */
- private final Rulebook myRules;
+class Square(Enum):
+ """Represents the state of a single square on a checkerboard."""
+ WHITE = -1
+ EMPTY = 0
+ LIGHT_PAWN = 1
+ LIGHT_KING = 2
+ DARK_PAWN = 3
+ DARK_KING = 4
- // -- Constructors ---------------------------------------------------------
- /**
- * Creates a new board for checkers.
- *
- * @param rules
- * The rules for this board.
- */
- public Board(Rulebook rules) {
- this.myRules = rules;
- final int size = this.myRules.getBoardSize();
- this.board = new int[size][size];
- this.boardSize = size;
- this.amIMirrored = this.myRules.isBoardMirrored();
- }
- // -- Public Methods (Setting Up the Board) --------------------------------
- /**
- * Clears the board of pieces. Creates a brand new empty board already laid
- * out by the rules (regular or mirrored).
- */
- public void clearBoard() {
- for (int row = 0; this.boardSize > row; row++) {
- for (int col = 0; this.boardSize > col; col++) {
+class Board(object):
+ """
+ * Container for the state of the checker board during a game.
+ *
+ * The size of the board is defined by the number of squares along one side,
+ * since all checker boards are square. The board coordinate system has both
+ * horizontal and vertical numeric components ranging from 0 to boardSize-1.
+ * Depicted on-screen, the horizontal component extends to the right and the
+ * vertical component extends downwards, making the upper left square (0, 0) and
+ * the lower right square (boardSize-1, boardSize-1).
+ *
+ * Navigating through the Board Internally, the checker board is
+ * organized as a two-dimensional array. So when iterating through the board,
+ * you first specify the vertical component and then the horizontal component.
+ * Another way of thinking about is first specifying which row you want to look
+ * at from top to bottom. Then you specify how across the row you are looking at
+ * from left to right.
+ *
+ * Players Places The light player (the starting player) starts at the
+ * top of the board. The dark player starts at the bottom of the board.
+ *
+ * @author Dorian Pula
+ * @author Ross Etchells
+ """
- // Mirrored has opposite setup to a regular board.
- if (row % 2 == 0 && col % 2 == 0) {
- if (this.amIMirrored) {
- this.board[row][col] = Board.ILLEGAL_SPACE;
- } else {
- this.board[row][col] = Board.EMPTY_SPACE;
- }
- } else if (row % 2 == 0 && col % 2 == 1) {
- if (this.amIMirrored) {
- this.board[row][col] = Board.EMPTY_SPACE;
- } else {
- this.board[row][col] = Board.ILLEGAL_SPACE;
- }
- } else if (row % 2 == 1 && col % 2 == 0) {
- if (this.amIMirrored) {
- this.board[row][col] = Board.EMPTY_SPACE;
- } else {
- this.board[row][col] = Board.ILLEGAL_SPACE;
- }
- } else {
- if (this.amIMirrored) {
- this.board[row][col] = Board.ILLEGAL_SPACE;
- } else {
- this.board[row][col] = Board.EMPTY_SPACE;
- }
- }
+ def __init__(self, size=rules.Rules.STANDARD_BOARD_SIZE, mirrored=False):
+ self.board_size = size
+ self._board = [[]]
- }
- }
- }
+ # /**
+ # * Clears the board of pieces. Creates a brand new empty board already laid
+ # * out by the rules (regular or mirrored).
+ # */
+ for row in xrange(0, size):
+ for col in xrange(0, size):
- // -- Get/Set Methods ------------------------------------------------------
- /**
- * Gets the size of the board. The board size is measured as the number of
- * squares down one side of the board.
- *
- * @return The size of the board.
- */
- public int getBoardSize() {
- return this.boardSize;
- }
+ # Mirrored has opposite setup to a regular board.
+ if (row % 2 == 0) and (col % 2 == 0):
+ if mirrored:
+ self._board[row][col] = Square.WHITE
+ else:
+ self._board[row][col] = Square.EMPTY
- /**
- * Provides a reference to a 2 dimensional array representation of the
- * current board state. This is for use by the user interface. Each
- * dimension of the array extends from 0 to boardSize - 1. Note that the
- * referenced array is a clone of the internal board representation. Changes
- * made to the array will not affect the board state.
- *
- * @return A 2 dimensional array representing the current state of the
- * board.
- */
- public int[][] getBoardState() {
- final int[][] repBoard = new int[this.boardSize][this.boardSize];
- System.arraycopy(this.board, 0, repBoard, 0, this.boardSize);
- return repBoard;
- }
+ elif (row % 2 == 0) and (col % 2 == 1):
+ if mirrored:
+ self._board[row][col] = Square.EMPTY
+ else:
+ self._board[row][col] = Square.WHITE
- /**
- * Determines whether the piece at board coordinate (row, col) is dark. If
- * the coordinates do not exist on the board or are empty, this method will
- * return false.
- *
- * @param row
- * The row of the square.
- * @param col
- * The column of the square.
- * @return True if the piece at the specified coordinate is dark. False if
- * otherwise.
- */
- public boolean isDark(int row, int col) {
- if (row >= 0 && row < this.boardSize && col >= 0
- && col < this.boardSize) {
- return this.board[row][col] == Board.DARK_KING
- || this.board[row][col] == Board.DARK_PAWN;
- }
- return false;
- }
+ elif (row % 2 == 1) and (col % 2 == 0):
+ if mirrored:
+ self._board[row][col] = Square.EMPTY
+ else:
+ self._board[row][col] = Square.WHITE
+ else:
+ if mirrored:
+ self._board[row][col] = Square.WHITE
+ else:
+ self._board[row][col] = Square.EMPTY
- /**
- * Determines whether the piece at board coordinate (row, col) is empty. If
- * the coordinates do not exist on the board or is illegal, this method will
- * return false.
- *
- * @param row
- * The row of the square.
- * @param col
- * The column of the square.
- * @return True if the piece at the specified coordinate is empty. False if
- * otherwise.
- */
- public boolean isEmpty(int row, int col) {
- if (row >= 0 && row < this.boardSize && col >= 0
- && col < this.boardSize) {
- return this.board[row][col] == Board.EMPTY_SPACE;
- }
- return false;
- }
+ def is_inside_board(self, row, col):
+ return (0 <= row < self.board_size) and (0 <= col < self.board_size)
- /**
- * Determines whether the board coordinate (x, y) is used in the game. In
- * most cases, all light spaces on the board will be considered illegal.
- * Also, any coordinate which does not exist is also considered illegal.
- *
- * @param row
- * The row of the square.
- * @param col
- * The column of the square.
- * @return True if the specified coordinate is nonexistent or unused in the
- * current rules. False if otherwise.
- */
- public boolean isIllegalSpace(int row, int col) {
- if (row >= 0 && row < this.boardSize && col >= 0
- && col < this.boardSize) {
- return this.board[row][col] == Board.ILLEGAL_SPACE;
- }
- return false;
- }
+ def is_dark(self, row, col):
+ """
+ /**
+ * Determines whether the piece at board coordinate (row, col) is dark. If
+ * the coordinates do not exist on the board or are empty, this method will
+ * return false.
+ *
+ * @param row
+ * The row of the square.
+ * @param col
+ * The column of the square.
+ * @return True if the piece at the specified coordinate is dark. False if
+ * otherwise.
+ */
+ """
+ return self.is_inside_board(row, col) and self._board[row][col] in [Square.DARK_KING, Square.DARK_PAWN]
- /**
- * Determines whether the piece at board coordinate (row, col) is a king. If
- * the coordinates do not exist on the board or are empty, this method will
- * return false.
- *
- * @param row
- * The row of the square.
- * @param col
- * The column of the square.
- * @return True if the piece at the specified coordinate is a king. False if
- * otherwise.
- */
- public boolean isKing(int row, int col) {
- if (row >= 0 && row < this.boardSize && col >= 0
- && col < this.boardSize) {
- return this.board[row][col] == Board.LIGHT_KING
- || this.board[row][col] == Board.DARK_KING;
- }
- return false;
- }
+ def is_empty(self, row, col):
+ """
+ /**
+ * Determines whether the piece at board coordinate (row, col) is empty. If
+ * the coordinates do not exist on the board or is illegal, this method will
+ * return False.
+ *
+ * @param row
+ * The row of the square.
+ * @param col
+ * The column of the square.
+ * @return True if the piece at the specified coordinate is empty. False if
+ * otherwise.
+ */
+ """
+ return self.is_inside_board(row, col) and self._board[row][col] == Square.EMPTY
- /**
- * Returns if a position specified is legal. Returns true if the position is
- * on the board, and if the space is not an illegal white space. Returns
- * false otherwise.
- *
- * @param row
- * The row coordinate of the position.
- * @param col
- * The column coordinate of the position.
- * @return Returns true if the position is a legal playing position.
- */
- public boolean isLegalPosition(int row, int col) {
- return row >= 0 && row < this.boardSize && col >= 0
- && col < this.boardSize && !this.isIllegalSpace(row, col);
- }
+ def is_illegal_space(self, row, col):
+ """
+ /**
+ * Determines whether the board coordinate (x, y) is used in the game. In
+ * most cases, all light spaces on the board will be considered illegal.
+ * Also, any coordinate which does not exist is also considered illegal.
+ *
+ * @param row
+ * The row of the square.
+ * @param col
+ * The column of the square.
+ * @return True if the specified coordinate is nonexistent or unused in the
+ * current rules. False if otherwise.
+ */
+ """
+ return self.is_inside_board(row, col) and self._board[row][col] == Square.WHITE
- /**
- * Determines whether the piece at board coordinate (row, col) is light. If
- * the coordinates do not exist on the board or are empty, this method will
- * return false.
- *
- * @param row
- * The row of the square.
- * @param col
- * The column of the square.
- * @return True if the piece at the specified coordinate is light. False if
- * otherwise.
- */
- public boolean isLight(int row, int col) {
- if (row >= 0 && row < this.boardSize && col >= 0
- && col < this.boardSize) {
- return this.board[row][col] == Board.LIGHT_KING
- || this.board[row][col] == Board.LIGHT_PAWN;
- }
- return false;
- }
+ # /**
+ # * Determines whether the piece at board coordinate (row, col) is a king. If
+ # * the coordinates do not exist on the board or are empty, this method will
+ # * return False.
+ # *
+ # * @param row
+ # * The row of the square.
+ # * @param col
+ # * The column of the square.
+ # * @return True if the piece at the specified coordinate is a king. False if
+ # * otherwise.
+ # */
+ def is_king(self, row, col):
+ return self.is_inside_board(row, col) and self._board[row][col] in [Square.LIGHT_KING, Square.DARK_KING]
- /**
- * Determines whether the piece at board coordinate (row, col) is a pawn. If
- * the coordinates do not exist on the board or are empty, this method will
- * return false.
- *
- * @param row
- * The row of the square.
- * @param col
- * The column of the square.
- * @return True if the piece at the specified coordinate is a pawn. False if
- * otherwise.
- */
- public boolean isPawn(int row, int col) {
- if (row >= 0 && row < this.boardSize && col >= 0
- && col < this.boardSize) {
- return this.board[row][col] == Board.LIGHT_PAWN
- || this.board[row][col] == Board.DARK_PAWN;
- }
- return false;
- }
+ # /**
+ # * Returns if a position specified is legal. Returns true if the position is
+ # * on the board, and if the space is not an illegal white space. Returns
+ # * False otherwise.
+ # *
+ # * @param row
+ # * The row coordinate of the position.
+ # * @param col
+ # * The column coordinate of the position.
+ # * @return Returns true if the position is a legal playing position.
+ # */
+ def is_legal_position(self, row, col):
+ return self.is_inside_board(row, col) and not self.is_illegal_space(row, col)
- // -- Board Updating Methods -----------------------------------------------
- /**
- * Moves a pieces from one location to another. This method should be called
- * from the Game using this Board. This method does not check for rule
- * validity but does check for illegal white spaces. Also checks that the
- * destination position is empty.
- *
- * @param sourceRow
- * The row from where the piece is moving from.
- * @param sourceCol
- * The column from where the piece is moving from.
- * @param targetRow
- * The row to where the piece is moving to.
- * @param targetCol
- * The column to where the piece is moving to.
- */
- protected void movePiece(int sourceRow, int sourceCol, int targetRow,
- int targetCol) {
+ # /**
+ # * Determines whether the piece at board coordinate (row, col) is light. If
+ # * the coordinates do not exist on the board or are empty, this method will
+ # * return False.
+ # *
+ # * @param row
+ # * The row of the square.
+ # * @param col
+ # * The column of the square.
+ # * @return True if the piece at the specified coordinate is light. False if
+ # * otherwise.
+ # */
+ def is_light(self, row, col):
+ return self.is_inside_board(row, col) and self._board[row][col] in [Square.LIGHT_KING, Square.LIGHT_PAWN]
- if (this.isLegalPosition(sourceRow, sourceCol)
- && this.isLegalPosition(targetRow, targetCol)
- && this.board[targetRow][targetCol] == Board.EMPTY_SPACE) {
+ # /**
+ # * Determines whether the piece at board coordinate (row, col) is a pawn. If
+ # * the coordinates do not exist on the board or are empty, this method will
+ # * return False.
+ # *
+ # * @param row
+ # * The row of the square.
+ # * @param col
+ # * The column of the square.
+ # * @return True if the piece at the specified coordinate is a pawn. False if
+ # * otherwise.
+ # */
+ def is_pawn(self, row, col):
+ return self.is_inside_board(row, col) and self._board[row][col] in [Square.LIGHT_PAWN, Square.DARK_PAWN]
- final int piece = this.board[sourceRow][sourceCol];
- this.board[targetRow][targetCol] = piece;
- this.board[sourceRow][sourceCol] = Board.EMPTY_SPACE;
+ # /**
+ # * Moves a pieces from one location to another. This method should be called
+ # * from the Game using this Board. This method does not check for rule
+ # * validity but does check for illegal white spaces. Also checks that the
+ # * destination position is empty.
+ # *
+ # * @param sourceRow
+ # * The row from where the piece is moving from.
+ # * @param sourceCol
+ # * The column from where the piece is moving from.
+ # * @param targetRow
+ # * The row to where the piece is moving to.
+ # * @param targetCol
+ # * The column to where the piece is moving to.
+ # */
+ def move_piece(self, source_row, source_col, target_row, target_col):
- }
- }
+ if (self.is_legal_position(source_row, source_col)
+ and self.is_legal_position(target_row, target_col)
+ and self._board[target_row][target_col] == Square.EMPTY):
- /**
- * Removes a pieces from the specified location. This method should be
- * called from the Game using this Board. This method does not check for
- * rule validity but does check for illegal white spaces.
- *
- * @param row
- * The row where the piece is to be removed from.
- * @param col
- * The column where the piece is to be removed from.
- */
- protected void removePiece(int row, int col) {
+ self._board[source_row][source_col], self._board[target_row][target_col] = (
+ Square.EMPTY, self._board[source_row][source_col])
- if (this.isLegalPosition(row, col)) {
- this.board[row][col] = Board.EMPTY_SPACE;
- }
- }
+ # /**
+ # * Removes a pieces from the specified location. This method should be
+ # * called from the Game using this Board. This method does not check for
+ # * rule validity but does check for illegal white spaces.
+ # *
+ # * @param row
+ # * The row where the piece is to be removed from.
+ # * @param col
+ # * The column where the piece is to be removed from.
+ # */
+ def remove_piece(self, row, col):
+ if self.is_legal_position(row, col):
+ self._board[row][col] = Square.EMPTY
- /**
- * Setups the board for a new game. There are three different setups for the
- * three different types of boards:
- *
- *
- *
- *
- * Name |
- * Size |
- * Number of Pieces Per Player |
- * Number of Rows Per Player |
- *
- *
- *
- * Standard |
- * 8 x 8 |
- * 12 |
- * 3 |
- *
- *
- * International |
- * 10 x 10 |
- * 20 |
- * 4 |
- *
- *
- * Canadian |
- * 12 x 12 |
- * 30 |
- * 5 |
- *
- *
- *
- * The columns containing the players' tokens alternate between columns. The
- * dark player traditionally takes the first few upper rows (0-3). The light
- * player takes the last of the lower rows (5-7, 6-9 or 7-11).
- *
- * Note that the suicide checkers variant has a completely different setup,
- * and has a setup function of its own: setupNewSuicideGame().
- */
- public void setupNewGame() {
- this.clearBoard();
+ # /**
+ # * Setups the board for a new game. There are three different setups for the
+ # * three different types of boards:
+ # *
+ # *
+ # *
+ # *
+ # * Name |
+ # * Size |
+ # * Number of Pieces Per Player |
+ # * Number of Rows Per Player |
+ # *
+ # *
+ # *
+ # * Standard |
+ # * 8 x 8 |
+ # * 12 |
+ # * 3 |
+ # *
+ # *
+ # * International |
+ # * 10 x 10 |
+ # * 20 |
+ # * 4 |
+ # *
+ # *
+ # * Canadian |
+ # * 12 x 12 |
+ # * 30 |
+ # * 5 |
+ # *
+ # *
+ # *
+ # * The columns containing the players' tokens alternate between columns. The
+ # * dark player traditionally takes the first few upper rows (0-3). The light
+ # * player takes the last of the lower rows (5-7, 6-9 or 7-11).
+ # *
+ # * Note that the suicide checkers variant has a completely different setup,
+ # * and has a setup function of its own: setupNewSuicideGame().
+ # */
+ def setup_new_game(self):
- if (this.myRules.getCheckersVariant() == Rulebook.SUICIDE_CHECKERS) {
- this.setupNewSuicideGame();
- } else {
+ # Used to decide which rows to fill up.
+ # Figure out the size of the board.
+ if self.board_size == rules.InternationalRules.INTERNATIONAL_BOARD_SIZE:
+ dark_player_bottom_row = 3
+ light_player_top_row = 6
+ elif self.board_size == rules.CanadianRules.CANADIAN_BOARD_SIZE:
+ dark_player_bottom_row = 3
+ light_player_top_row = 7
+ else:
+ # Default board is 8x8 Standard size.
+ dark_player_bottom_row = 2
+ light_player_top_row = 5
- // Used to decide which rows to fill up.
- int darkPlayerBottomRow;
- int lightPlayerTopRow;
+ # Go through the board and set it up.
+ for row in xrange(0, self.board_size):
+ for col in xrange(0, self.board_size):
+ if row <= dark_player_bottom_row and self._board[row][col] == Square.EMPTY:
+ self._board[row][col] = Square.DARK_PAWN
+ elif row >= light_player_top_row and self._board[row][col] == Square.EMPTY:
+ self._board[row][col] = Square.LIGHT_PAWN
- // Figure out the size of the board.
- if (this.boardSize == Rulebook.INTERNATIONAL_BOARD_SIZE) {
- darkPlayerBottomRow = 3;
- lightPlayerTopRow = 6;
- } else if (this.boardSize == Rulebook.CANADIAN_BOARD_SIZE) {
- darkPlayerBottomRow = 3;
- lightPlayerTopRow = 7;
- } else { // Default board is 8x8 Standard size.
- darkPlayerBottomRow = 2;
- lightPlayerTopRow = 5;
- }
+ # /**
+ # * Setups a checker board according to the suicide "French" rules.
+ # */
+ def setup_new_suicide_game(self):
+ # TODO: Implement the suicide game setup.
+ pass
- // Go through the board and set it up.
- for (int row = 0; row < this.boardSize; row++) {
- for (int col = 0; col < this.boardSize; col++) {
- if (row <= darkPlayerBottomRow
- && this.board[row][col] == Board.EMPTY_SPACE) {
- this.board[row][col] = Board.DARK_PAWN;
- } else if (row >= lightPlayerTopRow
- && this.board[row][col] == Board.EMPTY_SPACE) {
- this.board[row][col] = Board.LIGHT_PAWN;
- }
- }
- }
+ # /**
+ # * Returns a string to represent the board state. This string is formatted
+ # * for use as a simple board display in the command window.
+ # *
+ # * Legend ## - White space which the piece can not move on to. __ -
+ # * An empty space. LP - A light pawn. LK - A light king. DP - A dark pawn.
+ # * DK - A dark king.
+ # *
+ # * @return A string representing the current board state.
+ # */
+ def __str__(self):
+ # Prepare for output with a nice looking to banner.
+ output = " "
+ for row in xrange(0, self.board_size):
+ if row < 9:
+ output = '{}{}{}'.format(output, " ", row + 1)
+ else:
+ output = '{}{}{}'.format(output, " ", row + 1)
+ output = output + "\n\n"
- }
- }
+ output_atom = {
+ Square.WHITE: "## ",
+ Square.EMPTY: "__ ",
+ Square.LIGHT_PAWN: "LP ",
+ Square.LIGHT_KING: "LK ",
+ Square.DARK_PAWN: "DP ",
+ Square.DARK_KING:"DK ",
+ }
- /**
- * Setups a checker board according to the suicide "French" rules.
- */
- private void setupNewSuicideGame() {
- // TODO: Implement the suicide game setup.
- }
+ # Go row by row, printing out the row number and the board's state.
+ for row in xrange(0, self.board_size):
+ if row < 9:
+ output = '{}{}{}'.format(output, " ", row + 1)
+ else:
+ output = '{}{}{}'.format(output, " ", row + 1)
- // -- Private (Implementation) Methods -------------------------------------
+ # // Get current row's state.
+ for col in xrange(0, self.board_size):
+ output = output + output_atom[self._board[row][col]]
- /**
- * Returns a string to represent the board state. This string is formatted
- * for use as a simple board display in the command window.
- *
- * Legend ## - White space which the piece can not move on to. __ -
- * An empty space. LP - A light pawn. LK - A light king. DP - A dark pawn.
- * DK - A dark king.
- *
- * @return A string representing the current board state.
- */
- @Override
- public String toString() {
- // Prepare for output with a nice looking to banner.
- String output = " ";
- for (int i = 0; i < this.boardSize; i++) {
- if (i < 9) {
- output = output + " " + (i + 1);
- } else {
- output = output + " " + (i + 1);
- }
- }
- output = output + "\n\n";
+ output = output + "\n"
- // Go row by row, printing out the row number and the board's state.
- for (int row = 0; row < this.boardSize; row++) {
- if (row < 9) {
- output = output + " " + (row + 1);
- } else {
- output = output + " " + (row + 1);
- }
-
- // Get current row's state.
- for (int col = 0; col < this.boardSize; col++) {
- switch (this.board[row][col]) {
- case Board.ILLEGAL_SPACE:
- output = output + "## ";
- break;
- case Board.EMPTY_SPACE:
- output = output + "__ ";
- break;
- case Board.LIGHT_PAWN:
- output = output + "LP ";
- break;
- case Board.LIGHT_KING:
- output = output + "LK ";
- break;
- case Board.DARK_PAWN:
- output = output + "DP ";
- break;
- case Board.DARK_KING:
- output = output + "DK ";
- break;
- }
- }
-
- output = output + "\n";
- }
-
- return output;
-
- }
-}
+ return output
diff --git a/justcheckers/game/game_engine.py b/justcheckers/game/game_engine.py
index d14c7f2..54422ee 100644
--- a/justcheckers/game/game_engine.py
+++ b/justcheckers/game/game_engine.py
@@ -17,271 +17,240 @@
# Please share and enjoy!
#
-class GameEngine(object):
- // TODO: Add a constructor for games already in progress.
-
- // -- Game methods --------------------------------------------------------
-
- private static boolean canJump(Game game, int sourceRow, int sourceCol, int targetRow,
- int targetCol) {
-
- // TODO: Implement me.
- return false;
- }
+def canJump(game, sourceRow, sourceCol, targetRow, targetCol):
+ # TODO: Implement me.
+ # TODO: Make as private method.
+ return False
- /**
- * Returns if a piece can or cannot move. This move maybe either be a move
- * or a jump. This method is called by a user interface when a user wants to
- * moves a piece on screen or over the network. The piece can moved if the
- * current state of the game allows for it to do so.
- *
- * TODO: Add priority for king jumps over pawn jumps for any variants that
- * do so.
- *
- * @param sourceRow
- * The row from where the piece is moving from.
- * @param sourceCol
- * The column from where the piece is moving from.
- * @param targetRow
- * The row to where the piece is moving to.
- * @param targetCol
- * The column to where the piece is moving to.
- * @return True if the piece can move. False if the piece can not move.
- */
- public static boolean canMove(Game game, int sourceRow, int sourceCol, int targetRow,
- int targetCol) {
-
- // A few things to figure out priorities in moving a piece.
- boolean legalMove = false; // Is the proposed move/jump legal?
- boolean realPositions = false; // Are the positions really on the board?
- boolean isJump = false; // Is this a jump?
-
- // Sanity check.
- if (game.getGameBoard().isLegalPosition(sourceRow, sourceCol)
- && game.getGameBoard().isLegalPosition(targetRow, targetCol)) {
- realPositions = true;
-
- }
-
- // Is there a jump in progress?
- if (realPositions && game.getJumpInProgress() != null) {
-
- // Only allow the piece in movement to be moved.
- if (sourceRow == game.getJumpInProgress().getY()
- && sourceCol == game.getJumpInProgress().getX()) {
- legalMove = canJump(game, sourceRow, sourceCol, targetRow,
- targetCol);
- isJump = true;
- }
-
- } else if (realPositions) {
-
- // Go with the regular flow, jumps first then "slides".
- isJump = canPlayerJump(game);
- if (isJump) {
- legalMove = canJump(game, sourceRow, sourceCol, targetRow,
- targetCol);
- } else {
- legalMove = canSlide(game, sourceRow, sourceCol, targetRow,
- targetCol);
- }
-
- }
-
- return legalMove;
- }
- private static boolean canPlayerJump(Game game) {
- // TODO: Implement me.
- return false;
- }
+# /**
+# * Returns if a piece can or cannot move. This move maybe either be a move
+# * or a jump. This method is called by a user interface when a user wants to
+# * moves a piece on screen or over the network. The piece can moved if the
+# * current state of the game allows for it to do so.
+# *
+# * TODO: Add priority for king jumps over pawn jumps for any variants that
+# * do so.
+# *
+# * @param sourceRow
+# * The row from where the piece is moving from.
+# * @param sourceCol
+# * The column from where the piece is moving from.
+# * @param targetRow
+# * The row to where the piece is moving to.
+# * @param targetCol
+# * The column to where the piece is moving to.
+# * @return True if the piece can move. False if the piece can not move.
+# */
+def canMove(game, sourceRow, sourceCol, targetRow, targetCol):
- private static boolean canSlide(Game game, int sourceRow, int sourceCol, int targetRow,
- int targetCol) {
-
- boolean legalMove = true;
- boolean mustJump = canPlayerJump(game);
-
- // Is the move even on the board?
- legalMove = game.getGameBoard().isLegalPosition(sourceRow, sourceCol)
- && game.getGameBoard().isLegalPosition(targetRow, targetCol);
-
- // See if the destination is even empty.
- if (legalMove) {
- legalMove = game.getGameBoard().isEmpty(targetRow, targetCol);
- }
-
- // If yes, then look if right pieces were chosen.
- if (legalMove && !mustJump) {
- if (game.isLightPlayerTurn()
- && game.getGameBoard().isLight(sourceRow, sourceCol)) {
-
- // To deal with flying kings.
- if (game.getGameBoard().isKing(sourceRow, sourceCol)
- && game.getGameRules().canKingsFly()) {
-
- // FIXME: Fix this!
- } else {
- // if ((Math.abs(targetRow - sourceRow) == 1) && (Math.abs(targetRow - sourceRow) == 1)) {
- // legalMove = false;
- // }
- }
-
- // Is the path clear for that move?
-
- } else if (!game.isLightPlayerTurn()
- && game.getGameBoard().isDark(sourceRow, sourceCol)) {
-
- //TODO: Implement me, sometime.
- } else {
- legalMove = false;
- }
- }
-
- return legalMove;
- }
+ # // A few things to figure out priorities in moving a piece.
+ legalMove = False
+ # // Is the proposed move/jump legal?
+ realPositions = False
+ # // Are the positions really on the board?
+ isJump = False
+ # // Is this a jump?
- private static void checkForVictory(Game game) {
- // TODO: Implement me.
- }
+ # // Sanity check.
+ if (game.getGameBoard().isLegalPosition(sourceRow, sourceCol)
+ and game.getGameBoard().isLegalPosition(targetRow, targetCol)):
+ realPositions = True
- /**
- * Gets if a piece is movable. Returns true if the piece can slide or jump.
- * This method only calculates slides to the adjacent positions. Similarly,
- * the method only looks at jumping an adjacent enemy piece. This check is
- * used by the graphical user interface to determine if a piece can be moved
- * either for sliding or jumping. The method is aware of whose turn is it to
- * move.
- *
- * @param row
- * The row coordinate of the piece to check.
- * @param col
- * The column coordinate of the piece to check.
- * @return Returns true if the piece can slide or jump in this turn.
- */
- public static boolean isMovablePiece(Game game, int row, int col) {
-
- // Fields for determining of a piece is movable.
- boolean moveUpLeft = true;
- boolean moveUpRight = true;
- boolean moveDownLeft = true;
- boolean moveDownRight = true;
-
- /*
- * Checks first if the first colour of piece is being grabbed. Next if
- * the piece is blocked by its own pieces. Next if the opponent has
- * double blocked off the pieces. Also sanity checks if looking past the
- * size of the board.
- */
- if (game.isLightPlayerTurn() && game.getGameBoard().isLight(row, col)) { // Light
- // player.
-
- // Can piece move normally?
- moveDownLeft = canSlide(game, row, col, row + 1, col - 1);
- moveDownRight = canSlide(game, row, col, row + 1, col + 1);
-
- if (game.getGameBoard().isKing(row, col)) {
- moveUpLeft = canSlide(game, row, col, row - 1, col - 1);
- moveUpRight = canSlide(game, row, col, row - 1, col + 1);
- } else {
- moveUpLeft = false;
- moveUpRight = false;
- }
-
- // If no slides available try doing the same except for jumps.
- if (!moveDownLeft) {
- moveDownLeft = canJump(game, row, col, row + 2, col - 2);
- } else if (!moveDownRight) {
- moveDownRight = canJump(game, row, col, row + 2, col + 2);
- } else if (game.getGameBoard().isKing(row, col)
- || game.getGameRules().canPawnsJumpBackwards()) {
-
- if (!moveUpLeft) {
- moveUpLeft = canJump(game, row, col, row - 2, col + 2);
- } else if (!moveUpRight) {
- moveUpRight = canJump(game, row, col, row - 2, col - 2);
- }
-
- }
-
- return moveUpLeft || moveUpRight || moveDownLeft || moveDownRight;
-
- } else if (game.isLightPlayerTurn() && game.getGameBoard().isDark(row, col)) { // Dark
- // player
-
- // Can piece move normally?
- moveUpLeft = canSlide(game, row, col, row - 1, col - 1);
- moveUpRight = canSlide(game, row, col, row - 1, col + 1);
-
- if (game.getGameBoard().isKing(row, col)) {
- moveDownLeft = canSlide(game, row, col, row + 1, col - 1);
- moveDownRight = canSlide(game, row, col, row + 1, col + 1);
- } else {
- moveDownLeft = false;
- moveDownRight = false;
- }
-
- // If no slides available try doing the same except for jumps.
- if (!moveUpLeft) {
- moveUpLeft = canJump(game, row, col, row - 2, col - 2);
- } else if (!moveUpRight) {
- moveUpRight = canJump(game, row, col, row - 2, col + 2);
- } else if (game.getGameBoard().isKing(row, col)
- || game.getGameRules().canPawnsJumpBackwards()) {
-
- if (!moveDownLeft) {
- moveDownLeft = canJump(game, row, col, row + 2, col + 2);
- } else if (!moveDownRight) {
- moveDownRight = canJump(game, row, col, row + 2, col - 2);
- }
-
- }
-
- return moveUpLeft || moveUpRight || moveDownLeft || moveDownRight;
-
- } else {
- return false; // A wrong coloured piece.
- }
-
- }
+ # // Is there a jump in progress?
+ if (realPositions and game.getJumpInProgress() != None):
- /**
- * Moves a pieces from one location to another. This move maybe either be a
- * move or a jump. This method is called by a user interface when a user
- * moves a piece on screen or over the network. The piece is moved if the
- * current state of the game allows for it to do so.
- *
- * TODO: Add priority for king jumps over pawn jumps for any variants that
- * do so. TODO: Implement jumping by piece removal.
- *
- * @param sourceRow
- * The row from where the piece is moving from.
- * @param sourceCol
- * The column from where the piece is moving from.
- * @param targetRow
- * The row to where the piece is moving to.
- * @param targetCol
- * The column to where the piece is moving to.
- */
- public static void movePiece(Game game, int sourceRow, int sourceCol, int targetRow,
- int targetCol) {
-
- // If everything checks out... move the piece!
- if (canMove(game, sourceRow, sourceCol, targetRow, targetCol)) {
- if (game.getJumpInProgress() != null) {
-
- // TODO: Implement jumping via removing of piece.
- game.getGameBoard().movePiece(sourceRow, sourceCol, targetRow,
- targetCol);
- } else {
- game.getGameBoard().movePiece(sourceRow, sourceCol, targetRow,
- targetCol);
- }
-
- checkForVictory(game);
- }
-
- }
+ # // Only allow the piece in movement to be moved.
+ if (sourceRow == game.getJumpInProgress().getY()
+ and sourceCol == game.getJumpInProgress().getX()):
+ legalMove = canJump(game, sourceRow, sourceCol, targetRow,
+ targetCol)
+ isJump = True
-}
+ elif (realPositions):
+
+ # // Go with the regular flow, jumps first then "slides".
+ isJump = canPlayerJump(game)
+ if isJump:
+ legalMove = canJump(game, sourceRow, sourceCol, targetRow,
+ targetCol)
+ else:
+ legalMove = canSlide(game, sourceRow, sourceCol, targetRow,
+ targetCol)
+
+ return legalMove
+
+def canPlayerJump(game):
+ # // TODO: Implement me.
+ # TODO Make as private method
+ return False
+
+def canSlide(game, sourceRow, sourceCol, targetRow, targetCol):
+
+ # TODO Make private
+ legalMove = True
+ mustJump = canPlayerJump(game)
+
+ # // Is the move even on the board?
+ legalMove = game.getGameBoard().isLegalPosition(sourceRow, sourceCol)\
+ and game.getGameBoard().isLegalPosition(targetRow, targetCol)
+
+ # // See if the destination is even empty.
+ if (legalMove):
+ legalMove = game.getGameBoard().isEmpty(targetRow, targetCol)
+
+ # // If yes, then look if right pieces were chosen.
+ if (legalMove and not mustJump):
+ if (game.isLightPlayerTurn() and game.getGameBoard().isLight(sourceRow, sourceCol)):
+
+ # // To deal with flying kings.
+ if (game.getGameBoard().isKing(sourceRow, sourceCol)
+ and game.getGameRules().canKingsFly()):
+
+ # // FIXME: Fix this!
+ pass
+ else:
+ # // if ((Math.abs(targetRow - sourceRow) == 1) && (Math.abs(targetRow - sourceRow) == 1)) {
+ # // legalMove = false;
+
+ # // Is the path clear for that move?
+ pass
+
+ elif (not game.isLightPlayerTurn() and game.getGameBoard().isDark(sourceRow, sourceCol)):
+
+ # //TODO: Implement me, sometime.
+ pass
+ else:
+ legalMove = False
+
+ return legalMove;
+
+
+def checkForVictory(game):
+ # // TODO: Implement me.
+ pass
+
+# /**
+# * Gets if a piece is movable. Returns True if the piece can slide or jump.
+# * This method only calculates slides to the adjacent positions. Similarly,
+# * the method only looks at jumping an adjacent enemy piece. This check is
+# * used by the graphical user interface to determine if a piece can be moved
+# * either for sliding or jumping. The method is aware of whose turn is it to
+# * move.
+# *
+# * @param row
+# * The row coordinate of the piece to check.
+# * @param col
+# * The column coordinate of the piece to check.
+# * @return Returns True if the piece can slide or jump in this turn.
+# */
+def isMovablePiece(game, row, col):
+
+ # // Fields for determining of a piece is movable.
+ moveUpLeft = True
+ moveUpRight = True
+ moveDownLeft = True
+ moveDownRight = True
+
+ # /*
+ # * Checks first if the first colour of piece is being grabbed. Next if
+ # * the piece is blocked by its own pieces. Next if the opponent has
+ # * double blocked off the pieces. Also sanity checks if looking past the
+ # * size of the board.
+ # */
+ if (game.isLightPlayerTurn() and game.getGameBoard().isLight(row, col)):
+
+ # // Light player.
+
+ # // Can piece move normally?
+ moveDownLeft = canSlide(game, row, col, row + 1, col - 1)
+ moveDownRight = canSlide(game, row, col, row + 1, col + 1)
+
+ if (game.getGameBoard().isKing(row, col)):
+ moveUpLeft = canSlide(game, row, col, row - 1, col - 1)
+ moveUpRight = canSlide(game, row, col, row - 1, col + 1)
+ else:
+ moveUpLeft = False
+ moveUpRight = False
+
+ # // If no slides available try doing the same except for jumps.
+ if (not moveDownLeft):
+ moveDownLeft = canJump(game, row, col, row + 2, col - 2)
+ elif (not moveDownRight):
+ moveDownRight = canJump(game, row, col, row + 2, col + 2)
+ elif (game.getGameBoard().isKing(row, col)
+ or game.getGameRules().canPawnsJumpBackwards()):
+
+ if (not moveUpLeft):
+ moveUpLeft = canJump(game, row, col, row - 2, col + 2)
+ elif (not moveUpRight):
+ moveUpRight = canJump(game, row, col, row - 2, col - 2)
+
+ return moveUpLeft or moveUpRight or moveDownLeft or moveDownRight
+
+ elif (game.isLightPlayerTurn() and game.getGameBoard().isDark(row, col)):
+ # // Dark player
+
+ # // Can piece move normally?
+ moveUpLeft = canSlide(game, row, col, row - 1, col - 1)
+ moveUpRight = canSlide(game, row, col, row - 1, col + 1)
+
+ if (game.getGameBoard().isKing(row, col)):
+ moveDownLeft = canSlide(game, row, col, row + 1, col - 1)
+ moveDownRight = canSlide(game, row, col, row + 1, col + 1)
+ else:
+ moveDownLeft = False
+ moveDownRight = False
+
+ # // If no slides available try doing the same except for jumps.
+ if (not moveUpLeft):
+ moveUpLeft = canJump(game, row, col, row - 2, col - 2)
+ elif (not moveUpRight):
+ moveUpRight = canJump(game, row, col, row - 2, col + 2)
+ elif (game.getGameBoard().isKing(row, col)
+ or game.getGameRules().canPawnsJumpBackwards()):
+
+ if (not moveDownLeft):
+ moveDownLeft = canJump(game, row, col, row + 2, col + 2)
+ elif (not moveDownRight):
+ moveDownRight = canJump(game, row, col, row + 2, col - 2)
+
+ return moveUpLeft or moveUpRight or moveDownLeft or moveDownRight
+
+ else:
+ return False
+ # // A wrong coloured piece.
+
+# /**
+# * Moves a pieces from one location to another. This move maybe either be a
+# * move or a jump. This method is called by a user interface when a user
+# * moves a piece on screen or over the network. The piece is moved if the
+# * current state of the game allows for it to do so.
+# *
+# * TODO: Add priority for king jumps over pawn jumps for any variants that
+# * do so. TODO: Implement jumping by piece removal.
+# *
+# * @param sourceRow
+# * The row from where the piece is moving from.
+# * @param sourceCol
+# * The column from where the piece is moving from.
+# * @param targetRow
+# * The row to where the piece is moving to.
+# * @param targetCol
+# * The column to where the piece is moving to.
+# */
+def movePiece(game, sourceRow, sourceCol, targetRow, targetCol):
+
+ # // If everything checks out... move the piecenot
+ if (canMove(game, sourceRow, sourceCol, targetRow, targetCol)):
+ if (game.getJumpInProgress() != None):
+
+ # TODO: Implement jumping via removing of piece.
+ game.getGameBoard().movePiece(sourceRow, sourceCol, targetRow,
+ targetCol)
+ else:
+ game.getGameBoard().movePiece(sourceRow, sourceCol, targetRow,
+ targetCol)
+
+ checkForVictory(game)