示例#1
0
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)))
示例#2
0
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)
示例#3
0
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
示例#4
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
示例#5
0
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)
示例#6
0
 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
示例#7
0
    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)
示例#8
0
文件: EcbFSM.py 项目: well69/ecb-host
    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
示例#9
0
 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)
示例#10
0
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))
示例#11
0
def square_to_pos(command):
    return (chess.file_index(command.to_square), chess.rank_index(command.to_square))
示例#12
0
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
示例#13
0
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)
示例#14
0
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))
示例#15
0
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
示例#16
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)
示例#17
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
示例#18
0
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)
示例#19
0
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)
示例#20
0
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