20
Anthony Cozzie

Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

Embed Size (px)

Citation preview

Page 1: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

Anthony Cozzie

Page 2: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

• Quite possibly the nerdiest activity in the world

• But actually more fun than human chess• Zappa

o alpha-beta searcher, with a lot of trickso World Computer Chess Champion 2005o Much, much better than Deep Blue

Page 3: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

• Key move Nxh6• Novag Diablo: 7.5

monthso 1991, 16MHz 16-bits

• Deep Blue: 6 hours• Zappa: 2 minutes

Page 4: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

• Key move Nxe6• TASC R30: 1

montho 1993, 30MHz ARMo Chessmaster engine

• Deep Blue: 2.5 hours

• Zappa: 1 minute

Page 5: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

• Key move axb5• TASC R30:

centuries• Deep Blue: gave up

o (more system time than they cared to use, they estimated at a few days)

• Zappa: 10 minutes

Page 6: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

• Will feel like a collection of tricks• Search (tweaks to alpha-beta)

o Move orderingo Extensionso Forward Pruningo Branching factor 2-3 instead of sqrt(35)

• Evaluationo Automatic tuning

Page 7: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

• When do we stop searching?• Depth 1: capture the biggest piece we

can, regardless of whether opponent can recapture

• Qsearch: try captures, checks, check evasionso No depth parametero Can stand pat (terminate if eval>beta)o Prune stupid captures

Page 8: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

• Big hash table storing the results of the search

• Prevents engine from researching the same position (still exponential time, though)o 1. e4 d6 2. d4o 1. d4 d6 2. e4

• 64-bit key Zobrist hash key o (hashA1[pieceA1] ^ hashA2[pieceA2] ^ … )

Page 9: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

• The fine print of alpha-beta: “Thou must search thy best move first”

• Iterative deepening• Store best move transposition (hash) table• History heuristic:

o Table[piece-type][start-square][dest-square]o Increment when move fails high

• Result: 93% of fail highs occur on the first move

Page 10: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

• What happens if we search at the root with a smaller window?

• Alphabeta(a, a+1) is score > a?o All over the place in chess engines

• Aspirated alpha beta (change root score)• MTD(f): continue to try zero-window

searches until a goal is reachedo (not in Zappa)

Page 11: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

int NegaScout ( position p; int alpha, beta ) { /* compute minimax value of position p */ int a, b, t, i; if ( d == maxdepth ) return Evaluate(p); /* leaf node */ determine successors p_1,...,p_w of p; a = alpha; b = beta; for ( i = 1; i <= w; i++ ) { t = -NegaScout ( p_i, -b, -a ); if ( (t > a) && (t < beta) && (i > 1) && (d < maxdepth-1) ) a = -NegaScout ( p_i, -beta, -t ); /* re-search */ a = max( a, t ); if ( a >= beta ) return a; /* cut-off */ b = a + 1; /* set new null window */ } return a; }

int NegaScout ( position p; int alpha, beta ) { /* compute minimax value of position p */ int a, b, t, i; if ( d == maxdepth ) return Evaluate(p); /* leaf node */ determine successors p_1,...,p_w of p; a = alpha; b = beta; for ( i = 1; i <= w; i++ ) { t = -NegaScout ( p_i, -b, -a ); if ( (t > a) && (t < beta) && (i > 1) && (d < maxdepth-1) ) a = -NegaScout ( p_i, -beta, -t ); /* re-search */ a = max( a, t ); if ( a >= beta ) return a; /* cut-off */ b = a + 1; /* set new null window */ } return a; }

int NegaScout ( position p; int alpha, beta ) { /* compute minimax value of position p */ int a, b, t, i; if ( d == maxdepth ) return Evaluate(p); /* leaf node */ determine successors p_1,...,p_w of p; a = alpha; b = beta; for ( i = 1; i <= w; i++ ) { t = -NegaScout ( p_i, -b, -a ); if ( (t > a) && (t < beta) && (i > 1) && (d < maxdepth-1) ) a = -NegaScout ( p_i, -beta, -t ); /* re-search */ a = max( a, t ); if ( a >= beta ) return a; /* cut-off */ b = a + 1; /* set new null window */ } return a; }

int NegaScout ( position p; int alpha, beta ) { /* compute minimax value of position p */ int a, b, t, i; if ( d == maxdepth ) return Evaluate(p); /* leaf node */ determine successors p_1,...,p_w of p; a = alpha; b = beta; for ( i = 1; i <= w; i++ ) { t = -NegaScout ( p_i, -b, -a ); if ( (t > a) && (t < beta) && (i > 1) && (d < maxdepth-1) ) a = -NegaScout ( p_i, -beta, -t ); /* re-search */ a = max( a, t ); if ( a >= beta ) return a; /* cut-off */ b = a + 1; /* set new null window */ } return a; }

int NegaScout ( position p; int alpha, beta ) { /* compute minimax value of position p */ int a, b, t, i; if ( d == maxdepth ) return Evaluate(p); /* leaf node */ determine successors p_1,...,p_w of p; a = alpha; b = beta; for ( i = 1; i <= w; i++ ) { t = -NegaScout ( p_i, -b, -a ); if ( (t > a) && (t < beta) && (i > 1) && (d < maxdepth-1) ) a = -NegaScout ( p_i, -beta, -t ); /* re-search */ a = max( a, t ); if ( a >= beta ) return a; /* cut-off */ b = a + 1; /* set new null window */ } return a; }

int NegaScout ( position p; int alpha, beta ) { /* compute minimax value of position p */ int a, b, t, i; if ( d == maxdepth ) return Evaluate(p); /* leaf node */ determine successors p_1,...,p_w of p; a = alpha; b = beta; for ( i = 1; i <= w; i++ ) { t = -NegaScout ( p_i, -b, -a ); if ( (t > a) && (t < beta) && (i > 1) && (d < maxdepth-1) ) a = -NegaScout ( p_i, -beta, -t ); /* re-search */ a = max( a, t ); if ( a >= beta ) return a; /* cut-off */ b = a + 1; /* set new null window */ } return a; }

int NegaScout ( position p; int alpha, beta ) {/* compute minimax value of position p */ int a, b, t, i;if ( d == maxdepth ) return Evaluate(p); /* leaf node */ determine successors p_1,...,p_w of p; a = alpha; b = beta; for ( i = 1; i <= w; i++ ) { t = -NegaScout ( p_i, -b, -a ); if ( (t > a) && (t < beta) && (i > 1) && (d < maxdepth-1) ) a = -NegaScout ( p_i, -beta, -t ); /* re-search */ a = max( a, t ); if ( a >= beta ) return a; /* cut-off */ b = a + 1; /* set new null window */ } return a; }

int NegaScout ( position p; int alpha, beta ) { /* compute minimax value of position p */ int a, b, t, i; if ( d == maxdepth ) return Evaluate(p); /* leaf node */ determine successors p_1,...,p_w of p; a = alpha; b = beta; for ( i = 1; i <= w; i++ ) { t = -NegaScout ( p_i, -b, -a ); if ( (t > a) && (t < beta) && (i > 1) && (d < maxdepth-1) ) a = -NegaScout ( p_i, -beta, -t ); /* re-search */ a = max( a, t ); if ( a >= beta ) return a; /* cut-off */ b = a + 1; /* set new null window */ } return a; }

int NegaScout ( position p; int alpha, beta ) { /* compute minimax value of position p */ int a, b, t, i; if ( d == maxdepth ) return Evaluate(p); /* leaf node */ determine successors p_1,...,p_w of p; a = alpha; b = beta; for ( i = 1; i <= w; i++ ) { t = -NegaScout ( p_i, -b, -a ); if ( (t > a) && (t < beta) && (i > 1) && (d < maxdepth-1) ) a = -NegaScout ( p_i, -beta, -t ); /* re-search */ a = max( a, t ); if ( a >= beta ) return a; /* cut-off */ b = a + 1; /* set new null window */ } return a; }

Page 12: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

• Having the move is usually good in chess• If we can skip our turn and still win, we will

win bigger without skipping• Depth reduction R, usually 2/3 or 3

o Cut a depth 10 search if we could skip our turn and still win with a depth 6 search

• Worth a few plies of search depth

Page 13: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

• Short-Timman• Search looks like:

Kh2 NULL Kg3 NULL Kf4 NULL Kg5 NULL Kh6 NULL Qg7 (10 + 5R = 25 ply)

Page 14: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

• Suppose Zappa searches o A B C D E F G with score 0.1o A B C D E F G H with score -1

• Can play different moves instead of A C E Go Deeper search implies more places to

change!o Alpha-beta is completely blind to whether

alternatives are OK or terrible

Page 15: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

• One move is much better than the alternativeso Classic example; QxQ PxQ

• Check with additional searches of (d-m, m usually 4-5 ply)o Costs nodes because normally at cut nodes we

only search one move• Originally done by Deep Blue team

Page 16: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

• Count pieceso Standard chess weights are 1/3/3/5/9o Zappa uses 1/4/4/6/12

• Chess is easier than Goo Smaller branching factor (35 moves vs 200)o Material is the #1 term in the evaluation

Page 17: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

• Count squares a piece can attack

• Queen > Bishop because queen attacks more squares

• Potentially move wins

• Random eval works!

Page 18: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

• Pretty chess specific• Two connected passed pawns on the 6th

rank are worth about a rook to Zappa• A king with no pawn protection is about 1-

2 pawnso Rises to 5+ when attacked by a bunch of

pieces• About 1000 heuristics, 5,000 terms.

Page 19: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

• Very annoying to tune by hando Fix one position, break another

• Have some test, use genetic programming or simulated annealing

• Problem is it takes ~50,000 games to determine a few elo improvement

• Open problem• Also: automatically generating new terms

Page 20: Anthony Cozzie. Quite possibly the nerdiest activity in the world But actually more fun than human chess Zappa o alpha-beta searcher, with a lot of tricks

• Just ideas discussed here gives you a super-GM strength program

• http://chessprogramming.wikispaces.com/• But be careful, because computer chess is

surprisingly addictive