2015-12-24 4 views
0

У меня проблема. Я пытаюсь построить игру искусственного интеллекта, и я столкнулся с проблемой. Я скопировал игрока и наследовал предыдущий (класс Player (SelectiveAlphaBeta.Player)). На данный момент поиск в дереве игр, который я делаю, одинаковый (он отображает только максимальные и минимальные оценки каждого уровня - только для того, чтобы помочь мне выбрать правильный порог). Однако он врезается в:Вызов функции при сбое класса

class Player(SelectiveAlphaBeta.Player): 
def __init__(self, setup_time, player_color, time_per_k_turns, k): 
    SelectiveAlphaBeta.Player.__init__(self, setup_time, player_color, time_per_k_turns, k, 0.25) # TODO: w 

def get_move(self, board_state, possible_moves): 
    self.clock = time.process_time() 
    self.time_for_current_move = self.time_remaining_in_round/self.turns_remaining_in_round - 0.05 
    if len(possible_moves) == 1: 
     return possible_moves[0] 

    current_depth = 1 
    prev_alpha = -INFINITY 

    # Choosing an arbitrary move: 
    best_move = possible_moves[0] 

    if (self.w < 1): 
     minimax = MiniMaxWithAlphaBetaPruningWithWDeepeningUntilRestfulness 
     (self.utility, self.color, self.no_more_time, self.w) 
    else: # self.w == 1 
     minimax = MiniMaxWithAlphaBetaPruning(self.utility, self.color, self.no_more_time) 
    time_last_move = 0; 
    print('debugger - line 1') 

    # Iterative deepening until the time runs out. 
    while True: 
     print('{} going to depth: {}, remaining time: {}, prev_alpha: {}, best_move: {}'.format(
      self.__repr__(), current_depth, self.time_for_current_move - (time.process_time() - self.clock), 
      prev_alpha, best_move)) 

     time_before = time.process_time() 
     time_left = self.time_for_current_move - (time.process_time() - self.clock); 
     # if (time_last_move <= time_left): 
     try: 
      print('debugger - line 2') 
      (alpha, move), run_time = run_with_limited_time(
       minimax.search, (board_state, current_depth, -INFINITY, INFINITY, True), {}, 
       time_left) 
      print('debugger - line 3') 
     except (ExceededTimeError): 
      print('no more time') 
      break 
     except (MemoryError): 
      print('no more memory') 
      break 
     # else: 
     # print('{} has no enough time ({}) left to go deeper'.format(self.__repr__(), time_left)) 
     # break; 

     time_after = time.process_time() 
     time_last_move = time_after - time_before 

     if self.no_more_time(): 
      print('no more time') 
      break 

     prev_alpha = alpha 
     best_move = move 

     if alpha == INFINITY: 
      print('the move: {} will guarantee victory.'.format(best_move)) 
      break 

     if alpha == -INFINITY: 
      print('all is lost') 
      break 

     current_depth += 1 

    if self.turns_remaining_in_round == 1: 
     self.turns_remaining_in_round = self.k 
     self.time_remaining_in_round = self.time_per_k_turns 
    else: 
     self.turns_remaining_in_round -= 1 
     self.time_remaining_in_round -= (time.process_time() - self.clock) 
    return best_move 

def utility(self, state): 
    return SelectiveAlphaBeta.Player.utility(self, state) 

def no_more_time(self): 
    return SelectiveAlphaBeta.Player.no_more_time(self) 

def __repr__(self): 
    return '{} {}'.format(abstract.AbstractPlayer.__repr__(self), 'SelectiveAlphaBetaWithRestfulness{}'.format(str(self.w))) 

ничего не пропало, потому что это подпись функции:

class MiniMaxWithAlphaBetaPruningWithW(MiniMaxWithAlphaBetaPruning): 
def __init__(self, utility, my_color, no_more_time, w): 
    MiniMaxWithAlphaBetaPruning.__init__(self, utility, my_color, no_more_time) 
    self.w = w 

def search(self, state, depth, alpha, beta, maximizing_player): 
    """Start the MiniMax algorithm. 

    :param state: The state to start from. 
    :param depth: The maximum allowed depth for the algorithm. 
    :param alpha: The alpha of the alpha-beta pruning. 
    :param alpha: The beta of the alpha-beta pruning. 
    :param maximizing_player: Whether this is a max node (True) or a min node (False). 
    :return: A tuple: (The alpha-beta algorithm value, The move in case of max node or None in min mode) 
    """ 

    if depth == 0 or self.no_more_time(): 
     return self.utility(state), None 

    next_moves = state.legalMoves() 
    if not next_moves: 
     # This player has no moves. So the previous player is the winner. 
     return INFINITY if state.currPlayer != self.my_color else -INFINITY, None 

    list = [] 
    for next_move in next_moves: 
     if (self.no_more_time()): 
      del list[:] 
      return self.utility(state), None 
     new_state = copy.deepcopy(state) 
     new_state.doMove(next_move) 
     list.append((new_state, next_move, self.utility(new_state))) 

    list.sort(key=itemgetter(2)) 
    if (self.no_more_time()): 
     del list[:] 
     return self.utility(state), None 

    if maximizing_player: 
     selected_move = next_moves[0] 
     best_move_utility = -INFINITY 
     for i in range(int(len(list)) - 1, int(len(list)) - int(len(list) * self.w) - 1, -1): 
      minimax_value, _ = self.search(list[i][0], depth - 1, alpha, beta, False) 
      alpha = max(alpha, minimax_value) 
      if minimax_value > best_move_utility: 
       best_move_utility = minimax_value 
       selected_move = list[i][1] 
      if beta <= alpha or self.no_more_time(): 
       break 
     del list[:] 
     return alpha, selected_move 

    else: 
     for i in range(0, int(len(list) * self.w)): 
      beta = min(beta, self.search(list[i][0], depth - 1, alpha, beta, True)[0]) 
      if beta <= alpha or self.no_more_time(): 
       break 
     del list[:] 
     return beta, None 

class MiniMaxWithAlphaBetaPruningWithWDeepeningUntilRestfulness(MiniMaxWithAlphaBetaPruning): 
def __init__(self, utility, my_color, no_more_time, w): 
    MiniMaxWithAlphaBetaPruningWithW.__init__(self, utility, my_color, no_more_time, w) 
    # self.treshold_restfulness = TODO 

def search(self, state, depth, alpha, beta, maximizing_player): 
    """Start the MiniMax algorithm. 

    :param state: The state to start from. 
    :param depth: The maximum allowed depth for the algorithm. 
    :param alpha: The alpha of the alpha-beta pruning. 
    :param alpha: The beta of the alpha-beta pruning. 
    :param maximizing_player: Whether this is a max node (True) or a min node (False). 
    :return: A tuple: (The alpha-beta algorithm value, The move in case of max node or None in min mode) 
    """ 

    print('debugger - line 4') 

    if depth == 0 or self.no_more_time(): 
     return self.utility(state), None 

    next_moves = state.legalMoves() 
    if not next_moves: 
     # This player has no moves. So the previous player is the winner. 
     return INFINITY if state.currPlayer != self.my_color else -INFINITY, None 

    list = [] 
    for next_move in next_moves: 
     if (self.no_more_time()): 
      del list[:] 
      return self.utility(state), None 
     new_state = copy.deepcopy(state) 
     new_state.doMove(next_move) 
     list.append((new_state, next_move, self.utility(new_state))) 

    list.sort(key=itemgetter(2)) 
    if (self.no_more_time()): 
     del list[:] 
     return self.utility(state), None 

    if maximizing_player: 
     selected_move = next_moves[0] 
     best_move_utility = -INFINITY 
     for i in range(int(len(list)) - 1, int(len(list)) - int(len(list) * self.w) - 1, -1): 
      minimax_value, _ = self.search(list[i][0], depth - 1, alpha, beta, False) 
      alpha = max(alpha, minimax_value) 
      if minimax_value > best_move_utility: 
       best_move_utility = minimax_value 
       selected_move = list[i][1] 
      if beta <= alpha or self.no_more_time(): 
       break 
     print('Utility of best Move in deepening in depth of {} is {}'.format(depth, minimax_value)) 
     del list[:] 
     return alpha, selected_move 

    else: 
     for i in range(0, int(len(list) * self.w)): 
      beta = min(beta, self.search(list[i][0], depth - 1, alpha, beta, True)[0]) 
      if beta <= alpha or self.no_more_time(): 
       break 
     del list[:] 
     return beta, None 

сообщение об ошибке:

Exception in thread Thread-6: 
Traceback (most recent call last): 
    File "C:\Python34\lib\threading.py", line 921, in _bootstrap_inner 
self.run() 
File "C:\Python34\lib\threading.py", line 869, in run 
self._target(*self._args, **self._kwargs) 
File "C:\Users\Eli\workspace\HW2\amazons\utils.py", line 36, in function_wrapper 
result = func(*args, **kwargs) 
TypeError: search() missing 1 required positional argument: 'maximizing_player' 

для удобства оригинальный проигрыватель:

class Player(players.simple_player.Player): 
def __init__(self, setup_time, player_color, time_per_k_turns, k, w): 
    players.simple_player.Player.__init__(self, setup_time, player_color, time_per_k_turns, k) 
    self.w = w; 

def get_move(self, board_state, possible_moves): 
    self.clock = time.process_time() 
    self.time_for_current_move = self.time_remaining_in_round/self.turns_remaining_in_round - 0.05 
    if len(possible_moves) == 1: 
     return possible_moves[0] 

    current_depth = 1 
    prev_alpha = -INFINITY 

    # Choosing an arbitrary move: 
    best_move = possible_moves[0] 

    if (self.w < 1): 
     minimax = MiniMaxWithAlphaBetaPruningWithW(self.utility, self.color, self.no_more_time, self.w) 
    else: # self.w == 1 
     minimax = MiniMaxWithAlphaBetaPruning(self.utility, self.color, self.no_more_time) 
    time_last_move = 0; 

    # Iterative deepening until the time runs out. 
    while True: 
     print('{} going to depth: {}, remaining time: {}, prev_alpha: {}, best_move: {}'.format(
      self.__repr__(), current_depth, self.time_for_current_move - (time.process_time() - self.clock), 
      prev_alpha, best_move)) 

     time_before = time.process_time() 
     time_left = self.time_for_current_move - (time.process_time() - self.clock); 
     # if (time_last_move <= time_left): 
     try: 
      (alpha, move), run_time = run_with_limited_time(
       minimax.search, (board_state, current_depth, -INFINITY, INFINITY, True), {}, 
       time_left) 
     except (ExceededTimeError): 
      print('no more time') 
      break 
     except (MemoryError): 
      print('no more memory') 
      break 
     # else: 
     # print('{} has no enough time ({}) left to go deeper'.format(self.__repr__(), time_left)) 
     # break; 

     time_after = time.process_time() 
     time_last_move = time_after - time_before 

     if self.no_more_time(): 
      print('no more time') 
      break 

     prev_alpha = alpha 
     best_move = move 

     if alpha == INFINITY: 
      print('the move: {} will guarantee victory.'.format(best_move)) 
      break 

     if alpha == -INFINITY: 
      print('all is lost') 
      break 

     current_depth += 1 

    if self.turns_remaining_in_round == 1: 
     self.turns_remaining_in_round = self.k 
     self.time_remaining_in_round = self.time_per_k_turns 
    else: 
     self.turns_remaining_in_round -= 1 
     self.time_remaining_in_round -= (time.process_time() - self.clock) 
    return best_move 

и для удобства - run_with_limited_time:

def run_with_limited_time(func, args, kwargs, time_limit): 
"""Runs a function with time limit 

:param func: The function to run. 
:param args: The functions args, given as tuple. 
:param kwargs: The functions keywords, given as dict. 
:param time_limit: The time limit in seconds (can be float). 
:return: A tuple: The function's return value unchanged, and the running time for the function. 
:raises PlayerExceededTimeError: If player exceeded its given time. 
""" 
q = Queue() 
t = Thread(target=function_wrapper, args=(func, args, kwargs, q)) 
t.start() 

# This is just for limiting the runtime of the other thread, so we stop eventually. 
# It doesn't really measure the runtime. 
t.join(time_limit) 

if t.is_alive(): 
    raise ExceededTimeError 

q_get = q.get() 
if isinstance(q_get, MemoryError): 
    raise q_get 
return q_get 

Там нет, конечно, никакого упоминания к объекту только к функциям игр, которые управляют его. Я не знаю, почему это происходит. Это должно быть очень глупым, но я понятия не имею ... Я сделал только простую копию кода, и я не изменил эту линию ...

Спасибо заранее, Эли

+0

Выразить (цельная). Измените название. Перепишите свой вопрос (то, как вы пишете, странно и запутанно) – tglaria

+0

Что такое подпись 'run_with_limited_time'? –

+0

Определенно перепишите свой заголовок. –

ответ

2

Ваша проблема здесь:

minimax = MiniMaxWithAlphaBetaPruningWithWDeepeningUntilRestfulness 
    (self.utility, self.color, self.no_more_time, self.w) 

Это фактически две отдельные строки, вторая из которых ничего не делает, в то время как вы предполагали, что это одно выражение. Он назначит minimax как сам класс, а не экземпляр, что вызывает проблемы при вызове метода в классе позже.

Вы можете поставить все на одной линии, или просто переместить открывающую скобку в первой строке (как Python позволяет выражения продолжить на следующей строке, когда круглые скобки остаются открытыми):

minimax = MiniMaxWithAlphaBetaPruningWithWDeepeningUntilRestfulness(
    self.utility, self.color, self.no_more_time, self.w) 
+0

Спасибо, это мне очень помогло! –

Смежные вопросы