def ucinewgame(self, *, async_callback=None):
        """
        Tell the engine that the next search will be from a different game.

        This can be a new game the engine should play or if the engine should
        analyse a position from a different game. Using this command is
        recommended, but not required.

        :return: Nothing
        """
        # Warn if this is called while the engine is still calculating.
        with self.state_changed:
            if not self.idle:
                LOGGER.warning("ucinewgame while engine is busy")

        def command():
            with self.semaphore:
                with self.readyok_received:
                    self.send_line("ucinewgame")

                    self.send_line("isready")
                    self.readyok_received.wait()

                    if self.terminated.is_set():
                        raise EngineTerminatedException()

        return self._queue_command(command, async_callback)
Example #2
0
    def ucinewgame(self, async_callback=None):
        """
        Tell the engine that the next search will be from a different game.

        This can be a new game the engine should play or if the engine should
        analyse a position from a different game. Using this command is
        recommended, but not required.

        :return: Nothing
        """
        # Warn if this is called while the engine is still calculating.
        with self.state_changed:
            if not self.idle:
                LOGGER.warning("ucinewgame while engine is busy")

        def command():
            with self.semaphore:
                with self.readyok_received:
                    self.send_line("ucinewgame")

                    self.send_line("isready")
                    self.readyok_received.wait()

                    if self.terminated.is_set():
                        raise EngineTerminatedException()

        return self._queue_command(command, async_callback)
    def position(self, board, *, async_callback=None):
        """
        Set up a given position.

        Rather than sending just the final FEN, the initial FEN and all moves
        leading up to the position will be sent. This will allow the engine
        to use the move history (for example to detect repetitions).

        If the position is from a new game, it is recommended to use the
        *ucinewgame* command before the *position* command.

        :param board: A *chess.Board*.

        :return: Nothing

        :raises: :exc:`~chess.uci.EngineStateException` if the engine is still
            calculating.
        """
        # Raise if this is called while the engine is still calculating.
        with self.state_changed:
            if not self.idle:
                raise EngineStateException(
                    "position command while engine is busy")

        # Set UCI_Variant and UCI_Chess960.
        options = {}

        uci_variant = type(board).uci_variant
        if uci_variant != (self.uci_variant or "chess"):
            if self.uci_variant is None:
                LOGGER.warning(
                    "engine may not support UCI_Variant or has not been initialized with 'uci' command"
                )
            options["UCI_Variant"] = type(board).uci_variant

        if bool(self.uci_chess960) != board.chess960:
            if self.uci_chess960 is None:
                LOGGER.warning(
                    "engine may not support UCI_Chess960 or has not been initialized with 'uci' command"
                )
            options["UCI_Chess960"] = board.chess960

        option_lines = self._setoption(options)

        # Send starting position.
        builder = ["position"]
        root = board.root()
        fen = root.fen()
        if uci_variant == "chess" and fen == chess.STARTING_FEN:
            builder.append("startpos")
        else:
            builder.append("fen")
            builder.append(root.shredder_fen() if self.uci_chess960 else fen)

        # Send moves.
        if board.move_stack:
            builder.append("moves")
            builder.extend(move.uci() for move in board.move_stack)

        self.board = board.copy(stack=False)

        def command():
            with self.semaphore:
                for option_line in option_lines:
                    self.send_line(option_line)

                self.send_line(" ".join(builder))

                if self.terminated.is_set():
                    raise EngineTerminatedException()

        return self._queue_command(command, async_callback)