def min_value(self, board: Board, depth, alpha, beta): """ function MIN-VALUE(state, alpha, beta) returns a utility value if TERMINAL-TEST(state) the return UTILITY(state) v <- +infinity for each a in ACTIONS(state) do v <- MIN(v, MAX-VALUE(RESULT(state, a), alpha, beta)) if v <= alpha then return v beta <- MIN(beta, v) return v """ if self.time_left() < self.TIMER_THRESHOLD: raise SearchTimeout() mini = self if board.is_winner(mini) or board.is_loser(mini): return board.utility(mini) if depth <= 0: # what is the score function of the opponent? certainly not ours! return self.score(board, mini) min_value = math.inf for move in board.get_legal_moves(): min_value = min( min_value, self.max_value(board.forecast_move(move), depth - 1, alpha, beta)) if min_value <= alpha: return min_value beta = min(beta, min_value) return min_value
def max_value(self, board: Board, depth, alpha, beta): """ function MAX-VALUE(state, alpha, beta) returns a utility value if TERMINAL-TEST(state) the return UTILITY(state) v <- -infinity for each a in ACTIONS(state) do v <- MAX(v, MIN-VALUE(RESULT(state, a), alpha, beta)) if v >= beta then return v alpha <- MAX(alpha, v) return v """ if self.time_left() < self.TIMER_THRESHOLD: raise SearchTimeout() maxi = self if board.is_winner(maxi) or board.is_loser(maxi): return board.utility(maxi) if depth <= 0: return self.score(board, maxi) max_value = -math.inf for move in board.get_legal_moves(): max_value = max( max_value, self.min_value(board.forecast_move(move), depth - 1, alpha, beta)) if max_value >= beta: return max_value alpha = max(alpha, max_value) return max_value
def min_value(self, board: Board, depth): """ function MIN-VALUE(state) returns a utility value if TERMINAL-TEST(state) then return UTILITY(state) v <- infinity for each a in ACTIONS(state) do v <- MIN(v, MAX-VALUE(RESULT(state, a))) return v """ if self.time_left() < self.TIMER_THRESHOLD: raise SearchTimeout() mini = self if board.is_winner(mini) or board.is_loser(mini): return board.utility(mini) if depth <= 0: return self.score(board, mini) min_value = math.inf for move in board.get_legal_moves(): min_value = min( min_value, self.max_value(board.forecast_move(move), depth - 1)) return min_value
def max_value(self, board: Board, depth): """ function MAX-VALUE(state) returns a utility value if TERMINAL-TEST(state) then return UTILITY(state) v <- -infinity for each a in ACTIONS(state) do v <- MAX(v, MIN-VALUE(RESULT(state, a))) return v """ if self.time_left() < self.TIMER_THRESHOLD: raise SearchTimeout() maxi = self utility = board.utility(maxi) if utility != 0: return utility if depth <= 0: return self.score(board, maxi) max_value = -math.inf for move in board.get_legal_moves(): max_value = max( max_value, self.min_value(board.forecast_move(move), depth - 1)) return max_value