Raw translation of Java code into Python code.
This commit is contained in:
parent
cf103bcbb8
commit
d791840bdd
|
@ -17,477 +17,342 @@
|
||||||
# Please share and enjoy!
|
# Please share and enjoy!
|
||||||
#
|
#
|
||||||
|
|
||||||
/**
|
from enum import Enum
|
||||||
* 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).
|
|
||||||
*
|
|
||||||
* <b>Navigating through the Board</b> 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.
|
|
||||||
*
|
|
||||||
* <b>Players Places</b> 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 {
|
|
||||||
|
|
||||||
/** Constant representing a dark king. */
|
from justcheckers.game import rules
|
||||||
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;
|
|
||||||
|
|
||||||
// -- Object Fields --------------------------------------------------------
|
|
||||||
|
|
||||||
/** Is the board mirrored or a regular checker board. */
|
class Square(Enum):
|
||||||
private final boolean amIMirrored;
|
"""Represents the state of a single square on a checkerboard."""
|
||||||
/**
|
WHITE = -1
|
||||||
* Holds the positions of the pieces on the board.
|
EMPTY = 0
|
||||||
*/
|
LIGHT_PAWN = 1
|
||||||
private final int[][] board;
|
LIGHT_KING = 2
|
||||||
/** The size of the board. */
|
DARK_PAWN = 3
|
||||||
private final int boardSize;
|
DARK_KING = 4
|
||||||
/** A reference to the rules being used. */
|
|
||||||
private final Rulebook myRules;
|
|
||||||
|
|
||||||
// -- 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) --------------------------------
|
class Board(object):
|
||||||
/**
|
"""
|
||||||
* Clears the board of pieces. Creates a brand new empty board already laid
|
* Container for the state of the checker board during a game.
|
||||||
* out by the rules (regular or mirrored).
|
*
|
||||||
*/
|
* The size of the board is defined by the number of squares along one side,
|
||||||
public void clearBoard() {
|
* since all checker boards are square. The board coordinate system has both
|
||||||
for (int row = 0; this.boardSize > row; row++) {
|
* horizontal and vertical numeric components ranging from 0 to boardSize-1.
|
||||||
for (int col = 0; this.boardSize > col; col++) {
|
* 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).
|
||||||
|
*
|
||||||
|
* <b>Navigating through the Board</b> 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.
|
||||||
|
*
|
||||||
|
* <b>Players Places</b> 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.
|
def __init__(self, size=rules.Rules.STANDARD_BOARD_SIZE, mirrored=False):
|
||||||
if (row % 2 == 0 && col % 2 == 0) {
|
self.board_size = size
|
||||||
if (this.amIMirrored) {
|
self._board = [[]]
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
# /**
|
||||||
}
|
# * 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 ------------------------------------------------------
|
# Mirrored has opposite setup to a regular board.
|
||||||
/**
|
if (row % 2 == 0) and (col % 2 == 0):
|
||||||
* Gets the size of the board. The board size is measured as the number of
|
if mirrored:
|
||||||
* squares down one side of the board.
|
self._board[row][col] = Square.WHITE
|
||||||
*
|
else:
|
||||||
* @return The size of the board.
|
self._board[row][col] = Square.EMPTY
|
||||||
*/
|
|
||||||
public int getBoardSize() {
|
|
||||||
return this.boardSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
elif (row % 2 == 0) and (col % 2 == 1):
|
||||||
* Provides a reference to a 2 dimensional array representation of the
|
if mirrored:
|
||||||
* current board state. This is for use by the user interface. Each
|
self._board[row][col] = Square.EMPTY
|
||||||
* dimension of the array extends from 0 to boardSize - 1. Note that the
|
else:
|
||||||
* referenced array is a clone of the internal board representation. Changes
|
self._board[row][col] = Square.WHITE
|
||||||
* 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 == 1) and (col % 2 == 0):
|
||||||
* Determines whether the piece at board coordinate (row, col) is dark. If
|
if mirrored:
|
||||||
* the coordinates do not exist on the board or are empty, this method will
|
self._board[row][col] = Square.EMPTY
|
||||||
* return false.
|
else:
|
||||||
*
|
self._board[row][col] = Square.WHITE
|
||||||
* @param row
|
else:
|
||||||
* The row of the square.
|
if mirrored:
|
||||||
* @param col
|
self._board[row][col] = Square.WHITE
|
||||||
* The column of the square.
|
else:
|
||||||
* @return True if the piece at the specified coordinate is dark. False if
|
self._board[row][col] = Square.EMPTY
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
def is_inside_board(self, row, col):
|
||||||
* Determines whether the piece at board coordinate (row, col) is empty. If
|
return (0 <= row < self.board_size) and (0 <= col < self.board_size)
|
||||||
* 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_dark(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.
|
* 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
|
||||||
* @param row
|
* return false.
|
||||||
* The row of the square.
|
*
|
||||||
* @param col
|
* @param row
|
||||||
* The column of the square.
|
* The row of the square.
|
||||||
* @return True if the specified coordinate is nonexistent or unused in the
|
* @param col
|
||||||
* current rules. False if otherwise.
|
* The column of the square.
|
||||||
*/
|
* @return True if the piece at the specified coordinate is dark. False if
|
||||||
public boolean isIllegalSpace(int row, int col) {
|
* otherwise.
|
||||||
if (row >= 0 && row < this.boardSize && col >= 0
|
*/
|
||||||
&& col < this.boardSize) {
|
"""
|
||||||
return this.board[row][col] == Board.ILLEGAL_SPACE;
|
return self.is_inside_board(row, col) and self._board[row][col] in [Square.DARK_KING, Square.DARK_PAWN]
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
def is_empty(self, row, col):
|
||||||
* 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.
|
* 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
|
||||||
* @param row
|
* return False.
|
||||||
* The row of the square.
|
*
|
||||||
* @param col
|
* @param row
|
||||||
* The column of the square.
|
* The row of the square.
|
||||||
* @return True if the piece at the specified coordinate is a king. False if
|
* @param col
|
||||||
* otherwise.
|
* The column of the square.
|
||||||
*/
|
* @return True if the piece at the specified coordinate is empty. False if
|
||||||
public boolean isKing(int row, int col) {
|
* otherwise.
|
||||||
if (row >= 0 && row < this.boardSize && col >= 0
|
*/
|
||||||
&& col < this.boardSize) {
|
"""
|
||||||
return this.board[row][col] == Board.LIGHT_KING
|
return self.is_inside_board(row, col) and self._board[row][col] == Square.EMPTY
|
||||||
|| this.board[row][col] == Board.DARK_KING;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
def is_illegal_space(self, row, col):
|
||||||
* 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.
|
* 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.
|
||||||
* @param row
|
* Also, any coordinate which does not exist is also considered illegal.
|
||||||
* The row coordinate of the position.
|
*
|
||||||
* @param col
|
* @param row
|
||||||
* The column coordinate of the position.
|
* The row of the square.
|
||||||
* @return Returns true if the position is a legal playing position.
|
* @param col
|
||||||
*/
|
* The column of the square.
|
||||||
public boolean isLegalPosition(int row, int col) {
|
* @return True if the specified coordinate is nonexistent or unused in the
|
||||||
return row >= 0 && row < this.boardSize && col >= 0
|
* current rules. False if otherwise.
|
||||||
&& col < this.boardSize && !this.isIllegalSpace(row, col);
|
*/
|
||||||
}
|
"""
|
||||||
|
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
|
# * 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
|
# * the coordinates do not exist on the board or are empty, this method will
|
||||||
* return false.
|
# * return False.
|
||||||
*
|
# *
|
||||||
* @param row
|
# * @param row
|
||||||
* The row of the square.
|
# * The row of the square.
|
||||||
* @param col
|
# * @param col
|
||||||
* The column of the square.
|
# * The column of the square.
|
||||||
* @return True if the piece at the specified coordinate is light. False if
|
# * @return True if the piece at the specified coordinate is a king. False if
|
||||||
* otherwise.
|
# * otherwise.
|
||||||
*/
|
# */
|
||||||
public boolean isLight(int row, int col) {
|
def is_king(self, row, col):
|
||||||
if (row >= 0 && row < this.boardSize && col >= 0
|
return self.is_inside_board(row, col) and self._board[row][col] in [Square.LIGHT_KING, Square.DARK_KING]
|
||||||
&& 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 pawn. If
|
# * Returns if a position specified is legal. Returns true if the position is
|
||||||
* the coordinates do not exist on the board or are empty, this method will
|
# * on the board, and if the space is not an illegal white space. Returns
|
||||||
* return false.
|
# * False otherwise.
|
||||||
*
|
# *
|
||||||
* @param row
|
# * @param row
|
||||||
* The row of the square.
|
# * The row coordinate of the position.
|
||||||
* @param col
|
# * @param col
|
||||||
* The column of the square.
|
# * The column coordinate of the position.
|
||||||
* @return True if the piece at the specified coordinate is a pawn. False if
|
# * @return Returns true if the position is a legal playing position.
|
||||||
* otherwise.
|
# */
|
||||||
*/
|
def is_legal_position(self, row, col):
|
||||||
public boolean isPawn(int row, int col) {
|
return self.is_inside_board(row, col) and not self.is_illegal_space(row, 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Board Updating Methods -----------------------------------------------
|
# /**
|
||||||
/**
|
# * Determines whether the piece at board coordinate (row, col) is light. If
|
||||||
* Moves a pieces from one location to another. This method should be called
|
# * the coordinates do not exist on the board or are empty, this method will
|
||||||
* from the Game using this Board. This method does not check for rule
|
# * return False.
|
||||||
* validity but does check for illegal white spaces. Also checks that the
|
# *
|
||||||
* destination position is empty.
|
# * @param row
|
||||||
*
|
# * The row of the square.
|
||||||
* @param sourceRow
|
# * @param col
|
||||||
* The row from where the piece is moving from.
|
# * The column of the square.
|
||||||
* @param sourceCol
|
# * @return True if the piece at the specified coordinate is light. False if
|
||||||
* The column from where the piece is moving from.
|
# * otherwise.
|
||||||
* @param targetRow
|
# */
|
||||||
* The row to where the piece is moving to.
|
def is_light(self, row, col):
|
||||||
* @param targetCol
|
return self.is_inside_board(row, col) and self._board[row][col] in [Square.LIGHT_KING, Square.LIGHT_PAWN]
|
||||||
* The column to where the piece is moving to.
|
|
||||||
*/
|
|
||||||
protected void movePiece(int sourceRow, int sourceCol, int targetRow,
|
|
||||||
int targetCol) {
|
|
||||||
|
|
||||||
if (this.isLegalPosition(sourceRow, sourceCol)
|
# /**
|
||||||
&& this.isLegalPosition(targetRow, targetCol)
|
# * Determines whether the piece at board coordinate (row, col) is a pawn. If
|
||||||
&& this.board[targetRow][targetCol] == Board.EMPTY_SPACE) {
|
# * 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;
|
# * Moves a pieces from one location to another. This method should be called
|
||||||
this.board[sourceRow][sourceCol] = Board.EMPTY_SPACE;
|
# * 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):
|
||||||
|
|
||||||
/**
|
self._board[source_row][source_col], self._board[target_row][target_col] = (
|
||||||
* Removes a pieces from the specified location. This method should be
|
Square.EMPTY, self._board[source_row][source_col])
|
||||||
* 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) {
|
|
||||||
|
|
||||||
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
|
# * Setups the board for a new game. There are three different setups for the
|
||||||
* three different types of boards:
|
# * three different types of boards:
|
||||||
*
|
# *
|
||||||
* <table>
|
# * <table>
|
||||||
* <tr>
|
# * <tr>
|
||||||
* <b>
|
# * <b>
|
||||||
* <td>Name</td>
|
# * <td>Name</td>
|
||||||
* <td>Size</td>
|
# * <td>Size</td>
|
||||||
* <td>Number of Pieces Per Player</td>
|
# * <td>Number of Pieces Per Player</td>
|
||||||
* <td>Number of Rows Per Player</td>
|
# * <td>Number of Rows Per Player</td>
|
||||||
* </b>
|
# * </b>
|
||||||
* </tr>
|
# * </tr>
|
||||||
* <tr>
|
# * <tr>
|
||||||
* <td>Standard</td>
|
# * <td>Standard</td>
|
||||||
* <td>8 x 8</td>
|
# * <td>8 x 8</td>
|
||||||
* <td>12</td>
|
# * <td>12</td>
|
||||||
* <td>3</td>
|
# * <td>3</td>
|
||||||
* </tr>
|
# * </tr>
|
||||||
* <tr>
|
# * <tr>
|
||||||
* <td>International</td>
|
# * <td>International</td>
|
||||||
* <td>10 x 10</td>
|
# * <td>10 x 10</td>
|
||||||
* <td>20</td>
|
# * <td>20</td>
|
||||||
* <td>4</td>
|
# * <td>4</td>
|
||||||
* </tr>
|
# * </tr>
|
||||||
* <tr>
|
# * <tr>
|
||||||
* <td>Canadian</td>
|
# * <td>Canadian</td>
|
||||||
* <td>12 x 12</td>
|
# * <td>12 x 12</td>
|
||||||
* <td>30</td>
|
# * <td>30</td>
|
||||||
* <td>5</td>
|
# * <td>5</td>
|
||||||
* </tr>
|
# * </tr>
|
||||||
* </table>
|
# * </table>
|
||||||
*
|
# *
|
||||||
* The columns containing the players' tokens alternate between columns. The
|
# * The columns containing the players' tokens alternate between columns. The
|
||||||
* dark player traditionally takes the first few upper rows (0-3). The light
|
# * 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).
|
# * 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,
|
# * Note that the suicide checkers variant has a completely different setup,
|
||||||
* and has a setup function of its own: setupNewSuicideGame().
|
# * and has a setup function of its own: setupNewSuicideGame().
|
||||||
*/
|
# */
|
||||||
public void setupNewGame() {
|
def setup_new_game(self):
|
||||||
this.clearBoard();
|
|
||||||
|
|
||||||
if (this.myRules.getCheckersVariant() == Rulebook.SUICIDE_CHECKERS) {
|
# Used to decide which rows to fill up.
|
||||||
this.setupNewSuicideGame();
|
# Figure out the size of the board.
|
||||||
} else {
|
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.
|
# Go through the board and set it up.
|
||||||
int darkPlayerBottomRow;
|
for row in xrange(0, self.board_size):
|
||||||
int lightPlayerTopRow;
|
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) {
|
# * Setups a checker board according to the suicide "French" rules.
|
||||||
darkPlayerBottomRow = 3;
|
# */
|
||||||
lightPlayerTopRow = 6;
|
def setup_new_suicide_game(self):
|
||||||
} else if (this.boardSize == Rulebook.CANADIAN_BOARD_SIZE) {
|
# TODO: Implement the suicide game setup.
|
||||||
darkPlayerBottomRow = 3;
|
pass
|
||||||
lightPlayerTopRow = 7;
|
|
||||||
} else { // Default board is 8x8 Standard size.
|
|
||||||
darkPlayerBottomRow = 2;
|
|
||||||
lightPlayerTopRow = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go through the board and set it up.
|
# /**
|
||||||
for (int row = 0; row < this.boardSize; row++) {
|
# * Returns a string to represent the board state. This string is formatted
|
||||||
for (int col = 0; col < this.boardSize; col++) {
|
# * for use as a simple board display in the command window.
|
||||||
if (row <= darkPlayerBottomRow
|
# *
|
||||||
&& this.board[row][col] == Board.EMPTY_SPACE) {
|
# * <b>Legend</b> ## - White space which the piece can not move on to. __ -
|
||||||
this.board[row][col] = Board.DARK_PAWN;
|
# * An empty space. LP - A light pawn. LK - A light king. DP - A dark pawn.
|
||||||
} else if (row >= lightPlayerTopRow
|
# * DK - A dark king.
|
||||||
&& this.board[row][col] == Board.EMPTY_SPACE) {
|
# *
|
||||||
this.board[row][col] = Board.LIGHT_PAWN;
|
# * @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 ",
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
# Go row by row, printing out the row number and the board's state.
|
||||||
* Setups a checker board according to the suicide "French" rules.
|
for row in xrange(0, self.board_size):
|
||||||
*/
|
if row < 9:
|
||||||
private void setupNewSuicideGame() {
|
output = '{}{}{}'.format(output, " ", row + 1)
|
||||||
// TODO: Implement the suicide game setup.
|
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]]
|
||||||
|
|
||||||
/**
|
output = output + "\n"
|
||||||
* Returns a string to represent the board state. This string is formatted
|
|
||||||
* for use as a simple board display in the command window.
|
|
||||||
*
|
|
||||||
* <b>Legend</b> ## - 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";
|
|
||||||
|
|
||||||
// Go row by row, printing out the row number and the board's state.
|
return output
|
||||||
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;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,271 +17,240 @@
|
||||||
# Please share and enjoy!
|
# Please share and enjoy!
|
||||||
#
|
#
|
||||||
|
|
||||||
class GameEngine(object):
|
|
||||||
|
|
||||||
// TODO: Add a constructor for games already in progress.
|
def canJump(game, sourceRow, sourceCol, targetRow, targetCol):
|
||||||
|
# TODO: Implement me.
|
||||||
// -- Game methods --------------------------------------------------------
|
# TODO: Make as private method.
|
||||||
|
return False
|
||||||
private static boolean canJump(Game game, int sourceRow, int sourceCol, int targetRow,
|
|
||||||
int targetCol) {
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
*/
|
|
||||||
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.
|
# * Returns if a piece can or cannot move. This move maybe either be a move
|
||||||
return false;
|
# * 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,
|
# // A few things to figure out priorities in moving a piece.
|
||||||
int targetCol) {
|
legalMove = False
|
||||||
|
# // Is the proposed move/jump legal?
|
||||||
boolean legalMove = true;
|
realPositions = False
|
||||||
boolean mustJump = canPlayerJump(game);
|
# // Are the positions really on the board?
|
||||||
|
isJump = False
|
||||||
// Is the move even on the board?
|
# // Is this a jump?
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void checkForVictory(Game game) {
|
# // Sanity check.
|
||||||
// TODO: Implement me.
|
if (game.getGameBoard().isLegalPosition(sourceRow, sourceCol)
|
||||||
}
|
and game.getGameBoard().isLegalPosition(targetRow, targetCol)):
|
||||||
|
realPositions = True
|
||||||
|
|
||||||
/**
|
# // Is there a jump in progress?
|
||||||
* Gets if a piece is movable. Returns true if the piece can slide or jump.
|
if (realPositions and game.getJumpInProgress() != None):
|
||||||
* 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.
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
# // Only allow the piece in movement to be moved.
|
||||||
* Moves a pieces from one location to another. This move maybe either be a
|
if (sourceRow == game.getJumpInProgress().getY()
|
||||||
* move or a jump. This method is called by a user interface when a user
|
and sourceCol == game.getJumpInProgress().getX()):
|
||||||
* moves a piece on screen or over the network. The piece is moved if the
|
legalMove = canJump(game, sourceRow, sourceCol, targetRow,
|
||||||
* current state of the game allows for it to do so.
|
targetCol)
|
||||||
*
|
isJump = True
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
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)
|
||||||
|
|
Loading…
Reference in New Issue