How I Built a Competitive Chess Engine from Scratch
Building a chess engine is a classic challenge that tests both algorithmic thinking and software engineering skills. In this project, I set out to create a chess-playing agent from the ground up-starting with random play and evolving into a technically capable opponent using techniques like Minimax, alpha-beta pruning, and domain-specific heuristics.
Building a chess engine is a classic challenge that tests both algorithmic thinking and software engineering skills. In this project, I set out to create a chess-playing agent from the ground up-starting with random play and evolving into a technically capable opponent using techniques like Minimax, alpha-beta pruning, and domain-specific heuristics.
Initial Baselines and Greedy Agent
The development started with a random agent, which sampled uniformly from the list of legal moves at each turn. To establish a stronger baseline, a greedy agent was then built using a simple evaluation function based on material advantage—calculating the difference in the total value of pieces for both sides. This agent served as a benchmark for testing more advanced strategies.
To evaluate the agents, multiple self play games were conducted with each agent alternating between playing White and Black. Randomness was introduced to break ties between equally scored moves to prevent deterministic repetition of games, especially for search-based agents.
Minimax and Alpha-Beta Pruning
Next, a Minimax agent was implemented to look ahead and evaluate future board positions. To meet a 1-second-per-move runtime constraint, the search depth was initially limited to 2.
To improve performance and search deeper, Alpha-Beta pruning was added. This significantly reduced the number of nodes evaluated, enabling a search depth of 3. Further optimization was done by implementing a move ordering heuristic to improve pruning efficiency. Moves were presorted based on several priorities:
Captures involving high-value targets taken by lower-value pieces
Checks
Promotions
En passant captures
With move ordering in place, the pruning effectiveness improved, allowing the engine to reliably search to a depth of 4 within the same time budget.
Custom Evaluation Function and Heuristics
To address specific shortcomings in the greedy and Minimax agents, a context-sensitive evaluation function was introduced. The game was segmented into three stages—opening, middlegame, and endgame—with different evaluation strategies for each.
Opening Heuristics: Piece-square tables (heatmaps) were used to encourage development and center control. Knights were incentivized toward central squares, rooks toward open files, and king safety was prioritized. These heatmaps were manually designed and tuned using guidance from chessprogramming.org and referenced educational videos.
Endgame Heuristics: Factors included:
Encouraging the enemy king to the board edge
Bringing the own king toward the center and closer to the opposing king
Valuing passed pawns highly, as they have strong promotion potential
These evaluation upgrades addressed critical weaknesses such as:
Poor opening development due to capture-only heuristics.
Inability to consider sacrifices that may lead to positional or tactical advantages.
Drawing endgames despite material advantage due to lack of positional pressure.
