コード例 #1
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
    ]
コード例 #2
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)
コード例 #3
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)
コード例 #4
0
    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
コード例 #5
0
 def is_forward(self):
     """From the perspective of the current player, i.e. current player's pawns move up the board."""
     from_rank = chess.square_rank(self.move.from_square)
     to_rank = chess.square_rank(self.move.to_square)
     if self.aug.current_color == chess.WHITE:
         return from_rank < to_rank
     return from_rank > to_rank
コード例 #6
0
def get_random_board(num_pcs=None):
    board = chess.Board(None)
    lst = list(range(64))
    random.shuffle(lst)

    kingw = lst.pop()
    kingb = lst.pop()

    piecew = chess.Piece(chess.KING, True)
    board_map = {kingw: piecew}
    pieceb = chess.Piece(chess.KING, False)
    board_map[kingb] = pieceb

    if num_pcs is None:
        num_pcs = random.randint(0, len(lst))
    for pos in lst[0:num_pcs]:
        min_pcs = 1
        if chess.square_rank(pos) == 0 or chess.square_rank(pos) == 7:
            min_pcs = 2
        p = random.randint(min_pcs, 5)
        col = random.randint(0, 1)
        piece = chess.Piece(p, col)
        board_map[pos] = piece

    board.set_piece_map(board_map)
    return board
コード例 #7
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
コード例 #8
0
 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')
コード例 #9
0
ファイル: agent.py プロジェクト: adamklein/CS221
def utility1(board, print_board=False):
    global node_count
    node_count += 1

    factor = (1 if (board.turn == chess.WHITE) else -1)

    if board.is_variant_win():
        return 1000 * factor
    elif board.is_variant_loss():
        return -1000 * factor

    fen = Counter(board.board_fen())
    wk_rank = chess.square_rank(board.pieces(chess.KING, chess.WHITE).pop())
    bk_rank = chess.square_rank(board.pieces(chess.KING, chess.BLACK).pop())
    rankdiff = (wk_rank - bk_rank)
    material = (9 * (fen['Q'] - fen['q']) + 5 * (fen['R'] - fen['r']) + 3 *
                (fen['B'] - fen['b'] + fen['N'] - fen['n']))

    w_mobility = len(list(board.legal_moves))
    board.push(chess.Move.null())
    b_mobility = len(list(board.legal_moves))
    board.pop()
    mobility = (w_mobility -
                b_mobility) * (-1 if board.turn == chess.BLACK else 1)
    #mobility = 0

    # utility from white's perspective
    utility = material + 5 * rankdiff + 0.2 * mobility

    return utility * factor
コード例 #10
0
ファイル: main.py プロジェクト: guesswho798/computer-science
    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
コード例 #11
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
コード例 #12
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
コード例 #13
0
ファイル: baseline_v_oracle.py プロジェクト: adamklein/CS221
    def utility(self, board, player):
        #info = self.engine.analyse(board, chess.engine.Limit(time=0.001)) # nodes = 100
        #score = info['score'].pov(player).score()
        t = time.time()
        fen = Counter(board.board_fen())
        wk_rank = chess.square_rank(
            board.pieces(chess.KING, chess.WHITE).pop())
        bk_rank = chess.square_rank(
            board.pieces(chess.KING, chess.BLACK).pop())
        rankdiff = (wk_rank - bk_rank)
        material = 9 * (fen['Q'] - fen['q']) + 5 * (
            fen['R'] - fen['r']) + 3 * (fen['B'] - fen['b'] + fen['N'] -
                                        fen['n']) + (fen['P'] - fen['p'])

        w_mobility = len(list(board.legal_moves))
        board.push(chess.Move.null())
        b_mobility = len(list(board.legal_moves))
        board.pop()
        mobility = (w_mobility -
                    b_mobility) * (-1 if board.turn == chess.BLACK else 1)

        # utility from white's perspective
        utility = material + 5 * rankdiff + 0.2 * mobility

        utility *= (1 if (player == chess.WHITE) else -1)

        #print(board)
        #print(f"WHITE? {player == chess.WHITE} Util: {utility} Depth: {len(board.move_stack)} Elapsed: {time.time() - t}")
        #import pdb; pdb.set_trace()

        return utility
コード例 #14
0
ファイル: chess_env.py プロジェクト: Pol-GR/RL-chess_aidl
  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))
コード例 #15
0
ファイル: cook.py プロジェクト: mctwynne/lichess-puzzler
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
コード例 #16
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
コード例 #17
0
    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')
コード例 #18
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)
コード例 #19
0
    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')
コード例 #20
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)
コード例 #21
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))
コード例 #22
0
ファイル: pychess_utils.py プロジェクト: emdoyle/chess_ai
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}
コード例 #23
0
def detect_backward_pawns(board, color):

    backward_pawn_count = 0

    pawns = list(board.pieces(chess.PAWN, color))

    for i in pawns:
        is_backward = True
        for j in pawns:
            if i == j:
                continue
            else:
                # If any other pawn is found at the behind of this pawn, then is_backward value is setted as False
                # For white and black players, procedure is reversed
                if color == chess.WHITE and chess.square_rank(
                        i) > chess.square_rank(j):
                    is_backward = False
                    break
                elif color == chess.BLACK and chess.square_rank(
                        i) < chess.square_rank(j):
                    is_backward = False
                    break
        if is_backward == True:
            backward_pawn_count += 1

    return backward_pawn_count
コード例 #24
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
コード例 #25
0
ファイル: board.py プロジェクト: imjustaboi/python-basicChess
    def __init__(self, index):
        self.tile_index = index
        self.tile_name = chess.SQUARE_NAMES[index]

        self.tile_ofRowIndex = chess.square_rank(index)
        self.tile_ofRowName = chess.square_rank(index)

        self.tile_ofColumnIndex = chess.square_file(index)
コード例 #26
0
 def crowning(self, to):
     if self.map.piece_at(to).piece_type == chess.PAWN:
         if self.map.turn:
             if chess.square_rank(to) == 8:
                 return True
         else:
             if chess.square_rank(to) == 1:
                 return True
     return False
コード例 #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 _hw_detect_move_player(self):
        """ Detect move from player

        We compare the expected occupancy with the actual occupancy. If two squares are different then
        we set the square where the clients piece used to be as the from square and the other square as the too
        square. Using this we create a candidate move (from_square, to_square). If this is a legal move then we
        will place this move in the output field. Note that the chess library will detect any other side effects
        from the move like captures, promotions and en passant. The internal board will be updated correctly
        and the diff will be marked on the board.
        """
        draw_offer = False
        while not self.game_is_over():
            occupancy = self._hwi.get_occupancy()
            diff = self._diff_occupancy_board(occupancy)
            self._hwi.mark_squares(diff)

            offers = self._hwi.game_end_offers()
            if offers is HardwareInterface.Offer.RESIGN:
                self._resigned = True
                return engine.PlayResult(None, None, resigned=True)
            if offers is HardwareInterface.Offer.DRAW:
                draw_offer = True

            # Detect all changed squares
            squares = []
            for file in range(8):
                for rank in range(8):
                    if diff[file][rank]:
                        squares.append(chess.square(file, rank))

            if len(squares) == 2:  # Try to convert changed squares to legal move
                with self._board_lock:  # Promotion not implemented
                    if self._board.piece_at(squares[0]) is not None and \
                            self._board.piece_at(squares[0]).color == self.color:
                        move = chess.Move(squares[0], squares[1])
                    elif self._board.piece_at(squares[1]) is not None and \
                            self._board.piece_at(squares[1]).color == self.color:
                        move = chess.Move(squares[1], squares[0])
                    else:
                        continue
                    if self._board.piece_at(move.from_square).piece_type == chess.PAWN and \
                            ((self.color == chess.WHITE and chess.square_rank(move.to_square) == 7) or
                             (self.color == chess.BLACK and chess.square_rank(move.to_square) == 0)):
                        move.promotion = chess.QUEEN
                    move_is_legal = move in self._board.legal_moves  # save result to not use two locks
                    if move_is_legal and move.promotion is not None:
                        move.promotion = self._hwi.promotion_piece()

                if move_is_legal:
                    with self._board_lock:
                        self._board.push(move)
                    with self._playResult_lock:
                        self._output_playResult = engine.PlayResult(move, None, draw_offered=draw_offer)
                    return
            self._update_display()
            sleep(SLEEP_TIME)
コード例 #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)
コード例 #30
0
ファイル: utils.py プロジェクト: igres9014/gym_chess2
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
コード例 #31
0
ファイル: svg.py プロジェクト: teacoffee2017/python-chess
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")