def __init__(self, parent, squareWidth=64, squareHeight=64): self.player = 'w' self.moveNum = 1 Tkinter.Frame.__init__(self, parent) self.parent = parent self.chessState = ChessState(Common.initChessFEN) self.cb = ChessBoard(self) self.cb.setState(self.chessState) self.cb.refreshCanvasFromState() self.cb.pack() self.b = Tkinter.Button(self, text="flip", command=self.flipIt) self.b.pack() self.b2 = Tkinter.Button(self, text="clear", command=self.clearIt) self.b2.pack() #self.b = Tkinter.Button(self, text="html", command=self.html) #self.b.pack() self.moveEntry = Tkinter.Entry(self) self.moveEntry.pack() self.execMove = Tkinter.Button(self, text="execute move", command=self.executeMove) self.execMove.pack()
def __init__(self): self.stateSave = ChessState(Common.initChessFEN) self.stateCurr = ChessState(Common.initChessFEN) self.moves = [] self.lastOcc = [ \ 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, \ 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, \ 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1]
def __init__(self): self.initState = ChessState(Common.initChessFEN) self.moves = [] self.tags = {} self.comments = [] self.states = [self.initState] self.result = None
def __init__(self, parent, squareWidth=64, squareHeight=64): self.player = "w" self.moveNum = 1 Tkinter.Frame.__init__(self, parent) self.parent = parent self.chessState = ChessState(Common.initChessFEN) self.cb = ChessBoard(self) self.cb.setState(self.chessState) self.cb.refreshCanvasFromState() self.cb.pack() self.b = Tkinter.Button(self, text="flip", command=self.flipIt) self.b.pack() self.b2 = Tkinter.Button(self, text="clear", command=self.clearIt) self.b2.pack() # self.b = Tkinter.Button(self, text="html", command=self.html) # self.b.pack() self.moveEntry = Tkinter.Entry(self) self.moveEntry.pack() self.execMove = Tkinter.Button(self, text="execute move", command=self.executeMove) self.execMove.pack()
class ChessBoardTest(tkinter.Frame): def __init__(self, parent, squareWidth=64, squareHeight=64): self.player = 'w' self.moveNum = 1 tkinter.Frame.__init__(self, parent) self.parent = parent self.chessState = ChessState(Common.initChessFEN) self.cb = ChessBoard(self) self.cb.setState(self.chessState) self.cb.refreshCanvasFromState() self.cb.pack() self.b = tkinter.Button(self, text="flip", command=self.flipIt) self.b.pack() self.b2 = tkinter.Button(self, text="clear", command=self.clearIt) self.b2.pack() #self.b = tkinter.Button(self, text="html", command=self.html) # self.b.pack() self.moveEntry = tkinter.Entry(self) self.moveEntry.pack() self.execMove = tkinter.Button(self, text="execute move", command=self.executeMove) self.execMove.pack() def clearIt(self): self.cb.clear() def flipIt(self): self.cb.flip() def executeMove(self): whatMove = self.moveEntry.get() print("executing: " + whatMove) move = ChessMove(self.player, self.moveNum, whatMove) self.chessState = self.chessState.transition(move) self.cb.setState(self.chessState) print("new state: " + str(self.chessState)) self.player = {'w': 'b', 'b': 'w'}[self.player] self.moveNum += 1
class ChessBoardTest(Tkinter.Frame): def __init__(self, parent, squareWidth=64, squareHeight=64): self.player = "w" self.moveNum = 1 Tkinter.Frame.__init__(self, parent) self.parent = parent self.chessState = ChessState(Common.initChessFEN) self.cb = ChessBoard(self) self.cb.setState(self.chessState) self.cb.refreshCanvasFromState() self.cb.pack() self.b = Tkinter.Button(self, text="flip", command=self.flipIt) self.b.pack() self.b2 = Tkinter.Button(self, text="clear", command=self.clearIt) self.b2.pack() # self.b = Tkinter.Button(self, text="html", command=self.html) # self.b.pack() self.moveEntry = Tkinter.Entry(self) self.moveEntry.pack() self.execMove = Tkinter.Button(self, text="execute move", command=self.executeMove) self.execMove.pack() def clearIt(self): self.cb.clear() def flipIt(self): self.cb.flip() def executeMove(self): whatMove = self.moveEntry.get() print "executing: " + whatMove move = ChessMove(self.player, self.moveNum, whatMove) self.chessState = self.chessState.transition(move) self.cb.setState(self.chessState) print "new state: " + str(self.chessState) self.player = {"w": "b", "b": "w"}[self.player] self.moveNum += 1
def __init__(self, parent, pieceWidth=48, pieceHeight=48): Tkinter.Frame.__init__(self, parent) self.parent = parent self.chessState = ChessState(Common.initChessFEN) self.cb = ChessBoard(self) self.cb.setState(self.chessState) self.cb.draw() self.cb.pack() self.b = Tkinter.Button(self, text="flip", command=self.flipIt) self.b.pack() self.b = Tkinter.Button(self, text="html", command=self.html) self.b.pack() self.moveEntry = Tkinter.Entry(self) self.moveEntry.pack() self.execMove = Tkinter.Button(self, text="execute move", command=self.executeMove) self.execMove.pack()
class ChessBoardTest(Tkinter.Frame): def __init__(self, parent, pieceWidth=48, pieceHeight=48): Tkinter.Frame.__init__(self, parent) self.parent = parent self.chessState = ChessState(Common.initChessFEN) self.cb = ChessBoard(self) self.cb.setState(self.chessState) self.cb.draw() self.cb.pack() self.b = Tkinter.Button(self, text="flip", command=self.flipIt) self.b.pack() self.b = Tkinter.Button(self, text="html", command=self.html) self.b.pack() self.moveEntry = Tkinter.Entry(self) self.moveEntry.pack() self.execMove = Tkinter.Button(self, text="execute move", command=self.executeMove) self.execMove.pack() def flipIt(self): self.cb.flip() self.cb.draw() def html(self): print self.cb.draw_html() def executeMove(self): whatMove = self.moveEntry.get() print "Executing: " + whatMove self.chessState = self.chessState.transition(whatMove) self.cb.setState(self.chessState) self.cb.draw()
class OccupancyProcessor: def __init__(self): self.stateSave = ChessState(Common.initChessFEN) self.stateCurr = ChessState(Common.initChessFEN) self.moves = [] self.lastOcc = [ \ 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, \ 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, \ 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1] def update(self, occ): print "INFO: awaiting move by player: %s" % self.stateCurr.activePlayer # discard duplicates if occ == self.lastOcc: print "INFO: repeat state received, ignoring..." return # determine what squares were involved in the move srcSqrIdx = None dstSqrIdx = None for i in range(64): if self.lastOcc[i] == 1 and occ[i] == 0: if srcSqrIdx != None: raise Exception('multiple pieces moved! %s and %s are potential source squares!' % \ (Common.idxToSquare(srcSqrIdx), Common.idxToSquare(i))) srcSqrIdx = i if self.lastOcc[i] == 0 and occ[i] == 1: if dstSqrIdx != None: raise Exception('multiple pieces moved! %s and %s are potential destination squares!' % \ (Common.idxToSquare[srcSqrIdx], Common.idxToSquare[i])) dstSqrIdx = i if srcSqrIdx and not dstSqrIdx: raise Exception('a piece left %s but never appeared anywhere!' % Common.idxToSquare[srcSqrIdx]) if dstSqrIdx and not srcSqrIdx: raise Exception('a piece appeared at %s but never left anywhere!' % Common.idxToSquare[dstSqrIdx]) srcSqr = Common.idxToSquare[srcSqrIdx] dstSqr = Common.idxToSquare[dstSqrIdx] moveText = '%s%s' % (srcSqr, dstSqr) # discard multiple moves by the same player (favor the last move) # whom = Common.coloredPieceToPlayer(self.stateCurr.squares[srcSqr]) if whom != self.stateCurr.activePlayer: print "INFO: another move by previous player, recalculating..." if len(self.moves): m = ChessMove(self.stateCurr.activePlayer, self.stateCurr.fullMoveNum, moveText) self.stateCurr = self.stateSave.transition(m) self.moves[-1] = '%s%s' % (Common.idxToSquare[srcSqrIdx], Common.idxToSquare[dstSqrIdx]) self.lastOcc = occ return # otherwise it's a normal move # m = ChessMove(self.stateCurr.activePlayer, self.stateCurr.fullMoveNum, moveText) print "INFO: transitioning on move %s" % str(m) self.stateSave = self.stateCurr self.stateCurr = self.stateCurr.transition(m) self.moves.append(moveText) self.lastOcc = occ # finished def done(self): # TODO: construct PGN text pass
def parsePgn(self, text): tokens = PgnTokenizer.tokenize(text) currMoveNum = 0 player = 'W' while tokens: token = tokens.pop(0) #print "on token: -%s-" % token # tag tokens eg: [Event "May 2013 Tourney"] m = re.match(r'\[(.*?) "(.*?)"\]', token) if m: self.tags[m.group(1)] = m.group(2) continue # comment tokens eg: { good move! also consider Rxe8 } m = re.match('^{(.*)}$', token) if m: # if we're in the moves section, comment applies to a move if self.moves: self.moves[-1].addComment(m.group(1)) # else it applies to the match comments else: self.comments.append(m.group(1)) continue # result tokens eg: 0-1 m = re.match(Common.regexResults, token) if m: self.result = token if tokens: raise Exception("result token was not the final token! next is: " + tokens[0]) continue # move number token eg: 34. m = re.match(r'(\d+)\.', token) if m: if currMoveNum + 1 != int(m.group(1)): raise Exception("out of order move number: " + token) player = 'w' currMoveNum += 1 # normal move (SAN) m = re.match(Common.regexSanChess, token) if m: move = ChessMove.ChessMove() move.moveNum = currMoveNum move.player = player move.san = token self.moves.append(move) player = {'w':'b', 'b':'w'}[player] # calculate all board states # # initial state? or special state? (Fischer960, etc.) if 'SetUp' in self.tags and self.tags['SetUp'] == '1': if 'FEN' in self.tags: self.initState = ChessState(self.tags['FEN']) self.states = [self.initState] # loop over all moves... for move in self.moves: # exceptions (repeated moves due to time forfeiture, etc.) just carry state along... if 'TIME_FORFEIT' in move.flags: self.states.append(self.states[-1]) continue currState = self.states[-1] nextState = currState.transition(move) self.states.append(nextState)
def setFEN(self, fen): self.chessState = ChessState(fen) self.refreshCanvasFromState()
class OccupancyProcessor: def __init__(self): self.stateSave = ChessState(Common.initChessFEN) self.stateCurr = ChessState(Common.initChessFEN) self.moves = [] self.lastOcc = [ \ 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, \ 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, \ 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1] def update(self, occ): print "INFO: awaiting move by player: %s" % self.stateCurr.activePlayer # discard duplicates if occ == self.lastOcc: print "INFO: repeat state received, ignoring..." return # determine what squares were involved in the move srcSqrIdx = None dstSqrIdx = None for i in range(64): if self.lastOcc[i] == 1 and occ[i] == 0: if srcSqrIdx != None: raise Exception('multiple pieces moved! %s and %s are potential source squares!' % \ (Common.idxToSquare(srcSqrIdx), Common.idxToSquare(i))) srcSqrIdx = i if self.lastOcc[i] == 0 and occ[i] == 1: if dstSqrIdx != None: raise Exception('multiple pieces moved! %s and %s are potential destination squares!' % \ (Common.idxToSquare[srcSqrIdx], Common.idxToSquare[i])) dstSqrIdx = i if srcSqrIdx and not dstSqrIdx: raise Exception('a piece left %s but never appeared anywhere!' % Common.idxToSquare[srcSqrIdx]) if dstSqrIdx and not srcSqrIdx: raise Exception('a piece appeared at %s but never left anywhere!' % Common.idxToSquare[dstSqrIdx]) srcSqr = Common.idxToSquare[srcSqrIdx] dstSqr = Common.idxToSquare[dstSqrIdx] moveText = '%s%s' % (srcSqr, dstSqr) # discard multiple moves by the same player (favor the last move) # whom = Common.coloredPieceToPlayer(self.stateCurr.squares[srcSqr]) if whom != self.stateCurr.activePlayer: print "INFO: another move by previous player, recalculating..." if len(self.moves): self.stateCurr = self.stateSave.transition(moveText) self.moves[-1] = '%s%s' % (Common.idxToSquare[srcSqrIdx], Common.idxToSquare[dstSqrIdx]) self.lastOcc = occ return # otherwise it's a normal move # print "INFO: transitioning on move..." self.stateSave = self.stateCurr self.stateCurr = self.stateCurr.transition(moveText) self.moves.append(moveText) self.lastOcc = occ # finished def done(self): # TODO: construct PGN text pass
def __init__(self, initState, movesToMate): self.headState = ChessState(initState) self.depth = movesToMate + 1 self.lowestRow = [] self.lowestRow.append(self.headState) self.nodesExplored = 0
color = ["black", "white"] print("This is a text-based chess interface, where the computer will play against the user or itself.") #Prompts user for game type type_of_game = None while True: type_of_game = input("In order of white versus black, where c means computer and h means human, type cvc, hvc, or cvh: ") if type_of_game in ["cvc", "cvh", "hvc"]: break #Prompts user for starting position while True: fen = input("Type 'n' for the standard starting position or a specific FEN: ") if fen is 'n': board = ChessState() break else: try: board = ChessState(fen=fen) break except ValueError: print("Invalid FEN") #Plays calculated best move in given position def play_engine_move(): engine_move = board.san(player.best_move(board, board.turn)) print("Computer move for " + color[board.turn] + " is " + engine_move) board.push_san(engine_move) #Prompts and plays user's move
def heur(board: ChessState) -> int: """Evaluation function for a given ChessState. The upper- and lower-bounds for the value returned are 10000 and -10000. A value of 0 indicates an equal position.""" if board.is_checkmate(): if board.turn: #black won return -10000 else: #white won return 10000 elif board.is_stalemate() or board.is_insufficient_material(): return 0 #get piece positions white_pawns = board.pieces(chess.PAWN, chess.WHITE) black_pawns = board.pieces(chess.PAWN, chess.BLACK) white_knights = board.pieces(chess.KNIGHT, chess.WHITE) black_knights = board.pieces(chess.KNIGHT, chess.BLACK) white_bishops = board.pieces(chess.BISHOP, chess.WHITE) black_bishops = board.pieces(chess.BISHOP, chess.BLACK) white_rooks = board.pieces(chess.ROOK, chess.WHITE) black_rooks = board.pieces(chess.ROOK, chess.BLACK) white_queens = board.pieces(chess.QUEEN, chess.WHITE) black_queens = board.pieces(chess.QUEEN, chess.BLACK) white_king = board.pieces(chess.KING, chess.WHITE) black_king = board.pieces(chess.KING, chess.BLACK) num_of_pieces = len(black_knights) + len(black_bishops) + len(black_rooks) +\ len(white_knights) + len(white_bishops) + len(white_rooks) + len(white_queens) \ + len(black_queens) + len(white_king) + len(black_king) + len(white_pawns) + len(black_pawns) #returns number of pinned pieces from piece_set * value_of_pin def pinned_eval(piece_set, color, value_of_pin): cum_eval = 0 for piece in piece_set: if board.is_pinned(color, piece): cum_eval = cum_eval + value_of_pin return cum_eval pinned_value = pinned_eval(white_pawns, chess.WHITE, -20) + pinned_eval(black_pawns, chess.BLACK, 20) + \ pinned_eval(white_knights, chess.WHITE, -30) + pinned_eval(black_knights, chess.BLACK, 30) +\ pinned_eval(white_bishops,chess.WHITE, -30) + pinned_eval(black_bishops,chess.BLACK, 30) +\ pinned_eval(white_rooks,chess.WHITE, -150) + pinned_eval(black_bishops,chess.BLACK, 150) +\ pinned_eval(white_queens,chess.WHITE, -400) + pinned_eval(black_bishops,chess.BLACK, 400) #returns value representing how many pieces of any type in list_of_pieces_to_attack are being attacked by any piece in piece_set def attacking_eval(piece_set, list_of_pieces_to_attack, list_of_value_of_attack): cum_eval = 0 for piece in piece_set: attacked = board.attacks(piece) for i in range(0, len(list_of_pieces_to_attack)): num_of_attacks_on_piece_type = len( attacked.intersection(list_of_pieces_to_attack[i])) cum_eval = cum_eval + num_of_attacks_on_piece_type * list_of_value_of_attack[ i] return cum_eval attacking_value = attacking_eval(white_knights, [black_queens,black_rooks,black_bishops], [20, 10, 5]) + \ attacking_eval(white_bishops, [black_queens, black_rooks, black_bishops], [20, 10, 2]) + \ attacking_eval(white_pawns, [black_queens, black_rooks, black_bishops, black_knights], [30, 20, 10, 10]) +\ attacking_eval(white_rooks, [black_queens], [20]) + \ attacking_eval(black_knights, [white_queens, white_rooks, white_bishops], [-20, -10, -5]) + \ attacking_eval(black_bishops, [white_queens, white_rooks, white_bishops], [-20, -10, -2]) + \ attacking_eval(black_pawns, [white_queens, white_rooks, white_bishops, white_knights], [-30, -20, -10, -10]) + \ attacking_eval(black_rooks, [white_queens], [-20]) num_black_minor_pieces = len(black_knights) + len(black_bishops) + len( black_rooks) num_white_minor_pieces = len(white_knights) + len(white_bishops) + len( white_rooks) #boolean if board is in endgame endgame = (len(white_queens) + len(black_queens) is 0) or ( len(white_queens) is 1 and len(black_queens) is 1 and num_black_minor_pieces is 1 and num_white_minor_pieces is 1) kingstable = kingstable_endgame if endgame else kingstable_middlegame #bishop pair is more valuable white_value_of_bishops = 375 if len(white_bishops) >= 2 and len( black_bishops) < 2 else 360 black_value_of_bishops = 375 if len(black_bishops) >= 2 and len( white_bishops) < 2 else 360 #calculates value of material in centipawns with standard valuations from https://en.wikipedia.org/wiki/Chess_piece_relative_value white_material = 100 * len(white_pawns) + 350 * len( white_knights) + white_value_of_bishops * len( white_bishops) + 525 * len(white_rooks) + 900 * len(white_queens) black_material = 100 * len(black_pawns) + 350 * len( black_knights) + black_value_of_bishops * len( black_bishops) + 525 * len(black_rooks) + 900 * len(black_queens) #sums values of all the positions of the pieces on the board from the tables square_values = sum([pawntable[i] for i in white_pawns]) - sum([pawntable[chess.square_mirror(i)] for i in black_pawns]) +\ sum([knightstable[i] for i in white_knights]) - sum([knightstable[chess.square_mirror(i)] for i in black_knights]) +\ sum([bishopstable[i] for i in white_bishops]) - sum([bishopstable[chess.square_mirror(i)] for i in black_bishops])+\ sum([rookstable[i] for i in white_rooks]) - sum([rookstable[chess.square_mirror(i)] for i in black_rooks])+\ sum([queenstable[i] for i in white_queens]) - sum([queenstable[chess.square_mirror(i)] for i in black_queens])+\ sum([kingstable[i] for i in white_king]) - sum([kingstable[chess.square_mirror(i)] for i in black_king]) return white_material - black_material + square_values + pinned_value + attacking_value
def __init__(self, chessBoard): self._boardWidth = 8 self._boardHeight = 8 self._state = ChessState(chessBoard)