1. Overview
This parser is designed to support the PGN (Portable Game Notation) format, commonly used for recording chess games. The parser reads the movetext, which is written in Standard Algebraic Notation (SAN), and processes each move to update the internal chessboard state. It fully supports the PGN specification, ensuring compatibility with most chess applications.
At the end of the game, the board state is output in an 8x8 grid format, as shown below:
Input
|
|
Output
|
|
Project Requirements
- CMake 3.22
- GCC 12.1 and C++20 standard
- Ubuntu 23.10 or the Docker image iainttho/ubuntu:23.10.02 based on Ubuntu 23.10.
2. Architecture
This project uses a modern C++ design with CRTP
(Curiously Recurring Template Pattern) and std::variant
to represent pieces, providing a flexible and efficient approach to handle polymorphism without traditional inheritance or virtual function tables (vtables). The code achieves runtime polymorphism using std::visit
for handling different types of pieces.
2.1 BasePiece Class
The BasePiece
class provides the foundation for all chess pieces, using CRTP
to allow specific behavior for each piece type. This avoids the overhead of virtual function calls while keeping the code type-safe and efficient.
|
|
2.2 Concrete Piece Classes
Each piece type (like Bishop
, Knight
, etc.) inherits from BasePiece
and implements its specific movement logic.
|
|
2.3 Piece Representation Using std::variant
The chessboard contains pieces represented as std::variant
, allowing it to store different types of pieces in the same container while retaining type safety.
|
|
2.4 Square Class
The Square
class is responsible for processing moves and managing the state of the pieces. It validates moves, checks whether the king is in check, and applies the necessary updates to the board.
|
|
In Square::ProcessBasicMove, std::visit is used to handle pieces of different types polymorphically:
|
|
2.5 Polymorphism without vtables
Utilizing
std::visit
for Type Handling:std::visit
is a C++17 utility that enables the application of a callable, such as a lambda function, to the value stored in astd::variant
. This feature is especially beneficial for managing the diverse types of pieces that may be contained within the variant, facilitating a form of polymorphism.
Collection of Variants:
- The
subPieces
variable is designed as a collection ofstd::variant
, which allows it to store various types of chess pieces. This architecture supports the retention of type safety while accommodating multiple types within a single collection.
- The
Method Invocation Without Type Knowledge:
- With
std::visit
, we can call methods on the pieces stored in the variant without prior knowledge of their specific types at compile time. The lambda function provided tostd::visit
executes with the actual type contained in the variant, streamlining operations on the pieces.
- With
Achieving Polymorphic Behavior:
- The combination of
std::visit
andstd::variant
enables the implementation of polymorphic behavior without relying on traditional inheritance. This design choice ensures that multiple piece types can be managed in a type-safe manner, enhancing the flexibility and robustness of the system.
- The combination of
3. Pros and Cons
3.1 Pros
- Type Safety: Guarantees type-safe operations with
std::variant
. - Polymorphism: Achieves runtime polymorphism without virtual function overhead.
- Performance: Avoids pointer indirection and the cost of vtables, making the code more efficient.
3.2 Cons
- Compile-time Knowledge: All possible types must be known at compile time.
- Error Handling: Handling unexpected types or errors in
std::variant
can be complex. - Debugging: Debugging
std::variant
interactions can be challenging. - Memory Overhead: Variants may consume more memory if piece sizes differ significantly, leading to potential inefficiencies.
4. Improvements
- Add iterative move parsing and game state tracking.
- Support backward and forward navigation through the game’s moves.
- Improve the piece swap mechanism for better handling of complex moves.
For more insights, refer to the following resources: