Exemplo n.º 1
0
        def process_tree(node: ChessSearchNode, board: chess.Board):
            if node.move_index is None:
                fen = board.fen()
                move_san = ''
            else:
                move = chess.Move.from_uci(self.config.labels[node.move_index])
                move_san = board.san(move)
                board.push(move)
                fen = board.fen()

            tree = {
                'fen': fen,
                'prev_move': move_san,
                'static_value': node.static_value,
                'rollup_value': node.rollup_value,
                'move_probability': node.move_probability,
            }

            if node.children_created and node.depth < max_depth:
                children = [
                    process_tree(child, board)
                    for move_index, child in node.children.items()
                ]
                children = sorted(children,
                                  key=lambda child: child['move_probability'],
                                  reverse=True)

                tree['children'] = children

            if node.depth > 0:
                board.pop()

            return tree
Exemplo n.º 2
0
def get_root(fen, moves):
    board = Board(fen)
    root = Node(fen)
    if moves is not None:
        for move in moves:
            fen = board.fen().split(' ')
            root.previous.append(' '.join(fen[:2]))
            board.push(Move.from_uci(move))
    root.position = board.fen()
    return root
Exemplo n.º 3
0
def dfs(state, num_searches, isplayer):
    comp = max if isplayer else min
    board = Board(state)
    if (board.is_checkmate()):
        return 0.0 if isplayer else 1.0
    if (board.is_stalemate()):
        return 0.5
    if (board.can_claim_draw()):
        return 0.5
    rv = 0.0 if isplayer else 1.0
    moves = list(board.legal_moves)
    # if number of nodes to search exceeds the search limit provided
    # score all nodes
    if (len(moves) > num_searches):
        for move in moves:
            board.push(move)
            rv = comp(rv, score(board.fen()))
            board.pop()
        return rv
    search_move = [False for _ in range(len(moves))]
    search_count = 0
    i = 0
    while i < len(moves):
        inc = min(60, len(moves) - i)
        # gives 50% chance for all nodes to be searched
        # TODO make an adjustable probability parameter
        tp = random.randrange(1 << inc)
        while tp > 0:
            if (tp & 1):
                search_move[i] = True
                search_count += 1
            tp >>= 1
        i += inc
    score_count = len(moves) - search_count
    nodes_per_search = 0
    if (search_count != 0):
        nodes_per_search = (num_searches - score_count) // search_count
    vals = []
    for i in range(len(moves)):
        move = moves[i]
        if search_move[i]:
            board.push(move)
            rv = comp(rv, dfs(board.fen(), nodes_per_search, not isplayer))
            board.pop()
        else:
            board.push(move)
            rv = comp(rv, score(move))
            board.pop()
    return rv
Exemplo n.º 4
0
def repertoire(id=1):
    if request.args.get('practice'):
        print(practice(id))
    board = Board()
    form = MoveForm()
    if request.method == 'GET':
        position = Position.query.filter_by(id=id).first()
        moves = Move.query.join(User.moves).filter(User.id == current_user.id, Move.source_position_id == position.id).all()
        return render_template('tools/repertoire.html', fen=position.fen + ' 0 1', moves=moves, form=form, id=id)
    
    if request.method == 'POST':
        fen = form.append_fen.data
        san = form.append_san.data
        quality_id = form.quality.data
        board = Board(fen)
        board.push_san(san)
        source_position = Position.query.filter_by(fen=' '.join(fen.split()[:-2])).first()
        end_position_fen = ' '.join(board.fen().split()[:-2])
        end_position = Position.query.filter_by(fen=end_position_fen).first()
        if end_position is None:
            end_position = Position(fen=end_position_fen)
            db.session.add(end_position)
        move = Move.query.filter_by(source_position_id=source_position.id, destination_position_id=end_position.id).first()
        if move is None:
            move = Move(source_position_id=source_position.id, destination_position_id=end_position.id, san=san)
            um = UserMove(quality_id=quality_id)
            um.move = move
            current_user.moves.append(um)
        db.session.commit()
        moves = Move.query.join(User.moves).filter(User.id == current_user.id, Move.source_position_id == source_position.id).all()
        return render_template('tools/repertoire.html', fen=source_position.fen + ' 0 1', moves=moves, form=form, id=id)
Exemplo n.º 5
0
def evaluation_from_board(board: chess.Board,
                          evaluation_depth: int = 22) -> Dict:
    board_fen = board.fen()
    stockfish = Stockfish("/opt/homebrew/Cellar/stockfish/13/bin/stockfish")
    stockfish.set_depth(evaluation_depth)  # set engine depth
    stockfish.set_fen_position(board_fen)
    return stockfish.get_evaluation()
Exemplo n.º 6
0
    def evaluate(self, board: chess.Board) -> int:
        """
        Evaluate board via. piece position/value tables in addition
        to material differences

        Args:
            board (chess.Board): board state to evaluate
        Returns:
            (int)
        """
        val = 0
        for square in chess.SQUARES:
            piece = board.piece_type_at(square)
            color = board.color_at(square)

            if piece:
                # Get base piece value, add position based value from
                # piece value table
                piece_value = self.piece_values[PIECE_NAMES[piece]].value
                piece_value += get_piece_value_from_table(
                    PIECE_NAMES[piece], color, square, self.value_tables)
                if not color:
                    piece_value *= -1
                val += piece_value
        self.evaluations[board.fen()] = val

        return val
Exemplo n.º 7
0
def next_move(count):
    count = int(count) // 2
    fen = request.form['fen']
    if count <= 5:
        move = opening_book_next_move(fen, 'performance.bin')
        if move is not None:
            return move

    # use the c version one
    b = Board(fen)
    if is_endgame(b):
        move = query_end_game_move(b.fen())
        if move != None:
            return move

    if b.turn:
        side = '0'  # white
    else:
        side = '1'
    result = s.run(['./ai/c_modules/main', fen, side], stdout=s.PIPE)
    move = result.stdout.decode('utf-8').split("\n")[-2]

    # board = Board(fen)
    # move = min_f_root(board, -10001, 10001, 4)[1]		# black is the ai, so call min_f
    return move
Exemplo n.º 8
0
 def find_random_child(self) -> Node:
     """
     Get a random move
     """
     random_move = random.choice(list(Board(self.fen).legal_moves))
     new_board = Board(fen=self.fen)
     new_board.push(random_move)
     return Node(fen=new_board.fen())
Exemplo n.º 9
0
def command(depth: int, board: chess.Board, msg: str):
    """
    Accept UCI commands and respond.
    The board state is also updated.
    """
    msg = msg.strip()
    tokens = msg.split(" ")
    while "" in tokens:
        tokens.remove("")

    if msg == "quit":
        sys.exit()

    if msg == "uci":
        print("id name Andoma")  # Andrew/Roma -> And/oma
        print("id author Andrew Healey & Roma Parramore")
        print("uciok")
        return

    if msg == "isready":
        print("readyok")
        return

    if msg == "ucinewgame":
        return

    if msg.startswith("position"):
        if len(tokens) < 2:
            return

        # Set starting position
        if tokens[1] == "startpos":
            board.reset()
            moves_start = 2
        elif tokens[1] == "fen":
            fen = " ".join(tokens[2:8])
            board.set_fen(fen)
            moves_start = 8
        else:
            return

        # Apply moves
        if len(tokens) <= moves_start or tokens[moves_start] != "moves":
            return

        for move in tokens[(moves_start + 1):]:
            board.push_uci(move)

    if msg == "d":
        # Non-standard command, but supported by Stockfish and helps debugging
        print(board)
        print(board.fen())

    if msg[0:2] == "go":
        _move = next_move(depth, board)
        print(f"bestmove {_move}")
        return
Exemplo n.º 10
0
    def encode_state(self, board: chess.Board):
        '''
        Encode the board to check for repetitions
        :param board: chess.Board
        '''
        encoding = board.fen()
        self._encoded_state_counter[encoding] = self._encoded_state_counter.get(encoding, 0) + 1

        if self._encoded_state_counter[encoding] > self._max_repetitions:
            self._max_repetitions = self._encoded_state_counter[encoding]
Exemplo n.º 11
0
def make_ai_move(board: chess.Board):
    board_copy = chess.Board(board.fen(), chess960=True)
    move = ai.make_move(
        board_copy, 10.0
    )  # Change this float if you want to test your AI under time pressure

    if isinstance(move, str):
        move = chess.Move.from_uci(move)

    return move
Exemplo n.º 12
0
 def iterate(self, n_iters, s: chess.Board):
     s_fen = s.fen()
     self.nodes_parameters[s_fen] = np.array((1, 0))
     for i in range(n_iters):
         # v, n = self.search(s)
         # self.nodes_parameters[s_fen][0] += n
         # self.nodes_parameters[s_fen][1] += v
         self.search_iter(s_fen)
         if True or i % 5 == 0:
             print(f'Iteration {i+1} [{"=" * (i//5)}>{" " * ((n_iters-i-1)//5)}]')
Exemplo n.º 13
0
    def handle_state_change(self, event):
        board = Board(fen=self.initial_fen)
        for move in event["moves"].split():
            board.push(Move.from_uci(move))
        self.node = Node(fen=board.fen())
        self.my_turn = not self.my_turn

        print(f"My turn? {self.my_turn}")

        if self.my_turn:
            self.make_move()
Exemplo n.º 14
0
def children(fen: str) -> FrozenSet[Node]:
    """
    Get children of a given game state
    """
    board = Board(fen=fen)
    next_moves = []
    for move in board.legal_moves:
        new_board = Board(fen=fen)
        new_board.push(move)
        next_moves.append(Node(fen=new_board.fen()))
    return frozenset(next_moves)
Exemplo n.º 15
0
def alphabeta(board: chess.Board, depth: int, alpha: chess.Board, beta: chess.Board, player: chess.Color):
    if depth == 0:
        return eval(board, alpha, beta, player)
    
    if player == chess.WHITE:
        for move in board.generate_legal_moves():
            new_board = board.copy()
            new_board.push(move)
            alpha = alphabeta(new_board, depth-1, alpha, beta, chess.BLACK)
            if model.predict_mlp(utils.bitify(beta.fen()), utils.bitify(alpha.fen()))[0] == 1:
                break
        return alpha
    else:
        for move in board.generate_legal_moves():
            new_board = board.copy()
            new_board.push(move)
            beta = alphabeta(new_board, depth-1, alpha, beta, chess.WHITE)
            if model.predict_mlp(utils.bitify(beta.fen()), utils.bitify(alpha.fen()))[0] == 1:
                break
        return beta
def add_if_known(board: chess.Board, game_legal_moves: LegalMovesT,
                 game_states: List[np.ndarray]) -> None:
    """If board state hasn't already been observed: Adds state to set and list of observed states.
    Also adds legal moves and state corresponding to the Board."""
    board_fen = board.fen()
    if board_fen not in observed_states_set:
        observed_states_set.add(board_fen)
        observed_states.append(board_fen)

        state_legal_moves = get_state_legal_moves(board=board)
        game_legal_moves.append(state_legal_moves)

        add_board_state_to_list(board=board, in_list=game_states)
Exemplo n.º 17
0
def get_move(old_node: Node, new_node: Node) -> str:
    """
    Get the UCI of a move given an old and new state
    """
    old_board = Board(fen=old_node.fen)
    for move in old_board.legal_moves:
        temp_board = Board(fen=old_node.fen)
        temp_board.push(move)
        if temp_board.fen() == new_node.fen:
            return move.uci()
    else:
        raise RuntimeError(
            "Trying to make illegal move! " f"{old_node.fen} -> {new_node.fen}"
        )
Exemplo n.º 18
0
 def board_to_numpy(self, board: chess.Board):
     fen = board.fen().split(' ')[0].split('/')
     output = np.empty(shape=(8, 8), dtype=str)
     for i, row in enumerate(fen):
         j = 0
         for square in row:
             if square.isnumeric():
                 for _ in range(j, int(square) + j):
                     output[i][j] = '.'
                     j += 1
                 continue
             output[i][j] = square
             j += 1
     return output
Exemplo n.º 19
0
class Kidpawn():
    def __init__(self, board_fen: str = None):
        if board_fen:
            self.b = Board(board_fen)
        else:
            # Not sure why this is needed.
            self.b = Board()

    def svg(self):
        return self.b._repr_svg_()

    def fen(self):
        """Returns board state as a FEN string
        """
        return self.b.fen()

    def move(self, move: str) -> [bool, str]:
        """Returns true if the move succeeded
        """
        try:
            self.b.push_uci(move)
            return True, f"you moved: {move}"
        except ValueError as e:
            msg = str(e)
            if msg.startswith("illegal uci"):
                return False, f"illegal move: {move}.  Try something like d2d4 or h7h8q."
            else:
                return False, f"other error {msg}"
        except Exception as e:
            traceback.print_exc()
            return False, f"unknown error {e}"

    def bot_move(self):
        """Computer makes a move herself, and updates the board
        """
        m = lookahead1_move(self.b)
        if m:
            return self.move(m.uci())
        else:
            return False, "No valid moves"

    def game_over_msg(self) -> str:
        """If the game is over, returns a string why.
        If game is not over, return blank
        """
        if self.b.is_game_over():
            return f"Game over: {self.b.result()}"
        else:
            return None
Exemplo n.º 20
0
    def write_ascii(self, board: chess.Board):
        """
        Loops through a game board and prints it out as ascii. Useful for debugging.
        For example, the starting board would print out:

        ---|--------------------------------
         8 | r | n | b | q | k | b | n | r |
        ---|--------------------------------
         7 | p | p | p | p | p | p | p | p |
        ---|--------------------------------
         6 |   |   |   |   |   |   |   |   |
        ---|--------------------------------
         5 |   |   |   |   |   |   |   |   |
        ---|--------------------------------
         4 |   |   |   |   |   |   |   |   |
        ---|--------------------------------
         3 |   |   |   |   |   |   |   |   |
        ---|--------------------------------
         2 | P | P | P | P | P | P | P | P |
        ---|--------------------------------
         1 | R | N | B | Q | K | B | N | R |
        ---|--------------------------------
           | a | b | c | d | e | f | g | h |

        """

        fen = board.fen()
        rows = fen.split(' ')[0].split('/')
        output = '---|%s\n' % ('-' * 32)
        row_separator = '\n' + output
        row_nums = reversed(range(1, 9))

        for row_num, row in zip(row_nums, rows):
            output += ' %s | ' % row_num
            for piece in row:
                if piece.isdigit():
                    output += '  | ' * int(piece)
                else:
                    output += piece + ' | '
            output += row_separator

        output += '   | '
        for i in ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']:
            output += str(i) + ' | '

        self.set_header('Content-Type', 'text/plain; charset=utf-8')
        self.finish(output)
Exemplo n.º 21
0
    def write_json(self, board: chess.Board):
        """
        Writes all of the board info in json
        """

        best_move = self.get_best_move(board)

        output = OrderedDict([
            ('fen', board.fen()),
            ('fullmoveNumber', board.fullmove_number),
            ('result', board.result()),
            ('isGameOver', board.is_game_over()),
            ('isCheckmate', board.is_checkmate()),
            ('isStalemate', board.is_stalemate()),
            ('isInsufficientMaterial', board.is_insufficient_material()),
            ('isSeventyfiveMoves', board.is_seventyfive_moves()),
            ('isFivefoldRepetition', board.is_fivefold_repetition()),
            ('white',
             OrderedDict([
                 ('hasKingsideCastlingRights',
                  board.has_kingside_castling_rights(chess.WHITE)),
                 ('hasQueensideCastlingRights',
                  board.has_queenside_castling_rights(chess.WHITE)),
             ])),
            ('black',
             OrderedDict([
                 ('hasKingsideCastlingRights',
                  board.has_kingside_castling_rights(chess.BLACK)),
                 ('hasQueensideCastlingRights',
                  board.has_queenside_castling_rights(chess.BLACK)),
             ])),
            ('turn',
             OrderedDict([
                 ('color', 'white' if board.turn is chess.WHITE else 'black'),
                 ('isInCheck', board.is_check()),
                 ('bestMove', best_move),
                 ('legalMoves', [move.uci() for move in board.legal_moves]),
                 ('canClaimDraw', board.can_claim_draw()),
                 ('canClaimFiftyMoves', board.can_claim_fifty_moves()),
                 ('canClaimThreefoldRepetition',
                  board.can_claim_threefold_repetition()),
             ])),
        ])

        self.finish(output)
Exemplo n.º 22
0
    def get_board_values(self, board: chess.Board, white_multiplier: int):
        """

            :param board: chess board
            :param white_multiplier: 1 if AI is white else -1
            :return:
            """
        # using Hans Berliner's system

        fen = board.fen()

        total = 0
        for square in fen:
            if square in self.piece_value:
                total += self.piece_value[square]

        total *= white_multiplier

        return round(total, 2)
Exemplo n.º 23
0
    def _search(cls, board: chess.Board, value_func: Callable[[chess.Board], float], max_depth: int, memory: Optional[Dict[str, float]], curr_depth: int = 0, alpha: float = -float("inf"), beta: float = float("inf")) -> Tuple[float, chess.Move, Optional[Dict[str, float]]]:
        assert max_depth >= 1, f"max_depth should be positive integer, {max_depth} is passed"

        if curr_depth == max_depth:
            if memory is None:
                return value_func(board), None, None
            else:
                board_fen = board.fen()
                if board_fen in memory:
                    return memory[board_fen], None, memory
                else:
                    value = value_func(board)
                    memory[board_fen] = value
                    return value, None, memory

        # maximize
        if board.turn == chess.WHITE:
            best_valuation = -float("inf")
            best_move = None
            for move in board.legal_moves:
                board.push(move)
                valuation, _, memory = cls._search(board, value_func, max_depth, memory, curr_depth+1, best_valuation, beta)
                board.pop()
                if valuation > best_valuation:
                    best_valuation = valuation
                    best_move = move
                if best_valuation > beta:
                    return beta, best_move, memory
        # minimize
        elif board.turn == chess.BLACK:
            best_valuation = float("inf")
            best_move = None
            for move in board.legal_moves:
                board.push(move)
                valuation, _, memory = cls._search(board, value_func, max_depth, memory, curr_depth+1, alpha, best_valuation)
                board.pop()
                if valuation < best_valuation:
                    best_valuation = valuation
                    best_move = move
                if best_valuation < alpha:
                    return alpha, best_move, memory

        return best_valuation, best_move, memory
Exemplo n.º 24
0
def log_board(board: Board, unicode_pieces=True):
    """ Logs the fen string and board representation
    """
    log(Color.VIOLET, board.fen())
    w_color = Color.WHITE
    b_color = Color.DARK_GREY
    sq_color = Color.BLACK
    board_str = "\n  " + str(board).replace("\n", "\n  ")
    board_str = re.sub("[a-z]", lambda p: b_color + p[0] + sq_color, board_str)
    board_str = re.sub("[A-Z]", lambda p: w_color + p[0] + sq_color, board_str)
    if unicode_pieces:
        piece_map = {
            "k": "\u2654",
            "q": "\u2655",
            "r": "\u2656",
            "b": "\u2657",
            "n": "\u2658",
            "p": "\u2659",
        }
        for p, code in piece_map.items():
            board_str = board_str.replace(p, code).replace(p.capitalize(), code)
    log(sq_color, board_str + "\n")
Exemplo n.º 25
0
 def nn_select_best_moves(self, board: chess.Board):
     """Select best moves in board."""
     good_moves = True
     if self.use_nn:
         hash = chess.polyglot.zobrist_hash(board)
         if hash not in self.nn_tb:
             good_moves = list()
             for move in board.legal_moves:
                 if self.nn.check_move(board.fen(), move.uci()):
                     good_moves.append(move)
             self.nn_tb[hash] = good_moves
         good_moves = self.nn_tb[hash]
         if not good_moves:
             good_moves = list(board.legal_moves)
             self.nn_tb[hash] = good_moves
         if int(sys.getsizeof(self.nn_tb) / 1024 /
                1024) >= self.hashlimit / 2:
             del self.nn_tb[list(self.nn_tb.keys())[0]]
             self.hashfull += 1
         return good_moves
     else:
         return list(board.legal_moves)
Exemplo n.º 26
0
 def check(self: PuzzleChecker) -> None:
     unchecked_puzzles = self.list_unchecked_puzzles()
     log.info(f"{len(unchecked_puzzles)} still need to be checked")
     with open(PUZZLE_CHECKED_PATH, "a") as output:
         for i, (puzzle_id, puzzle_info) in enumerate(unchecked_puzzles):
             print(f"\r{i} puzzles processed, {self.tl():.2f}s", end="")
             b = Board(fen=puzzle_info.fen)
             res: Set[Error] = set()
             for i, move in enumerate(puzzle_info.moves):
                 if i % 2 and nb_piece(
                         b
                 ) <= 7:  # 0, 2, 4... are moves made by the opponent, we don't check them
                     res = res.union(
                         self.req(b.fen(), move,
                                  puzzle_info.expected_winning))
                 b.push_uci(move)
             if bool(res):  # Not empty
                 log.error(
                     f"puzzle {puzzle_id} contains some errors: {res}")
             output.write(puzzle_id + " " +
                          " ".join(map(lambda x: x.name, res)) + "\n")
             time.sleep(0.55)  #rate-limited otherwise
Exemplo n.º 27
0
def get_move(state):
    #assume both players play the best moves
    #states where you play, take the maximum calculated as rv
    #states where opponent plays, take the min calculated as rv
    #limit number of searches artificially for now
    #choose better numbers later
    print('started search over state', state)
    search_limit = 1000
    board = Board(state)
    mx = 0
    rv = None
    vals = []
    for move in board.legal_moves:
        board.push(move)
        val = dfs(board.fen(), search_limit, False)
        if (val > mx):
            rv = move
            mx = val
        board.pop()
        vals.append((str(move), val))
    print(vals)
    print('found move', rv)
    return rv
Exemplo n.º 28
0
def game2permove(d):
    result, moves = d
    data = []
    result = result.strip()
    moves = sum(
        [m.strip().split() for m in re.split(r'[0-9]+\. ', moves) if m], [])
    # value of state from player's perspective
    # 1 from winner's perspective, -1 from loser's perspective, 0 if tie
    value = 1 if result == '1-0' else -1 if result == '0-1' else 0
    board = Board()
    for move_str in moves:
        move = board.parse_san(move_str)

        assert idx2move(board, *move2idx(move)) == move

        data.append((board.fen(), value, move_str))

        # Move to next data point
        board.push(move)

        value *= -1

    return data
Exemplo n.º 29
0
    def evaluate(self, board: chess.Board) -> int:
        """
        Evaluate boardstate via. material difference on board

        Args:
            board (chess.Board): board state to evaluate
        Returns:
            (int)
        """
        val = 0
        for square in chess.SQUARES:
            # For each piece on board, get value of piece on board.
            piece = board.piece_type_at(square)
            color = board.color_at(square)
            if piece:
                piece_value = self.piece_values[PIECE_NAMES[piece]].value
                if not color:
                    # BLACK encoded as False
                    piece_value *= -1
                val += piece_value
        self.evaluations[board.fen()] = val

        # Return difference in piece values between white & black
        return val
Exemplo n.º 30
0
class DialogEnterPosition(QDialog):

    def __init__(self, board=None, parent=None):
        super(DialogEnterPosition, self).__init__(parent)
        #self.resize(600, 400)

        self.setWindowTitle(self.trUtf8("Enter Position"))

        self.displayBoard = DisplayBoard(self.deep_copy_board_pos(board),self)

        # create a copy of the current board
        if(board):
            # create a deepcopy of current board
            self.current = self.deep_copy_board_pos(board)
        else:
            self.current = Board()

        self.cbWhiteShort = QCheckBox(self.trUtf8("White O-O"))
        self.cbWhiteLong = QCheckBox(self.trUtf8("White O-O-O"))
        self.cbBlackShort = QCheckBox(self.trUtf8("Black O-O"))
        self.cbBlackLong = QCheckBox(self.trUtf8("Black O-O-O"))
        grpBox_castle = QGroupBox(self.trUtf8("Castling Rights"))
        vbox_castle = QVBoxLayout()
        vbox_castle.addWidget(self.cbWhiteShort)
        vbox_castle.addWidget(self.cbWhiteLong)
        vbox_castle.addWidget(self.cbBlackShort)
        vbox_castle.addWidget(self.cbBlackLong)
        vbox_castle.addStretch(1)
        grpBox_castle.setLayout(vbox_castle)

        self.rbWhite = QRadioButton(self.trUtf8("White To Move"))
        self.rbBlack = QRadioButton(self.trUtf8("Black To Move"))
        grpBox_turn = QGroupBox(self.trUtf8("Turn"))
        vbox_radio = QVBoxLayout()
        vbox_radio.addWidget(self.rbWhite)
        vbox_radio.addWidget(self.rbBlack)
        vbox_radio.addStretch(1)
        grpBox_turn.setLayout(vbox_radio)

        self.buttonInit = QPushButton(self.trUtf8("Initial Position"))
        self.buttonClear = QPushButton(self.trUtf8("Clear Board"))
        self.buttonCurrent = QPushButton(self.trUtf8("Current Position"))

        vbox_config = QVBoxLayout()
        vbox_config.addWidget(grpBox_castle)
        vbox_config.addWidget(grpBox_turn)
        vbox_config.addStretch(1)
        vbox_config.addWidget(self.buttonInit)
        vbox_config.addWidget(self.buttonClear)
        vbox_config.addWidget(self.buttonCurrent)

        hbox = QHBoxLayout()
        hbox.addWidget(self.displayBoard)
        hbox.addLayout(vbox_config)

        vbox = QVBoxLayout()
        vbox.addLayout(hbox)
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok| QDialogButtonBox.Cancel)
        vbox.addWidget(self.buttonBox)

        self.setLayout(vbox)

        self.connect(self.buttonBox, SIGNAL("accepted()"),
                 self, SLOT("accept()"))
        self.connect(self.buttonBox, SIGNAL("rejected()"),
                 self, SLOT("reject()"))

        self.cbWhiteShort.toggled.connect(self.set_castling_rights)
        self.cbWhiteLong.toggled.connect(self.set_castling_rights)
        self.cbBlackShort.toggled.connect(self.set_castling_rights)
        self.cbBlackLong.toggled.connect(self.set_castling_rights)

        self.rbWhite.toggle()
        self.rbWhite.toggled.connect(self.set_turn)
        self.rbBlack.toggled.connect(self.set_turn)

        self.buttonInit.clicked.connect(self.initial_position)
        self.buttonClear.clicked.connect(self.clear_board)
        self.buttonCurrent.clicked.connect(self.set_current)

        # reset who's current turn it is and the current
        # castling rights of the position
        self.set_castling_rights()
        self.set_turn()

    def set_castling_rights(self):
        self.displayBoard.board.castling_rights = 0
        if(self.cbWhiteShort.isChecked()):
            self.displayBoard.board.castling_rights = self.displayBoard.board.castling_rights  | chess.BB_H1
        if(self.cbWhiteLong.isChecked()):
            self.displayBoard.board.castling_rights = self.displayBoard.board.castling_rights | chess.BB_A1
        if(self.cbBlackShort.isChecked()):
            self.displayBoard.board.castling_rights = self.displayBoard.board.castling_rights | chess.BB_H8
        if(self.cbBlackLong.isChecked()):
            self.displayBoard.board.castling_rights = self.displayBoard.board.castling_rights | chess.BB_A8
        if(self.displayBoard.board.status() == chess.STATUS_VALID):
            self.enable_ok_button()
        else:
            self.disable_ok_button()

    def set_turn(self):
        if(self.rbWhite.isChecked()):
            self.displayBoard.board.turn = WHITE
        else:
            self.displayBoard.board.turn = BLACK
        if(self.displayBoard.board.status() == 0):
            self.enable_ok_button()
        else:
            self.disable_ok_button()

    def clear_board(self):
        self.displayBoard.board.clear()
        self.set_castling_rights()
        self.set_turn()
        self.update()

    def initial_position(self):
        self.displayBoard.board.reset()
        self.set_castling_rights()
        self.set_turn()
        self.update()

    def set_current(self):
        fen = self.current.fen()
        board = Board(fen)
        self.displayBoard.board = board
        self.set_castling_rights()
        self.set_turn()
        self.update()

    # creates a deep copy of the given
    # board into a clean new board, resetting
    # all move histories, castling rights, etc.
    def deep_copy_board_pos(self,board):
        fresh = Board()
        for i in range(0,8):
            for j in range(0,8):
                piece = board.piece_at(j*8+i)
                if(piece):
                    sym = piece.symbol()
                    fresh.set_piece_at(j*8+i,Piece.from_symbol(sym))
                else:
                    fresh.remove_piece_at(j*8+i)
        return fresh

    def enable_ok_button(self):
        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(True)
        self.update()

    def disable_ok_button(self):
        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
        self.update()
Exemplo n.º 31
0
class DialogEnterPosition(QDialog):
    def __init__(self, board=None, parent=None):
        super(DialogEnterPosition, self).__init__(parent)
        # self.resize(600, 400)

        self.setWindowTitle(self.trUtf8("Enter Position"))

        self.displayBoard = DisplayBoard(self.deep_copy_board_pos(board), self)

        # create a copy of the current board
        if board:
            # create a deepcopy of current board
            self.current = self.deep_copy_board_pos(board)
        else:
            self.current = Board()

        self.cbWhiteShort = QCheckBox(self.trUtf8("White O-O"))
        self.cbWhiteLong = QCheckBox(self.trUtf8("White O-O-O"))
        self.cbBlackShort = QCheckBox(self.trUtf8("Black O-O"))
        self.cbBlackLong = QCheckBox(self.trUtf8("Black O-O-O"))
        grpBox_castle = QGroupBox(self.trUtf8("Castling Rights"))
        vbox_castle = QVBoxLayout()
        vbox_castle.addWidget(self.cbWhiteShort)
        vbox_castle.addWidget(self.cbWhiteLong)
        vbox_castle.addWidget(self.cbBlackShort)
        vbox_castle.addWidget(self.cbBlackLong)
        vbox_castle.addStretch(1)
        grpBox_castle.setLayout(vbox_castle)

        self.rbWhite = QRadioButton(self.trUtf8("White To Move"))
        self.rbBlack = QRadioButton(self.trUtf8("Black To Move"))
        grpBox_turn = QGroupBox(self.trUtf8("Turn"))
        vbox_radio = QVBoxLayout()
        vbox_radio.addWidget(self.rbWhite)
        vbox_radio.addWidget(self.rbBlack)
        vbox_radio.addStretch(1)
        grpBox_turn.setLayout(vbox_radio)

        self.buttonInit = QPushButton(self.trUtf8("Initial Position"))
        self.buttonClear = QPushButton(self.trUtf8("Clear Board"))
        self.buttonCurrent = QPushButton(self.trUtf8("Current Position"))

        vbox_config = QVBoxLayout()
        vbox_config.addWidget(grpBox_castle)
        vbox_config.addWidget(grpBox_turn)
        vbox_config.addStretch(1)
        vbox_config.addWidget(self.buttonInit)
        vbox_config.addWidget(self.buttonClear)
        vbox_config.addWidget(self.buttonCurrent)

        hbox = QHBoxLayout()
        hbox.addWidget(self.displayBoard)
        hbox.addLayout(vbox_config)

        vbox = QVBoxLayout()
        vbox.addLayout(hbox)
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        vbox.addWidget(self.buttonBox)

        self.setLayout(vbox)

        self.connect(self.buttonBox, SIGNAL("accepted()"), self, SLOT("accept()"))
        self.connect(self.buttonBox, SIGNAL("rejected()"), self, SLOT("reject()"))

        self.cbWhiteShort.toggled.connect(self.set_castling_rights)
        self.cbWhiteLong.toggled.connect(self.set_castling_rights)
        self.cbBlackShort.toggled.connect(self.set_castling_rights)
        self.cbBlackLong.toggled.connect(self.set_castling_rights)

        self.rbWhite.toggle()
        self.rbWhite.toggled.connect(self.set_turn)
        self.rbBlack.toggled.connect(self.set_turn)

        self.buttonInit.clicked.connect(self.initial_position)
        self.buttonClear.clicked.connect(self.clear_board)
        self.buttonCurrent.clicked.connect(self.set_current)

        # reset who's current turn it is and the current
        # castling rights of the position
        self.set_castling_rights()
        self.set_turn()

    def set_castling_rights(self):
        self.displayBoard.board.castling_rights = 0
        if self.cbWhiteShort.isChecked():
            self.displayBoard.board.castling_rights = self.displayBoard.board.castling_rights | chess.BB_H1
        if self.cbWhiteLong.isChecked():
            self.displayBoard.board.castling_rights = self.displayBoard.board.castling_rights | chess.BB_A1
        if self.cbBlackShort.isChecked():
            self.displayBoard.board.castling_rights = self.displayBoard.board.castling_rights | chess.BB_H8
        if self.cbBlackLong.isChecked():
            self.displayBoard.board.castling_rights = self.displayBoard.board.castling_rights | chess.BB_A8
        if self.displayBoard.board.status() == chess.STATUS_VALID:
            self.enable_ok_button()
        else:
            self.disable_ok_button()

    def set_turn(self):
        if self.rbWhite.isChecked():
            self.displayBoard.board.turn = WHITE
        else:
            self.displayBoard.board.turn = BLACK
        if self.displayBoard.board.status() == 0:
            self.enable_ok_button()
        else:
            self.disable_ok_button()

    def clear_board(self):
        self.displayBoard.board.clear()
        self.set_castling_rights()
        self.set_turn()
        self.update()

    def initial_position(self):
        self.displayBoard.board.reset()
        self.set_castling_rights()
        self.set_turn()
        self.update()

    def set_current(self):
        fen = self.current.fen()
        board = Board(fen)
        self.displayBoard.board = board
        self.set_castling_rights()
        self.set_turn()
        self.update()

    # creates a deep copy of the given
    # board into a clean new board, resetting
    # all move histories, castling rights, etc.
    def deep_copy_board_pos(self, board):
        fresh = Board()
        for i in range(0, 8):
            for j in range(0, 8):
                piece = board.piece_at(j * 8 + i)
                if piece:
                    sym = piece.symbol()
                    fresh.set_piece_at(j * 8 + i, Piece.from_symbol(sym))
                else:
                    fresh.remove_piece_at(j * 8 + i)
        return fresh

    def enable_ok_button(self):
        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(True)
        self.update()

    def disable_ok_button(self):
        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
        self.update()
Exemplo n.º 32
0
class PyCachEngine:
    def __init__(self, path, db_path, options=dict()):
        self.board = Board()
        self.db = UnQLite(db_path)
        self.engine = Popen(path,
                            universal_newlines=True,
                            stdin=PIPE,
                            stdout=PIPE)
        self._put('uci')
        self._ready()
        for option, val in options.items():
            self._set_option(option, val)
        self.num_games = 1
        while True:
            self.board.reset()
            self.learn(200)

    def __del__(self):
        self.db.close()
        self.engine.kill()

    def _put(self, line):
        if not self.engine.stdin:
            raise BrokenPipeError()
        self.engine.stdin.write(line + '\n')
        self.engine.stdin.flush()

    def _read(self):
        if not self.engine.stdout:
            raise BrokenPipeError()
        return self.engine.stdout.readline().strip()

    def _ready(self):
        self._put('isready')
        while self._read() != 'readyok':
            continue

    def _bestmove(self):
        while True:
            line = self._read()
            if 'depth' in line:
                depth = int(line.split()[2])
            if 'bestmove' in line:
                move = line.split()[1]
                return (move, depth)

    def _set_option(self, option, value):
        self._put(f'setoption option {option} value {value}')

    def _store(self, new_fen, move, depth):
        with self.db.transaction():
            if new_fen in self.db:
                _move, _depth = eval(self.db[new_fen].decode('utf-8'))
                print(_move, _depth)
                if int(_depth) >= depth:
                    return
            self.db[new_fen] = (move, depth)
        self.db.commit()

    def learn(self, movetime):
        fen = self.board.fen()
        new_fen = ' '.join(fen.split()[:-2])
        self._put(f'position fen {fen}')
        self._put(f'go movetime {movetime}')
        move, depth = self._bestmove()
        self.board.push_uci(move)
        self._store(new_fen, move, depth)
        system('clear')
        #		print(fen)
        print(self.board)
        print()
        print('new_fen:', new_fen)
        print('depth:', depth)
        print('move:', move)
        print('db_size:', len(self.db))
        print('num_games:', self.num_games)
        if not self.board.is_game_over():
            self.learn(movetime)
        else:
            result = self.board.outcome().result()
            self.num_games += 1
            print(result)