/cmd_line_chess

♟️ Making chess for the command line.

Primary LanguageC++

Chess

Goals

  1. Use design patterns ✔️
  2. Dynamic / Linear Programming if possible
  3. NAMESPACES ??
  4. Implement undo/redo features
  5. Implement Castling ✔️
  6. With the UI, reflect the board's printing such that the player who is playing is on the bottom
  7. Letter = x, Number = y system ✔️
  8. Check for moving into check
  9. Pawn (+2) movement ✔️
  10. Checkmate check 👈

Savepoints

  1. Create UML ✔️
  2. Determine representation of the Board / Pieces on the Board ✔️
  3. Create Chess Pieces 👈
  4. Test Chess Pieces & Chess Eating
  5. Add pawn-transformation functionality ✔️
  6. Create Board representation ✔️
  7. Create Board builder
  8. Give option to reverse the printing of the board based on which player is playing
  9. Optimize the physical representation of the board

Algorithms & Implementations

Checkmate Check

Only check if a check is detected.

Returns: true (checkmate), false (no checkmate)

  1. Get the king's coordinates.
  2. Get the square around the king. Create a 2D array of booleans that represents the square around the king.
  3. For the main offender (the piece that places the King in check), check that it can't/can be eaten. If it can be eaten, NO CHECKMATE. If it can't, continue...
  4. Check for pieces that occupy the square.
  • If the piece is of the same color, cross out the availability of the square in the 2D array.
  • If the piece is of a different color, store this position. This position needs to be checked for if it's covered by another opposing piece. (If not, this place is avaliable, no checkmate. If covered, this place is not available, checkmate).
  • If the square is taken, checkmate. If not, continue...
  1. 2D Array: For every placement on the board, check for if a piece occupies the board.
  • If a piece occupies the board, then check if it covers any portion of the square. Mark appropiately.
  1. At the end, check the 2D array of booleans. If it's full of true's, then checkmate.

  2. Get the king's coordinates, and manipulate them to get the appropiate square around the king. Store in a 2D array ( (x,y), (x,y), ...,).

  3. Check if pieces of the opposite team can hit all pieces in the square around the king. The alogorithm is pretty brute force:

  • Store an array of booleans. If a (true) (for the coordinate in the 2D array being a valid move) is returned from a Chess piece, break.
  • This will be a double for-loop: for every board piece, check across all coordinates in the array.
  • Check the array of booleans. If there is a false, there is no checkmate. If there are all trues then there is a checkmate.

Things to consider:

  1. If a piece is occupying a placement in the square and is of the same color as the King, then "true" is returned.
  2. If a piece is occupying a placement in the square and is of the different color, then this placement is considered as "false."

Support for mulitple methods of position input

The following input styles are sought to be supported in this application:

  1. Algebraic-style notation (ex. A1; H 3; H,3)
  2. Coordinates-style notation (ex. (1, 3); 1, 3; 1,3)

To do this, all algorithms that deal with string-to-coordinates conversions and validation will be moved its own seperate class. This allows for the decoupling of string validation from the client (the Chess Board), and allows the possible complexity of string validation to not affect the Chess Board-related algorithms.

The algorithm generally works as such:

  1. Clean the string (does not need to be called by the client)
  2. Check the validity of the string (must be called by the client)
  3. Return the x and y coordindates (must be called by the client)

Collision Detection and Game Over Detection

Collision detection WILL NOT require the latest concretion, BUT GAME OVER DETECTION WILL.

For collision detection: check the color (does not depend on latest concretion), if different then replace. For Game Over dectection: get the concretion, if opposing color & king, then return game_over.\

  • use double dispatching to get the concretion -- get_result() will return true IF A KING (and you can get the color because all base Chess_Piece will have an is_white attribute)!!!!

Castling Detection

  • Neither the king nor the rook has previously moved.
  • There are no pieces between the king and the rook.
  • The king is not currently in check.
  • The king does not pass through or finish on a square that is attacked by an enemy piece.
  1. If the user attempts to move the king left/right 2 spaces -and- this is the King's first move:
  2. Check that the rook in the direction of movement (if moves_.size() is 0, then it can be inferred that a rook is at this position)
  3. Check that there are not pieces in between the king and rook
  4. The king moves two spaces over in the direction specified
  5. The corresponding rook moves +/-1 where the king's original position was (depends on the king's direction of motion) ^ Additional implementation: you can allow for movement on top of the rook to activate castling behavior

Transformation Algorithm

  1. For every pawn movement (in the Strategy), if the Pawn is moved to the end of the board, prompt the user for the piece they wish to transform the pawn into
  2. Replace the pawn with the appropiate instance ^ Note, one does not need to check that the pawn moved to the 'correct end' of the board, because Pawn's are programmed to only allow forward movement

Undo

Currently, undo() is only supported for when the user inputs a faulty coordinate. However, supporting undo for "undoing" the conglomerate moves that the two players have done is simple: pop the Chess_Piece off of Chess_Board.moves_, and pop off the Chess_Piece's previous placement stored in Chess_Piece.moves_. Then, restore the Chess_Piece's previous placement.

User Interface

~ insert Board ~
WHITE'S TURN (input 'QUIT' to quit):
Choose a piece to move: x, y
New X coordinate:
New Y coordinate:

..
..
..

Board Representation (2D Array)

The current implementation of the chess board is via a 2D array; however, to increase the ease of replacing representations of the chess board in the future, the board is wrapped in a class that does not specify representation. Along with ease of replacing representation of the board, the strategy for movement of the chess piece's can also be easily replaced. It is the client's responsibility to pair the appropiate strategy with the board representation.

The following symbols represent the following chess pieces: K – king
Q – queen
R – rook
B – bishop
N – knight
P – pawn
| R | N | B | Q | K | B | N | R |
| P | P | P | P | P | P | P | P |
| -- | -- | -- | -- | -- | -- | -- | -- |
| -- | -- | -- | -- | -- | -- | -- | -- |
| -- | -- | -- | -- | -- | -- | -- | -- |
| -- | -- | -- | -- | -- | -- | -- | -- |
| -P- | -P- | -P- | -P- | -P- | -P- | -P- | -P- |
| -R- | -N- | -B- | -Q- | -K- | -B- | -N- | -R- |

  • differentiation of -white- and black pieces.

image

Bugs

Minor Bugs

1.1 Stream Corruption upon 'QUIT'

The following will cause a stream corruption: image In other words, upon 'QUIT'-ing from the movement interface, there is a minor bug. This causes no problems to the program, but may confuse users. This may be a nice minor fix in the longrun.

UML