Python 如何在迭代过程中使用计时器停止alpha beta

Python 如何在迭代过程中使用计时器停止alpha beta,python,minimax,alpha-beta-pruning,iterative-deepening,Python,Minimax,Alpha Beta Pruning,Iterative Deepening,我用alpha-beta修剪创建了一个minimax函数,我用迭代深化调用它。问题是,当定时器完成时,该函数会一直运行,直到它在定时器用完之前的深度上完成 我想要的:当计时器运行完时,minimax函数应该退出并返回none(我将best move保留在minimax之外,请参阅下面的minimax调用代码),或者返回先前计算的best move。我只是想不出如何在minimax函数中实现它,我尝试的每件事都使它仍然完成了当前的深度 极小极大函数: def minimax(gamestate,

我用alpha-beta修剪创建了一个minimax函数,我用迭代深化调用它。问题是,当定时器完成时,该函数会一直运行,直到它在定时器用完之前的深度上完成

我想要的:当计时器运行完时,minimax函数应该退出并返回none(我将best move保留在minimax之外,请参阅下面的minimax调用代码),或者返回先前计算的best move。我只是想不出如何在minimax函数中实现它,我尝试的每件事都使它仍然完成了当前的深度

极小极大函数:

def minimax(gamestate, depth, alpha, beta, maximizing_player):

    if depth == 0 or gamestate.is_check_mate or gamestate.is_stale_mate:
        return None, evaluate(gamestate)

    gamestate.is_white_turn = not maximizing_player
    children = gamestate.get_valid_moves()

    best_move = children[0]

    if maximizing_player:
        max_eval = -math.inf
        for child in children:
            board_copy = copy.deepcopy(gamestate)
            board_copy.make_move(child)
            current_eval = ai_minimax(board_copy, depth - 1, alpha, beta, False)[1]
            if current_eval > max_eval:
                max_eval = current_eval
                best_move = child
            alpha = max(alpha, current_eval)
            if beta <= alpha:
                break
        return best_move, max_eval

    else:
        min_eval = math.inf
        for child in children:
            board_copy = copy.deepcopy(gamestate)
            board_copy.make_move(child)
            current_eval = ai_minimax(board_copy, depth - 1, alpha, beta, True)[1]
            if current_eval < min_eval:
                min_eval = current_eval
                best_move = child
            beta = min(beta, current_eval)
            if beta <= alpha:
                break
        return best_move, min_eval 

我经常使用自定义的
Timeout
类来解决此类问题

import signal

class TimeoutError(Exception):
    """
    Custom error for Timeout class.
    """

    pass


class Timeout:
    """
    A timeout handler with context manager.
    Based on UNIX signals.
    """

    def __init__(self, seconds=1, error_message="Timeout"):
        self.seconds = seconds
        self.error_message = error_message

    def handle_timeout(self, signum, frame):
        raise TimeoutError(self.error_message)

    def __enter__(self):
        signal.signal(signal.SIGALRM, self.handle_timeout)
        signal.alarm(self.seconds)

    def __exit__(self, type, value, traceback):
        signal.alarm(0)
您可以在
语句中运行递归函数,如下所示:

with Timeout(5):
    try:
        result = minimax(gamestate, depth, alpha, beta, maximizing_player)
    except TimeoutError:
        result = None
with Timeout(5):
    try:
        result = minimax(gamestate, depth, alpha, beta, maximizing_player)
    except TimeoutError:
        result = None