Personal Project

Chess Engine + AI

A chess engine and AI opponent built from scratch in C++17 with minimax search, alpha-beta pruning, quiescence search, and an SDL2 graphical interface.

Personal Project
C++17 / SDL2 / CMake
Play in Browser View on GitHub

Overview

A ground-up chess engine and AI opponent in modern C++17. The engine handles every rule — castling, en passant, pawn promotion, check/checkmate/stalemate — with an efficient board representation and legal move generation system.

The AI uses minimax search with alpha-beta pruning to explore game trees, extended by quiescence search to resolve capture sequences and avoid tactical blunders. A killer move heuristic speeds up pruning by remembering moves that caused cutoffs. Positional evaluation includes king safety, pawn structure analysis, bishop pair bonuses, and piece-square tables.

The SDL2 graphical interface features click-to-move interaction, move highlighting, an undo button, a promotion dialog, a live scoreboard tracking wins/losses/draws across games, and a status panel showing real-time game messages. The entire application is compiled to WebAssembly via Emscripten, making it playable directly in the browser with no install required.

Key Features

AI with Alpha-Beta Search
Minimax engine with alpha-beta pruning explores thousands of positions per move. Three difficulty levels from beginner-friendly to challenging (depth 5 search).
Quiescence Search
Extends search beyond the depth limit to resolve capture sequences, preventing the AI from misjudging exchanges and hanging pieces.
Advanced Evaluation
Positional scoring with king safety (pawn shield, attack detection), pawn structure (doubled/isolated/passed pawns), bishop pair bonus, and piece-square tables.
Killer Move Heuristic
Remembers quiet moves that caused beta cutoffs at each depth, trying them earlier in subsequent searches to dramatically speed up pruning.
SDL2 Graphical Interface
Click-to-move board with legal move highlighting, promotion dialog, in-app menus for game mode and difficulty, live scoreboard, and status messages.
Complete Chess Rules
Every rule implemented: castling with right tracking, en passant, pawn promotion, check/checkmate/stalemate, 50-move rule, and insufficient material draws.
Move/Undo System
Full game state history with push/pop semantics. Every move can be undone, restoring castling rights, en passant targets, and half-move clock.
MVV-LVA Move Ordering
Captures sorted by most-valuable-victim / least-valuable-attacker, combined with killer moves and promotion priority for optimal search ordering.

Challenges & Solutions

  • Horizon Effect: The AI would misjudge positions mid-capture-sequence, hanging pieces. Solved with quiescence search that continues evaluating captures past the depth limit until the position is "quiet."
  • Search Performance: Depth 5 search with naive ordering was too slow. Implemented killer move heuristic and MVV-LVA capture ordering to maximize alpha-beta cutoffs, making deeper searches feasible.
  • Evaluation Balance: Pure material counting led to passive play. Added king safety scoring (pawn shield, attacker counting), pawn structure penalties (doubled/isolated pawns), and passed pawn bonuses for more strategic play.
  • State Restoration: The undo system must perfectly restore all game state — not just piece positions, but castling rights, en passant target, and half-move clock. Used a state snapshot stack.
  • GUI Responsiveness: The AI blocks the main thread while searching. Rendered a "CPU is thinking..." frame before the search to keep the UI informative during computation.
  • WebAssembly Port: SDL2's blocking main loop doesn't work in the browser. Refactored into a single-frame callback using emscripten_set_main_loop_arg, bundled assets with --preload-file, and replaced system fonts with embedded TTF files.

What I Learned

  • Practical understanding of game tree search algorithms — minimax, alpha-beta pruning, and quiescence search, and how move ordering dramatically affects performance.
  • Designing heuristic evaluation functions that balance multiple competing factors (material, position, king safety, pawn structure) into a single score.
  • Building a real-time GUI application with SDL2 — event-driven rendering, texture management, and managing blocking computation in a render loop.
  • Deep understanding of OOP design and efficient data structure design for board representation and move encoding.
  • Building a multi-target CMake project with proper header organization, compilation units, and external library integration via vcpkg.
  • Porting a native C++ application to WebAssembly with Emscripten — adapting the main loop, bundling assets for a virtual filesystem, and handling platform differences between desktop and browser.

Tech Stack

C++17 SDL2 CMake Minimax / Alpha-Beta Quiescence Search Data Structures Algorithms OOP Design WebAssembly Emscripten

Want to see more of my work?

All Projects