Esempio n. 1
0
 def select_move(self, game_state: GameState):
     best_moves: List[Move] = []
     best_score = MIN_SCORE
     best_black = MIN_SCORE
     best_white = MIN_SCORE
     for possible_move in game_state.legal_moves():
         next_state = game_state.apply_move(possible_move)
         # Since our opponent plays next, figure out their best
         # possible outcome from there.
         opponent_best_outcome = alpha_beta_result(next_state,
                                                   self.max_depth,
                                                   best_black, best_white,
                                                   self.eval_fn)
         # Our outcome is the opposite of our opponent's outcome.
         our_best_outcome = -opponent_best_outcome
         if len(best_moves) == 0 or our_best_outcome > best_score:
             # This is the best move so far.
             best_moves = [possible_move]
             best_score = our_best_outcome
             if game_state.next_player == Player.BLACK:
                 best_black = best_score
             elif game_state.next_player == Player.WHITE:
                 best_white = best_score
         elif our_best_outcome == best_score:
             # This is as good as our previous best move.
             best_moves.append(possible_move)
     # For variety, randomly select among all equally good moves.
     return random.choice(best_moves)
Esempio n. 2
0
def alpha_beta_result(game_state: GameState, max_depth: int, best_black: int,
                      best_white: int, eval_fn: Callable) -> int:
    if game_state.is_over():
        return MAX_SCORE if game_state.winner(
        ) == game_state.next_player else MIN_SCORE

    if max_depth == 0:
        return eval_fn(game_state)

    best_so_far = MIN_SCORE
    for candidate_move in game_state.legal_moves():
        next_state = game_state.apply_move(candidate_move)
        opponent_best_result = alpha_beta_result(next_state, max_depth - 1,
                                                 best_black, best_white,
                                                 eval_fn)
        our_result = -opponent_best_result

        if our_result > best_so_far:
            best_so_far = our_result
        if game_state.next_player == Player.WHITE:
            if best_so_far > best_white:
                best_white = best_so_far
            outcome_for_black = -best_so_far
            if outcome_for_black < best_black:
                return best_so_far
        elif game_state.next_player == Player.BLACK:
            if best_so_far > best_black:
                best_black = best_so_far
            outcome_for_white = -best_so_far
            if outcome_for_white < best_white:
                return best_so_far
    return best_so_far
Esempio n. 3
0
def best_result(game_state: GameState, max_depth: int, eval_fn: Callable):
    if game_state.is_over():
        return MAX_SCORE if game_state.winner(
        ) == game_state.next_player else MIN_SCORE

    if max_depth == 0:
        return eval_fn(game_state)

    best_so_far = MIN_SCORE
    for candidate_move in game_state.legal_moves():
        next_state = game_state.apply_move(candidate_move)
        opponent_best_result = best_result(next_state, max_depth - 1, eval_fn)
        our_result = -1 * opponent_best_result
        if our_result > best_so_far:
            best_so_far = our_result
    return best_so_far
Esempio n. 4
0
def best_result(game_state: GameState) -> GameResult:
    if game_state.is_over():
        if game_state.winner() == game_state.next_player:
            return GameResult.Win
        elif game_state.winner() is None:
            return GameResult.Draw
        else:
            return GameResult.Loss

    best_result_so_far = GameResult.Loss
    for candidate_move in game_state.legal_moves():
        next_state = game_state.apply_move(candidate_move)
        opponent_best_result = best_result(next_state)
        our_result = reverse_game_result(opponent_best_result)
        if our_result.value > best_result_so_far.value:
            best_result_so_far = our_result

    return best_result_so_far
Esempio n. 5
0
 def select_move(self, game_state: GameState) -> Move:
     best_moves: List[Move] = []
     best_score = None
     # Loop over all legal moves.
     for possible_move in game_state.legal_moves():
         # Calculate the game state if we select this move.
         next_state = game_state.apply_move(possible_move)
         # Since our opponent plays next, figure out their best
         # possible outcome from there.
         opponent_best_outcome = best_result(next_state, self.max_depth,
                                             self.eval_fn)
         # Our outcome is the opposite of our opponent's outcome.
         our_best_outcome = -1 * opponent_best_outcome
         if (not best_moves) or our_best_outcome > best_score:
             # This is the best move so far.
             best_moves = [possible_move]
             best_score = our_best_outcome
         elif our_best_outcome == best_score:
             # This is as good as our previous best move.
             best_moves.append(possible_move)
     # For variety, randomly select among all equally good moves.
     return random.choice(best_moves)
Esempio n. 6
0
    def select_move(self, game_state: GameState) -> Move:
        winning_moves: List[Move] = []
        draw_moves: List[Move] = []
        losing_moves: List[Move] = []

        for possible_move in game_state.legal_moves():
            next_state = game_state.apply_move(possible_move)
            opponent_best_outcome = best_result(next_state)
            our_best_outcome = reverse_game_result(opponent_best_outcome)
            if our_best_outcome == GameResult.Win:
                winning_moves.append(possible_move)
            elif our_best_outcome == GameResult.Draw:
                draw_moves.append(possible_move)
            else:
                losing_moves.append(possible_move)

        if len(winning_moves) > 0:
            return random.choice(winning_moves)
        elif len(draw_moves) > 0:
            return random.choice(draw_moves)
        else:
            return random.choice(losing_moves)