Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Chess Engine Programming

Arno Huetter
September 27, 2018

Chess Engine Programming

Arno Huetter

September 27, 2018
Tweet

More Decks by Arno Huetter

Other Decks in Programming

Transcript

  1. About the Author Arno Huetter I wrote my first lines

    of code on a Sinclair ZX80 in 1984. My daytime job is at Dynatrace, where I work as Development Lead. Being a history buff in general, I also enjoy reading and writing about computer history.
  2. A brief History • Chess originated in 6th century India

    • 1770: Wolfgang von Kempelen's Mechanical Turk • 1928: John von Neumann describes MiniMax • 1948-51: Alan Turing's Turochamp / Paper Machine, later on Mark1 (2012: Kasparov vs. Turochamp, Kasparov wins in 15 moves) • 1950: Claude Shannon publishes "Programming a Computer for Playing Chess", builds limited relay chess machine • 1957: Bernstein Chess on IBM 704 • 1978: Ken Thompson's Belle • 1983: 1K ZX Chess
  3. A brief History • 1997: IBM's Deep Blue beats Gary

    Kasparov 3.5 : 2.5 • In 1996 Kasparov had won 4 : 2 • 32 node IBM RS/6000, 120 MHz P2SC + 8 VLSI chips per node for MiniMax / Alpha-Beta Pruning • 32GB transposition table • 200m moves / sec, Ply 8-12, ELO 2750 • 2002-2006: Hydra Project • FPGA-based, Dr. Christian Donninger (AT / JKU), similar to Deep Blue, 150m moves / sec • 2014: StockFish Computer Chess World Champion • 70m moves / sec on off-the-shelf hardware, Ply 20-45 (much better ordering/pruning), ELO 3400 • 1TB transposition table
  4. A brief History • 2017: AlphaZero Chess wins against StockFish

    • 28 wins, 72 draws, 0 losses • Controversy: StockFish on limited hardware (8 CPUs), too many threads for the HW (64), wrong time management settings and too small transposition table memory • AlphaZero running on 5000 1st gen TPUs to generate self-played games + 64 2nd gen TPUs (45 TFLOPS each) to train neural network (only 4 TPUs used) • Residual neural network, two outputs: board evaluation and move evaluation • Blank state reinforcement learning, playing against itself (nothing supervised from human chess history / knowledge) • Monte Carlo Tree Search (instead of MiniMax): expanding by applying board/move evaluations • 80k moves / sec, est. ELO 3750 Source: (8)
  5. Chess Engine Fundamentals • Board Representation • BitBoards • Evaluation

    Function • Material / Position / Mobility • MiniMax Algorithm • Search tree backtracking algorithm, minimize possible loss (expect opponent to make best possible move) • Move Generator / Iterator • Alpha-Beta Pruning • Decrease number of node evaluations in search tree • Opening Book • Performance Tuning
  6. BitBoards • 64bit int / bitmask • 1 bitboard for

    every piece-type and color => 12 bitboards for board state • Compact representation, perfect for bitwise operations, CPU pipelining • Used for lookup tables, bitmasks, move and attack tables, etc. // A pawn is backward when it is behind all pawns of the same color // on the adjacent files and cannot be safely advanced. backward = !(ourPawns & PawnAttackSpan[Them][s + Up]) && (stoppers & (leverPush | (s + Up))); Source: (10)
  7. Evaluation Mobility MobilityBonus[][32] = { // snip { S(-75,-76), S(-56,-54),

    S( -9,-26), S( -2,-10), S( 6, 5), S( 15, 11), // Knights S( 22, 26), S( 30, 28), S( 36, 29) }, // snip { S(-40,-35), S(-25,-12), S( 2, 7), S( 4, 19), S( 14, 37), S( 24, 55), // Queens S( 25, 62), S( 40, 76), S( 43, 79), S( 47, 87), S( 54, 94), S( 56,102), S( 60,111), S( 70,116), S( 72,118), S( 73,122), S( 75,128), S( 77,130), S( 85,133), S( 94,136), S( 99,140), S(108,157), S(112,158), S(113,161), S(118,174), S(119,177), S(123,191), S(128,199) } }; Source: (10)
  8. Move Generator • The Move Generator creates a list of

    legal moves or pseudo-legal moves (check not considered) • MiniMax usually just invokes a PickMove() method within a loop, which encapsulates move generation and iteration. After a move is applied, MiniMax calls itself again for the next ply. • Moves are often created lazily during iteration - in anticipation that early cutoffs will likely happen within the first few moves, and no unnecessary move generation work is done.
  9. Horizon Effects / Quiescence Search • Evaluation should always happen

    on "quiet positions, e.g. not immediately after a capture or a check. • This avoids erroneous move selection due to Horizon Effects, which are overly optimistic evaluations due to the fact that negative consequences are looming beyond the maximum search depth (or also pessimistic evaluations, in case of positive consequences). • Horizon effects can also lead to suicidal moves, e.g. sacrificing more pieces for material that is already lost for certain anyway, but is obscured as the certain loss is thus moved behind the horizon by the sacrifice. • Quiescence Search adds additional noisy moves (=capture moves, possibly also promotions and check-replies) on unstable positions at the end of the search tree, until no more captures are possible. This then prevents horizon effects.
  10. Alpha-Beta Pruning • Developed independently by several researchers in the

    1950s. 1975: Donald Knuth: "An Analysis of Alpha-Beta Pruning" • Allows for ignoring paths not worth evaluating - just what the human mind does intuitively (ignoring moves that don't make sense) • Alpha: min. score for maximizing player - lower bound • Beta: max. score for minimizing player - upper bound • Alpha and beta are passed up and down during search tree traversal. Nodes outside those bounds don't need to be traversed ("cutoff"), and we can safely return prematurely. Savings: Source: (12)
  11. Move Ordering What if we would have found board evaluation

    "6" earlier in the example, instead of "3"? For Alpha-Beta pruning to perform well, the (supposedly) best moves must be searched first => early cutoff 1. Order according to previous depth-limited search results (see: Iterative deepening) 2. Hash move (if cached via transposition table, previous best move on same board or at least good enough to trigger cutoffs) 3. Winning captures (MVV-LVA: Most Valuable Victim - Least Valuable Aggressor), including pawn promotions 4. Killer moves (which caused earlier cutoffs at the same ply) 5. Quiet moves (sorted by positional delta) 6. Losing captures / opponent captures
  12. Transposition Tables Store and re-use results of previous searches via

    large Hashtable • Key: board representation, e.g. 64bit Zobrist hash • Zobrist hash: based on 12 (piece type) x 64 (positions) = 768 64bit random numbers. XOR hashes when pieces are moved => rapid incremental hash calculation • Value: depth, evaluation (exact, lower bound, upper bound), best move, depth Collision detection: check if stored move is pseudo-legal move Applied for • Re-using cached evaluations (check on each node before deeper search) • Move ordering (hash move)
  13. Iterative Deepening • Run depth-first search repeatedly with ever- increasing

    depths • Originally for time management reasons (has searched all moves, albeit not with the same depth, and can provide a good-enough intermediate result when time runs out) • Evaluations and best moves from previous runs can then be retrieved per transposition table • Return cached exact evaluations straight away, or adjust alpha/beta on cached bound evaluations • Apply caches hash moves for quick cutoffs in follow-up-run Source: (1)
  14. There is more… • NegaMax (simplified MiniMax implementation) • Incremental…

    • … Calculations (board hash (Zobrist), attack tables, etc) • … Move Generator • … Evaluation • Aspiration Windows • Principal Variation Search (assuming first node is best, search rest with a null window, rerun with normal window if needed) • Futility Pruning, Late Move Reduction (in combinatioin with PVS) • Null-Moves (unless under "Zugzwang") • King Safety / Pawn Storms / Open Files • Piece Square Table interpolation depending on game stage (midgame vs. endgame) • Static Exchange Evaluation
  15. Tools and Protocols • Arena - Free Chess GUI (http://www.playwitharena.com/)

    • Universal Chess Interface (UCI) enables chess engines to communicate with user interfaces • Let two chess engines play against each other • Lichess (https://lichess.org/) • Great chess platform, online community, StockFish in browser, board editor/analysis • Forsyth–Edwards Notation (FEN) • Board position data • 1rbqkb2/2p2p1p/p1p1pp2/8/3P4/P1NQpP2/1PP3rP/2KR2NR w - - 0 13 • Portable Game Notation (PGN) • Chess game recording • 1. e4 e6 2. d4 d5 3. Nc3 dxe4 4. a3 Nc6 5. Bb5 Nf6 6. Be3 a6 7. Bxc6+ bxc6 8. Bg5 Rb8 9. Bxf6 gxf6 10. f3 e3 11. Qd3 Rg8 12. O-O-O
  16. Sources (1) https://www.chessprogramming.org/ (2) https://en.chessbase.com/post/reconstructing-turing-s-paper-machine (3) https://thebestschools.org/magazine/brief-history-of-computer-chess/ (4) https://www.eff.org/ai/metrics (5)

    https://www.slideshare.net/carlosjustiniano2/how-computers-play-chess-26552933 (6) https://medium.freecodecamp.org/simple-chess-ai-step-by-step-1d55a9266977 (7) http://members.home.nl/matador/Inside%20Rebel.pdf (8) https://www.chess.com/article/view/how-does-alphazero-play-chess (9) https://www.chess.com/article/view/whats-inside-alphazeros-brain (10) https://github.com/official-stockfish/Stockfish (11) https://en.wikipedia.org/wiki/Minimax (12) https://en.wikipedia.org/wiki/Alpha%E2%80%93beta_pruning (13) http://www.dcc.fc.up.pt/~fds/aulas/PPD/1314/project3.html