Steven
Hansen
5776-22222
Table of Contents
Data
Structures................................................................................................................... 3
Data structure used to store the board configuration........................................................................................... 3
Data structure used to store sets of moves.................................................................................................................. 3
Data structure used to store move history.................................................................................................................. 3
Class Responsibilities.......................................................................................................... 4
Piece super-class containing behavior common to all
piece types................................................................ 4
Piece.h.............................................................................................................................................................................................. 4
Separate subclasses for each different piece type
(pawn, rook, etc.)............................................................ 6
King.h............................................................................................................................................................................................... 6
Queen.h............................................................................................................................................................................................ 7
Rook.h.............................................................................................................................................................................................. 8
Knight.h.......................................................................................................................................................................................... 9
Bishop.h....................................................................................................................................................................................... 10
Pawn.h.......................................................................................................................................................................................... 11
Track current piece positions on the board.............................................................................................................. 13
Board.h......................................................................................................................................................................................... 13
BoardPosition.h...................................................................................................................................................................... 14
Store and manage the move history................................................................................................................................ 16
MoveHistory.h.......................................................................................................................................................................... 16
Move.h........................................................................................................................................................................................... 17
Initialize a new game by creating and initializing
the board, move history, pieces, etc................. 19
Game.h.......................................................................................................................................................................................... 19
Execute moves as directed by the user......................................................................................................................... 20
Game.h.......................................................................................................................................................................................... 20
Undo moves as directed by the user............................................................................................................................... 21
Game.h.......................................................................................................................................................................................... 21
Detect check, checkmate, and stalemate....................................................................................................................... 21
Game.h.......................................................................................................................................................................................... 21
Save and load games................................................................................................................................................................... 22
Game.h.......................................................................................................................................................................................... 22
GameFiles.h................................................................................................................................................................................ 23
Detailed description of the Move Piece use case..................................................................................................... 25
Detailed description of the Undo Move use case..................................................................................................... 29
Detailed description of the Save Game use case....................................................................................................... 30
Detailed description of the Load Game use case...................................................................................................... 31
Detailed description of the New Game use case....................................................................................................... 32
Detailed description of the following data structures, including justification for each choice
Inside of my Board class I will have a 2d array which will actually be a vector of vectors of type Square. Since this will have to track the squares and it will mostly just need quick access to indexable locations. Inserting and removing quickly on one end will also be sufficient since we will not be dynamically creating a larger board, but only loading the board during the game start..
I will use the STL set to store a set of BoardPositions. A set since we only want unique board positions when calling functions like GetLegalMoves.
The MoveHistory will definitely be a stack. The program will have to continuously add moves to the history and remove moves from the history when the undo button is pressed. The MoveHistory does not need to be indexable or searchable. Only simple push and pop operations will be needed and then the iterator will be used when saving the game.
/*
*
Piece.h
*
chess
*
*
Created by Steven Hansen on 3/22/09.
*
Copyright 2009 Spatical Company. All rights reserved.
*
*/
#ifndef PIECE_H
#define PIECE_H
#include <set>
#include "BoardPosition.h"
/*
* The two basic player/piece colors
* Will
be used to track turns and moves
*/
enum PieceColor {
BLACK,
WHITE
};
/*
* Enumeration of the types of Board
Pieces
* Will
be used to create the objects of the right type
* and
also to maintain easy accessibility to the types
* of
pieces on the board
*/
enum PieceType {
KING,
QUEEN,
ROOK,
BISHOP,
KNIGHT,
PAWN
};
/*
* base class (or interface) that defines
virtual methods
* for
all of the operations on a chess piece
*
* This will allow the program to easily
deal with the differences
* between
the pieces, and also make it easy to add new kinds of pieces.
*
* The piece will also contain all of the
valid moves for that type of piece
* but
the piece will not calculate Check or CheckMate
*
* The actual location of the pieces will
be maintained by the
* the
board and not inside the actual piece, therefore to get the candidate
* moves
a BoardPosition will need to be passed into the Piece
*
* Each of the 6 types of piece have
different rules for moving around the
* board,
and can take pieces from the other team under certain conditions.
*
*/
class Piece {
private:
// The color (representing the player that owns this piece
PieceColor color;
// The possible move locations for this piece
int moves[][2]; // { { row direction, col direction }, { ..., ...}, ...}
// The number of of different move direction this piece
can go
int directions;
// The type of piece
PieceType type;
public:
/*
* no-arg constructor
* Initialize
object variables
*/
Piece();
/*
* Destructor, delete the Piece
*/
~Piece();
/*
* Iterate over moves array and return
all valid moves (disregarding
* any
check or check-mate rules)
*
* The move is a Candidate move if the
piece belongs to the current player.
* and
the move follows the pattern that applies to that piece.
*
* Also, the default piece cannot move
over other pieces. This method,
should
* only
return possible BoardPositions up until it finds a piece, then if the
*
piece is of the same color it should not be included, if it is a piece
of
* another
color it then should be included and look for no more spaces in that
* direction.
*
* Parameters:
* board - the current board to reflect
the state of the board
* position - the current BoardPosition
of the piece
*
* Returns:
* A set of valid BoardPositions
representing possible moves
*
*/
set<BoardPosition>
GetCandidateMoves(Board & board, BoardPosition position);
public:
/*
* Simple Getters and Setters (removed to
save paper)
* Just
the public methods to return the private variables of the Move object
*/
};
#endif
/*
*
King.h
*
chess
*
*
Created by Steven Hansen on 3/23/09.
*
Copyright 2009 Spatical Company. All rights reserved.
*
*/
#ifndef KING_H
#define KING_H
#include "Piece.h"
/*
* Defined moves for this Piece type
*/
#define
NUM_MOVE_DIRECTIONS 8
#define
THE_DIRECTIONS { {1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {1, -1}, {-1, -1}, {-1, 1} }
/*
* The King can only move a single square
in any direction.
*
* The
King cannot move into a 'check' position (a square
* in
which he could be taken by an opposing piece) or be left
* in
one. (but this will be calculated elsewhere)
*
*/
class King : public Piece {
private:
// Just inherits super variables
public:
/*
* Special Piece constructor for the
specific King type
* of
piece. It sets up all of the
variables for the
* the
piece and makes it ready to place on the board
*
* Parameters:
* color
- the Color (representing the owning player) of which to
* create
the piece
*
*/
King(PieceColor c) :
color(c), moves(int[NUM_MOVES][2]), type(KING){
moves =
THE_MOVES;
return;
}
/*
* Override the GetCandidateMoves
function since a King
* can
only move 1 space in any direction
*
* Parameters:
* board
- the current board to reflect the state of the board
* position
- the current BoardPosition of the piece
*
* Returns:
* A
set of valid BoardPositions representing possible moves
*/
set<BoardPosition>
GetCandidateMoves(Board * board, BoardPosition position);
public:
// Getters and Setters inherited from Parent super class
// Also, the other important methods are also simply
inherited
};
#endif
/*
*
Queen.h
*
chess
*
*
Created by Steven Hansen on 3/23/09.
*
Copyright 2009 Spatical Company. All rights reserved.
*
*/
#ifndef QUEEN_H
#define QUEEN_H
#include "Piece.h"
/*
* Defined moves for this Piece type
*/
#define
NUM_MOVE_DIRECTIONS 8
#define
THE_DIRECTIONS { {1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {1, -1}, {-1, -1}, {-1, 1} }
/*
* The Queen's movement is a combination
of the Rook's and the Bishop's movement.
* This
means that the Queen can move both horizontally, vertically and diagonally
* in
any direction.
*
*/
class Queen : public Piece {
private:
// Just inherits super variables
public:
/*
* Special Piece constructor for the
specific Queen type
* of
piece. It sets up all of the
variables for the
* the
piece and makes it ready to place on the board
*
* Parameters:
* color
- the Color (representing the owning player) of which to
* create
the piece
*
*/
Queen(PieceColor c) :
color(c), moves(int[NUM_MOVES][2]), type(QUEEN){
moves =
THE_MOVES;
return;
}
// Just uses the inherited method to get candidate moves
public:
// Getters and Setters inherited from Parent super class
// Also, the other important methods are also simply
inherited
};
#endif
/*
*
Rook.h
*
chess
*
*
Created by Steven Hansen on 3/23/09.
*
Copyright 2009 Spatical Company. All rights reserved.
*
*/
#ifndef CASTLE_H
#define CASTLE_H
#include "Piece.h"
/*
* Defined moves for this Piece type
*/
#define
NUM_MOVE_DIRECTIONS 4
#define
THE_DIRECTIONS { {1, 0}, {-1, 0}, {0, 1}, {0, -1} }
/*
* Rooks may move horizontally or
vertically as many squares as possible. The range
* of
their movement is only terminated by the edge of the board or another piece.
* Rooks
may take the first opposing piece that blocks their movement in any vertical
* or
horizontal direction.
*
*/
class Rook : public Piece {
private:
// Just inherits super variables
public:
/*
* Special Piece constructor for the
specific Rook type
* of
piece. It sets up all of the
variables for the
* the
piece and makes it ready to place on the board
*
* Parameters:
* color
- the Color (representing the owning player) of which to
* create
the piece
*
*/
Rook(PieceColor c) :
color(c), moves(int[NUM_MOVES][2]), type(ROOK){
moves =
THE_MOVES;
return;
}
// Just uses the inherited method to get candidate moves
public:
// Getters and Setters inherited from Parent super class
// Also, the other important methods are also simply
inherited
};
#endif
/*
*
Knight.h
*
chess
*
*
Created by Steven Hansen on 3/23/09.
*
Copyright 2009 Spatical Company. All rights reserved.
*
*/
#ifndef PIECE_H
#define PIECE_H
#include "Piece.h"
/*
* Defined moves for this Piece type
*/
#define NUM_MOVES
8
#define THE_MOVES
{ { 1, 2}, { 1, -2}, {-1, 2}, {-1, -2}, \
{ 2, 1}, {-2, 1}, { 2, -1}, {-2, -1} }
/*
* Knights always move in the shape of
the letter "L". This
* means
that they move two squares forward and one to the
* left
or right in any direction. The Knight is the only
* piece
that can jump over other pieces.
*
*/
class Knight : public Piece {
private:
// Just inherits super variables
public:
/*
* Special Piece constructor for the
specific Rook type
* of
piece. It sets up all of the
variables for the
* the
piece and makes it ready to place on the board
*
* Parameters:
* color
- the Color (representing the owning player) of which to
* create
the piece
*
*/
Knight(PieceColor c) :
color(c), moves(int[NUM_MOVES][2]), type(KNIGHT){
moves =
THE_MOVES;
}
/*
* Override the GetCandidateMoves
function since a Knight
* can
actuall move over other pieces
*
* Parameters:
* board
- the current board to reflect the state of the board
* position
- the current BoardPosition of the piece
*
* Returns:
* A
set of valid BoardPositions representing possible moves
*/
set<BoardPosition>
GetCandidateMoves(Board * board, BoardPosition position);
public:
// Getters and Setters inherited from Parent super class
// Also, the other important methods are also simply
inherited
};
#endif
/*
*
Bishop.h
*
chess
*
*
Created by Steven Hansen on 3/23/09.
*
Copyright 2009 Spatical Company. All rights reserved.
*
*/
#ifndef PIECE_H
#define PIECE_H
#include "Piece.h"
/*
* Defined moves for this Piece type
*/
#define
NUM_MOVE_DIRECTIONS 4
#define
THE_DIRECTIONS { {1, 1}, {1, -1}, {-1, -1}, {-1, 1} }
/*
* The Bishop's movement is similar to
the Rook's except that the Bishop can move
* diagonally
in any direction.
*
*/
class Bishop : public Piece {
private:
// Just inherits super variables
public:
/*
* Special Piece constructor for the
specific Bishop type
* of
piece. It sets up all of the
variables for the
* the
piece and makes it ready to place on the board
*
* Parameters:
* color
- the Color (representing the owning player) of which to
* create
the piece
*
*/
Bishop(PieceColor c) :
color(c), moves(int[NUM_MOVES][2]), type(BISHOP){
moves =
THE_MOVES;
}
// Just uses the inherited method to get candidate moves
public:
// Getters and Setters inherited from Parent super class
// Also, the other important methods are also simply
inherited
};
#endif
/*
*
Pawn.h
*
chess
*
*
Created by Steven Hansen on 3/23/09.
*
Copyright 2009 Spatical Company. All rights reserved.
*
*/
#ifndef PIECE_H
#define PIECE_H
#include "Piece.h"
/*
* Defined moves for this Piece type
*/
#define NUM_MOVES
4
#define THE_MOVES
{ { 1, 0}, { 2, 0}, { 1, 1}, { 1, -1} }
/*
* On their first move, pawns may move
either one or two squares
* directly
ahead of them (unless blocked by another piece). After
* their
first move, they may only move one square directly ahead
* of
them per turn. They may only take pieces of the other color
* when
the opposing piece is in a square diagonally in front of them.
*
*/
class Pawn : public Piece {
private:
// Inherits super variables
bool hasMoved;
public:
/*
* Special Piece constructor for the
specific Pawn type
* of
piece. It sets up all of the
variables for the
* the
piece and makes it ready to place on the board
*
* Parameters:
* color
- the Color (representing the owning player) of which to
* create
the piece
*
*/
Pawn(PieceColor c) :
color(c), moves(int[NUM_MOVES][2]), type(PAWN), hasMoved(false){
moves =
THE_MOVES;
}
/*
* Override the GetCandidateMoves
function since a Pawn
* has
a special move that it can only make when it is capturing
* an
opponent piece, also it can move to squares only on the 1st move
*
*
* Parameters:
* board
- the current board to reflect the state of the board
* position
- the current BoardPosition of the piece
*
* Returns:
* A
set of valid BoardPositions representing possible moves
*/
set<BoardPosition>
GetCandidateMoves(Board * board, BoardPosition position);
public:
// Getters and Setters inherited from Parent super class
// Also, the other important methods are also simply
inherited
};
#endif
/*
*
Board.h
*
chess
*
*
Created by Steven Hansen on 3/23/09.
*
Copyright 2009 Spatical Company. All rights reserved.
*
*/
#ifndef BOARD_H
#define BOARD_H
#include <vector>
#include "BoardPosition.h"
#include "Piece.h"
/*
* The Square class or struct will simply
contain a pointer
* to
a piece. If their is no piece on
the square then it will
* be
a NULL pointer.
*/
struct Square {
Piece * Piece;
};
/*
* The Board class will maintian the
current state of the board
* it
will include functions to get and set pieces on the board
* It
will also be called to iterate over the board squares or
* return
true if their is a piece on a particular square
*
*/
class Board {
private:
// The actual array of squares representing the squares
on the board
vector< vector<Square>
> BoardSquares;
public:
/*
* no-arg constructor
* Initialize
object variables
*/
Board();
/*
* Destructor, delete the BoardSquares in
order to delete
* and
clean-up the entire current board
*/
~Board();
/*
* Get the piece on the given BoardPosition
*
* Parameters:
* position - The BoardPosition
object representing the square
* to
find a piece
*
* Returns:
* piece
pointer - a pointer to the piece that is on the given position
*
NULL - whent there is not a piece on the given square
*/
Piece * GetPiece(BoardPosition
position);
/*
* Set a piece on the board on the given BoardPosition,
we will
* assume
the Game has already verified and only given the possibility
* to
place a piece on a valid Square
*
* Parameters:
* piece -
the Piece to set on the board (the piece itself
* contains
the information like type and color.
* position - The BoardPosition
object representing where to place the piece
*
*/
void SetPiece(Piece
& piece, BoardPosition position);
};
#endif
/*
*
BoardPosition.h
*
chess
*
*
Created by Steven Hansen on 3/22/09.
*
Copyright 2009 Spatical Company. All rights reserved.
*
*/
#ifndef
BOARD_POSITION_H
#define
BOARD_POSITION_H
/*
* Maximum size of the board is defined
*/
#define ROWS 8
#define COLS 8
/*
* This is a simple class used to pass
around between the other classes
* a
specific board position. The BoardPosition
class will also
* check
the bounds on the indexed row and column to make sure that
* a
square is not queried or set off of the board
*
* The game is played on a board with 64
squares arranged in 8 columns
* and
8 rows. Players alternate turns makeing moves, with the white
* player
moving first.
*/
class BoardPosition {
private:
// The row of the position
unsigned row;
// The column of the position
unsigned col;
public:
/*
* no-arg constructor
* Initialize
object variables
*/
BoardPosition() row(0), col(0){
return NULL
}
/*
* Constructor for a Board position given
a specified index
* Initialize
object variables
*
* Parameters
* row
- row of the position (unsigned integer)
* col
- column of the position (unsigned integer)
*
*/
BoardPosition(unsigned row, unsigned col)
row(row), col(col){
return NULL;
}
/*
* Destructor, delete the Piece
*/
~BoardPosition();
/*
* Method to check the bounds on the
indexed row and column to make sure that
* a
square is not queried or set off of the board
*
* Parameters
* row
- row of the position (unsigned integer)
* col
- column of the position (unsigned integer)
*
* Returns:
* true
- if the indexed position is valid
* false
- if the indexed position is not on the board
*/
static bool
IsValidPosition(unsigned row, unsigned col);
public:
/*
* Simple Getters and Setters (removed to
save paper)
* Just
the public methods to return the private variables of the Move object
*/
};
#endif
/*
*
MoveHistory.h
*
chess
*
*
Created by Steven Hansen on 3/23/09.
*
Copyright 2009 Spatical Company. All rights reserved.
*
*/
#ifndef
MOVE_HISTORY_H
#define
MOVE_HISTORY_H
#include <stack>
/*
* Each time a piece moves, need to add
the move to the history of
* the
game. Any move may be undone to restore the position of the
* board
before the move took place. Thus, it would be possible to
* repeatedly
select Undo until the chess board is reset to its original
* position.
When a game is loaded from a file, the previous history must
* be
cleared. Using the undo option must maintain proper turn order enforcement.
*
* The MoveHistory will maintian a stack
of all of the completed
* moves
during the current game. Whenever
a new game is started a
*
new stack of moves will also be created. It will need to be able
*
to iterate.
*
* The MoveHistory will definitely be a
stack. The program will have
* to
continuously add moves to the history and remove moves from the
* history
when the undo button is pressed. The MoveHistory does not
* need
to be indexable or searchable.
Only simple push and pop operations
* will
be needed and then the iterator will be used when saving the game.
*/
class MoveHistory {
private:
// The actual stack containing the Move objects
stack<Move>
history;
public:
/*
* no-arg constructor
* Initialize
object variables
*/
MoveHistory();
/*
* Destructor, delete the Moves in order
to delete
* and
clean-up the entire current history
*/
~MoveHistory();
/*
* Wrapper function around the push
function on the
* board
history stack, the most recent Move will
* always
be the top move on the stack
*
* Parameters:
* move - the move to push onto the stack
*
*/
void AddMove(Move
& move);
/*
* Wrapper functon around the pop
function of the stack
* it
will always just pop off the most recent Move
* from
the Stack (when there is a move still left to undo)
*
*/
void UndoMove();
/*
* Look at the last Move in the History
(but do not pop it off)
* We
can use this when we finish loading the history, this will
* tell
us which player or color made the last move in the history
*
* Returns
* pointer
to the last Move object
* NULL
if there have not been any moves
*
*/
Move * LastMove();
/*
* Function to create a new history
(clear the current history)
* All
moves will be deleted and taken out of the history, this
* will
be called when a New Game is being started
*/
void Clear();
};
#endif
/*
*
Move.h
*
chess
*
*
Created by Steven Hansen on 3/23/09.
*
Copyright 2009 Spatical Company. All rights reserved.
*
*/
#ifndef MOVE_H
#define MOVE_H
#define "Piece.h"
#define "BoardPosition.h"
/*
* Simple class just to represent the
Moves made on the board
* These
moves will be passed around by the different classes
* especially
to the MoveHistory which will maintian a stack
* of
all of the Moves made in the current game
*
* A move is used to represent a move
that has been made during
* the
course of the game. Shows the original position of the
* piece
that was moved. Shows the final position of the piece
* after
it was moved.
*
* The captured piece is optional. It
represents a piece that
* was
taken when the piece was moved.
*
*/
class Move {
private:
// The start position for the move
BoardPosition start;
// The ending position for the move
BoardPosition end;
// The piece that was moved
Piece * piece;
// A piece that was captured (can be NULL)
Piece * captured;
public:
/*
* no-arg constructor
* Initialize
object variables
*/
Move();
/*
* Constructor to create the Move given
all of the
* given
parameters
*
* Parameters:
* start - BoardPosition of the piece's start
location
* end -
BoardPosition of the piece's end location
*/
Move(BoardPosition
& start, BoardPosition & end, Piece * p1, Piece * p2)
: start(start), end(end),
piece(p1), captured(p2);
/*
* Destructor, delete the Move (but not
the pieces)
*/
~Move();
public:
/*
* Simple Getters and Setters (removed to
save paper)
* Just
the public methods to return the private variables of the Move object
*/
};
#endif
/*
*
Game.h
*
chess
*
*
Created by Steven Hansen on 3/23/09.
*
Copyright 2009 Spatical Company. All rights reserved.
*
*/
#ifndef GAME_H
#define GAME_H
#include <stack>
#include "Piece.h"
#include "MoveHistory.h"
#include "BoardPosition.h"
// Define the
color that always moves first each new game
#define
MOVES_FIRST WHITE
/*
* Facade class for back-end, this is the
main class that will contain the
* other
objects and call the methods inside of them to perform all of the methods
needed
* by
the program to operate correctly and maintain the current state of the game
*/
class Game {
private:
// The current player that gets to make the next Move
PieceColor player;
// History stack object containing the entire history of
the current game
MoveHistory history;
// The board object that maintains the current state of
all piece positions
Board board;
// The gamefiles object to handle the xml files
GameFiles files;
// Game variable, Selected Piece
Piece * selectedPiece;
// Game variable, Start move position
BoardPosition startBoardPosition;
// Game variable, End move position
BoardPosition endBoardPosition;
public:
/*
* no-arg constructor
* Initialize
object variables
*/
Game() :
player(MOVES_FIRST), history(new MoveHistory()), board(new Board()){
return NULL;
}
/*
* Called from Chess Class when the New
Game event has been fired.
* The
user may request a "new game", in which case the current game
* should
be discarded and the program re-initialized to its original state.
*
*/
void NewGame();
//!!!!!! The Game.h
file is continued into the next sections
// Continued from
Game.h
public:
/*
* Method that will get the piece given a
particular position and return whether
* or
not that position has a piece currently on it.
*
* Parameters:
* row
- index of the selected row
* col
- index of the selected column
*
* Returns:
*
true if there is a piece on that square
*
false if there is not a piece on that square
*/
bool IsPiece(unsigned row, unsigned col);
/*
* Only one chess piece can occupy a
single square. Each piece moves in a
* specific
pattern. Each side has 16 pieces of 6 different types: Pawn,
* Rook,
Knight, Bishop, Queen and King. Players alternate turns makeing moves,
* with
the white player moving first. Each of the 6 types of piece have different
* rules
for moving around the board, and can take pieces from the other team
* under
certain conditions.
*
* Each time a piece moves, you need to
add the move to the history of the game.
*
* Parameters:
* row
- index of the selected row
* col
- index of the selected column
*
*/
void MovePiece(unsigned row, unsigned col);
/*
* Called from Chess Class to return all
of the legal moves a piece can make
* this
method will need to get the candidate moves from the piece
* then
check any Check or CheckMate situations, This is includes the rules
* about
moving in and out of check, and stopping the game when checkmate or
* stalemate
have been reached. So it will need to call the CheckForCheck
*
function before returning the full set of legal moves
*
* It will need to get the piece from the
Board given the parameter position
*
* Parameters:
* position
- the current BoardPosition of the piece
*
* Returns:
* A
set of valid BoardPositions representing possible moves
*/
set<BoardPosition>
GetLegalMoves(unsigned row, unsigned col);
// Continued from
Game.h
public:
/*
* Any move may be undone to restore the
position of the board before the move
* took
place. Thus, it would be possible to repeatedly select Undo until the
* chess
board is reset to its original position. When a game is loaded from
* a
file, the previous history must be cleared. Using the undo option must
* maintain
proper turn order enforcement.
*
* This method will simply pop the most
recent Move off of the Move History
* stack
and then change the turns
*
*/
void UndoMove();
/*
* Called when it is the end of the turn
and we need to switch the current
* player
to the other player, just a toggle of BLACK and WHITE for the
* variable
player.
*
* The two players playing your game of
chess must alternate turns. White
* always
goes first. The current player's turn must be displayed.
*/
void ChangePlayer();
// Continued from
Game.h
public:
/*
* Iterates over the possible moves
returned by a piece and
* checks
each one to see if moving the piece to that location
* will
cause the current player to be in a state of Check or CheckMate
*
* The BoardPositions that would cause
the current player to be in check
* are
not added to the final set returned and therefore passed
* to
the Chess class to display to the user as legal moves
*
* Parameters:
* positions
- the current BoardPositions set of the piece
*
* Returns:
* A
set of valid BoardPositions representing possible moves
*/
set<BoardPosition> CheckForCheck(set<BoardPosition> & positions);
/*
* Check if the board is currently in
Stalemate or CheckMate
* Detect
when checkmate or stalemate has occurred, in which case the program
* should
display an appropriate message and not allow further moves to be taken.
* However,
even when checkmate or stalemate is reached, the undo function should
* still
work.
*
*/
void IsStaleMateOrCheckMate();
// Continued from Game.h
public:
/*
* Called from Chess class on_LoadGame(),
the filename will be passed to the
* GameFiles
class which will then Parse the XML file and load the history
* and
board with all of the data given from the XML file
*
* Parameters:
* filename
- string local location of the filename
*
*/
void LoadGame(string filename);
/*
* Called from Chess class on_SaveGameAs()
and on_SaveGame(), the filename
* will
be passed to the GameFiles class which will then create the XML
* file
with the history and board with information
*
* Parameters:
* filename
- string local location of the filename
*
*/
void SaveGameAs(string filename);
/*
* Returns true if the game nas
previously been saved and a file has already
* been created for this game
*/
bool
IsSavedGame();
/*
* Called from Chess class on_SaveGameAs()
and on_SaveGame(), the filename
* will
be passed to the GameFiles class which will then create the XML
* file
with the history and board with information, using the existing
* file
that has already been created.
*
*/
void SaveGame();
private:
bool gameSaved;
/*
*
GameFiles.h
*
chess
*
*
Created by Steven Hansen on 3/26/09.
*
Copyright 2009 Spatical Company. All rights reserved.
*
*/
#ifndef
GAME_FILES_H
#define
GAME_FILES_H
#include "XMLParser.h"
#include <istream>
#include <ostream>
/*
* Seperate Class to handle loading and
Saving game files
* It
will handle all of the file input and output and
* will
also parse the XML and create the XML for the files
* (by
calling some separate XML parser classes)
*/
class GameFiles {
private:
// XML parser object to call the functions on
XMLParser parser;
public:
/*
* no-arg constructor
* Initialize
object variables
*/
GameFiles();
/*
* Destructor, delete the GameFiles
*/
~GameFiles();
/*
* Method to load the given filename and
then
* instantiate
the XML parser (borrowed class) and
* iterate
over all of the XML objects in the file
* and
setup the board and history according to those files
*
* Parameters:
* filename - string filename of the file to open
*/
void ParseXML(string filename);
/*
* Method to create the given filename
and then
* instantiate
the print the XML by iterating over
* all
the board and history according to the XML specs
*
* Parameters:
* filename - string filename of the file to create
*/
void CreateXML(string filename);
};
#endif
Algorithms
The following is the top-level code for
the algorithms (see header files to find how the methods in these algorithms
call other classes).
/*
Each square of the chess board is reffered
to in the GUI code as a cell.
This Function is called whenever the
uses clicks and releases the mous button over
a cell without initiating a drag. Row
and Column coordinates begin in the top left corner.The button paramter tells
which mouse button was clicked(1 for left, 2 for middle, 3 for right). You do
not need to worry about wich button was used to complete the project.
*/
void Chess::on_CellSelected(int row, int col, int button)
{
g_debug("Chess::on_CellSelected (%d,%d)",row,col);
//! We will keep a record in this class if we have a
currently selected piece
//! if
we already have a piece selected then we will move that piece to the newly
//! selected
cell, otherwise change nothing of the current game.
if( PieceIsSelected
){
//! Check if the newly checked spot is highlighted
if( IsHightlighted ) {
//! move the piece!
game.MovePiece(row,col);
//! method to unhighlight all of the squares
UnHighlightAllPositions();
} else if ( game.IsPiece(row,col) ){
//! method to unhighlight all of the squares
UnHighlightAllPositions();
//! New piece was selected
//! Get the set of legal positions and pass it to a
method to
//! highlight the set of BoardPositions
HighlightPositions(game.GetLegalMoves(row,col));
}
} else {
//! select a piece if there is a piece on the selected
position
//! and
only if it is the current players piece
if( game.IsPiece(row, col) ){
//! Get the set of legal positions and pass it to a
method to
//! highlight the set of BoardPositions
HighlightPositions(game.GetLegalMoves(row,col));
}
}
DrawBoard();
}
/*
* Method that will get the piece given a
particular position and return whether
* or
not that position has a piece currently on it.
*
* Parameters:
* row
- index of the selected row
* col
- index of the selected column
*
* Returns:
*
true if there is a piece on that square
*
false if there is not a piece on that square
*/
bool Game::IsPiece(unsigned row, unsigned col){
//! first check to make sure the row and col is a valid
//! row
and col position
if( BoardPosition::IsValidBoardPosition(row, col) ){
//! Create a board position object from the row and col
BoardPosition position = BoardPosition(row, col);
//! Get the piece on that position, returns NULL if
//! there is not actually a piece
on that position
Piece * possiblePiece
= board.GetPiece(position);
if( possiblePiece != NULL ){
//! check if the current player owns this piece
if( possiblePiece->color == player
){
//! There is a piece on that square so save the
//! game
variable of the selected piece and then
//! return
true to tell the gui a piece was selected
startBoardPosition
= position;
selectedPiece
= possiblePiece;
return true;
}
else {
//! local game variable saving the selected piece
//! return
false, no piece was selected
selectedPiece
= NULL;
return false;
}
} else {
//! local game variable saving the selected piece
//! return
false, no piece was selected
selectedPiece
= NULL;
return false;
}
} else {
//! local game variable saving the selected piece
//! return
false, no piece was selected
selectedPiece
= NULL;
return false;
}
}
/*
* Only one chess piece can occupy a
single square. Each piece moves in a
* specific
pattern. Each side has 16 pieces of 6 different types: Pawn,
* Rook,
Knight, Bishop, Queen and King. Players alternate turns makeing moves,
* with
the white player moving first. Each of the 6 types of piece have different
* rules
for moving around the board, and can take pieces from the other team
* under
certain conditions.
*
* Each time a piece moves, you need to
add the move to the history of the game.
*
*/
void Game::MovePiece(unsigned row, unsigned col){
//! Just to make sure we don't try and access a NULL
pointer
if( selectedPiece
!= NULL ){
//! Create a board position object from the row and col
endBoardPosition
= BoardPosition(row, col);
//! Get the piece on that position, returns NULL if
//! there is not actually a piece
on that position
Piece * capturedPiece
= board.GetPiece(endBoardPosition);
//! actually
create the Move object from the saved Game variables
Move pieceMove = Move(startBoardPosition, endBoardPosition,
selectedPiece, capturedPiece);
//! remove the
piece from the previous boardposition
board.SetPiece(NULL,
startBoardPosition);
//! remove the
captured piece from the end position
//! and
put the new piece on that position
//! the
captured piece will automatically be handled and removed
//! by
the board if there is a piece already on that board position
board.SetPiece(selectedPiece,
endBoardPosition);
//! add this move to the history
history.AddMove(pieceMove);
}
}
/*
* Called from Chess Class to return all
of the legal moves a piece can make
* this
method will need to get the candidate moves from the piece
* then
check any Check or CheckMate situations, This is includes the rules
* about
moving in and out of check, and stopping the game when checkmate or
* stalemate
have been reached. So it will need to call the CheckForCheck
*
function before returning the full set of legal moves
*
* It will need to get the piece from the
Board given the parameter position
*
* Parameters:
* position
- the current BoardPosition of the piece
*
* Returns:
* A
set of valid BoardPositions representing possible moves
*/
set<BoardPosition> Game::GetLegalMoves(unsigned row, unsigned col){
//! Create a board position object from the row and col
BoardPosition position = BoardPosition(row, col);
//! Get the piece on that position, returns NULL if
//! there
is not actually a piece on that position
Piece * selectedPiece
= board.GetPiece(position);
//! if the selected piece exists get the moves for it
if( selectedPiece
!= NULL ){
//! Get a set of candidate moves from the piece
set<BoardPosition> candidatePositions = selectedPiece.GetCandidateMoves(position);
//! Get a final set of legal moves after checking
Check/Stalemate/Checkmate
return CheckForCheck( candidatePositions );
} else {
//! return an empty set
return set<BoardPosition>();
}
}
/*
Called when someone selects 'Undo' from
the toolbar, 'Game' menu, or presses 'Ctrl-Z'.
*/
void Chess::on_UndoMove()
{
g_debug("Chess::on_UndoMove");
game.UndoMove();
DrawBoard();
}
/*
* Called from Chess Class when the Save Game
event has been fired.
* The
user may request "save game", in which case the current game
* should
be saved to the given filename
*
* Any move may be undone to restore the
position of the board before the move
* took
place. Thus, it would be possible to repeatedly select Undo until the
* chess
board is reset to its original position. When a game is loaded from
* a
file, the previous history must be cleared. Using the undo option must
* maintain
proper turn order enforcement.
*
* This method will simply pop the most
recent Move off of the Move History
* stack
and then change the turns (if there were no moves to pop off the
*
history then it can just keep the turn at the FIRST player)
*
*/
void Game::UndoMove(){
//! Call the undo move method on the history if there
still exists moves
//! that
need to be undone
if( !history.IsEmpty()
){
//! Undo the last move
history.UndoMove();
//! Change the current player
ChangePlayer();
}
}
/*
Called when someone selects 'Save' from
the toolbar, 'Game' menu, or presses 'Ctrl-S'.
*/
void Chess::on_SaveGame()
{
g_debug("Chess::on_SaveGame");
if( game.IsSavedGame() ){
game.SaveGame();
} else {
string filename = SelectSaveFile();
if( filename.compare("") != 0 ){
game.SaveGame();
} else {
// Print out file error
}
}
}
/*
* Called from Chess Class when the Save Game
event has been fired.
* The
user may request "save game", in which case the current game
* should
be saved to the given filename
*
* Nothing with the actual game play or
board changes
*
* SaveGameAs() just sets the current
filename first then calls this method
*
*/
void Game::SaveGame(){
//! the files object of the GameFiles class is
initialized with a pointer to
//! the
board and history objects, so we just need to run the parser in
//! that
class and it will add all of the information to the board
//! and
to the move history.
//! The basic process of the CreateXML method will be to
iterate through the
//! board
positions and the move history and save the filename the
//! appropriate
tags and elements for each board position with a piece
//! currently
on it and all of the moves from oldest to newest from the
//! the
move history stack
files.CreateXML(filename);
}
/*
Called when someone selects 'Open' from
the toolbar, 'Game' menu, or presses 'Ctrl-O'.
*/
void Chess::on_LoadGame()
{
g_debug("Chess::on_LoadGame");
string filename = SelectLoadFile();
if( filename.compare("") != 0 ){
game.LoadGame();
DrawBoard();
}
else {
// Print out file error
}
}
/*
* Called from Chess Class when the Load Game
event has been fired.
* The
user may request "load game", in which case the current game
* should
be discarded and the program re-initialized to the saved state
* of
the loaded game
*
*/
void Game::LoadGame(string filename){
//! Do not worry about the
game having been saved or anything, just reset
//! all
of the values for the object
NewGame();
//! the files object of the
GameFiles class is initialized with a pointer to
//! the
board and history objects, so we just need to run the parser in
//! that
class and it will add all of the information to the board
//! and
to the move history.
//! The basic process of the
ParseXML method will be to read through the
//! file
and first load the Board with all of the board positions parsed
//! out
of the XML document, then it will load each of the moves in the
//! order
that they appear in the XML document
files.ParseXML(filename);
//! Set current turn to the
player moved the last piece (then switch to the other)
player
= history.LastMove()->GetPiece()->GetColor();
ChangePlayer();
}
/*
Called when someone selects 'New' from the
toolbar, 'Game' menu, or presses 'Ctrl-N'.
*/
void Chess::on_NewGame()
{
g_debug("Chess::on_NewGame");
game.NewGame();
DrawBoard();
}
/*
* Called from Chess Class when the New Game
event has been fired.
* The
user may request a "new game", in which case the current game
* should
be discarded and the program re-initialized to its original state.
*
*/
void Game::NewGame(){
//! Do not worry about the game having been saved or
anything, just reset
//! all
of the values for the object
//! Create a new move history, the assignment operator of
the MoveHistory
//! object
will need to clear any existing moves from the history
//! and
clean up any memory those moves where using
history = new MoveHistory();
//! Create a new board and reset all of the pieces to the
starting locations
//! the
board assignment operator will need to make sure to first
//! clean
up all of the previous board positions and Squares
//! The Board() constructor will need to set all of the
starting pieces
//! onto
the board in their starting locations
board = new Board();
//! Set current turn to the player that has been defined
as moving first (white)
player = MOVES_FIRST;
}