Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Castling #26

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Assets/pieces/bB.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets/pieces/bK.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets/pieces/bN.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets/pieces/bP.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets/pieces/bQ.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets/pieces/bR.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets/pieces/wB.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets/pieces/wK.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets/pieces/wN.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets/pieces/wP.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets/pieces/wQ.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets/pieces/wR.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified CHESS-AI/__pycache__/chessboard.cpython-39.pyc
Binary file not shown.
156 changes: 151 additions & 5 deletions CHESS-AI/chessboard.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import struct
import numpy as np
import json
import copy

class Board:

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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

Expand All @@ -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
Expand All @@ -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
Expand All @@ -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":
Expand All @@ -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

Expand Down Expand Up @@ -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
Expand Down
Loading