Note that all the classes that you will implement below must be inside a package called a1. For the ease of understanding the program, we describe the tasks related to the program implementation before listing the tasks related to the unit tests. However, you will use test driven development, where you will write your test cases to specify the program.
We are just creating a toy chess program that lets you set up pieces on a chessboard, move them, and find possible moves for a given piece in a certain position. We are not implementing Deep Blue. Because we are simplifying so many rules, we'll call this game, Modified chESS or MESS!
Chess is played on an 8 X 8 board where the initial placement of pieces is as shown in the following figure, taken from Wikipedia. Note the indexing scheme. The white king is on e1, and the black king is on e8. Familiarize yourself with the names of the pieces.
Each chess piece can move in a specific way. Details of the original rules are provided here. However, we will follow a simplified version in this assignment. Most importantly, we will ignore an important rule in chess: Moving any piece in a way that puts your own king in check is illegal. Since we don't know what check means, for us a move is legal if the piece we are moving has an empty square to move to or can capture (replace) an opponent's piece (including their king, although that's also illegal in real chess). The simplified rules are as follows:
You will implement eight classes ChessBoard, ChessPiece, Rook, Knight, Bishop, Queen, King, and Pawn, and two exception classes called IllegalPositionException and IllegalMoveException that are described below.
This class only stores the state of the board and its pieces for this assignment. In a real program, it would need to store more information (e.g., whoseTurn, etc). The board is represented by a 2-dimensional array of size 8X8.
Since the positions on a chess board are represented using a letter followed by a number, our array needs to represent the directions accordingly. We will make the following association: a=0, b=1, c=2, d=3, e=4, f=5, g=6, and h=7. In the initial position, the white king at e1 is at index [0][4]. The black queen at d8 is at index [7][3].
Implement the following attribute:
Implement the following constructor:
Implement the following methods:
This method initializes the board to the standard chess opening state with indexing as shown in the figure. This method should use the constructors of the appropriate pieces, and call placePiece below to place the newly constructed pieces in the right position.
This method returns the chess piece at a given position. The position is represented as a two-character string (e.g., e8) as described above. The first letter is in lowercase (a..h) and the second letter is a digit (1..8). If the position is illegal because the string contains illegal characters or represents a position outside the board, the exception is thrown.
This method tries to place the given piece at a given position, and returns true if successful, and false if there is already a piece of the same player in the given position or the position was illegal for any of the two reasons mentioned in the description of getPiece. If an opponent's piece exists, that piece is captured. If successful, this method should call an appropriate method in the ChessPiece class (i.e., setPosition) to set the piece's position.
This method checks if moving the piece from the fromPosition to toPosition is a legal move. Legality is defined based on the rules described above in Section 2.1. If the move is legal, it executes the move, changing the value of the board as needed. Otherwise, the stated exception is thrown.
You must include the following toString method to help debug your program. We assume that ChessPiece has an appropriately implemented toString method, whose implementation is described below. The code for the method is here.
A barebones main method is provided for the ChessBoard class in case you want to try out the entire application at the end. Note that this method is not to be tested using JUnit.
public static void main(String[] args) { ChessBoard board = new ChessBoard(); board.initialize(); System.out.println(board); board.move("c2", "c4"); System.out.println(board); }
The abstract class ChessPiece is the parent class for all the actual chess pieces classes. This class keeps a reference to the board the piece is on (if any), stores the position where the piece is located, and the color.
Include the following enum type as shown below:
public enum Color {WHITE, BLACK}
Implement the following attribute:
Implement the following constructor:
This constructor sets the board and color attributes.
Implement the following methods:
This method returns the color of the piece. There is no need for a setColor method because a piece cannot change color.
This method returns the position of the piece in the format single letter (a..h) followed by a single digit (1..8).
This method sets the position of the piece to the appropriate row and column based on the argument, which in the format single letter (a..h) followed by a single digit (1..8). If the position is illegal for any of the two reasons mentioned earlier, throw the stated exception.
This method will be implemented in the concrete subclasses corresponding to each chess piece. This method returns a String composed of a single character that corresponds to which piece it is. In the unicode character encoding scheme there are characters that represent each chess piece. Use one of the following characters:
character piece ---------- ----------- "\u2654" white king "\u2655" white queen "\u2656" white rook "\u2657" white bishop "\u2658" white knight "\u2659" white pawn "\u265A" black king "\u265B" black queen "\u265C" black rook "\u265D" black bishop "\u265E" black knight "\u265F" black pawn
It is important that your toString method return the right character string, as we will use it to display the board position when testing your code.
This method will be implemented in the concrete subclasses corresponding to each chess piece. This method returns all the legal moves that piece can make based on the rules described above in the assignment. Each string in the ArrayList should be the position of a possible destination for the piece (in the same format described above). If there are multiple legal moves, the order of moves in the ArrayList does not matter. If there are no legal moves, return an empty ArrayList, i.e., the size should be zero.
Implement each class to extend ChessPiece and override the methods toString and legalMoves. Note that the legalMoves methods of King, Knight, and Queen return an empty ArrayList<String>.
Implement each exception to extend Exception.
Implement JUnit test classes, called ChessBoardTest, RookTest, KnightTest, BishopTest, QueenTest, KingTest, and PawnTest containing JUnit test cases for each of the classes listed above. Also implement a JUnit test suite class called ChessSuite that defines a main method and a test suite that includes all the above test classes.
Create a Jar file called a1.jar containing the 18 Java files. Doublecheck that you have included source files (i.e., .java files), not compiled class files (i.e., .class files). The folder hierarchy should not include src; it should start from a1. That is, the jar file should contain a1/*.java.
Submit the a1.jar file using Assignment Submission in Canvas.
Up to 5 points may be deducted for not following the packaging structure or names used for the classes and the methods of each class.