def play_game(strategy_p1, strategy_p2, max_allowed_turn_count): """ The players take turns until one player has 5 or less pebbles left on their board. Stop if the game takes too long. """ p1_board = game_area() p2_board = game_area() outcome = None turn_count = 0 text = "" print(print_field(p1_board, p2_board)) while pebbles_left(p1_board) > 5 and pebbles_left( p2_board) > 5 and turn_count < max_allowed_turn_count: turn(p1_board, p2_board, strategies(strategy_p1, p1_board, p2_board)) print(print_field(p1_board, p2_board)) turn(p2_board, p1_board, strategies(strategy_p2, p2_board, p1_board)) print(print_field(p1_board, p2_board)) turn_count += 1 if pebbles_left(p1_board) > 5: winning_player = 1 text = ("Player 1 won the game after %d turns." % turn_count) if pebbles_left(p2_board) > 5: winning_player = 2 text = ("Player 2 won the game after %d turns." % turn_count) if turn_count == 100: winning_player = 0 print("Too many turns!") print(text) outcome = ({'Winner': winning_player, 'turn count': turn_count}) return outcome
def min_pebbles_to_steal(current_board, opponent_board): """ Start at the (first) hole that minimizes the sum of pebbles the opponent will be able to eat in the next move, i.e. minimize the sum of pebbles lying in opposing holes of each other where both are filled. """ intermediate_eatable_pebbles = 64 for i in range(0, 16): frozen_current_board = current_board.copy() frozen_opponent_board = opponent_board.copy() turn(frozen_current_board, frozen_opponent_board, i) pebbles_to_eat = sum_eatable_pebbles(frozen_current_board) if pebbles_to_eat < intermediate_eatable_pebbles: intermediate_eatable_pebbles = pebbles_to_eat start = i return start
def maxmin(current_board, opponent_board): """ Start at the (first) hole that maximizes the difference between the sum of pebbles on the board and the sum of pebbles the opponent will be able to eat in the next move. """ diff = -1 for i in range(0, 16): frozen_current_board = current_board.copy() frozen_opponent_board = opponent_board.copy() turn(frozen_current_board, frozen_opponent_board, i) intermediate_diff = pebbles_left(frozen_current_board) -sum_eatable_pebbles(frozen_current_board) if intermediate_diff > diff: diff = intermediate_diff start = i return start
def max_pebbles(current_board, opponent_board): """ Start at the (first) hole that maximises the sum of pebbles left at the end of each turn. If none does, start at the hole that minimizes the sum of pebbles the opponent will be able to eat in the next move. """ sum_pebbles = pebbles_left(current_board) intermediate_sum_pebbles = 0 for i in range(0, 16): frozen_current_board = current_board.copy() frozen_opponent_board = opponent_board.copy() turn(frozen_current_board, frozen_opponent_board, i) if pebbles_left(frozen_current_board) > sum_pebbles: intermediate_sum_pebbles = pebbles_left(frozen_current_board) start = i if sum_pebbles > intermediate_sum_pebbles: start = min_pebbles_to_steal(current_board, opponent_board) return start
def alpha_game(alpha_player, opponent_strategy, AI_data, max_allowed_turn_count): """ Play a game of Bao where one player is the Alpha-Player and each turn the hashed game status plus the starting hole is saved in a dictionary. """ p1_board = game_area() p2_board = game_area() turn_count = 0 dict_of_hashs = {} game_states = [] while pebbles_left(p1_board) > 5 and pebbles_left( p2_board) > 5 and turn_count < 100: turn_count += 1 if alpha_player == 1: status = game_status(p1_board, p2_board) start = alpha_strategy(p1_board, p2_board, AI_data) turn(p1_board, p2_board, start) dict_of_hashs.update({status: start}) game_states.append(status) turn(p2_board, p1_board, strategies(opponent_strategy, p2_board, p1_board)) else: turn(p1_board, p2_board, strategies(opponent_strategy, p1_board, p2_board)) status = game_status(p1_board, p2_board) start = alpha_strategy(p2_board, p1_board, AI_data) turn(p2_board, p1_board, start) dict_of_hashs.update({status: start}) game_states.append(status) if turn_count < max_allowed_turn_count: if pebbles_left(p1_board) > 5: winning_player = 1 if pebbles_left(p2_board) > 5: winning_player = 2 else: winning_player = 0 print("Player {} won after {} turns.".format(winning_player, turn_count)) return winning_player, turn_count, dict_of_hashs, game_states