C++: Simulating Chess

C++: Simulating Chess
Second Year Computing Laboratory
Department of Computing
Imperial College London
Exercise Objectives:
• To demonstrate your understanding of C++ and its libraries.
• To implement a non-trivial program from only an abstract specification.
• To refresh you object oriented programming/design skills.
Summary
This exercise asks you to write a program to simulate and manage chess games. Your program will be
expected to validate each move and keep track of the state of the game, detecting when the game is over
and producing appropriate output to the user.
You should implement your program and its components in an object oriented manner using C++ classes
and inheritance.
Chess (A Reminder)1
A chess board is initially set up as per the following diagram:
Each row (numbered 1 - 8) is called a rank, and each column (labelled A to H) is called a file. White moves
first, and thereafter players take it in turns to make moves. A Piece can be moved to either an unoccupied
1 The
information in this section is taken from the Wikipedia page on Chess: http://en.wikipedia.org/wiki/Chess
1
square or one occupied by an opponent’s piece, in which case the opponent’s piece is captured and removed
from play. Each piece moves according to the following rules:
The king can move one square in any direction, but may not move through other
pieces.
The rook (or castle) can move any number of squares along any rank or file, but may
not move through other pieces.
The bishop can move any number of squares diagonally, but may not move through
other pieces.
The queen combines the power of the rook and bishop and can move any number of
squares along a rank, file, or diagonal, but it may not move through other pieces.
The knight moves to any of the closest squares that are not on the same rank, file,
or diagonal, thus the move forms an ”L”-shape: two squares vertically and one square
horizontally, or two squares horizontally and one square vertically. The knight is the
only piece that can move through other pieces.
The pawn may move forward to the unoccupied square immediately in front of it
on the same file; or on its first move it may advance two squares along the same file
provided both squares are unoccupied. A pawn may also move to a square occupied
by an opponent’s piece which is diagonally in front of it on an adjacent file, capturing
that piece.
When a player’s king could be captured by one or more of the opponent’s pieces, it is said to be in check.
A player’s only response to being in check is to make a legal move that results in a position where the king
can no longer be captured (i.e. it is not in check). This can involve capturing the checking piece; interposing
a piece between the checking piece and the king (which is possible only if the threatening piece is not a
knight and there is a square between it and the king); or moving the king to a square where it is not in
check. It is not legal for a player to make a move that would put or leave his own king in check.
The object of the game is to checkmate your opponent. This occurs when your opponent’s king is in
check, and there is no legal way to remove it from being in check. When checkmate occurs, the game is over
and the player whose king is checkmated loses.
The game may also end in a stalemate (draw). This occurs if a player is unable to make a legal move on
their turn when their king is not in check.
N.B. There are some additional rules of chess (castling, en passant and pawn promotion), but you are not
required to implement these for this exercise.
Submit by: midnight on Monday 27th January 2014
What To Do:
You are to implement a chess simulation/management program in C++. Your program should accept moves
in the format (source square, destination square), where a square is referred to using a letter in the
2
range A-H and a number in the range 1-8. It should validate each move and keep track of the state of the
game, detecting when the game is over and producing appropriate output to the user.
Getting the files required for the exercise
You have each been provided with a Git repository on the department’s GitLab server that contains the
files needed for this exercise. To obtain this skeleton repository you will need to clone it into your local
workspace. You can do this with the following command:
prompt > git clone https :// gitlab . doc . ic . ac . uk / lab1314_spring / chess_ < login >. git
replacing <login> with your normal college login.
You should work on the files in your local workspace, making regular commits back to this Git repository.
Your final submission will be taken from the GitLab git repository, so make sure that you push your work to
it correctly.
The provided files for this exercise are:
makefile
ChessMain.cpp
ChessBoard.hpp
ChessBoard.cpp
a
a
a
a
skeleton makefile that you will need to edit
main program describing a short chess game
skeleton C++ header file that you will need to edit and extend
skeleton C++ file that you will need to edit and extend
You will need to write appropriate class definitions in C++ which correctly interface with the main
program given in the provided file ChessMain.cpp. You will also need to edit the makefile so that running
make in the root of your repository (with no arguments!) builds your whole chess program (including the
ChessMain.cpp frontend).
Note that your program should be able to simulate an arbitrary game of chess that is communicated
through this interface. In particular, the main program ChessMain.cpp contains code that tries to give
various kinds of erroneous input and your program should handle such inputs in a graceful way (it should
output useful error messages and continue to function, it should not just crash!).
Suggested Approach
We suggest that you approach the exercise as follows:
1. Create a class for each different kind of chess piece - each class should be responsible for determining
which moves are valid for itself.
2. Create an abstract superclass for chess pieces, which provides the interface through which the ChessBoard
class interacts with its pieces.
3. If you wish, you may use the C++ STL (Standard Template Library), and any other libraries that you
think will be useful (e.g. you could use the map class to store the chess pieces on the board, indexed
by their positions).
You might like to ask yourself the following questions:
• What information does the ChessBoard class require from each of its pieces to be able to validate the
moves that are submitted to it?
• What information does a chess piece need to know in order to determine which moves it can make?
• What conditions must be checked after each piece has been moved?
3
Testing
It should be possible to incrementally test your chess program, and you should do so thoroughly. We have
provided you with an example chess game to help you test your code, but our automated tests will be
running several arbitrary games of chess (with both valid and invalid moves) to assess the correctness of
your submission.
The specific game which is simulated in the main function found in chessMain.cpp is a short game played
between Alexander Alekhine, and his opponent Vasic in 1931. In algebraic chess notation 2 , the game played
out as follows:
1. e4 e6
2. d4 d5
3. Nc3 Bb4
4. Bd3 Bxc3+
5. bxc3 h6
6. Ba3 Nd7
7. Qe2 dxe4
8. Bxe4 Ngf6
9. Bd3 b6
10. Qxe6+ fxe6
11. Bg6#
The main program also tests that your solution can detect and handle erroneous input (e.g. trying to
move a non-existent piece, trying to move a piece of the wrong colour, making illegal moves, etc.). We provide
a copy of the expected outcome of running this main program with your chess program in the appendix.
Unassessed Extensions
Once you have successfully implemented your chess program, you may like to try and extend it with some
extra features. The obvious initial extensions would be to implement the rules for castling, en passant
and pawn promotion. However you might also like to add a user interface to your program, maybe with a
graphical representation of the current state of the game board, or you could consider implementing a game
clock or an A.I. player.
Submission
As you work, you should add, commit and push your changes to your Git repository. Your GitLab repository
should contain the source code and header files for your program.
The auto-tester will be cloning your repository for testing. To be sure that we test the correct version of
your code you will need to submit a text file to CATe containing the revision id that you consider to be your
final solution. You are advised to choose a revision that does not include any extensions or extra features.
You should check the state of your GitLab repository using the GitLab webpages at https://gitlab.
doc.ic.ac.uk. If you click through to your chess_<login> repository, and view the Commits tab, you will
see a list of the different versions of your work that you have pushed. Next to each commit you will see an
2 see
http://en.wikipedia.org/wiki/Algebraic_notation_(chess) for details
4
alpha-numeric link to a more detailed view of that commit. At the top of this detailed view there will be a
full 40 character revision ID for that commit (e.g. 0d48b439ee7b71be6037f9351284946be322c608).
You should copy the full revision ID for the commit that you want to submit as your “final” version into
a text file and save this as cate_token.txt. You can of course change this later by resubmitting to CATe as
usual.
You should submit your chosen revision ID (cate_token.txt) to CATe by midnight on Monday 27th
January 2014.
Important: Make sure your cate_token.txt file contains only the 40 character revision ID. Any other
content in the file is likely to confuse the autotesting system.
Assessment
In total there are 100 marks available in this exercise. These are allocated as follows:
Validating/Making moves for each chess piece
Testing for check
Testing for checkmate/stalemate
Validating moves submitted to the ChessBoard
Overall program structure/design
30
20
10
20
20
marks (5 per piece type)
marks
marks
marks
marks
Any program that does not compile will be subject to a 10 mark penalty.
Feedback on the exercise will be returned by Monday 4th November 2014.
5
Appendix A - Sample Program Output
When run against the main program ChessMain.cpp, your program should produce the following output:
===========================
Testing the Chess Engine
===========================
A new chess game is started!
It is not Black’s turn to move!
There is no piece at position D4!
White’s Pawn moves from D2 to D4
Black’s Bishop cannot move to B4!
===========================
Alekhine vs. Vasic (1931)
===========================
A new chess game is started!
White’s Pawn moves from E2 to E4
Black’s Pawn moves from E7 to E6
White’s Pawn moves from D2 to D4
Black’s Pawn moves from D7 to D5
White’s Knight moves from B1 to C3
Black’s Bishop moves from F8 to B4
White’s Bishop moves from F1 to D3
Black’s Bishop moves from B4 to C3 taking White’s Knight
White is in check
White’s Pawn moves from B2 to C3 taking Black’s Bishop
Black’s Pawn moves from H7 to H6
White’s Bishop moves from C1 to A3
Black’s Knight moves from B8 to D7
White’s Queen moves from D1 to E2
Black’s Pawn moves from D5 to E4 taking White’s Pawn
White’s Bishop moves from D3 to E4 taking Black’s Pawn
Black’s Knight moves from G8 to F6
White’s Bishop moves from E4 to D3
Black’s Pawn moves from B7 to B6
White’s Queen moves from E2 to E6 taking Black’s Pawn
Black is in check
Black’s Pawn moves from F7 to E6 taking White’s Queen
White’s Bishop moves from D3 to G6
Black is in checkmate
6