For this assignment, you will create a class, Gameboard, that will contain metho
ID: 3740228 • Letter: F
Question
For this assignment, you will create a class, Gameboard, that will contain methods to create a game board and manage certain parts of the game of Checkers. The board will consist of a 2D array, with each individual space designated by an array of integers representing the row and column indexes. The upper-left square on the board will be at coordinate [0,0]. In the picture above, the white piece in the lower-left corner would be at [7,0], and the upper-right red piece would be at [0,7].
class Gameboard
Variables:
public char[][] board - a public variable containing the 8x8 game board of characters.
Methods:
public Gameboard(boolean setup) - Constructor that creates a game board as an 8x8 2D array of characters. If the parameter “setup” is false, the board will be created empty. If “setup” is true, the board will be populated with pieces as per the standard game setup in the picture above. The value of each location in the 2D array will be a char with the following characteristics:
“-” for an empty space
“w” for a space occupied by a white checker (note the lowercase “w”)
“r” for a space occupied by a red piece (note the lowercase “r”)
For the sake of this assignment, white pieces will start along the bottom 3 rows and have a piece occupying the lower left corner, and red pieces will occupy the top 3 rows and will have a piece occupying the upper right corner.
boolean move(int x, int y, boolean left) - This method will take a board space as a coordinate pair as a parameter, as well as a boolean “left” that signifies if the piece should move left (true) or right (false) in the event that a piece can move in both directions. The method will then check for the following conditions, in order of priority
Can the piece jump another piece, either forward-left or forward-right? If so, it will do so, in that order of priority. This will involve a) moving “this” piece to the proper square on the other side of the opponent’s piece, and then b) removing the opponent’s piece from the board. Write the helper method “jump” below to use for this.
If “left” is true, can the piece move forward and to the player’s left? Note that “forward” and “left” are relative to the player; in looking at the gameboard above, forward and to the left for the white player means one spot up and one spot left, but for the red player that means moving one spot down and one spot to the right. If the forward-left spot is available, move the piece to that spot.
If “left” is false, can the piece move forward and to the player’s right? Again, note that “forward” and “right” are relative to the player.
If the intended spot is occupied, the move should not occur.
The method will return “true” if a move was successfully executed, or “false” if a move does not occur. Hint: watch out for moves that take a piece off the edge of the board!
boolean jump(int x, int y) - This method takes a board location as a parameter and, if a piece exists in that spot, will determine if the piece can capture an opponent piece by jumping forward-left and will do so if it can. If not, it will determine if the piece can jump an opponent piece by jumping forward-right and will do so if it can. Remember, when a piece gets jumped, it is captured and removed from the board. The method will return “true” if either condition occurs, or “false” if no jump occurs. Upon landing, this method should immediately check again to see if it can execute a further jump, and execute it if it can. This should continue until no more jumps are possible. Hint: use recursion! You can also make other helper methods to simplify your code.
boolean kingMe(int x, int y) - This method should take in a board location as a parameter and “king” the piece in it by turning the lowercase letter for the piece (“w” or “r”) into the uppercase version of the same letter (“W” or “R”). This should return “true” if a piece was successfully kinged, or “false” if the spot is empty. NOTE: You do not need to worry about handling moves for kings in this assignment.
String toString() - Renders the board using the characters “-”, ”r”, ”w”, ”R”, and ”W” as applicable, in the board’s correct shape (8 rows of 8 symbols). In order to make the board easier to read, insert a space between each space’s character.
Final Notes
For this assignment, both the board variable and all methods should have an access level of public.
To test your code, download the student runner file (Links to an external site.)Links to an external site. into the same folder as your Gameboard.java file, run it in DrJava, and check your output against the sample run of the file below. We will use a different runner to grade the program. Remember to change the runner to test different values to make sure your program fits the requirements.
When you are ready, paste your entire Gameboard.java class from start to finish in the box below, click run to test the output, and click submit when you are satisfied with your results.
Sample run of Student_Runner_Gameboard.java (Links to an external site.)Links to an external site.:
Explanation / Answer
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.util.Vector;
public class Checkers extends Applet {
public void init() {
setLayout(null); // I will do the layout myself.
setBackground(new Color(0,150,0)); // Dark green background.
CheckersCanvas board = new CheckersCanvas();
add(board);
board.newGameButton.setBackground(Color.lightGray);
add(board.newGameButton);
board.resignButton.setBackground(Color.lightGray);
add(board.resignButton);
board.message.setForeground(Color.green);
board.message.setFont(new Font("Serif", Font.BOLD, 14));
add(board.message);
board.setBounds(20,20,164,164); // Note: size MUST be 164-by-164 !
board.newGameButton.setBounds(210, 60, 100, 30);
board.resignButton.setBounds(210, 120, 100, 30);
board.message.setBounds(0, 200, 330, 30);
}
} // end class Checkers
class CheckersCanvas extends Canvas implements ActionListener, MouseListener {
Button resignButton; // Current player can resign by clicking this button.
Button newGameButton;
Label message;
CheckersData board;
boolean gameInProgress; // Is a game currently in progress?
int currentPlayer;
int selectedRow, selectedCol;
CheckersMove[] legalMoves; // An array containing the legal moves for the
// current player.
public CheckersCanvas() {
setBackground(Color.black);
addMouseListener(this);
setFont(new Font("Serif", Font.BOLD, 14));
resignButton = new Button("Resign");
resignButton.addActionListener(this);
newGameButton = new Button("New Game");
newGameButton.addActionListener(this);
message = new Label("",Label.CENTER);
board = new CheckersData();
doNewGame();
}
public void actionPerformed(ActionEvent evt) {
Object src = evt.getSource();
if (src == newGameButton)
doNewGame();
else if (src == resignButton)
doResign();
}
void doNewGame() {
if (gameInProgress == true) {
message.setText("Finish the current game first!");
return;
}
board.setUpGame(); // Set up the pieces.
currentPlayer = CheckersData.RED; // RED moves first.
legalMoves = board.getLegalMoves(CheckersData.RED); // Get RED's legal moves.
selectedRow = -1; // RED has not yet selected a piece to move.
message.setText("Red: Make your move.");
gameInProgress = true;
newGameButton.setEnabled(false);
resignButton.setEnabled(true);
repaint();
}
void doResign() {
if (gameInProgress == false) {
message.setText("There is no game in progress!");
return;
}
if (currentPlayer == CheckersData.RED)
gameOver("RED resigns. BLACK wins.");
else
gameOver("BLACK resigns. RED winds.");
}
void gameOver(String str) {
message.setText(str);
newGameButton.setEnabled(true);
resignButton.setEnabled(false);
gameInProgress = false;
}
void doClickSquare(int row, int col) {
for (int i = 0; i < legalMoves.length; i++)
if (legalMoves[i].fromRow == row && legalMoves[i].fromCol == col) {
selectedRow = row;
selectedCol = col;
if (currentPlayer == CheckersData.RED)
message.setText("RED: Make your move.");
else
message.setText("BLACK: Make your move.");
repaint();
return;
}
if (selectedRow < 0) {
message.setText("Click the piece you want to move.");
return;
}
for (int i = 0; i < legalMoves.length; i++)
if (legalMoves[i].fromRow == selectedRow && legalMoves[i].fromCol == selectedCol
&& legalMoves[i].toRow == row && legalMoves[i].toCol == col) {
doMakeMove(legalMoves[i]);
return;
}
/* If we get to this point, there is a piece selected, and the square where
the user just clicked is not one where that piece can be legally moved.
Show an error message. */
message.setText("Click the square you want to move to.");
} // end doClickSquare()
void doMakeMove(CheckersMove move) {
board.makeMove(move);
if (move.isJump()) {
legalMoves = board.getLegalJumpsFrom(currentPlayer,move.toRow,move.toCol);
if (legalMoves != null) {
if (currentPlayer == CheckersData.RED)
message.setText("RED: You must continue jumping.");
else
message.setText("BLACK: You must continue jumping.");
selectedRow = move.toRow; // Since only one piece can be moved, select it.
selectedCol = move.toCol;
repaint();
return;
}
}
if (currentPlayer == CheckersData.RED) {
currentPlayer = CheckersData.BLACK;
legalMoves = board.getLegalMoves(currentPlayer);
if (legalMoves == null)
gameOver("BLACK has no moves. RED wins.");
else if (legalMoves[0].isJump())
message.setText("BLACK: Make your move. You must jump.");
else
message.setText("BLACK: Make your move.");
}
else {
currentPlayer = CheckersData.RED;
legalMoves = board.getLegalMoves(currentPlayer);
if (legalMoves == null)
gameOver("RED has no moves. BLACK wins.");
else if (legalMoves[0].isJump())
message.setText("RED: Make your move. You must jump.");
else
message.setText("RED: Make your move.");
}
selectedRow = -1;
if (legalMoves != null) {
boolean sameStartSquare = true;
for (int i = 1; i < legalMoves.length; i++)
if (legalMoves[i].fromRow != legalMoves[0].fromRow
|| legalMoves[i].fromCol != legalMoves[0].fromCol) {
sameStartSquare = false;
break;
}
if (sameStartSquare) {
selectedRow = legalMoves[0].fromRow;
selectedCol = legalMoves[0].fromCol;
}
}
repaint();
} // end doMakeMove();
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
g.setColor(Color.black);
g.drawRect(0,0,getSize().width-1,getSize().height-1);
g.drawRect(1,1,getSize().width-3,getSize().height-3);
for (int row = 0; row < 8; row++) {
for (int col = 0; col < 8; col++) {
if ( row % 2 == col % 2 )
g.setColor(Color.lightGray);
else
g.setColor(Color.gray);
g.fillRect(2 + col*20, 2 + row*20, 20, 20);
switch (board.pieceAt(row,col)) {
case CheckersData.RED:
g.setColor(Color.red);
g.fillOval(4 + col*20, 4 + row*20, 16, 16);
break;
case CheckersData.BLACK:
g.setColor(Color.black);
g.fillOval(4 + col*20, 4 + row*20, 16, 16);
break;
case CheckersData.RED_KING:
g.setColor(Color.red);
g.fillOval(4 + col*20, 4 + row*20, 16, 16);
g.setColor(Color.white);
g.drawString("K", 7 + col*20, 16 + row*20);
break;
case CheckersData.BLACK_KING:
g.setColor(Color.black);
g.fillOval(4 + col*20, 4 + row*20, 16, 16);
g.setColor(Color.white);
g.drawString("K", 7 + col*20, 16 + row*20);
break;
}
}
}
if (gameInProgress) {
g.setColor(Color.cyan);
for (int i = 0; i < legalMoves.length; i++) {
g.drawRect(2 + legalMoves[i].fromCol*20, 2 + legalMoves[i].fromRow*20, 19, 19);
}
if (selectedRow >= 0) {
g.setColor(Color.white);
g.drawRect(2 + selectedCol*20, 2 + selectedRow*20, 19, 19);
g.drawRect(3 + selectedCol*20, 3 + selectedRow*20, 17, 17);
g.setColor(Color.green);
for (int i = 0; i < legalMoves.length; i++) {
if (legalMoves[i].fromCol == selectedCol && legalMoves[i].fromRow == selectedRow)
g.drawRect(2 + legalMoves[i].toCol*20, 2 + legalMoves[i].toRow*20, 19, 19);
}
}
}
}
public Dimension getPreferredSize() {
return new Dimension(164, 164);
}
public Dimension getMinimumSize() {
return new Dimension(164, 164);
}
public void mousePressed(MouseEvent evt) {
if (gameInProgress == false)
message.setText("Click "New Game" to start a new game.");
else {
int col = (evt.getX() - 2) / 20;
int row = (evt.getY() - 2) / 20;
if (col >= 0 && col < 8 && row >= 0 && row < 8)
doClickSquare(row,col);
}
}
public void mouseReleased(MouseEvent evt) { }
public void mouseClicked(MouseEvent evt) { }
public void mouseEntered(MouseEvent evt) { }
public void mouseExited(MouseEvent evt) { }
}
class CheckersMove {
int fromRow, fromCol; // Position of piece to be moved.
int toRow, toCol; // Square it is to move to.
CheckersMove(int r1, int c1, int r2, int c2) {
fromRow = r1;
fromCol = c1;
toRow = r2;
toCol = c2;
}
boolean isJump() {
return (fromRow - toRow == 2 || fromRow - toRow == -2);
}
}
class CheckersData {
public static final int
EMPTY = 0,
RED = 1,
RED_KING = 2,
BLACK = 3,
BLACK_KING = 4;
private int[][] board;
public CheckersData() {
board = new int[8][8];
setUpGame();
}
public void setUpGame() {
for (int row = 0; row < 8; row++) {
for (int col = 0; col < 8; col++) {
if ( row % 2 == col % 2 ) {
if (row < 3)
board[row][col] = BLACK;
else if (row > 4)
board[row][col] = RED;
else
board[row][col] = EMPTY;
}
else {
board[row][col] = EMPTY;
}
}
}
}
public int pieceAt(int row, int col) {
return board[row][col];
}
public void setPieceAt(int row, int col, int piece) {
board[row][col] = piece;
}
public void makeMove(CheckersMove move) {
makeMove(move.fromRow, move.fromCol, move.toRow, move.toCol);
}
public void makeMove(int fromRow, int fromCol, int toRow, int toCol) {
board[toRow][toCol] = board[fromRow][fromCol];
board[fromRow][fromCol] = EMPTY;
if (fromRow - toRow == 2 || fromRow - toRow == -2) {
int jumpRow = (fromRow + toRow) / 2;
int jumpCol = (fromCol + toCol) / 2;
board[jumpRow][jumpCol] = EMPTY;
}
if (toRow == 0 && board[toRow][toCol] == RED)
board[toRow][toCol] = RED_KING;
if (toRow == 7 && board[toRow][toCol] == BLACK)
board[toRow][toCol] = BLACK_KING;
}
public CheckersMove[] getLegalMoves(int player) {
if (player != RED && player != BLACK)
return null;
int playerKing;
if (player == RED)
playerKing = RED_KING;
else
playerKing = BLACK_KING;
Vector moves = new Vector(); // Moves will be stored in this vector.
for (int row = 0; row < 8; row++) {
for (int col = 0; col < 8; col++) {
if (board[row][col] == player || board[row][col] == playerKing) {
if (canJump(player, row, col, row+1, col+1, row+2, col+2))
moves.addElement(new CheckersMove(row, col, row+2, col+2));
if (canJump(player, row, col, row-1, col+1, row-2, col+2))
moves.addElement(new CheckersMove(row, col, row-2, col+2));
if (canJump(player, row, col, row+1, col-1, row+2, col-2))
moves.addElement(new CheckersMove(row, col, row+2, col-2));
if (canJump(player, row, col, row-1, col-1, row-2, col-2))
moves.addElement(new CheckersMove(row, col, row-2, col-2));
}
}
}
if (moves.size() == 0) {
for (int row = 0; row < 8; row++) {
for (int col = 0; col < 8; col++) {
if (board[row][col] == player || board[row][col] == playerKing) {
if (canMove(player,row,col,row+1,col+1))
moves.addElement(new CheckersMove(row,col,row+1,col+1));
if (canMove(player,row,col,row-1,col+1))
moves.addElement(new CheckersMove(row,col,row-1,col+1));
if (canMove(player,row,col,row+1,col-1))
moves.addElement(new CheckersMove(row,col,row+1,col-1));
if (canMove(player,row,col,row-1,col-1))
moves.addElement(new CheckersMove(row,col,row-1,col-1));
}
}
}
}
if (moves.size() == 0)
return null;
else {
CheckersMove[] moveArray = new CheckersMove[moves.size()];
for (int i = 0; i < moves.size(); i++)
moveArray[i] = (CheckersMove)moves.elementAt(i);
return moveArray;
}
}
public CheckersMove[] getLegalJumpsFrom(int player, int row, int col) {
if (player != RED && player != BLACK)
return null;
int playerKing;
if (player == RED)
playerKing = RED_KING;
else
playerKing = BLACK_KING;
Vector moves = new Vector(); // The legal jumps will be stored in this vector.
if (board[row][col] == player || board[row][col] == playerKing) {
if (canJump(player, row, col, row+1, col+1, row+2, col+2))
moves.addElement(new CheckersMove(row, col, row+2, col+2));
if (canJump(player, row, col, row-1, col+1, row-2, col+2))
moves.addElement(new CheckersMove(row, col, row-2, col+2));
if (canJump(player, row, col, row+1, col-1, row+2, col-2))
moves.addElement(new CheckersMove(row, col, row+2, col-2));
if (canJump(player, row, col, row-1, col-1, row-2, col-2))
moves.addElement(new CheckersMove(row, col, row-2, col-2));
}
if (moves.size() == 0)
return null;
else {
CheckersMove[] moveArray = new CheckersMove[moves.size()];
for (int i = 0; i < moves.size(); i++)
moveArray[i] = (CheckersMove)moves.elementAt(i);
return moveArray;
}
}
private boolean canJump(int player, int r1, int c1, int r2, int c2, int r3, int c3) {
if (r3 < 0 || r3 >= 8 || c3 < 0 || c3 >= 8)
return false;
if (board[r3][c3] != EMPTY)
return false;
if (player == RED) {
if (board[r1][c1] == RED && r3 > r1)
return false;
if (board[r2][c2] != BLACK && board[r2][c2] != BLACK_KING)
return false;
return true;
}
else {
if (board[r1][c1] == BLACK && r3 < r1)
return false;
if (board[r2][c2] != RED && board[r2][c2] != RED_KING)
return false;
return true;
}
}
private boolean canMove(int player, int r1, int c1, int r2, int c2) {
if (r2 < 0 || r2 >= 8 || c2 < 0 || c2 >= 8)
return false;
if (board[r2][c2] != EMPTY)
return false;
if (player == RED) {
if (board[r1][c1] == RED && r2 > r1)
return false;
return true;
}
else {
if (board[r1][c1] == BLACK && r2 < r1)
return false;
return true;
}
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.