def create_move_encoding(self, move):
        assert isinstance(move, chess.Move)
        index = 0
        move_key = (chess.square_rank(move.to_square) -
                    chess.square_rank(move.from_square),
                    chess.square_file(move.to_square) -
                    chess.square_file(move.from_square),
                    0 if move.promotion is None else move.promotion)
        init_vector = [0 for x in range(64 * 73)]
        if move is None or move == chess.Move.null():
            return init_vector
        if self.board.piece_at(move.from_square).piece_type == chess.KNIGHT \
                or move.promotion is not None and move.promotion != chess.QUEEN:
            index = 56 + self.special_move_indices[move_key]
        else:
            king_steps = chess.square_distance(move.from_square,
                                               move.to_square)
            unit_vector = (move_key[0], move_key[1])
            if king_steps != 0:
                unit_vector = (move_key[0] / king_steps,
                               move_key[1] / king_steps)

            if unit_vector != (0, 0):
                index = 7 * self.unit_moves[unit_vector] + king_steps - 1

        print(index)
        init_vector[move.from_square * 73 + index] = 1
        return init_vector
예제 #2
0
파일: qboard.py 프로젝트: aole/Chess-Coach
 def paint_pieces(self, painter, board, flip, piece_size):
     last_move = self.game.get_last_move()
     
     for s in chess.SQUARES:
         x = piece_size * ((7 - chess.square_file(s)) if flip else chess.square_file(s))
         y = piece_size * (chess.square_rank(s) if flip else (7 - chess.square_rank(s)))
         
         p = board.piece_at(s)
         if p:
             if s == self.from_square and self.mouseMovePos:
                 x = self.mouseMovePos.x() - self.offset_x
                 y = self.mouseMovePos.y() - self.offset_y
                 
             # center images
             if show_ascii:
                 sym = p.unicode_symbol()
                 painter.drawText(x, y, piece_size, piece_size, Qt.AlignCenter, sym)
             else:
                 piece_index = PIECE_IMAGE_INDEX[p.piece_type] + (0 if p.color else 6)
                 img = QImage.scaled(self.piece_map[piece_index], piece_size, piece_size, Qt.KeepAspectRatio)
                 offset_x = (piece_size-img.width())/2
                 offset_y = (piece_size-img.height())/2
                 painter.drawImage(x+offset_x, y+offset_y, img)
     
         if last_move and (last_move.from_square == s or last_move.to_square == s):
             painter.drawRect(x, y, piece_size, piece_size)
예제 #3
0
    def generate_rook_move(self, move):
        print('Creating castling move')
        a_side = chess.square_file(move.to_square) < chess.square_file(
            move.from_square)
        print('a_side: {}'.format(a_side))

        #TODO: Simplify this using the last digit of the move
        # if board.turn == chess.BLACK: #black's turn next
        #     #Create white rook move
        #     if a_side:
        #         rook_move = 'a1-d1'
        #     else:
        #         rook_move = 'h1-f1'
        # else:
        #     #Create black rook move
        #     if a_side:
        #         rook_move = 'a8-d8'
        #     else:
        #         rook_move = 'h8-f8'

        rank = str(move)[-1]  #'8' or '1'
        if a_side:
            rook_move = 'a{}-d{}'.format(rank, rank)
        else:
            rook_move = 'h{}-f{}'.format(rank, rank)

        print('Rook move: {}'.format(rook_move))
        return rook_move
예제 #4
0
파일: train.py 프로젝트: dshawul/nn-train
def fill_piece(iplanes, ix, bb, b, flip_rank, flip_file):
    """ Compute piece placement and attack plane for a given piece type """
    if AUX_INP:
        abb = 0
        squares = chess.SquareSet(bb)
        for sq in squares:
            abb = abb | b.attacks_mask(sq)
            f = chess.square_file(sq)
            r = chess.square_rank(sq)
            if flip_rank: r = RANK_U - r
            if flip_file: f = FILE_U - f
            iplanes[r, f, ix + 12] = 1.0

        squares = chess.SquareSet(abb)
        for sq in squares:
            f = chess.square_file(sq)
            r = chess.square_rank(sq)
            if flip_rank: r = RANK_U - r
            if flip_file: f = FILE_U - f
            iplanes[r, f, ix] = 1.0
    else:
        squares = chess.SquareSet(bb)
        for sq in squares:
            f = chess.square_file(sq)
            r = chess.square_rank(sq)
            if flip_rank: r = RANK_U - r
            if flip_file: f = FILE_U - f
            iplanes[r, f, ix] = 1.0
예제 #5
0
파일: train.py 프로젝트: dshawul/nn-train
def fill_planes(iplanes, b):
    """ Compute input planes for ResNet training """

    #fill planes
    flip_rank = (b.turn == chess.BLACK)
    flip_file = (chess.square_file(b.king(b.turn)) < 4)
    fill_planes_(iplanes, b, b.turn, flip_rank, flip_file)

    #enpassant, castling, fifty and on-board mask
    if b.ep_square:
        f = chess.square_file(b.ep_square)
        r = chess.square_rank(b.ep_square)
        if flip_rank: r = RANK_U - r
        if flip_file: f = FILE_U - f
        iplanes[r, f, CHANNELS - 8] = 1.0

    if b.has_queenside_castling_rights(b.turn):
        iplanes[:, :, CHANNELS - (6 if flip_file else 7)] = 1.0
    if b.has_kingside_castling_rights(b.turn):
        iplanes[:, :, CHANNELS - (7 if flip_file else 6)] = 1.0
    if b.has_queenside_castling_rights(not b.turn):
        iplanes[:, :, CHANNELS - (4 if flip_file else 5)] = 1.0
    if b.has_kingside_castling_rights(not b.turn):
        iplanes[:, :, CHANNELS - (5 if flip_file else 4)] = 1.0

    iplanes[:, :, CHANNELS - 3] = b.fullmove_number / 200.0
    iplanes[:, :, CHANNELS - 2] = b.halfmove_clock / 100.0
    iplanes[:, :, CHANNELS - 1] = 1.0
예제 #6
0
def dovetail_mate(puzzle: Puzzle) -> bool:
    node = puzzle.game.end()
    board = node.board()
    king = board.king(not puzzle.pov)
    assert king is not None
    assert isinstance(node, ChildNode)
    if square_file(king) in [0, 7] or square_rank(king) in [0, 7]:
        return False
    queen_square = node.move.to_square
    if (util.moved_piece_type(node) != QUEEN
            or square_file(queen_square) == square_file(king)
            or square_rank(queen_square) == square_rank(king)
            or square_distance(queen_square, king) > 1):
        return False
    for square in [
            s for s in SquareSet(chess.BB_ALL) if square_distance(s, king) == 1
    ]:
        if square == queen_square:
            continue
        attackers = list(board.attackers(puzzle.pov, square))
        if attackers == [queen_square]:
            if board.piece_at(square):
                return False
        elif attackers:
            return False
    return True
 def box_corner(self, available_squares, square):
     if chess.square_file(square) == 0 or chess.square_file(square) == 7:
         if (available_squares[1] and available_squares[2]) in self.board.attacks(self.board.king(self.winner())):
             print('Box mate')
     elif chess.square_rank(square) == 0 or chess.square_rank(square) == 7:
         if (available_squares[0] and available_squares[1]) in self.board.attacks(self.board.king(self.winner())):
             print('Box mate')
예제 #8
0
    def get_model_num_from_move(self, move):
        directions = [-1, 1, -7, 7, -8, 8, -9, 9]
        knight_moves = [17, 15, 10, 6, -17, -15, -10, -6]
        diff = move.to_square - move.from_square

        # Underpromotion
        if move.promotion != 5 and move.promotion != None:
            directions = [7, 8, 9]
            for d in directions:
                if abs(diff) == d:
                    direction = d
            _type = 3 * directions.index(direction) + move.promotion - 2 + 64
        # Knight move
        elif diff in knight_moves and square_distance(move.to_square,
                                                      move.from_square) == 2:
            _type = 56 + knight_moves.index(diff)
        else:
            direction = 0
            for d in reversed(directions):
                if np.sign(diff) == np.sign(d) and diff % d == 0:
                    direction = d
                    break
            if square_rank(move.to_square) == square_rank(move.from_square):
                direction = np.sign(diff) * 1
            elif square_file(move.to_square) == square_file(move.from_square):
                direction = np.sign(diff) * 8

            distance = abs(diff / direction)
            _type = 7 * directions.index(direction) + (distance - 1)

        move_num = move.from_square * (7 * 8 + 8 + 9) + _type
        return int(move_num)
예제 #9
0
def get_mobility(board, pieces, num):
    x = []
    pieces = list(pieces)
    for i in range(num):
        if len(pieces) - 1 < i:
            x.append([0, 0, 0, 0])
            continue
        mir = 8
        mar = 0
        mif = 8
        maf = 0
        index = pieces[i]
        ora = chess.square_rank(index)
        ofa = chess.square_file(index)
        for attack in board.attacks(index):
            sr = chess.square_rank(attack)
            sf = chess.square_file(attack)
            if sr < mir:
                mir = sr
            if sr > mar:
                mar = sr
            if sf < mif:
                mif = sf
            if sf > maf:
                maf = sf
        
        x.append([
                (mir - ora) / 7., 
                (mar - ora) / 7., 
                (mif - ofa) / 7., 
                (maf - ofa) / 7.
        ])
    return x
    def ladder_corner(self, available_squares, square):
        # 8 plausible ways to get ladder mated on a corner
        ladder = False

        if chess.square_file(square) == 0 or chess.square_file(square) == 7:
            for i in available_squares[:2]:
                for attacker in self.board.attackers(self.winner(), i):
                    if (square != i and
                        (str(self.board.piece_at(attacker)).upper() == 'Q'
                         or str(self.board.piece_at(attacker)).upper() == 'R')
                            and (chess.square_file(attacker) == 1
                                 or chess.square_file(attacker) == 6)):
                        ladder = True

        elif chess.square_rank(square) == 0 or chess.square_rank(square) == 7:
            for i in available_squares[1:]:
                for attacker in self.board.attackers(self.winner(), i):
                    if (square != i and
                        (str(self.board.piece_at(attacker)).upper() == 'Q'
                         or str(self.board.piece_at(attacker)).upper() == 'R')
                            and (chess.square_rank(attacker) == 1
                                 or chess.square_rank(attacker) == 6)):
                        ladder = True

        # Prevents from printing it out multiple times
        if ladder:
            print('Ladder mate')
예제 #11
0
def exposed_king(puzzle: Puzzle) -> bool:
    if puzzle.pov:
        pov = puzzle.pov
        board = puzzle.mainline[0].board()
    else:
        pov = not puzzle.pov
        board = puzzle.mainline[0].board().mirror()
    king = board.king(not pov)
    assert king is not None
    if chess.square_rank(king) < 5:
        return False
    squares = SquareSet.from_square(king - 8)
    if chess.square_file(king) > 0:
        squares.add(king - 1)
        squares.add(king - 9)
    if chess.square_file(king) < 7:
        squares.add(king + 1)
        squares.add(king - 7)
    for square in squares:
        if board.piece_at(square) == Piece(PAWN, not pov):
            return False
    for node in puzzle.mainline[1::2][1:-1]:
        if node.board().is_check():
            return True
    return False
예제 #12
0
 def is_short_diagonal(from_sq, to_sq):
     '''
     return True if diagonal is short
     '''
     if (((chess.square_rank(to_sq) <= 3) and
          (chess.square_file(to_sq) <= 3))
             or ((chess.square_rank(to_sq) > 3) and
                 (chess.square_file(to_sq) > 3))):
         # This means that King is in lower-left quadrant or
         # in upper-right quadrant
         # In this quadrants NW_SE_diagonals are shortest
         if nw_se_diagonal(from_sq, to_sq):
             return True
         elif sw_ne_diagonal(from_sq, to_sq):
             return False
         else:  # pragma: no cover
             raise KeyError
     else:
         # Other two quadrants. And diagonals are vise-versa.
         if nw_se_diagonal(from_sq, to_sq):
             return False
         elif sw_ne_diagonal(from_sq, to_sq):
             return True
         else:  # pragma: no cover
             raise KeyError
예제 #13
0
  def BoardEncode(self): 
    """Converts a board to numpy array representation (8,8,21) same as Alphazero with history_length = 1 (only one board)"""

    array = np.zeros((8, 8, 26), dtype=int)

    for square, piece in self.board.piece_map().items():
      rank, file = chess.square_rank(square), chess.square_file(square)
      piece_type, color = piece.piece_type, piece.color
        
      # The first six planes encode the pieces of the active player, 
      # the following six those of the active player's opponent. Since
      # this class always stores boards oriented towards the white player,
      # White is considered to be the active player here.
      offset = 0 if color == chess.WHITE else 6
      offset1 = 6 if color == chess.WHITE else 18        
      # Chess enumerates piece types beginning with one, which we have
      # to account for
      idx = piece_type - 1
      # We use now a for loop to save the squares attacked by the piece we just found
      for i in list(self.board.attacks(square)):
            array[chess.square_rank(i),chess.square_file(i),idx+offset1] = 1

      array[rank, file, idx + offset] = 1

      # Repetition counters
    array[:, :, 24] = self.board.is_repetition(2)
    array[:, :, 25] = self.board.is_repetition(3)

    #return array

    #def observation(self, board: chess.Board) -> np.array:
    #Converts chess.Board observations instance to numpy arrays.
    #self._history.push(board)

    #history = self._history.view(orientation=board.turn)
    history = array
    meta = np.zeros(
    shape=(8 ,8, 7),
    dtype=int
    )
    
    # Active player color
    meta[:, :, 0] = int(self.board.turn)
    
    # Total move count
    meta[:, :, 1] = self.board.fullmove_number

    # Active player castling rights
    meta[:, :, 2] = self.board.has_kingside_castling_rights(self.board.turn)
    meta[:, :, 3] = self.board.has_queenside_castling_rights(self.board.turn)
    
    # Opponent player castling rights
    meta[:, :, 4] = self.board.has_kingside_castling_rights(not self.board.turn)
    meta[:, :, 5] = self.board.has_queenside_castling_rights(not self.board.turn)

    # No-progress counter
    meta[:, :, 6] = self.board.halfmove_clock
    observation = np.concatenate([history, meta], axis=-1)

    return np.transpose(observation, (2, 0, 1))
예제 #14
0
def dir_and_dist(square1, square2):
    rank1 = chess.square_rank(square1)
    rank2 = chess.square_rank(square2)
    file1 = chess.square_file(square1)
    file2 = chess.square_file(square2)

    horiz = 'W' if file1 > file2 else 'E'
    vert = 'S' if rank1 > rank2 else 'N'

    filedist = abs(file1 - file2)
    rankdist = abs(rank1 - rank2)
    diag = filedist == rankdist
    straight = filedist == 0 or rankdist == 0
    knight = (filedist == 1 and rankdist == 2) or (filedist == 2
                                                   and rankdist == 1)
    far = 'F' if rankdist == 2 else 'S'

    if diag:
        dist = filedist
        return {'dir': '{}{}'.format(vert, horiz), 'dist': dist}
    elif straight:
        queen_dir = horiz if filedist != 0 else vert
        dist = filedist if filedist != 0 else rankdist
        return {'dir': '{}'.format(queen_dir), 'dist': dist}
    elif knight:
        # The distance should not be needed when handling a knight move, -1 is an indicator
        return {'dir': '{}{}{}'.format(vert, horiz, far), 'dist': -1}
예제 #15
0
    def click(self, x, y):
        global focus, turn
        x = int(x / 50)
        y = int(y / 50)

        # moving the piece that is in my team
        if focus != None and focus.p.color == turn:
            # wheter the move was legal or not
            if focus.Move(x * 50, y * 50, s) == True:
                # moving a turn
                turn = not turn
                focus = None
                return
            # unselecting when move is illigal but staying in function to see if player selected something else
            focus = None

        # on which soldier did the player click and is it on his team
        for square in chess.SQUARES:
            f = board.piece_at(square)
            if f != None and chess.square_file(
                    square
            ) == x and 7 - chess.square_rank(square) == y and f.color == turn:
                focus = soldier(chess.square_file(square),
                                7 - chess.square_rank(square), f)
                break
예제 #16
0
def en_passant(puzzle: Puzzle) -> bool:
    for node in puzzle.mainline[1::2]:
        if (util.moved_piece_type(node) == PAWN and square_file(
                node.move.from_square) != square_file(node.move.to_square)
                and not node.parent.board().piece_at(node.move.to_square)):
            return True
    return False
예제 #17
0
 def moveMatch(candidateMove):
     if move[1] == 0:
         match = board.is_castling(candidateMove)
     elif move[1] == 1:
         match = board.is_capture(candidateMove) and chess.square_rank(
             candidateMove.from_square) < chess.square_rank(
                 candidateMove.to_square)  # forward capture (y-axis)
     elif move[1] == 2:
         match = board.is_capture(candidateMove) and chess.square_rank(
             candidateMove.from_square) > chess.square_rank(
                 candidateMove.to_square)  # backwards capture
     elif move[1] == 3:
         match = board.is_capture(candidateMove) and chess.square_rank(
             candidateMove.from_square) == chess.square_rank(
                 candidateMove.to_square)  # horizontal capture
     elif move[1] == 4:
         match = board.is_into_check(candidateMove)
     elif move[1] == 5:
         match = chess.square_rank(
             candidateMove.from_square) < chess.square_rank(
                 candidateMove.to_square)  # forward candidateMove
     elif move[1] == 6:
         match = chess.square_rank(
             candidateMove.from_square) > chess.square_rank(
                 candidateMove.to_square)
     elif move[1] == 7:
         match = chess.square_file(
             candidateMove.from_square) > chess.square_file(
                 candidateMove.to_square)
     elif move[1] == 8:
         match = chess.square_file(
             candidateMove.from_square) < chess.square_file(
                 candidateMove.to_square)
     return match
예제 #18
0
def back_rank_mate(puzzle: Puzzle) -> bool:
    node = puzzle.game.end()
    board = node.board()
    king = board.king(not puzzle.pov)
    assert king is not None
    assert isinstance(node, ChildNode)
    back_rank = 7 if puzzle.pov else 0
    if board.is_checkmate() and square_rank(king) == back_rank:
        squares = SquareSet.from_square(king + (-8 if puzzle.pov else 8))
        if puzzle.pov:
            if chess.square_file(king) < 7:
                squares.add(king - 7)
            if chess.square_file(king) > 0:
                squares.add(king - 9)
        else:
            if chess.square_file(king) < 7:
                squares.add(king + 9)
            if chess.square_file(king) > 0:
                squares.add(king + 7)
        for square in squares:
            piece = board.piece_at(square)
            if piece is None or piece.color == puzzle.pov or board.attackers(
                    puzzle.pov, square):
                return False
        return any(
            square_rank(checker) == back_rank for checker in board.checkers())
    return False
    def ladder(self, available_squares, square):
        # If all the remaining squares are attacked by a queen or a rook
        ladder = False

        checkmater_file = 0
        checkmater_rank = 0
        attacker_file = 0
        attacker_rank = 0

        for i in available_squares[1:4]:
            for attacker in self.board.attackers(self.winner(), i):       
                if square != i and (str(self.board.piece_at(attacker)).upper() == 'Q' or str(self.board.piece_at(attacker)).upper() == 'R'):
                    # For some reason, it would print 'Ladder mate' 3 times. This just bypasses it.
                    attacker_file = chess.square_file(attacker)
                    attacker_rank = chess.square_rank(attacker)
                    ladder = True

        if (available_squares[0] and available_squares[4]) in self.board.attacks(square):
            checkmater_file = chess.square_file(square)
            checkmater_rank = chess.square_rank(square)
            ladder = True
        else:
            ladder = False

        
        if (((checkmater_file == 0 and attacker_file == 1) or (checkmater_file == 7 and attacker_file == 6)) or 
        ((checkmater_rank == 0 and attacker_rank == 1) or (checkmater_rank == 7 and attacker_rank == 6))):
            if ladder:
                print('Ladder mate')
예제 #20
0
def move_to_tensor(move):
    return [
        chess.square_file(move.from_square) / 8,
        chess.square_rank(move.from_square) / 8,
        chess.square_file(move.to_square) / 8,
        chess.square_rank(move.to_square) / 8
    ]
예제 #21
0
    def remove_closest(self, pieces_squares, square, piece_type):
        #skip if the list of possible squares is empty
        if not pieces_squares:
            return

        min = 100
        pr = 0
        sr = chess.square_file(square)
        if piece_type is chess.PAWN:
            #print("pawn")
            new_ps = []
            for ps in pieces_squares:
                if chess.square_file(ps) is sr:
                    new_ps.append(ps)
            if new_ps:
                pieces_squares = new_ps

        for ps in pieces_squares:
            dist = chess.square_distance(ps, square)
            if dist < min:
                pr = ps
                min = dist

        self.board.remove_piece_at(pr)
        #print(pr)
        return
예제 #22
0
    def adjust_move_tensor(self, move_tensor):
        def move_tensor_diff(tensor_1, tensor_2):
            """
            Compute the difference between two move tensors.
            """
            source_diff = scipy.spatial.distance.euclidean(
                tensor_1[:2], tensor_2[:2])
            target_diff = scipy.spatial.distance.euclidean(
                tensor_1[2:], tensor_2[2:])
            return source_diff**2 + target_diff

        tensor_1 = [x * 8 for x in move_tensor[0][:-1]]
        legal_moves = list(self.legal_moves)
        min_diff = 139  # Maximum diff between two moves.
        for i, legal_move in enumerate(legal_moves):
            tensor_2 = [
                chess.square_file(legal_move.from_square),
                chess.square_rank(legal_move.from_square),
                chess.square_file(legal_move.to_square),
                chess.square_rank(legal_move.to_square)
            ]
            diff = move_tensor_diff(tensor_1, tensor_2)
            if diff < min_diff:
                min_diff = diff
                move_i = i
        return (legal_moves[move_i], min_diff / 139)
예제 #23
0
def encode_knight_move(move):
    def encode_delta(delta):
        return 0 if delta >= 0 else 1
    file_delta = chess.square_file(move.to_square) - chess.square_file(move.from_square)
    rank_delta = chess.square_rank(move.to_square) - chess.square_rank(move.from_square)
    move_type = 0 if abs(rank_delta) > abs(file_delta) else 4  # Provides 8 unique encodings without 8 ifs
    return move_type + 2 * encode_delta(file_delta) + encode_delta(rank_delta)
예제 #24
0
def draw_pieces(screen, state):
    if state.PLAYING_SIDE is chess.WHITE:
        for i in range(len(chess.SQUARES)):
            square = chess.SQUARES[len(chess.SQUARES) - 1 - i]
            x = chess.square_file(square)
            y = chess.square_rank(square)
            piece = state.board.piece_at(i)
            if piece is not None:
                bpiece = pieces[piece.symbol()]
            else:
                bpiece = None

            if bpiece != None:
                screen.blit(
                    IMAGES[bpiece],
                    pg.Rect(WIDTH - SQUARE_SIZE - (x * SQUARE_SIZE),
                            y * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE))
    else:
        for i in range(len(chess.SQUARES)):
            square = chess.SQUARES[i]
            x = chess.square_file(square)
            y = chess.square_rank(square)
            piece = state.board.piece_at(i)
            if piece is not None:
                bpiece = pieces[piece.symbol()]
            else:
                bpiece = None

            if bpiece != None:
                screen.blit(
                    IMAGES[bpiece],
                    pg.Rect(WIDTH - SQUARE_SIZE - (x * SQUARE_SIZE),
                            y * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE))
예제 #25
0
def deflection(puzzle: Puzzle) -> bool:
    for node in puzzle.mainline[1::2][1:]:
        captured_piece = node.parent.board().piece_at(node.move.to_square)
        if captured_piece or node.move.promotion:
            capturing_piece = util.moved_piece_type(node)
            if captured_piece and util.king_values[
                    captured_piece.
                    piece_type] > util.king_values[capturing_piece]:
                continue
            square = node.move.to_square
            prev_op_move = node.parent.move
            assert (prev_op_move)
            grandpa = node.parent.parent
            assert isinstance(grandpa, ChildNode)
            prev_player_move = grandpa.move
            prev_player_capture = grandpa.parent.board().piece_at(
                prev_player_move.to_square)
            if ((not prev_player_capture
                 or util.values[prev_player_capture.piece_type] <
                 util.moved_piece_type(grandpa))
                    and square != prev_op_move.to_square
                    and square != prev_player_move.to_square
                    and (prev_op_move.to_square == prev_player_move.to_square
                         or grandpa.board().is_check()) and
                (square in grandpa.board().attacks(prev_op_move.from_square)
                 or node.move.promotion and square_file(node.move.to_square)
                 == square_file(prev_op_move.from_square)
                 and node.move.from_square in grandpa.board().attacks(
                     prev_op_move.from_square))
                    and (not square in node.parent.board().attacks(
                        prev_op_move.to_square))):
                return True
    return False
예제 #26
0
def is_passed(board, pawn, color):
    enemy_pawns = board.pieces(chess.PAWN, not color)
    opposing_squares = squares_ahead(pawn, color)
    if chess.square_file(pawn) != 0:
        opposing_squares |= squares_ahead(pawn - 1, color)
    if chess.square_file(pawn) != 7:
        opposing_squares |= squares_ahead(pawn + 1, color)
    return len(enemy_pawns & opposing_squares) == 0
예제 #27
0
def move_to_cat(board, move):
    pieceFile = chess.square_file(move.from_square)
    pieceType = board.piece_type_at(move.from_square)
    if pieceType == 3:
        piece = 0
    elif pieceType == 2:
        piece = 1
    elif pieceType == 4:
        piece = 2
    if pieceType == 1 and pieceFile < 2:
        piece = 3
    if pieceType == 1 and 1 < pieceFile < 4:
        piece = 4
    if pieceType == 1 and 3 < pieceFile < 6:
        piece = 5
    if pieceType == 1 and 5 < pieceFile < 8:
        piece = 6
    elif pieceType == 6:
        piece = 7
    elif pieceType == 5:
        piece = 8
    pieces = [0, 0, 0, 0, 0, 0, 0, 0, 0]
    pieces[piece] = 1

    moves = [0, 0, 0, 0, 0, 0, 0, 0, 0]

    def checking(board, move):
        board.push(move)
        check = board.is_check()
        board.pop()
        return check

    if board.is_castling(move):
        moves[0] = 1
    elif board.is_capture(move) and chess.square_rank(
            move.from_square) < chess.square_rank(move.to_square):
        moves[1] = 1
    elif board.is_capture(move) and chess.square_rank(
            move.from_square) > chess.square_rank(move.to_square):
        moves[2] = 1
    elif board.is_capture(move) and chess.square_rank(
            move.from_square) == chess.square_rank(move.to_square):
        moves[3] = 1
    if checking(board, move):
        moves[4] = 1
    if chess.square_rank(move.from_square) < chess.square_rank(
            move.to_square):  # forward move:
        moves[5] = 1
    if chess.square_rank(move.from_square) > chess.square_rank(move.to_square):
        moves[6] = 1
    if chess.square_file(move.from_square) > chess.square_file(move.to_square):
        moves[7] = 1
    if chess.square_file(move.from_square) < chess.square_file(move.to_square):
        moves[8] = 1

    return pieces + moves
예제 #28
0
def unpack(move: chess.Move) -> Tuple[int, int, int, int]:
    """Converts chess.Move instances into move coordinates."""

    from_rank = chess.square_rank(move.from_square)
    from_file = chess.square_file(move.from_square)

    to_rank = chess.square_rank(move.to_square)
    to_file = chess.square_file(move.to_square)

    return from_rank, from_file, to_rank, to_file
예제 #29
0
def get_kings_distance_euclidean(board):
    king_white_square = board.king(True)
    king_black_square = board.king(False)
    king_white_file = chess.square_file(king_white_square)
    king_white_rank = chess.square_rank(king_white_square)
    king_black_file = chess.square_file(king_black_square)
    king_black_rank = chess.square_rank(king_black_square)
    x = abs(king_white_file - king_black_file)
    y = abs(king_white_rank - king_black_rank)
    return math.sqrt(x**2 + y**2)
 def grecos(self, available_squares, square):
     if self.is_blocked(available_squares[1]):
         if chess.square_file(square) == 0 or chess.square_file(square) == 7:
             for attacker in self.board.attackers(self.winner(), available_squares[0]):
                 if str(self.board.piece_at(attacker)) == 'B':
                     print("Greco's mate")
         elif chess.square_rank(square) == 0 or chess.square_rank(square) == 7:
             for attacker in self.board.attackers(self.winner(), available_squares[2]):
                 if str(self.board.piece_at(attacker)) == 'B':
                     print("Greco's mate")
예제 #31
0
    def hash_ep_square(self, board: chess.Board) -> int:
        # Hash in the en passant file.
        if board.ep_square:
            # But only if there's actually a pawn ready to capture it. Legality
            # of the potential capture is irrelevant.
            if board.turn == chess.WHITE:
                ep_mask = chess.shift_down(chess.BB_SQUARES[board.ep_square])
            else:
                ep_mask = chess.shift_up(chess.BB_SQUARES[board.ep_square])
            ep_mask = chess.shift_left(ep_mask) | chess.shift_right(ep_mask)

            if ep_mask & board.pawns & board.occupied_co[board.turn]:
                return self.array[772 + chess.square_file(board.ep_square)]
        return 0
예제 #32
0
def board(board=None, squares=None, flipped=False, coordinates=True, lastmove=None, check=None, arrows=(), size=None, style=None):
    """
    Renders a board with pieces and/or selected squares as an SVG image.

    :param board: A :class:`chess.BaseBoard` for a chessboard with pieces or
        ``None`` (the default) for a chessboard without pieces.
    :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 arrows: A list of :class:`~chess.svg.Arrow` objects like
        ``[chess.svg.Arrow(chess.E2, chess.E4)]`` or a list of tuples like
        ``[(chess.E2, chess.E4)]``. An arrow from a square pointing to the same
        square is drawn as a circle, like ``[(chess.E2, chess.E2)]``.
    :param size: The size of the image in pixels (e.g., ``400`` for a 400 by
        400 board) or ``None`` (the default) for no size limit.
    :param style: A CSS stylesheet to include in the SVG image.

    >>> import chess
    >>> import chess.svg
    >>>
    >>> from IPython.display import SVG
    >>>
    >>> board = chess.Board("8/8/8/8/4N3/8/8/8 w - - 0 1")
    >>> squares = board.attacks(chess.E4)
    >>> SVG(chess.svg.board(board=board, squares=squares))  # doctest: +SKIP

    .. image:: ../docs/Ne4.svg
    """
    margin = 20 if coordinates else 0
    svg = _svg(8 * SQUARE_SIZE + 2 * margin, size)

    if style:
        ET.SubElement(svg, "style").text = style

    defs = ET.SubElement(svg, "defs")
    if board:
        for color in chess.COLORS:
            for piece_type in chess.PIECE_TYPES:
                if board.pieces_mask(piece_type, color):
                    defs.append(ET.fromstring(PIECES[chess.Piece(piece_type, color).symbol()]))
    if squares:
        defs.append(ET.fromstring(XX))
    if check is not None:
        defs.append(ET.fromstring(CHECK_GRADIENT))

    for square, bb in enumerate(chess.BB_SQUARES):
        file_index = chess.square_file(square)
        rank_index = chess.square_rank(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"]
        if lastmove and square in [lastmove.from_square, lastmove.to_square]:
            cls.append("lastmove")
        fill_color = DEFAULT_COLORS[" ".join(cls)]
        cls.append(chess.SQUARE_NAMES[square])

        ET.SubElement(svg, "rect", {
            "x": str(x),
            "y": str(y),
            "width": str(SQUARE_SIZE),
            "height": str(SQUARE_SIZE),
            "class": " ".join(cls),
            "stroke": "none",
            "fill": fill_color,
        })

        if square == check:
            ET.SubElement(svg, "rect", {
                "x": str(x),
                "y": str(y),
                "width": str(SQUARE_SIZE),
                "height": str(SQUARE_SIZE),
                "class": "check",
                "fill": "url(#check_gradient)",
            })

        # Render pieces.
        if board is not None:
            piece = board.piece_at(square)
            if piece:
                ET.SubElement(svg, "use", {
                    "xlink:href": "#%s-%s" % (chess.COLOR_NAMES[piece.color], chess.PIECE_NAMES[piece.piece_type]),
                    "transform": "translate(%d, %d)" % (x, y),
                })

        # Render selected squares.
        if squares is not None and squares & bb:
            ET.SubElement(svg, "use", {
                "xlink:href": "#xx",
                "x": str(x),
                "y": str(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
            svg.append(_text(file_name, x, 0, SQUARE_SIZE, margin))
            svg.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
            svg.append(_text(rank_name, 0, y, margin, SQUARE_SIZE))
            svg.append(_text(rank_name, margin + 8 * SQUARE_SIZE, y, margin, SQUARE_SIZE))

    for tail, head in arrows:
        tail_file = chess.square_file(tail)
        tail_rank = chess.square_rank(tail)
        head_file = chess.square_file(head)
        head_rank = chess.square_rank(head)

        xtail = margin + (tail_file + 0.5 if not flipped else 7.5 - tail_file) * SQUARE_SIZE
        ytail = margin + (7.5 - tail_rank if not flipped else tail_rank + 0.5) * SQUARE_SIZE
        xhead = margin + (head_file + 0.5 if not flipped else 7.5 - head_file) * SQUARE_SIZE
        yhead = margin + (7.5 - head_rank if not flipped else head_rank + 0.5) * SQUARE_SIZE

        if (head_file, head_rank) == (tail_file, tail_rank):
            ET.SubElement(svg, "circle", {
                "cx": str(xhead),
                "cy": str(yhead),
                "r": str(SQUARE_SIZE * 0.9 / 2),
                "stroke-width": str(SQUARE_SIZE * 0.1),
                "stroke": "#888",
                "fill": "none",
                "opacity": "0.5",
            })
        else:
            marker_size = 0.75 * SQUARE_SIZE
            marker_margin = 0.1 * SQUARE_SIZE

            dx, dy = xhead - xtail, yhead - ytail
            hypot = math.hypot(dx, dy)

            shaft_x = xhead - dx * (marker_size + marker_margin) / hypot
            shaft_y = yhead - dy * (marker_size + marker_margin) / hypot

            xtip = xhead - dx * marker_margin / hypot
            ytip = yhead - dy * marker_margin / hypot

            ET.SubElement(svg, "line", {
                "x1": str(xtail),
                "y1": str(ytail),
                "x2": str(shaft_x),
                "y2": str(shaft_y),
                "stroke": "#888",
                "stroke-width": str(SQUARE_SIZE * 0.2),
                "opacity": "0.5",
                "stroke-linecap": "butt",
                "class": "arrow",
            })

            marker = []
            marker.append((xtip, ytip))
            marker.append((shaft_x + dy * 0.5 * marker_size / hypot,
                           shaft_y - dx * 0.5 * marker_size / hypot))
            marker.append((shaft_x - dy * 0.5 * marker_size / hypot,
                           shaft_y + dx * 0.5 * marker_size / hypot))

            ET.SubElement(svg, "polygon", {
                "points": " ".join(str(x) + "," + str(y) for x, y in marker),
                "fill": "#888",
                "opacity": "0.5",
                "class": "arrow",
            })

    return ET.tostring(svg).decode("utf-8")