C SC 483 Chess and AI: Computation and...
Transcript of C SC 483 Chess and AI: Computation and...
Task 1 Report
• Report:– Come up and demo/describe what you did
• Task:– Set up graphical representation of chess board– allow you to set up chess positions– allow you to move pieces
• Lecture 3:– about a page of code
Chessboard
• Lecture 3:– I demoed a board
built using the Tktoolkit
– illustrating what theboard should be ableto do in terms ofsetup andrepresenting attacksetc.
– about one page ofcode
Chessboard• Besides setup and
move ability– it’s handy to have the
following functions definedover (arbitrary) bitboardsfor testing
– Example:highlight_bitboard [file_moves $r]
• print_bitboard(BB) # in hex• highlight_bitboard(BB) # marks bitboard BB using red background• unhighlight_bitboard(BB) # unmarks bitboard BB• also good to have rotated bitboard counterparts
Bitboards: Recap
• Behind the scenes:– use a 64-bit
bitboard torepresent wherepieces are
– Example:• initial position: black
pawns• 0x000000000000FF00
(hex)
byte1byte2byte3byte4byte5byte6byte7byte8
lsbmsb byte 1
byte 8
byte 2
byte 3byte 4
byte 5
byte 6
byte 7
Bitboards: Recap• initial position: black pawns 0x000000000000FF00 (hex)
hex 0hex 1
hex 2hex 3
hex 4hex 5
hex 6hex 7
hex 8hex 9
hex 10hex 11
hex 12hex 13
hex 14hex 15
hex15 hex14 hex13 hex12 hex6 hex5 hex3 hex0hex1hex2hex4hex7hex8hex9hex10hex11
Bitboards: Recap
• 12 bitboards, one foreach piece and color– k white king– K black king– q white queen– Q black queen– and so on...
• Bit Logic– white = k | q | r | b | n | p– black = K | Q | R | B | N | P– empty = ~ ( white | black )– occupied = white | black
• Initially:– k 0x0800000000000000– K 0x0000000000000008– q 0x1000000000000000– Q 0x0000000000000010– r 0x8100000000000000– R 0x0000000000000081– b 0x2400000000000000– B 0x0000000000000024– n 0x4200000000000000– N 0x0000000000000042– p 0x00FF000000000000– P 0x000000000000FF00
Bitboards: Recap
• Bitboard Masksrank8 = 0x00000000000000FFrank7 = 0x000000000000FF00rank6 = 0x0000000000FF0000rank5 = 0x00000000FF000000rank4 = 0x000000FF00000000rank3 = 0x0000FF0000000000rank2 = 0x00FF000000000000rank1 = 0xFF00000000000000rank12 = 0xFFFF000000000000rank78 = 0x000000000000FFFF
• Bitboard Masksfilea = 0x8080808080808080fileb = 0x4040404040404040filec = 0x2020202020202020filed = 0x1010101010101010filee = 0x0808080808080808filef = 0x0404040404040404fileg = 0x0202020202020202fileh = 0x0101010101010101fileab = 0xC0C0C0C0C0C0C0C0filegh = 0x0303030303030303
Bitboards: Recap• Pawn moves
– forward one rank (if notblocked) (bitparallel: all pawnsof a color)
– Bit LogicP << 8(or equivalently p >> 8)
– Combine with maskoperation: P_move1 = P << 8 &empty
– Bit Logic– forward two ranks if not moved
(and not blocked)P_move2 = ((P & rank7) << 8 & empty)<< 8 & empty
– Explanation:pick out only the black pawns on rank 7shift forward one rankmask out those not on empty squares(on rank 6)shift forward one more rankmask out those not on empty squares(on rank 5)
(we can then shift back 16 to discoverwhich of the pawns on rank 7 couldmove forward 2 ranks)
Bitboards: Recap• Pawn moves
– capture diagonallyP_captures = (((P & ~fileh) << 7 | (P & ~filea) << 9) )& white
• Masking at the edges
filehfilea
<<7<<9 <<7
Bitboards: Recap
• King moves– one step in any direction
to an empty square oropponent’s square (thatis not attacked)(excluding castling)
• Bit Logic:– let bb be the bitboard
associated with a king (black orwhite)
– define:k_moves(bb) = (bb & ~ rank8)>> 8 | (bb & ~ rank1) << 8 |(bb & ~ fileh) >> 1 | (bb & ~filea) << 1 | (bb & ~ ( rank8 |filea)) >> 7 | (bb & ~ ( rank8 |fileh)) >> 9 | (bb & ~ (rank1 |fileh )) << 7 | (bb & ~ (rank1 |filea )) << 9
white king: k_moves(k) & ~ whiteblack king: k_moves(K) & ~ black
>>8
<<8 <<7<<9
>>9>>7
>>1<<1
Bitboards: Recap• Without loss of generality
– can pre-computeking moves for eachpossible bitboard bb(set_k_moves)
– so k_moves functionbecomes an arraylookup
– 64 possible single bitbitboards
• k_moves(bb) = (bb & ~rank8) >> 8 | (bb & ~rank1) << 8 | (bb & ~fileh) >> 1 | (bb & ~filea) << 1 | (bb & ~ (rank8 | filea)) >> 7 | (bb& ~ ( rank8 | fileh)) >> 9| (bb & ~ (rank1 | fileh ))<< 7 | (bb & ~ (rank1 |filea )) << 9
Bitboards: Recap• k_moves(bb) array• 0x0000000000000001 -> 0x0000000000000302• 0x0000000000000002 -> 0x0000000000000705• 0x0000000000000004 -> 0x0000000000000e0a• 0x0000000000000008 -> 0x0000000000001c14• 0x0000000000000010 -> 0x0000000000003828• 0x0000000000000020 -> 0x0000000000007050• 0x0000000000000040 -> 0x000000000000e0a0• 0x0000000000000080 -> 0x000000000000c040• 0x0000000000000100 -> 0x0000000000030203• 0x0000000000000200 -> 0x0000000000070507• 0x0000000000000400 -> 0x00000000000e0a0e• 0x0000000000000800 -> 0x00000000001c141c• 0x0000000000001000 -> 0x0000000000382838• 0x0000000000002000 -> 0x0000000000705070• 0x0000000000004000 -> 0x0000000000e0a0e0• 0x0000000000008000 -> 0x0000000000c040c0• 0x0000000000010000 -> 0x0000000003020300• 0x0000000000020000 -> 0x0000000007050700• 0x0000000000040000 -> 0x000000000e0a0e00• 0x0000000000080000 -> 0x000000001c141c00• 0x0000000000100000 -> 0x0000000038283800• 0x0000000000200000 -> 0x0000000070507000• 0x0000000000400000 -> 0x00000000e0a0e000• 0x0000000000800000 -> 0x00000000c040c000
• 0x0000100000000000 -> 0x0038283800000000• 0x0000200000000000 -> 0x0070507000000000• 0x0000400000000000 -> 0x00e0a0e000000000• 0x0000800000000000 -> 0x00c040c000000000• 0x0001000000000000 -> 0x0302030000000000• 0x0002000000000000 -> 0x0705070000000000• 0x0004000000000000 -> 0x0e0a0e0000000000• 0x0008000000000000 -> 0x1c141c0000000000• 0x0010000000000000 -> 0x3828380000000000• 0x0020000000000000 -> 0x7050700000000000• 0x0040000000000000 -> 0xe0a0e00000000000• 0x0080000000000000 -> 0xc040c00000000000• 0x0100000000000000 -> 0x0203000000000000• 0x0200000000000000 -> 0x0507000000000000• 0x0400000000000000 -> 0x0a0e000000000000• 0x0800000000000000 -> 0x141c000000000000• 0x1000000000000000 -> 0x2838000000000000• 0x2000000000000000 -> 0x5070000000000000• 0x4000000000000000 -> 0xa0e0000000000000• 0x8000000000000000 -> 0x40c0000000000000
• 0x0000000100000000 -> 0x0000030203000000• 0x0000000200000000 -> 0x0000070507000000• 0x0000000400000000 -> 0x00000e0a0e000000• 0x0000000800000000 -> 0x00001c141c000000• 0x0000001000000000 -> 0x0000382838000000• 0x0000002000000000 -> 0x0000705070000000• 0x0000004000000000 -> 0x0000e0a0e0000000• 0x0000008000000000 -> 0x0000c040c0000000• 0x0000010000000000 -> 0x0003020300000000• 0x0000020000000000 -> 0x0007050700000000• 0x0000040000000000 -> 0x000e0a0e00000000• 0x0000080000000000 -> 0x001c141c00000000• 0x0000100000000000 -> 0x0038283800000000• 0x0000200000000000 -> 0x0070507000000000• 0x0000400000000000 -> 0x00e0a0e000000000• 0x0000800000000000 -> 0x00c040c000000000
Bitboards: Recap• Knight moves
– L-shaped pattern– same goes for knight moves,
we can pre-compute(set_n_moves)
• bit operations:
<<17 <<15
<<10 <<6
>>6 >>10
>>15 >>17
n_moves(bb) =(bb & ~ (rank1 | filegh)) << 6 | (bb & ~ (rank8 | filegh)) >> 10 | (bb & ~ (rank1 | fileab)) << 10 | (bb & ~ (rank8 | fileab)) >> 6 | (bb & ~ (rank12 | fileh)) << 15 | (bb & ~ (rank12 | filea)) << 17 | (bb & ~ (rank78 | fileh)) >> 17 | (bb & ~ (rank78 | filea)) >> 15
Bitboards: Recap• n_moves(bb) array• assuming single knight• 0x0000000000000001 -> 0x0000000000020400• 0x0000000000000002 -> 0x0000000000050800• 0x0000000000000004 -> 0x00000000000a1100• 0x0000000000000008 -> 0x0000000000142200• 0x0000000000000010 -> 0x0000000000284400• 0x0000000000000020 -> 0x0000000000508800• 0x0000000000000040 -> 0x0000000000a01000• 0x0000000000000080 -> 0x0000000000402000• 0x0000000000000100 -> 0x0000000002040004• 0x0000000000000200 -> 0x0000000005080008• 0x0000000000000400 -> 0x000000000a110011• 0x0000000000000800 -> 0x0000000014220022• 0x0000000000001000 -> 0x0000000028440044• 0x0000000000002000 -> 0x0000000050880088• 0x0000000000004000 -> 0x00000000a0100010• 0x0000000000008000 -> 0x0000000040200020• 0x0000000000010000 -> 0x0000000204000402• 0x0000000000020000 -> 0x0000000508000805• 0x0000000000040000 -> 0x0000000a1100110a• 0x0000000000080000 -> 0x0000001422002214
• 0x0000000000100000 -> 0x0000002844004428• 0x0000000000200000 -> 0x0000005088008850• 0x0000000000400000 -> 0x000000a0100010a0• 0x0000000000800000 -> 0x0000004020002040• 0x0000000001000000 -> 0x0000020400040200• 0x0000000002000000 -> 0x0000050800080500• 0x0000000004000000 -> 0x00000a1100110a00• 0x0000000008000000 -> 0x0000142200221400• 0x0000000010000000 -> 0x0000284400442800• 0x0000000020000000 -> 0x0000508800885000• 0x0000000040000000 -> 0x0000a0100010a000• 0x0000000080000000 -> 0x0000402000204000• 0x0000000100000000 -> 0x0002040004020000• 0x0000000200000000 -> 0x0005080008050000• 0x0000000400000000 -> 0x000a1100110a0000• 0x0000000800000000 -> 0x0014220022140000• 0x0000001000000000 -> 0x0028440044280000• 0x0000002000000000 -> 0x0050880088500000• 0x0000004000000000 -> 0x00a0100010a00000• 0x0000008000000000 -> 0x0040200020400000• 0x0000010000000000 -> 0x0204000402000000• and so on...
Rotated Bitboards
• Basic Idea:– positions in a rank are in the same byte– (assuming row major order as implemented)– we can perform computations or do lookup upon
one byte conveniently
– rotate the whole chessboard by -90 degrees, cando column major operations conveniently
– rotate the chessboard by -45 degrees or +45degrees, can do diagonal operations conveniently
lsbmsb byte 1
Rotated Bitboards• Sliding pieces:
– queen: rank, file, eitherdiagonal
– rook: rank, file– bishop: either diagonal
• Worked example:Rook– may move along file or
rank– extent: as far unoccupied– capture: opposing piece
on first non-empty squareon file or rank
• Example:
occupation pattern on rank8:(white & black) & rank8 = 11001010Note there are 28 = 256 possible bit patterns for a rank
possible attack squares 01110110can mask out white (later) to eliminate attacking own piece, as in:
Rotated Bitboards• Define function
rank(byte,position)– byte = occupation pattern
on the rank– position = position of
sliding piece on the rank(e.g. rook)
• Then– rank(byte,position)
returns a byte indicatingsquares to which piececould slide to
• Example:1 11 1 1
returns 11101100rank
pre-compute
Rotated Bitboards• Example:
Rank pattern and piece lookup(11110010,32) -> 01010000(10011110,16) -> 11101000(11000001,1) -> 01111110(11001011,1) -> 00000010(11001011,2) -> 00001101(00111000,32) -> 11010000(00110000,16) -> 00101111(01101100,64) -> 10100000(11110101,1) -> 00000110(11001011,8) -> 01110110(11110101,4) -> 00011011(11111010,64) -> 10100000(11111001,64) -> 10100000(01000000,64) -> 10111111(00100100,4) -> 00111011(11101010,32) -> 01011000(10010111,16) -> 11101100
(11100100,128) -> 01000000(01111011,1) -> 00000010(01111011,2) -> 00001101(00110000,32) -> 11010000(01001110,2) -> 00000101(01001110,4) -> 00001010(01100101,64) -> 10100000(10111100,128) -> 01100000(10100101,1) -> 00000110(01111011,8) -> 00010110(01001110,8) -> 01110100(10100101,4) -> 00111011(10011110,128) -> 01110000(11110010,64) -> 10100000(11011001,1) -> 00001110(10000000,128) -> 01111111(11100010,32) -> 01011110(11011010,16) -> 01101000
Rotated Bitboards
• Example:– on rank 7– white rook: 0x10 (= 16)– occupied: 11010001 (= 209)– rank(209,0x10) = 01101111
(= 111 or 0x6F)– convert byte back to
bitboard:0x6F << (8*(8-rank))
– i.e. 0x0000000000006F00
• board:
Rotated Bitboards
• Example:– on rank 7– white rook: 0x10 (= 16)– occupied: 11010001 (= 209)
same as before– rank(208,0x10) = 0x6F– Bit Logic:– white =
0x0000000000001100– (0x6F << 8) & ~ white
= 0x0000000000006E00
• board:
6 = 0110~1 = 1110& = 0110 = 6
F = 1111~1 = 1110& = 1110 = E
Rotated Bitboards• Note:
two rooks on the same rank• Example
– on rank 7– white rooks: 0x11 (= 17)– occupied: 11010001 (= 209)– lookup must be made for
each rook– Bit Logic:
(rank(209,0x10) |rank(209,0x01)) & ~ white
• board:
or you could pre-compute a larger array
Rotated Bitboards• Similarly, lookup must be
done disjunctively for rookson different ranks
– Bit Logic:– ((rank(209,0x10) << 8) |
(rank(8,0x08) << 24)) & ~white
• board:
Rotated Bitboards
• Rooks can also movealong a file– subject to the same look-
up constraints as therank case
– solution: maintain (inparallel) a 90° rotatedboard representation
– re-use the pre-computedrank array look-up withthe 90° rotated board forfile sliding cases
• Rotated board:
byte 8 byte 1
hex
0he
x 1
hex
14he
x 15
Rotated Bitboards
• Example:– white = 0x0000001000001000– black = 0x0000000000004400– r = 0x0000000000001000– let rwhite. rblack, rr be
rotated white, black and r,respectively
– rwhite = 0x0000004800000000– rblack = 0x0040000000400000– rr = 0x0000004000000000
• Board:
Rotated Bitboards• Rotated counterparts to regular
bitboards can be set up at pieceplacement time
• Example:return a bitboard with a bit set at (x,y)proc xytobitboard {x y} { return [format "0x%s%s" [tohex $x]
[string repeat "00" [expr $y - 1]]]}proc xytorbitboard {x y} { return [format "0x%s%s" [tohex $y]
[string repeat "00" [expr 8 - $x]]]}proc tohex {x} { switch $x {1 {return
"80"} 2 {return "40"} ... 7 {return"02"} 8 {return "01} } }
• regular board(1,1) (8,1)
(1,8) (8,8)
• rotated board (-90°)
(1,1)
(8,1) (8,8)
(1,8)
xy
Rotated Bitboards• Example:
Given– white = 0x0000001000001000– black = 0x0000000000004400– r = 0x0000000000001000– rank occupation = 01010100 =
0x54 = 84– position = 0x10 = 16
• Bit Logic:– rank_moves(r) = rank(84,16) << 8– = 01101100 << 8– = 0x6c << 8
= 0x0000000000006c00
• Board:
Rotated Bitboards• Example:
– Given– rwhite = 0x0000004800000000– rblack = 0x0040000000400000– rr = 0x0000004000000000– file occupation = 0x48 = 72– position = 0x40 = 64
• Bit Logic:– file_moves(rr) = rank(72,64) <<
32– = 10111000 << 32– = 0x000000b800000000– file_moves(rr) & ~ rwhite
• Board:1 0 1 1 1 0 0 0
lsb
msb
note the re-use of the pre-computed rank array
Rotated Bitboards• Summary
– simple case: 1 white rookin bitboard
– rank_moves(r) & ~ white– file_moves(rr) & ~ rwhite
multiple rooks on same file(different ranks)generalize functionsfile_moves andrank_moves as before
(see example on the right)
• Example:
Rotated Bitboards• Sliding pieces:
– queen: rank, file, eitherdiagonal
– rook: rank, file– bishop: either diagonal
• Key idea:– make diagonals consecutive
bits in rotated bitboard• Worked example: Bishop
– may move along eitherdiagonal
• leading diagonal (╲):
b0b1
b2
b3
b4
b5
b6
b7
2b0
2b1
2b2
2b3
2b4
2b5
2b6
2b7
3b0
2b7 2b6 2b5 2b4 b6 b5 b3 b0b1b2b4b72b02b12b22b3
(1,1) (8,1)
(1,8) (8,8)
Rotated Bitboards• leading and trailing diagonal bitboards
– maintained simultaneously with regularand 90° rotated bitboards
• Access diagonal– diagonal right shift (>>) length
1 0 12 1 23 3 34 6 45 10 56 15 67 21 78 28 89 36 710 43 611 49 512 54 413 58 314 61 215 63 1
• trailing diagonal (╱):
b0
b2
b1
b5
b4
b3
2b1
2b0
b7
b6
2b6
2b5
2b4
2b3
2b2 2b7
3b0
(1,1) (8,1)
(1,8) (8,8)