def whiteDefRook(board, wr, wk): score = 0 guard = board.attackers(chess.WHITE, list(wk)[0]) if len(guard) > 0: score = 50 #King gaurding Rook x = chess.rank_index(list(wr)[0]) - chess.rank_index(list(wk)[0]) y = chess.file_index(list(wr)[0]) - chess.file_index(list(wk)[0]) return score + (20 - floor((y**2 + x**2)**(1 / 2)))
def main(): global move_array game = True engine = uci.popen_engine('./Engine/stockfish_8_x64') engine.uci() while game: SCREEN.blit(BACKGROUND, (0, 512)) button("Reset", 50, 520, 100, 30, BUTTON_BACK, BUTTON_BACK, resetBoard) button("<<", 200, 520, 50, 30, BUTTON_BACK, BUTTON_BACK, toBeginning) button("<", 270, 520, 50, 30, BUTTON_BACK, BUTTON_BACK, oneBack) button(">", 340, 520, 50, 30, BUTTON_BACK, BUTTON_BACK, pushOne) button(">>", 410, 520, 50, 30, BUTTON_BACK, BUTTON_BACK, toEnd) for row in range(8): for column in range(8): if (row, column) not in move_array: if (row + column) % 2 == 0: SCREEN.blit(SQUARE_DARK, (row * 64, column * 64)) else: SCREEN.blit(SQUARE_LIGHT, (row * 64, column * 64)) for event in pygame.event.get(): if event.type == pygame.QUIT: game = False if event.type == pygame.MOUSEBUTTONUP: pos = pygame.mouse.get_pos() x_val, y_val = int(pos[0] / 64), 7 - (int(pos[1] / 64)) if y_val >= 0: move_array.append((x_val, y_val)) if len(move_array) == 1: SCREEN.blit(SQUARE_CLICKED, (move_array[0][0] * 64, (7 - move_array[0][1]) * 64)) if len(move_array) == 2: square_x = chess.square(move_array[0][0], move_array[0][1]) square_y = chess.square(move_array[1][0], move_array[1][1]) if (str(BOARD.piece_at(square_x)) == 'P' or str(BOARD.piece_at(square_x)) == 'p') \ and chess.file_index(square_x) != chess.file_index(square_y) and \ (chess.rank_index(square_y) == 0 or chess.rank_index(square_y) == 7): cur_move = chess.Move(square_x, square_y, promotion=5) else: cur_move = chess.Move(square_x, square_y) if cur_move in BOARD.legal_moves: BOARD.push(cur_move) engine_position = engine.position(BOARD) engine_moves = engine.go() BOARD.push(engine_moves[0]) else: move_array = [] updateBoard() pygame.display.flip() CLOCK.tick(30)
def whiteDefRook(board, wr, wk): score = 0 guard = board.attackers(chess.WHITE, list(wk)[0]) for squares in guard: if squares == list(wk)[0]: score = 50 #King gaurding Rook x = abs(chess.rank_index(list(wr)[0]) - chess.rank_index(list(wk)[0])) y = abs(chess.file_index(list(wr)[0]) - chess.file_index(list(wk)[0])) return score - min(x, y) return 0
def kingDistance(board, wk, bk): x = (chess.rank_index(list(wk)[0]) - chess.rank_index(list(wk)[0])) y = (chess.rank_index(list(bk)[0]) - chess.rank_index(list(bk)[0])) xSquared = math.pow(x, 2) ySquared = math.pow(y, 2) kingMath = xSquared + ySquared distance = math.sqrt(kingMath) floorDistance = math.floor(distance) score = 10 - floorDistance return score
def generateData(game): whiteElo = int(game.headers['WhiteElo']) node = game output = [] turn = 1 lastseen1 = [57,0] lastseen2 = [62,0] result = int(game.headers['Result'][0]) while node.variations: next_node = node.variation(0) if(str(node.board().san(next_node.move))[0] == "N" and turn%2 ==0): row = [0] * 8 row[0] = turn row[6] = whiteElo row[7] = result # If the knight is the left knight if next_node.move.from_square == lastseen1[0]: # From Square FromSquare = next_node.move.from_square row[1] = chess.rank_index(FromSquare) row[2] = chess.file_index(FromSquare) # To Square ToSquare = next_node.move.to_square row[3] = chess.rank_index(ToSquare) row[4] = chess.file_index(ToSquare) # Updating lastseen vectors lastseen1[0] = next_node.move.to_square # Entering Time Spent timespent = turn - lastseen1[1] lastseen1[1] = turn/2 row[5] = timespent/2 # If the knight is the right knight if next_node.move.from_square == lastseen2[0]: FromSquare = next_node.move.from_square row[1] = chess.rank_index(FromSquare) row[2] = chess.file_index(FromSquare) # To Square ToSquare = next_node.move.to_square row[3] = chess.rank_index(ToSquare) row[4] = chess.file_index(ToSquare) # Updating lastseen vectors lastseen2[0] = next_node.move.to_square # Entering Time Spent timespent = turn - lastseen2[1] lastseen2[1] = turn/2 row[5] = timespent/2 output.append(row) node = next_node turn += 1 return(output)
def checkGoal(self, fen): ########################################################################## print "DEBUG bot checkgoal checking goal %s in fen %s" % (self.player_goal, fen) sys.stdout.flush() if self.player_goal == "": return False board = chess.Board(fen) piece = self.player_goal[0] file = self.player_goal[1] rank = self.player_goal[2] print "DEBUG bot checkgoal piece=%s rank=%s file=%s" % (piece, rank, file) sys.stdout.flush() if piece == "*": raise Exception("checkGoal", "not implemented") elif (string.lower(piece) in ["p", "r", "b", "n", "k", "q"]) == False: raise Exception("checkGoal", "invalid piece type") a = chess.Piece.from_symbol(piece) piece_type = a.piece_type if piece.isupper(): color = chess.WHITE else: color = chess.BLACK print "DEBUG bot checkgoal piece type %d color %d " % (piece_type, color) sys.stdout.flush() squares = board.pieces(piece_type, color) rankmatch = False filematch = False for sq in squares: print "DEBUG bot checkgoal piece found at %s (rank %s file %s) " % ( chess.SQUARE_NAMES[sq], chess.RANK_NAMES[chess.rank_index(sq)], chess.FILE_NAMES[chess.file_index(sq)], ) sys.stdout.flush() if rank == "*": rankmatch = True else: if chess.RANK_NAMES[chess.rank_index(sq)] == rank: rankmatch = True if file == "*": filematch = True else: if chess.FILE_NAMES[chess.file_index(sq)] == file: filematch = True if rankmatch and filematch: return True else: return False
def squareIndexToImageCoords(self, i): rank_ind = chess.rank_index(i) file_ind = chess.file_index(i) row = 448 - (rank_ind * 512 / 8) col = file_ind * 512 / 8 return (col, row)
def _is_promotion(self, ecb, move_start, move_end): sq_from = chess.SQUARE_NAMES.index(move_start) sq_to = chess.SQUARE_NAMES.index(move_end) piece_type = ecb.board.piece_type_at(sq_from) if not piece_type == chess.PAWN: return False if chess.rank_index(sq_to) == 7: return True return False
def sendMove(self, toSquare, fromSquare=None): """ Emits moveInputted after first asking for a promotion piece if there should be one. Then updates the board graphics. Does not validate move, although it should be valid. """ if fromSquare is None: fromSquare = self.selectedSquare m = chess.Move(fromSquare, toSquare) if (self.board.piece_at(m.from_square).piece_type == chess.PAWN and chess.rank_index(m.to_square) in [0, 7]): # TODO: ask for a real promotion piece print('promoting to queen') m.promotion = chess.QUEEN # In order to be as responsive as possible, the board is updated with # its own move before being sent to the engine, ect. self.updateAfterMove(m) self.moveInputted.emit(m)
def updateBoard(): for square in chess.SQUARES: piece = str(BOARD.piece_at(square)) x_cord = chess.file_index(square) y_cord = 7 - chess.rank_index(square) piece_dict = { 'P': LIGHT_PAWN.image, 'p': DARK_PAWN.image, 'B': L_BISHOP.image, 'b': D_BISHOP.image, 'R': L_ROOK.image, 'r': D_ROOK.image, 'N': L_KNIGHT.image, 'n': D_KNIGHT.image, 'Q': L_QUEEN.image, 'q': D_QUEEN.image, 'K': L_KING.image, 'k': D_KING.image } if piece != "None": SCREEN.blit(piece_dict[piece], (x_cord * 64, y_cord * 64))
def square_to_pos(command): return (chess.file_index(command.to_square), chess.rank_index(command.to_square))
def piece_vector(board): board_type = board.__class__.__name__ out_vec = [] piece_types = [chess.PAWN, chess.KNIGHT, chess.BISHOP, chess.ROOK, chess.QUEEN, chess.KING] # total numbers of pieces per color white_counts = [0] * 6 black_counts = [0] * 6 # factoring in support for pieces on the board white_attacked = 0 white_supported = 0 black_attacked = 0 black_supported = 0 # summed pawn distances from the opposing end of the board (how far from promotion?) white_pawn_dist = 0 black_pawn_dist = 0 # add the squares of each piece on the board for ptype in piece_types: white_set = board.pieces(ptype, chess.WHITE) black_set = board.pieces(ptype, chess.BLACK) # encode existence and type of promotions by piece counts but not locations white_counts[ptype - 1] = len(white_set) black_counts[ptype - 1] = len(black_set) if ptype == chess.PAWN: if len(white_set) > 8: white_set = list(white_set)[:8] if len(black_set) > 8: black_set = list(black_set)[:8] for p_square in white_set: out_vec.append(chess.file_index(p_square) + 1) out_vec.append(chess.rank_index(p_square) + 1) end_dist = (7 - (chess.rank_index(chess.H8) - chess.rank_index(p_square))) ** 2 white_pawn_dist += end_dist out_vec += [0] * (16 - len(white_set) * 2) for p_square in black_set: out_vec.append(chess.file_index(p_square) + 1) out_vec.append(chess.rank_index(p_square) + 1) end_dist = (7 - (chess.rank_index(p_square) - chess.rank_index(chess.H1))) ** 2 black_pawn_dist += end_dist out_vec += [0] * (16 - len(black_set) * 2) elif ptype == chess.KNIGHT: if len(white_set) > 2: white_set = list(white_set)[:2] if len(black_set) > 2: black_set = list(black_set)[:2] if len(white_set) > 8: white_set = white_set[:8] for n_square in white_set: out_vec.append(chess.file_index(n_square) + 1) out_vec.append(chess.rank_index(n_square) + 1) out_vec += [0] * (4 - len(white_set) * 2) for n_square in black_set: out_vec.append(chess.file_index(n_square) + 1) out_vec.append(chess.rank_index(n_square) + 1) out_vec += [0] * (4 - len(black_set) * 2) elif ptype == chess.BISHOP: if len(white_set) > 2: white_set = list(white_set)[:2] if len(black_set) > 2: black_set = list(black_set)[:2] for b_square in white_set: out_vec.append(chess.file_index(b_square) + 1) out_vec.append(chess.rank_index(b_square) + 1) out_vec += [0] * (4 - len(white_set) * 2) for b_square in black_set: out_vec.append(chess.file_index(b_square) + 1) out_vec.append(chess.rank_index(b_square) + 1) out_vec += [0] * (4 - len(black_set) * 2) elif ptype == chess.ROOK: if len(white_set) > 2: white_set = list(white_set)[:2] if len(black_set) > 2: black_set = list(black_set)[:2] for r_square in white_set: out_vec.append(chess.file_index(r_square) + 1) out_vec.append(chess.rank_index(r_square) + 1) out_vec += [0] * (4 - len(white_set) * 2) for r_square in black_set: out_vec.append(chess.file_index(r_square) + 1) out_vec.append(chess.rank_index(r_square) + 1) out_vec += [0] * (4 - len(black_set) * 2) elif ptype == chess.QUEEN: if len(white_set) > 1: white_set = list(white_set)[:1] if len(black_set) > 1: black_set = list(black_set)[:1] for q_square in white_set: out_vec.append(chess.file_index(q_square) + 1) out_vec.append(chess.rank_index(q_square) + 1) out_vec += [0] * (2 - len(white_set) * 2) for q_square in black_set: out_vec.append(chess.file_index(q_square) + 1) out_vec.append(chess.rank_index(q_square) + 1) out_vec += [0] * (2 - len(black_set) * 2) else: if len(white_set) > 1: white_set = list(white_set)[:1] if len(black_set) > 1: black_set = list(black_set)[:1] for k_square in white_set: out_vec.append(chess.file_index(k_square) + 1) out_vec.append(chess.rank_index(k_square) + 1) out_vec += [0] * (2 - len(white_set) * 2) for k_square in black_set: out_vec.append(chess.file_index(k_square) + 1) out_vec.append(chess.rank_index(k_square) + 1) out_vec += [0] * (2 - len(black_set) * 2) # get piece support numbers for square in white_set: if board.is_attacked_by(chess.BLACK, square): white_attacked += 1 if board.is_attacked_by(chess.WHITE, square): white_supported += 1 for square in black_set: if board.is_attacked_by(chess.WHITE, square): black_attacked += 1 if board.is_attacked_by(chess.BLACK, square): black_supported += 1 # number of pieces on each side under attack out_vec.append(white_attacked) out_vec.append(black_attacked) # promotions via piece counts out_vec += white_counts out_vec += black_counts # en passant rights if board.has_legal_en_passant(): if board_type == 'LosingBoard': out_vec.append(board.ep_square()) else: out_vec.append(board.ep_square) else: out_vec.append(0) # turn if board_type == 'LosingBoard': out_vec.append(int(board.turn())) else: out_vec.append(int(board.turn)) return out_vec
def board(board=None, squares=None, flipped=False, coordinates=True, style=None, pre="", post=""): """ Renders a board with pieces and/or selected squares as an SVG. :param board: A :class:`chess.BaseBoard` with pieces or ``None``. :param squares: A :class:`chess.SquareSet` with selected squares. :param flipped: Pass ``True`` to flip the board. :param coordinates: Pass ``False`` to disable coordinates in the margin. :param style: CSS to use instead of the default stylesheet. Custom verbatim XML can be added before (*pre*) and after (*post*) all elements. >>> board = chess.Board("8/8/8/8/4N3/8/8/8 w - - 0 1") >>> squares = board.attacks(chess.E4) >>> chess.svg.board(board=board, squares=squares) .. image:: ../docs/Ne4.svg """ builder = [] builder.append(pre) builder.append("<style>") builder.append(DEFAULT_STYLE if style is None else style) builder.append("</style>") builder.append("<defs>") if board: for piece_def in PIECES.values(): builder.append(piece_def) if squares: builder.append(XX) builder.append("</defs>") margin = 20 for square, bb in enumerate(chess.BB_SQUARES): file_index = chess.file_index(square) rank_index = chess.rank_index(square) x = (file_index if not flipped else 7 - file_index) * 45 + margin y = (7 - rank_index if not flipped else rank_index) * 45 + margin cls = "light" if chess.BB_LIGHT_SQUARES & bb else "dark" name = chess.SQUARE_NAMES[square] builder.append( """<rect x="%d" y="%d" class="square %s %s" width="45" height="45" style="stroke: none;" />""" % (x, y, cls, name)) # Render pieces. if board is not None: piece = board.piece_at(square) if piece: href = "%s-%s" % (chess.COLOR_NAMES[piece.color], chess.PIECE_NAMES[piece.piece_type]) builder.append("""<use xlink:href="#%s" x="%d" y="%d" />""" % (href, x, y)) # Render selected squares. if squares is not None and squares & bb: builder.append("""<use xlink:href="#xx" x="%d" y="%d" />""" % (x, y)) if coordinates: for file_index, file_name in enumerate(chess.FILE_NAMES): x = (file_index if not flipped else 7 - file_index) * 45 + margin builder.append(_text(file_name, x, 0, 45, margin)) builder.append(_text(file_name, x, margin + 8 * 45, 45, margin)) for rank_index, rank_name in enumerate(chess.RANK_NAMES): y = (7 - rank_index if not flipped else rank_index) * 45 + margin builder.append(_text(rank_name, 0, y, margin, 45)) builder.append(_text(rank_name, margin + 8 * 45, y, margin, 45)) builder.append(post) return _svg("".join(builder), 45 * 8 + 2 * margin, 45 * 8 + 2 * margin)
def wkMove2bk(wk, bk): x = chess.rank_index(list(wk)[0]) - chess.rank_index(list(bk)[0]) y = chess.file_index(list(wk)[0]) - chess.file_index(list(bk)[0]) return 20 - floor((y**2 + x**2)**(1 / 2))
def whiteRookAtk(board, wr, bk): x = abs(chess.rank_index(list(wr)[0]) - chess.rank_index(list(bk)[0])) y = abs(chess.file_index(list(wr)[0]) - chess.file_index(list(bk)[0])) return -min(x, y) return 0
def GLJweight(orig, dest): x1 = chess.file_index(orig) y1 = chess.rank_index(orig) x2 = chess.file_index(dest) y2 = chess.rank_index(dest) return 1 - ((7.0 * ChebyshevDistance(x1, y1, x2, y2)) / 64.0)
def heuristicX(board, wR, wN, wK, bK, bN, c): score = 0 if bool(wR): #Check to see if white rook exists score += 300 #Has a rook x = abs(chess.rank_index(list(wR)[0]) - chess.rank_index(list(bK)[0])) y = abs(chess.file_index(list(wR)[0]) - chess.file_index(list(bK)[0])) score -= min(x, y) #Rook attacking around Black King if bool( board.attacks(list(bK)[0]).intersection( board.attacks(list(wR)[0]))): score += 5 #defend rook with king if bool(board.attacks(list(wK)[0]).intersection(wR)): score += 5 #Rook attacking king if bool(board.attacks(list(wR)[0]).intersection(bK)): score += 10 if bool(wN): score += 150 #has a Knight #Knight attacking around Black King if bool( board.attacks(list(bK)[0]).intersection( board.attacks(list(wN)[0]))): score += 5 #defend Knight with king if bool(board.attacks(list(wK)[0]).intersection(wN)): score += 5 #Knight attacking king if bool(board.attacks(list(wN)[0]).intersection(bK)): score += 10 x = abs(chess.rank_index(list(wN)[0]) - chess.rank_index(list(bK)[0])) y = abs(chess.file_index(list(wN)[0]) - chess.file_index(list(bK)[0])) score -= min(x, y) if not bool(bN): score += 76 if not bool(wN): score += 75 if board.is_pinned(chess.BLACK, list(bK)[0]): score += 40 if bool( board.attacks(list(bK)[0]).intersection(board.attacks( list(wK)[0]))): score += 10 x = abs(chess.rank_index(list(wK)[0]) - chess.rank_index(list(bK)[0])) y = abs(chess.file_index(list(wK)[0]) - chess.file_index(list(bK)[0])) score -= min(x, y) * 2 score += len(board.attacks(list(wK)[0])) return score
def board(board=None, squares=None, flipped=False, coordinates=True, lastmove=None, check=None, size=400, style=None, pre="", post=""): """ Renders a board with pieces and/or selected squares as an SVG. :param board: A :class:`chess.BaseBoard` with pieces or ``None``. :param squares: A :class:`chess.SquareSet` with selected squares. :param flipped: Pass ``True`` to flip the board. :param coordinates: Pass ``False`` to disable coordinates in the margin. :param lastmove: A :class:`chess.Move` to be highlighted. :param check: A square to be marked as check. :param size: The width and height of the image. :param style: CSS to use instead of the default stylesheet. Custom verbatim XML can be added before (*pre*) and after (*post*) all elements. >>> board = chess.Board("8/8/8/8/4N3/8/8/8 w - - 0 1") >>> squares = board.attacks(chess.E4) >>> chess.svg.board(board=board, squares=squares) .. image:: ../docs/Ne4.svg """ builder = [] builder.append(pre) builder.append("<style>") builder.append(DEFAULT_STYLE if style is None else style) builder.append("</style>") builder.append("<defs>") if board: for piece_def in PIECES.values(): builder.append(piece_def) if squares: builder.append(XX) if check is not None: builder.append(CHECK_GRADIENT) builder.append("</defs>") margin = 0.05 * size if coordinates else 0 square_size = (size - 2 * margin) / 8.0 piece_scale = square_size / 45.0 for square, bb in enumerate(chess.BB_SQUARES): file_index = chess.file_index(square) rank_index = chess.rank_index(square) x = (file_index if not flipped else 7 - file_index) * square_size + margin y = (7 - rank_index if not flipped else rank_index) * square_size + margin cls = ["square", "light" if chess.BB_LIGHT_SQUARES & bb else "dark", chess.SQUARE_NAMES[square]] if lastmove and square in [lastmove.from_square, lastmove.to_square]: cls.append("lastmove") builder.append("""<rect x="%f" y="%f" class="%s" width="%f" height="%f" style="stroke: none;" />""" % (x, y, " ".join(cls), square_size, square_size)) if square == check: builder.append("""<rect x="%f" y="%f" class="check" width="%f" height="%f" />""" % (x, y, square_size, square_size)) # Render pieces. if board is not None: piece = board.piece_at(square) if piece: href = "%s-%s" % (chess.COLOR_NAMES[piece.color], chess.PIECE_NAMES[piece.piece_type]) builder.append("""<use xlink:href="#%s" transform="translate(%f, %f) scale(%f %f)" />""" % (href, x, y, piece_scale, piece_scale)) # Render selected squares. if squares is not None and squares & bb: builder.append("""<use xlink:href="#xx" x="%f" y="%f" />""" % (x, y)) if coordinates: for file_index, file_name in enumerate(chess.FILE_NAMES): x = (file_index if not flipped else 7 - file_index) * square_size + margin builder.append(_text(file_name, x, 0, square_size, margin)) builder.append(_text(file_name, x, margin + 8 * square_size, square_size, margin)) for rank_index, rank_name in enumerate(chess.RANK_NAMES): y = (7 - rank_index if not flipped else rank_index) * square_size + margin builder.append(_text(rank_name, 0, y, margin, square_size)) builder.append(_text(rank_name, margin + 8 * square_size, y, margin, square_size)) builder.append(post) return _svg("".join(builder), size, size)
def board(board=None, squares=None, flipped=False, coordinates=True, lastmove=None, check=None, size=400, style=None, pre="", post=""): """ Renders a board with pieces and/or selected squares as an SVG. :param board: A :class:`chess.BaseBoard` with pieces or ``None``. :param squares: A :class:`chess.SquareSet` with selected squares. :param flipped: Pass ``True`` to flip the board. :param coordinates: Pass ``False`` to disable coordinates in the margin. :param lastmove: A :class:`chess.Move` to be highlighted. :param check: A square to be marked as check. :param size: The width and height of the image. :param style: CSS to use instead of the default stylesheet. Custom verbatim XML can be added before (*pre*) and after (*post*) all elements. >>> board = chess.Board("8/8/8/8/4N3/8/8/8 w - - 0 1") >>> squares = board.attacks(chess.E4) >>> chess.svg.board(board=board, squares=squares) .. image:: ../docs/Ne4.svg """ builder = [] builder.append(pre) builder.append("<style>") builder.append(DEFAULT_STYLE if style is None else style) builder.append("</style>") builder.append("<defs>") if board: for piece_def in PIECES.values(): builder.append(piece_def) if squares: builder.append(XX) if check is not None: builder.append(CHECK_GRADIENT) builder.append("</defs>") margin = 0.05 * size if coordinates else 0 square_size = (size - 2 * margin) / 8.0 piece_scale = square_size / 45.0 for square, bb in enumerate(chess.BB_SQUARES): file_index = chess.file_index(square) rank_index = chess.rank_index(square) x = (file_index if not flipped else 7 - file_index) * square_size + margin y = (7 - rank_index if not flipped else rank_index) * square_size + margin cls = [ "square", "light" if chess.BB_LIGHT_SQUARES & bb else "dark", chess.SQUARE_NAMES[square] ] if lastmove and square in [lastmove.from_square, lastmove.to_square]: cls.append("lastmove") builder.append( """<rect x="%f" y="%f" class="%s" width="%f" height="%f" style="stroke: none;" />""" % (x, y, " ".join(cls), square_size, square_size)) if square == check: builder.append( """<rect x="%f" y="%f" class="check" width="%f" height="%f" />""" % (x, y, square_size, square_size)) # Render pieces. if board is not None: piece = board.piece_at(square) if piece: href = "%s-%s" % (chess.COLOR_NAMES[piece.color], chess.PIECE_NAMES[piece.piece_type]) builder.append( """<use xlink:href="#%s" transform="translate(%f, %f) scale(%f %f)" />""" % (href, x, y, piece_scale, piece_scale)) # Render selected squares. if squares is not None and squares & bb: builder.append("""<use xlink:href="#xx" x="%f" y="%f" />""" % (x, y)) if coordinates: for file_index, file_name in enumerate(chess.FILE_NAMES): x = (file_index if not flipped else 7 - file_index) * square_size + margin builder.append(_text(file_name, x, 0, square_size, margin)) builder.append( _text(file_name, x, margin + 8 * square_size, square_size, margin)) for rank_index, rank_name in enumerate(chess.RANK_NAMES): y = (7 - rank_index if not flipped else rank_index) * square_size + margin builder.append(_text(rank_name, 0, y, margin, square_size)) builder.append( _text(rank_name, margin + 8 * square_size, y, margin, square_size)) builder.append(post) return _svg("".join(builder), size, size)
def p_val_w(piece, square, board, end_game): value, a_value, d_value = 0, 0, 0 index, pawn_columns_offset, bishop_index = 63 - square, OFFSET_WHITE, 0 # score for defending and attacking pieces # find attacking pieces attacker_positions = board.attackers(chess.BLACK, square) # find defensive pieces defender_positions = board.attackers(chess.WHITE, square) # score attacking pieces based on corresponding action value for position in attacker_positions: a_value += action_value(board.piece_type_at(position)) # score defensive pieces based on corresponding action value for position in defender_positions: d_value += action_value(board.piece_type_at(position)) # find the action value of the position actn_value = d_value - a_value value += actn_value if actn_value < 0: # double penalty for hanging pieces ie. more attacking value += actn_value * 5 # score for pieces and piece positions if piece.piece_type == chess.PAWN: r = chess.rank_index(square) value += (P + pawn_table[index]) # set bools for pawn positioning # add or subtract weights for bools: # pawns on sides lose 15% of value if square % 8 == 0 or square % 8 == 7: value -= 15 # 2 pawns on same file lose value if pawn_columns[(square % 8) + pawn_columns_offset] > 0: value -= 16 if r == 6: # pawns that are moved forward potentially gain value if a_value == 0: pawn_columns[(square % 8) + pawn_columns_offset] += 100 elif d_value != 0: pawn_columns[(square % 8) + pawn_columns_offset] += 25 elif r == 7: # same as above if a_value == 0: pawn_columns[(square % 8) + pawn_columns_offset] += 200 elif d_value != 0: pawn_columns[(square % 8) + pawn_columns_offset] += 50 pawn_columns[(square % 8) + pawn_columns_offset] += 10 elif piece.piece_type == chess.KNIGHT: value += (N + knight_table[index]) if end_game: value -= 10 # Knights are strong mid-game and weak endgame elif piece.piece_type == chess.BISHOP: bishop_count[bishop_index] += 1 value += (B + bishop_table[index]) if bishop_count[bishop_index] >= 2: value += 10 # having 2 bishops is good for board control elif end_game: value += 10 # bishops are more valuable in the end game elif piece.piece_type == chess.ROOK: value += (R + rook_table[index]) elif piece.piece_type == chess.QUEEN: value += (Q + queen_table[index]) else: if not end_game: value += (K + king_table_early[index]) else: value += (K + king_table_late[index]) return value