diff --git a/Assets/pieces/bB.png b/Assets/pieces/bB.png new file mode 100644 index 0000000..e04fd34 Binary files /dev/null and b/Assets/pieces/bB.png differ diff --git a/Assets/pieces/bK.png b/Assets/pieces/bK.png new file mode 100644 index 0000000..504ad05 Binary files /dev/null and b/Assets/pieces/bK.png differ diff --git a/Assets/pieces/bN.png b/Assets/pieces/bN.png new file mode 100644 index 0000000..796f5b9 Binary files /dev/null and b/Assets/pieces/bN.png differ diff --git a/Assets/pieces/bP.png b/Assets/pieces/bP.png new file mode 100644 index 0000000..008e41d Binary files /dev/null and b/Assets/pieces/bP.png differ diff --git a/Assets/pieces/bQ.png b/Assets/pieces/bQ.png new file mode 100644 index 0000000..e07515a Binary files /dev/null and b/Assets/pieces/bQ.png differ diff --git a/Assets/pieces/bR.png b/Assets/pieces/bR.png new file mode 100644 index 0000000..38fd8ca Binary files /dev/null and b/Assets/pieces/bR.png differ diff --git a/Assets/pieces/wB.png b/Assets/pieces/wB.png new file mode 100644 index 0000000..3f4f0a2 Binary files /dev/null and b/Assets/pieces/wB.png differ diff --git a/Assets/pieces/wK.png b/Assets/pieces/wK.png new file mode 100644 index 0000000..968cb33 Binary files /dev/null and b/Assets/pieces/wK.png differ diff --git a/Assets/pieces/wN.png b/Assets/pieces/wN.png new file mode 100644 index 0000000..d0a64e2 Binary files /dev/null and b/Assets/pieces/wN.png differ diff --git a/Assets/pieces/wP.png b/Assets/pieces/wP.png new file mode 100644 index 0000000..fa3708a Binary files /dev/null and b/Assets/pieces/wP.png differ diff --git a/Assets/pieces/wQ.png b/Assets/pieces/wQ.png new file mode 100644 index 0000000..14694ae Binary files /dev/null and b/Assets/pieces/wQ.png differ diff --git a/Assets/pieces/wR.png b/Assets/pieces/wR.png new file mode 100644 index 0000000..6574bbd Binary files /dev/null and b/Assets/pieces/wR.png differ diff --git a/CHESS-AI/__pycache__/chessboard.cpython-39.pyc b/CHESS-AI/__pycache__/chessboard.cpython-39.pyc index eb2bb29..a958a48 100644 Binary files a/CHESS-AI/__pycache__/chessboard.cpython-39.pyc and b/CHESS-AI/__pycache__/chessboard.cpython-39.pyc differ diff --git a/CHESS-AI/chessboard.py b/CHESS-AI/chessboard.py index 8cc943a..25f61a7 100644 --- a/CHESS-AI/chessboard.py +++ b/CHESS-AI/chessboard.py @@ -1,6 +1,7 @@ import struct import numpy as np import json +import copy class Board: @@ -57,6 +58,10 @@ def __init__(self): } self.enpassant = 0 + self.WKingCastle = True + self.WQueenCastle = True + self.BKingCastle = True + self.BQueenCastle = True # function that takes self.board from the Board object and populates self.bitboards @@ -389,6 +394,95 @@ def queenMovesGen(self, index): def makeMove(self, start, end, lookingForward=False): if lookingForward or 0b1 << end & self.legalMoves(start): + + if 0b1 << start & self.bitboards['k'] : + if end == 62 and self.BKingCastle: + + #update rook position + self.bitboards[self.board[63]] = self.toggleBit(self.toggleBit(self.bitboards[self.board[63]], 63), 61) + self.board[61], self.board[63] = self.board[63], "." + + #update king position + self.bitboards[self.board[start]] = self.toggleBit(self.toggleBit(self.bitboards[self.board[start]], start), end) + self.board[end], self.board[start] = self.board[start], "." + # update the bitboards of white and black pieces + self.bitboards["white"] = self.bitboards['B'] | self.bitboards['N'] | self.bitboards[ + 'R'] | self.bitboards['Q'] | self.bitboards['P'] | self.bitboards["K"] + self.bitboards["black"] = self.bitboards['b'] | self.bitboards['n'] | self.bitboards[ + 'r'] | self.bitboards['q'] | self.bitboards['p'] | self.bitboards['k'] + + self.BKingCastle = False + self.BQueenCastle = False + return + + elif end == 58 and self.BQueenCastle: + #update rook position + self.bitboards[self.board[56]] = self.toggleBit(self.toggleBit(self.bitboards[self.board[56]], 56), 59) + self.board[59], self.board[56] = self.board[56], "." + #update king position + self.bitboards[self.board[start]] = self.toggleBit(self.toggleBit(self.bitboards[self.board[start]], start), end) + self.board[end], self.board[start] = self.board[start], "." + # update the bitboards of white and black pieces + self.bitboards["white"] = self.bitboards['B'] | self.bitboards['N'] | self.bitboards[ + 'R'] | self.bitboards['Q'] | self.bitboards['P'] | self.bitboards["K"] + self.bitboards["black"] = self.bitboards['b'] | self.bitboards['n'] | self.bitboards[ + 'r'] | self.bitboards['q'] | self.bitboards['p'] | self.bitboards['k'] + + self.BKingCastle = False + self.BQueenCastle = False + return + + elif 0b1 << start & self.bitboards['K']: + if end == 6 and self.WKingCastle: + #update rook position + self.bitboards[self.board[7]] = self.toggleBit(self.toggleBit(self.bitboards[self.board[7]], 7), 5) + self.board[5], self.board[7] = self.board[7], "." + + #update king position + self.bitboards[self.board[start]] = self.toggleBit(self.toggleBit(self.bitboards[self.board[start]], start), end) + self.board[end], self.board[start] = self.board[start], "." + # update the bitboards of white and black pieces + self.bitboards["white"] = self.bitboards['B'] | self.bitboards['N'] | self.bitboards[ + 'R'] | self.bitboards['Q'] | self.bitboards['P'] | self.bitboards["K"] + self.bitboards["black"] = self.bitboards['b'] | self.bitboards['n'] | self.bitboards[ + 'r'] | self.bitboards['q'] | self.bitboards['p'] | self.bitboards['k'] + + self.WKingCastle = False + self.WQueenCastle = False + return + elif end == 2 and self.WQueenCastle: + #update rook position + self.bitboards[self.board[0]] = self.toggleBit(self.toggleBit(self.bitboards[self.board[0]], 0), 3) + self.board[3], self.board[0] = self.board[0], "." + #update king position + self.bitboards[self.board[start]] = self.toggleBit(self.toggleBit(self.bitboards[self.board[start]], start), end) + self.board[end], self.board[start] = self.board[start], "." + # update the bitboards of white and black pieces + self.bitboards["white"] = self.bitboards['B'] | self.bitboards['N'] | self.bitboards[ + 'R'] | self.bitboards['Q'] | self.bitboards['P'] | self.bitboards["K"] + self.bitboards["black"] = self.bitboards['b'] | self.bitboards['n'] | self.bitboards[ + 'r'] | self.bitboards['q'] | self.bitboards['p'] | self.bitboards['k'] + + self.WKingCastle = False + self.WQueenCastle = False + return + + if 0b1 << start & self.bitboards['K']: + self.WKingCastle = False + self.WQueenCastle = False + elif 0b1 << start & self.bitboards['k']: + self.BKingCastle = False + self.BQueenCastle = False + elif 0b1 << start & self.bitboards['r'] & self.fileMasks[0]: + self.BQueenCastle = False + elif 0b1 << start & self.bitboards['r'] & self.fileMasks[7]: + self.BKingCastle = False + elif 0b1 << start & self.bitboards['R'] & self.fileMasks[0]: + self.WQueenCastle = False + elif 0b1 << start & self.bitboards['R'] & self.fileMasks[7]: + self.WKingCastle = False + + if 0b1 << start & self.bitboards['p']: if start // 8 == 6 and end // 8 == 4: self.enpassant = 0b1 << (end + 8) @@ -483,11 +577,18 @@ def legalMoves(self, index): while tempBb > 0: end = self.bitboard2Index(tempBb) + prevBoard = copy.deepcopy(self.board) prevBoardStart, prevBoardEnd = self.board[index], self.board[end] #Storing initial board and piece bitboards - prevStartBb = self.bitboards[self.board[index]] - prevEndPiece = self.board[end] + prevStartBb = self.bitboards[self.board[index]] + prevEndPiece = self.board[end] # do this for rook + + + prevWhiteRookBb = self.bitboards["R"] + prevBlackRookBb = self.bitboards["r"] + prevWhiteBb = self.bitboards["white"] prevBlackBb = self.bitboards["black"] + prevBKCastle, prevBQCastle, prevWKCastle, prevWQCastle = self.BKingCastle, self.BQueenCastle, self.WKingCastle, self.WQueenCastle prevEnpassant = self.enpassant didEnpassant = 0 # 0 for no, 1 for white, -1 for black @@ -514,6 +615,9 @@ def legalMoves(self, index): self.board[index] = prevBoardStart # restoring board and piece bitboards to initial positions self.bitboards[self.board[index]] = prevStartBb + self.BKingCastle, self.BQueenCastle, self.WKingCastle, self.WQueenCastle = prevBKCastle, prevBQCastle, prevWKCastle, prevWQCastle + + if didEnpassant < 0: self.board[end] = '.' self.board[end + 8] = prevBoardEnd @@ -528,11 +632,49 @@ def legalMoves(self, index): else: self.board[end] = '.' self.bitboards[end] = 0 + + self.enpassant = prevEnpassant + self.bitboards["R"] = prevWhiteRookBb + self.bitboards["r"] = prevBlackRookBb self.bitboards["white"] = prevWhiteBb self.bitboards["black"] = prevBlackBb - self.enpassant = prevEnpassant + self.board = prevBoard tempBb = self.toggleBit(tempBb, end) return legalBb + + def castleMoves(self, index, isBlack): + + BKingCastleMask = 6917529027641081856 + BQueenCastleMask = 1008806316530991104 + BQueenCheckMask = 864691128455135232 + + WKingCastleMask = 96 + WQueenCastleMask = 14 + WQueenCheckMask = 12 + + castleBb = 0; + occBb = self.bitboards['white'] | self.bitboards['black'] + + if isBlack: + atkedSquares = self.attackedSquares('white') + if self.BKingCastle: + if (not (BKingCastleMask & occBb)) and not ((0b1 << index | BKingCastleMask) & atkedSquares): + castleBb |= (0b1 << (index + 2)) + if self.BQueenCastle: + if (not (BQueenCastleMask & occBb)) and not ((0b1 << index | BQueenCheckMask) & atkedSquares): + castleBb |= (0b1 << (index -2)) + else: + atkedSquares = self.attackedSquares('black') + if self.WKingCastle: + if (not (WKingCastleMask & occBb)) and not ((0b1 << index | WKingCastleMask) & atkedSquares): + castleBb |= (0b1 << (index + 2)) + if self.WQueenCastle: + if (not (WQueenCastleMask & occBb)) and not ((0b1 << index | WQueenCheckMask) & atkedSquares): + castleBb |= (0b1 << (index -2)) + + return castleBb + + # Returns a bitboard of the pseudovalid moves a piece could make at the given index. # wrapper function for all the move bitboard generators @@ -549,7 +691,7 @@ def pseudovalidMoves(self, index): elif temp == "r": return self.rookAttack(index, True) elif temp == "k": - return self.validKingMoves(index, True) + return self.validKingMoves(index, True) | self.castleMoves(index, True) elif temp == "P": return self.pawnMoves(index) elif temp == "N": @@ -561,7 +703,7 @@ def pseudovalidMoves(self, index): elif temp == "R": return self.rookAttack(index, False) elif temp == "K": - return self.validKingMoves(index, False) + return self.validKingMoves(index, False) | self.castleMoves(index, False) else: return 0 @@ -689,6 +831,10 @@ def attackedSquares(self, color): attacked |= 0b1 << (index - 9) else: attacked |= 0b1 << (index - 7) | 0b1 << (index - 9) + elif 0b1 << index & self.bitboards['k'] : + attacked |= self.validKingMoves(index, True) + elif 0b1 << index & self.bitboards['K']: + attacked |= self.validKingMoves(index, False) else: attacked |= self.pseudovalidMoves(index) return attacked diff --git a/preloadedData.json b/preloadedData.json new file mode 100644 index 0000000..105b9e5 --- /dev/null +++ b/preloadedData.json @@ -0,0 +1,129 @@ +{ + "fileRank": [ + ["a", 1], ["b", 1], ["c", 1], ["d", 1], ["e", 1], ["f", 1], ["g", 1], ["h", 1], + ["a", 2], ["b", 2], ["c", 2], ["d", 2], ["e", 2], ["f", 2], ["g", 2], ["h", 2], + ["a", 3], ["b", 3], ["c", 3], ["d", 3], ["e", 3], ["f", 3], ["g", 3], ["h", 3], + ["a", 4], ["b", 4], ["c", 4], ["d", 4], ["e", 4], ["f", 4], ["g", 4], ["h", 4], + ["a", 5], ["b", 5], ["c", 5], ["d", 5], ["e", 5], ["f", 5], ["g", 5], ["h", 5], + ["a", 6], ["b", 6], ["c", 6], ["d", 6], ["e", 6], ["f", 6], ["g", 6], ["h", 6], + ["a", 7], ["b", 7], ["c", 7], ["d", 7], ["e", 7], ["f", 7], ["g", 7], ["h", 7], + ["a", 8], ["b", 8], ["c", 8], ["d", 8], ["e", 8], ["f", 8], ["g", 8], ["h", 8] + ], + "fileRank2index": { + "a1": 0, "b1": 1, "c1": 2, "d1": 3, "e1": 4, "f1": 5, "g1": 6, "h1": 7, + "a2": 8, "b2": 9, "c2": 10, "d2": 11, "e2": 12, "f2": 13, "g2": 14, "h2": 15, + "a3": 16, "b3": 17, "c3": 18, "d3": 19, "e3": 20, "f3": 21, "g3": 22, "h3": 23, + "a4": 24, "b4": 25, "c4": 26, "d4": 27, "e4": 28, "f4": 29, "g4": 30, "h4": 31, + "a5": 32, "b5": 33, "c5": 34, "d5": 35, "e5": 36, "f5": 37, "g5": 38, "h5": 39, + "a6": 40, "b6": 41, "c6": 42, "d6": 43, "e6": 44, "f6": 45, "g6": 46, "h6": 47, + "a7": 48, "b7": 49, "c7": 50, "d7": 51, "e7": 52, "f7": 53, "g7": 54, "h7": 55, + "a8": 56, "b8": 57, "c8": 58, "d8": 59, "e8": 60, "f8": 61, "g8": 62, "h8": 63 + }, + "board": [ + "R", "N", "B", "Q", "K", "B", "N", "R", + "P", "P", "P", "P", "P", "P", "P", "P", + ".", ".", ".", ".", ".", ".", ".", ".", + ".", ".", ".", ".", ".", ".", ".", ".", + ".", ".", ".", ".", ".", ".", ".", ".", + ".", ".", ".", ".", ".", ".", ".", ".", + "p", "p", "p", "p", "p", "p", "p", "p", + "r", "n", "b", "q", "k", "b", "n", "r" + ], + + "bitboards": { "p": 0, + "r": 0, + "n": 0, + "b": 0, + "q": 0, + "k": 0, + "P": 0, + "R": 0, + "N": 0, + "B": 0, + "Q": 0, + "K": 0, + "white": 0, + "black": 0, + "whiteatk": 0, + "blackatk": 0, + ".": 0 + }, + + "knightMoves": [ + 132096, 329728, 659712, 1319424, 2638848, 5277696, 10489856, 4202496, 33816580, 84410376, + 168886289, 337772578, 675545156, 1351090312, 2685403152, 1075839008, 8657044482, 21609056261, + 43234889994, 86469779988, 172939559976, 345879119952, 687463207072, 275414786112, 2216203387392, + 5531918402816, 11068131838464, 22136263676928, 44272527353856, 88545054707712, 175990581010432, + 70506185244672, 567348067172352, 1416171111120896, 2833441750646784, 5666883501293568, 11333767002587136, + 22667534005174272, 45053588738670592, 18049583422636032, 145241105196122112, 362539804446949376, + 725361088165576704, 1450722176331153408, 2901444352662306816, 5802888705324613632, 11533718717099671552, + 4620693356194824192, 288234782788157440, 576469569871282176, 1224997833292120064, 2449995666584240128, + 4899991333168480256, 9799982666336960512, 1152939783987658752, 2305878468463689728, 1128098930098176, + 2257297371824128, 4796069720358912, 9592139440717824, 19184278881435648, 38368557762871296, 4679521487814656, + 9077567998918656 + ], + "kingMoves": [770, 1797, 3594, 7188, 14376, 28752, 57504, 49216, 197123, 460039, 920078, 1840156, 3680312, 7360624, 14721248, + 12599488, 50463488, 117769984, 235539968, 471079936, 942159872, 1884319744, 3768639488, 3225468928, 12918652928, + 30149115904, 60298231808, 120596463616, 241192927232, 482385854464, 964771708928, 825720045568, 3307175149568, + 7718173671424, 15436347342848, 30872694685696, 61745389371392, 123490778742784, 246981557485568, 211384331665408, + 846636838289408, 1975852459884544, 3951704919769088, 7903409839538176, 15806819679076352, 31613639358152704, + 63227278716305408, 54114388906344448, 216739030602088448, 505818229730443264, 1011636459460886528, + 2023272918921773056, 4046545837843546112, 8093091675687092224, 16186183351374184448, 13853283560024178688, + 144959613005987840, 362258295026614272, 724516590053228544, 1449033180106457088, 2898066360212914176, + 5796132720425828352, 11592265440851656704, 4665729213955833856], + + "bishopMoves": [9241421688590303744, 36099303471056128, 141012904249856, 550848566272, 6480472064, 1108177604608, 283691315142656, + 72624976668147712, 4620710844295151618, 9241421688590368773, 36099303487963146, 141017232965652, 1659000848424, + 283693466779728, 72624976676520096, 145249953336262720, 2310355422147510788, 4620710844311799048, 9241421692918565393, + 36100411639206946, 424704217196612, 72625527495610504, 145249955479592976, 290499906664153120, 1155177711057110024, + 2310355426409252880, 4620711952330133792, 9241705379636978241, 108724279602332802, 145390965166737412, 290500455356698632, + 580999811184992272, 577588851267340304, 1155178802063085600, 2310639079102947392, 4693335752243822976, 9386671504487645697, + 326598935265674242, 581140276476643332, 1161999073681608712, 288793334762704928, 577868148797087808, 1227793891648880768, + 2455587783297826816, 4911175566595588352, 9822351133174399489, 1197958188344280066, 2323857683139004420, 144117404414255168, + 360293502378066048, 720587009051099136, 1441174018118909952, 2882348036221108224, 5764696068147249408, 11529391036782871041, + 4611756524879479810, 567382630219904, 1416240237150208, 2833579985862656, 5667164249915392, 11334324221640704, 22667548931719168, + 45053622886727936, 18049651735527937], + + "bishopForeslash": [9241421688590303744, 36099303471055872, 141012904183808, 550831656960, 2151686144, 8404992, 32768, 0, 4620710844295151616, + 9241421688590303233, 36099303471054850, 141012904181764, 550831652872, 2151677968, 8388640, 64, 2310355422147510272, + 4620710844295020800, 9241421688590041601, 36099303470531586, 141012903135236, 550829559816, 2147491856, 16416, 1155177711056977920, + 2310355422114021376, 4620710844228043008, 9241421688456086017, 36099303202620418, 141012367312900, 549757915144, 4202512, 577588851233521664, + 1155177702483820544, 2310355404967706624, 4620710809935413504, 9241421619870827009, 36099166032102402, 140738026276868, 1075843080, + 288793326105133056, 577586656505233408, 1155173313027244032, 2310346626054553600, 4620693252109107456, 9241386504218214913, + 36028934726878210, 275415828484, 144115188075855872, 288231475663339520, 576462955621646336, 1152925911260069888, 2305851822520205312, + 4611703645040410880, 9223407290080821761, 70506452091906, 0, 281474976710656, 564049465049088, 1128103225065472, 2256206466908160, + 4512412933881856, 9024825867763968, 18049651735527937], + + "bishopBackslash": [0, 256, 66048, 16909312, 4328785920, 1108169199616, 283691315109888, 72624976668147712, 2, 65540, 16908296, 4328783888, 1108169195552, + 283691315101760, 72624976668131456, 145249953336262656, 516, 16778248, 4328523792, 1108168675360, 283691314061376, 72624976666050688, + 145249953332101120, 290499906664136704, 132104, 4295231504, 1108102090784, 283691180892224, 72624976399712384, 145249952799424512, + 290499905598783488, 580999811180789760, 33818640, 1099579265056, 283674135240768, 72624942308409472, 145249884616818688, 290499769233571840, + 580999538450366464, 1161999072605765632, 8657571872, 281492291854400, 72620578621636736, 145241157243273216, 290482314486480896, + 580964628956184576, 1161929253617401856, 2323857407723175936, 2216338399296, 72062026714726528, 144124053429452800, 288248106858840064, + 576496213700902912, 1152992423106838528, 2305983746702049280, 4611686018427387904, 567382630219904, 1134765260439552, 2269530520813568, + 4539061024849920, 9078117754732544, 18155135997837312, 36028797018963968, 0], + + "rookMoves": [72340172838076926, 144680345676153597, 289360691352306939, 578721382704613623, 1157442765409226991, 2314885530818453727, + 4629771061636907199, 9259542123273814143, 72340172838141441, 144680345676217602, 289360691352369924, 578721382704674568, + 1157442765409283856, 2314885530818502432, 4629771061636939584, 9259542123273813888, 72340172854657281, 144680345692602882, + 289360691368494084, 578721382720276488, 1157442765423841296, 2314885530830970912, 4629771061645230144, 9259542123273748608, + 72340177082712321, 144680349887234562, 289360695496279044, 578721386714368008, 1157442769150545936, 2314885534022901792, + 4629771063767613504, 9259542123257036928, 72341259464802561, 144681423712944642, 289361752209228804, 578722409201797128, + 1157443723186933776, 2314886351157207072, 4629771607097753664, 9259542118978846848, 72618349279904001, 144956323094725122, + 289632270724367364, 578984165983651848, 1157687956502220816, 2315095537539358752, 4629910699613634624, 9259541023762186368, + 143553341945872641, 215330564830528002, 358885010599838724, 645993902138460168, 1220211685215703056, 2368647251370188832, + 4665518383679160384, 9259260648297103488, 18302911464433844481, 18231136449196065282, 18087586418720506884, 17800486357769390088, + 17226286235867156496, 16077885992062689312, 13781085504453754944, 9187484529235886208], + + "queenMoves": [9313761861428380670, 180779649147209725, 289501704256556795, 578721933553179895, 1157442771889699055, 2314886638996058335, + 4630054752952049855, 9332167099941961855, 4693051017133293059, 9386102034266586375, 325459994840333070, 578862399937640220, + 1157444424410132280, 2315169224285282160, 4702396038313459680, 9404792076610076608, 2382695595002168069, 4765391190004401930, + 9530782384287059477, 614821794359483434, 1157867469641037908, 2387511058326581416, 4775021017124823120, 9550042029937901728, + 1227517888139822345, 2455035776296487442, 4910072647826412836, 9820426766351346249, 1266167048752878738, 2460276499189639204, + 4920271519124312136, 9840541934442029200, 649930110732142865, 1299860225776030242, 2600000831312176196, 5272058161445620104, + 10544115227674579473, 2641485286422881314, 5210911883574396996, 10421541192660455560, 361411684042608929, 722824471891812930, + 1517426162373248132, 3034571949281478664, 6068863523097809168, 12137446670713758241, 5827868887957914690, 11583398706901190788, + 287670746360127809, 575624067208594050, 1079472019650937860, 2087167920257370120, 4102559721436811280, 8133343319517438240, + 16194909420462031425, 13871017173176583298, 18303478847064064385, 18232552689433215490, 18090419998706369540, 17806153522019305480, + 17237620560088797200, 16100553540994408480, 13826139127340482880, 9205534180971414145] +} \ No newline at end of file