c sc 483 chess and ai: computation and...

33
C SC 483 Chess and AI: Computation and Cognition Lecture 4 September 17th

Upload: trinhcong

Post on 29-Apr-2018

217 views

Category:

Documents


3 download

TRANSCRIPT

C SC 483Chess and AI: Computation

and CognitionLecture 4

September 17th

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

• If you didn’t present this time,• please bring laptop etc. to present next

time

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

Task 2

• Compute possible legal moves andattacks

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)