Advanced Project 1 — Chess Engine Core¶
Difficulty: Advanced · Estimated effort: 2–3 weeks · Prerequisites: Modules 6–8, Module 11 — RAII and Smart Pointers, Module 13 — Exception Handling, Module 15 — SOLID and Design Patterns · Demanded pattern decisions: factory, command
This is one of the designated integration projects, and one of the projects that requires a design-pattern decision: at least two patterns must be named, justified by a requirement, and one alternative must be considered and declined in writing.
No complete solution is provided. The rule set is described as behaviour; deriving the object model from it is the project.
1. Scenario¶
A university chess club wants a program that holds a position, validates moves, plays through a game and can take a move back — because the club's coaching sessions depend on replaying a blunder and asking what else was possible. Rendering is out of scope: the board prints as text, and the value is in the rules and the history.
2. Problem statement¶
Build the core of a chess engine: a board holding a position, pieces that know their own move rules, a legality check that includes leaving your own king in check, move application and undo, and a save/load format for positions and move history. Illegal moves are refused with a reason; malformed positions are refused with a line number.
3. User requirements¶
- [ ] Set up a position from a documented text format, including a partly developed game.
- [ ] See the board in text, with whose turn it is and whether a side is in check.
- [ ] Attempt a move; it is either applied or refused with a reason.
- [ ] Take back the last move and see the previous position.
- [ ] Save a game and load it back, both position and move list.
- [ ] Play a short scripted game from a file and print the moves made.
4. Functional requirements¶
- [ ]
Square,Boardand a piece hierarchy with per-piece move generation. - [ ] A
Movevalue type: origin, destination and any promotion information. - [ ] Legality checking that includes king safety, plus castling and en-passant special cases (choose a subset if you must, but document what is out of scope).
- [ ] Move application and undo, both rejecting an impossible request.
- [ ] A creation point turning position text into pieces — the factory decision in this project.
- [ ] Typed errors: illegal move, unknown square, malformed position, malformed move script.
- [ ] A documented file format for the position and for a game's move list.
5. Non-functional requirements¶
- [ ] The position invariant holds after every operation: exactly one king per side, no piece off the board, turn flag consistent.
- [ ] No raw owning pointers; pieces owned through
std::unique_ptr. - [ ] Undo restores the position exactly, including whose turn it is — tested by comparing before and after.
- [ ] No
switchon a piece's type in move generation; each piece generates its own. - [ ] Builds warning-free with
g++ -std=c++17 -Wall -Wextra -Werror.
6. Suggested features¶
- Move notation output, and a parser for it.
- Check, checkmate and stalemate detection over the pseudo-legal move set.
- Repetition detection over the move history, needing a position key.
- A simple evaluation score, with the scoring table loaded from a file.
7. OOP concepts involved¶
| Concept | Required | Where it appears |
|---|---|---|
| Multiple classes | yes | Board, squares, six piece types, Move, history, position loader, error types |
| Relationships | yes | Board ◆ pieces; piece ──> board for legality; history ◆ moves |
| Encapsulation | yes | The board's contents and the turn flag can only change through a validated move |
| Inheritance or composition | yes | Piece hierarchy for move rules; consider whether a data-driven move table is better and answer in the report |
| Polymorphism | yes | Move generation and symbol dispatch; no piece-type tags in the engine |
| The STL | yes | std::array for the board, std::vector for history and legal moves, algorithms for scanning |
| Exception handling | yes | Four distinct error types with the offending coordinate or line number |
8. Suggested design considerations¶
The pattern decision you must make and justify¶
Creating pieces. Position text must become objects, and the naive version is a switch on
the character. A factory — a function per piece type held in a lookup table, or a class
hierarchy of creators — replaces that with a registration. Decide which, and answer: did the
factory remove the conditional, or relocate it into a table? Both are legitimate answers; the
requirement that earns the factory is adding a variant without editing the loader.
Undo. Two honest designs: a command that stores its own inverse, or a memento — a snapshot of the affected squares plus the turn flag. Command is efficient and harder to get right; memento is obviously correct and copies more state. Pick one, say what it costs, and name the alternative you declined with the reason. This is the declined-pattern item.
Ideas you should also weigh and record: a visitor for a rules pass (probably not earned yet), and a strategy for promotion choice (earned the moment promotion becomes configurable).
Other design points¶
Legality is not the same as move generation. A piece generates pseudo-legal moves; the board filters them for king safety. Mixing the two is what makes chess engines unauditable.
The invariant is your friend. "One king per side, no piece off the board" catches most loader bugs before the rules do. Check it after every mutation in the tests.
Undo must restore the turn flag. Forgetting it is the single most common bug in this project, and the checklist tests for it directly.
9. Minimum viable version¶
A board, two or three piece types, pseudo-legal moves, a text print, and apply/undo. No castling, no en passant, no checkmate detection — but the invariant is checked, and illegal moves are refused.
10. Intermediate extension¶
Add the remaining piece types through the factory, king-safety filtering, and the position loader with line-numbered errors. Then demonstrate undo across five moves by comparing the board before and after the sequence.
11. Advanced extension¶
Add save/load of games, detection of check and checkmate, and one special rule of your choice (castling or en passant) with its own tests. Then write the design note: the two patterns, the one declined, and the decision you would reverse — with the cost of reversing it.
12. Testing checklist¶
- [ ] The starting position loads and prints with white to move
- [ ] A pawn's legal moves are generated forwards only, and captures only diagonally
- [ ] A knight on a corner has two moves; in the centre, eight
- [ ] A move that leaves your own king in check is refused, with the reason stated
- [ ] An illegal move leaves the board byte-for-byte unchanged
- [ ] Undo after a move restores the board and the turn flag
- [ ] Undo with no moves reports that there is nothing to undo
- [ ] A malformed position (no king, two kings, piece off the board) is refused with a line number
- [ ] Apply → undo → apply gives the same position as the first apply
- [ ] A scripted game of at least ten moves replays identically from the saved file
- [ ] No piece is leaked: a destruction counter reaches zero at program end
13. Documentation checklist¶
- [ ] The position format and the move-script format, with examples
- [ ] The rules implemented, and the rules deliberately out of scope
- [ ] The class diagram with multiplicities and ownership
- [ ] The two patterns, the requirement each satisfies, and the alternative declined
- [ ] The decision you would reverse and the cost — one paragraph, honest
14. Self-evaluation rubric¶
| Criterion | Excellent looks like | Weight |
|---|---|---|
| Domain modelling | Piece rules polymorphic; legality separate from generation; no type tags | 25% |
| Pattern decisions | Two patterns named and justified; one alternative declined with reasoning | 20% |
| Undo correctness | Board and turn state both restored, proven by test | 15% |
| Invariants | Position validity checked after every mutation; loader rejects nonsense | 15% |
| Persistence | Round trip for position and move list, with version marker | 10% |
| Failure handling | Four typed refusals with coordinates or line numbers | 10% |
| Documentation | Rules, formats, patterns and the reversed decision written down | 5% |
Related: Advanced projects · Project roadmap · All projects · Module 15 — SOLID and Design Patterns