Seyed Masoud Hosseini · Overview · Study log · Weekly summaries · Ideas · Search · Transcript · RSS feed
Performance Engineering of Software Systems · Lecture 19 of 23 · 1:12:42
Lecture 19: Leiserchess Codewalk
Study guide
What this lecture covers
This session is a project orientation rather than a standard lecture: TA Helen Xu introduces Leiserchess, a laser-tag variant of chess that is the subject of the course's final project, then walks through the roughly 4,500-line reference codebase students will optimize. It covers the game rules, the testing infrastructure (scrimmage server, cloud autotester), the board and move representation, and the search algorithm used to pick moves.
This video sits at the start of the final project in MIT's performance engineering course, after lectures on parallelism and synchronization that the project will draw on. After watching, you'll understand how Leiserchess is played and scored, how moves are represented and generated, how alpha-beta and principal variation search prune the game tree, and which optimization structures (transposition table, killer moves, opening book) already exist in the starter code.
Key ideas
- Leiserchess rules: two teams of pawns and a king move and rotate on a board, and each turn ends with the king firing a laser that reflects off the long edge of pawns and kills them on the short edge; a side loses if its king is hit.
- Move representation: moves are packed into a compact struct with piece type, orientation, and from/intermediate/to squares, since a "swap" move touches an opposing piece before a following non-swap move.
- Board representation: the reference implementation uses a 16x16 array (an 8x8 board padded with sentinel squares) to simplify detecting when a move goes off the board.
- Static evaluation: the
eval.cheuristics (king facing, king aggressiveness, king mobility, pawn centrality, pawn-between, laser coverage) score a position without searching further, and the lecture recommends tuning these existing heuristics before inventing new ones. - Alpha-beta pruning: searching a game tree with a
[alpha, beta]window lets a search skip subtrees it proves cannot change the outcome, cutting the nodes examined fromb^dtoward roughlyb^(d/2)when moves are well ordered. - Principal variation search: an alpha-beta variant that assumes the first move is best and verifies the rest with cheap zero-window "scout" searches, only doing a full search when a scout search disproves the assumption.
- Search infrastructure: a transposition table (indexed via incrementally updatable Zobrist hashing) avoids re-searching repeated positions, while killer-move and best-move tables help order moves to trigger earlier cutoffs.
- Elo-based grading: bots are compared by Elo rating from many games rather than raw search speed, since faster search only helps insofar as it lets the bot search deeper and play better moves.
- Correctness-first testing: the instructor stresses fixed-depth, deterministic testing (node counts,
perft) and keeping old and new board representations side by side during migration, warning that "30 changes with something broken" is a common and painful failure mode.
Walkthrough
Game rules and example plays (1:03)
Helen Xu introduces Leiserchess pieces, orientations, basic and swap moves, the Ko rule (borrowed from Go, preventing immediate reversal of the opponent's last move), and draw conditions. Working through a board example, she shows students how firing the king's laser to kill an opposing pawn can expose their own king to a counter-shot, illustrating that naive captures can lose the game.
Notation, tooling, and grading (10:21)
The lecture covers Forsythe-Edwards-style position notation and game logs, then demonstrates the scrimmage server for one-off matches and the cloud autotester for running many games with a chosen time control and set of binaries. Bots are ranked by Elo rating rather than raw speed, though the lecture notes that searching deeper (i.e., being faster) does tend to raise Elo.
Board and move representation, and move generation (21:38)
The lecture details the position struct (padded 16x16 board, move history, Zobrist hash key, ply, king locations) and the packed move representation. It introduces perft, a debugging function that enumerates all moves to a given depth, as a way to confirm that optimizations to move generation haven't changed which moves are produced.
Static evaluation heuristics (24:39)
Xu walks through the heuristics in eval.c that score a position: bonuses for the king facing the opponent, being central, and having free adjacent squares; bonuses for pawns near the center or between the two kings; and laser coverage, a heuristic estimating how much of the board a side's laser could threaten from its possible moves.
Search: game trees, alpha-beta, and principal variation search (26:41)
The lecture builds up from a naive full game-tree search, explains quiescence search (extending search past captures to avoid stopping mid-exchange), then walks through a worked alpha-beta example showing how a beta cutoff lets a search skip entire subtrees, backed by the theorem that best-ordered alpha-beta search examines roughly b^(d/2) nodes instead of b^d. It then extends this to principal variation search, where cheap zero-window scout searches verify (or disprove) the assumption that the first move considered is best.
Search optimizations and correctness discipline (45:27)
The lecture surveys existing optimizations in the codebase: move ordering via a sort key, the transposition table with Zobrist hashing, killer-move and best-move tables, null-move pruning, futility pruning, late-move reduction, opening books, and endgame databases. The professor then emphasizes testing discipline for this large, non-trivial codebase: use fixed-depth, deterministic searches and node counts to verify optimizations haven't changed behavior, and keep old and new board representations running side by side during any migration so assertions can catch mismatches before removing the old code.
Live code walkthrough (55:39)
The session closes with a live look at eval.c and the UCI command interface in leiserchess.c, showing how heuristic weights can be tuned through UCI commands without recompiling, and how perft and depth-limited search reveal node counts useful for regression testing.
Before you watch
- Familiarity with alpha-beta pruning or minimax search from a prior algorithms course is helpful but not required, since the lecture explains it from scratch.
- Earlier lectures in this course on parallelism, races, and synchronization are directly relevant, since the final project parallelizes this search.
- This video assumes you have access to the course's Leiserchess project handout to follow the code references.
Check your understanding
- Why can naively killing an opposing pawn with the laser sometimes lose the game for the player who fired it?
- What problem does the Ko rule solve, and how does it do so?
- How does alpha-beta pruning reduce the number of nodes searched compared to a naive full-tree search, and why does move ordering matter for that reduction?
- What is the core idea behind principal variation search's "scout" (zero-window) searches, and when does it fall back to a full search?
- Why does the lecture recommend keeping both old and new board representations active during a migration, rather than replacing one outright?
Vocabulary
- codewalk (noun)
- A guided tour through a piece of software's code, explaining how it works.
This session is a codewalk through the Leiserchess reference implementation. - orientation (noun)
- The direction a piece is facing on the board.
Each piece's orientation determines which way its laser beam reflects. - swap move (noun)
- A move where a piece switches places with an opposing piece.
A swap move touches an opposing piece before continuing the turn. - Ko rule (noun)
- A rule that prevents a player from immediately reversing the opponent's last move.
The Ko rule, borrowed from Go, stops repeated back-and-forth moves. - scrimmage server (noun)
- A tool for running one-off matches between two programs to test them.
Students use the scrimmage server to test their bot against a friend's. - autotester (noun)
- A tool that automatically runs many test games and reports results.
The cloud autotester runs many games between different bot versions. - sentinel square (noun)
- An extra padding cell added around a board to make edge detection easier.
The 16x16 array uses sentinel squares to simplify off-board checks. - static evaluation (noun)
- Scoring a board position using fixed rules, without searching further moves.
Static evaluation gives a quick score without exploring future moves. - heuristic (noun)
- A practical scoring rule based on experience rather than exact calculation.
King mobility is one heuristic used in the evaluation function. - game tree (noun)
- A tree structure representing all possible sequences of moves in a game.
Searching the whole game tree is far too slow for a real game. - alpha-beta pruning (noun)
- A search technique that skips parts of a game tree that cannot affect the final decision.
Alpha-beta pruning lets the search skip branches that are already worse than the best found. - cutoff (noun)
- The point where a search stops exploring a branch because it can't improve the result.
A beta cutoff lets the search skip an entire subtree. - principal variation search (noun)
- A search method that assumes the first move is best and quickly checks the rest.
Principal variation search speeds up alpha-beta by verifying with cheap searches. - quiescence search (noun)
- Extra searching past captures so the evaluation doesn't stop in the middle of an exchange.
Quiescence search avoids evaluating a position right after a capture starts. - transposition table (noun)
- A memory structure that stores results of previously searched positions to avoid repeating work.
The transposition table avoids re-searching a position reached by a different move order. - Zobrist hashing (noun)
- A method for quickly computing a unique number representing a board position.
Zobrist hashing lets the transposition table look up positions quickly. - killer move (noun)
- A move that caused a cutoff earlier and is tried early again to find cutoffs faster.
The killer-move table helps order moves for earlier cutoffs. - null-move pruning (noun)
- A shortcut that skips a turn to quickly test if a position is already clearly good or bad.
Null-move pruning speeds up search by testing a hypothetical passed turn. - futility pruning (noun)
- Skipping moves that are unlikely to be good enough to matter, to save search time.
Futility pruning cuts off clearly weak moves before searching them fully. - late-move reduction (noun)
- Searching less-promising moves with reduced effort since they are less likely to be best.
Late-move reduction saves time on moves that are searched later in the list. - opening book (noun)
- A prepared set of known good moves for the start of a game.
The opening book helps the bot avoid weak early moves. - endgame database (noun)
- A precomputed table of perfect results for positions with few pieces remaining.
An endgame database gives exact answers for simple late-game positions. - Elo rating (noun)
- A number used to measure and compare the skill of players or programs based on game results.
Bots are ranked by Elo rating from many games rather than raw speed. - regression testing (noun)
- Testing that checks whether recent changes have broken previously working behavior.
Node counts from perft are used for regression testing after code changes. - perft (noun)
- A debugging function that counts all possible moves to a given search depth.
Perft confirms move generation hasn't changed after an optimization.
Chapters
- 0:00 <Untitled Chapter 1>
- 1:40 Leiserchess Board Game
- 2:15 General Gameplay
- 2:47 How to Move
- 3:00 Basic Moves
- 3:33 Swap Moves
- 3:59 Ko Rule
- 4:41 Draws
- 4:56 Time Control
- 6:52 Leiserchess Tactics
- 11:59 Algebraic Notation for Games
- 13:43 Leiserchess Scrimmage Server
- 15:34 Cloud Autotester
- 17:57 README
- 19:13 Java Autotester Configuration
- 19:51 Universal Chess Interface (UCI)
- 20:21 Elo Ratings
- 21:25 Webgui
- 21:58 Board Representation
- 23:15 Move Representation
- 24:02 Move Generation
- 24:26 Perft
- 25:07 Static Evaluation
- 25:38 King Heuristics
- 26:01 Pawn Heuristics
- 26:19 Distance Heuristics
- 26:58 Game Search Trees
- 28:08 Quiescence Search
- 28:51 Higher Depth Search = Better Al
- 29:13 Min-Max Search
- 29:58 Alpha-Beta Strategy
- 32:35 Alpha-Beta Analysis
- 33:22 Code for Alpha-Beta Pruning
- 42:25 Principal Variation Search Pruning
- 45:20 Move Ordering in Search
- 46:09 Transposition Table
- 46:34 Zobrist Hashing
- 47:17 Killer-Move Table
- 47:53 Best-Move Table
- 48:45 Futility Pruning
- 49:11 Late-Move Reduction
- 49:30 Opening Book
- 50:14 Endgame Database
- 50:49 Chess Programming
- 51:03 General Guidelines
From the YouTube description
MIT 6.172 Performance Engineering of Software Systems, Fall 2018
Instructor: Helen Xu
View the complete course: https://ocw.mit.edu/6-172F18
YouTube Playlist: https://www.youtube.com/playlist?list=PLUl4u3cNGP63VIBQVWguXxZZi0566y7Wf
This lecture is an introduction to Leiserchess and Project 4 of the course.
License: Creative Commons BY-NC-SA
More information at https://ocw.mit.edu/terms
More courses at https://ocw.mit.edu
← Lecture 18: Domain-Specific Languages and Autotuning · Lecture 20: Speculative Parallelism and Leiserchess →
