def fight(ann, best, dump=False): board = game.getEmptyBoard() current = 'O' action = random.randint(0, game.BOARD_SIZE * game.BOARD_SIZE - 1) board, won = game.move(board, action, current) if dump: print(game.render(board)) current = 'O' if current == 'X' else 'X' while True: entry = state_lists_to_batch([board], current) probs = best(entry)[0] if current == 'O' else ann(entry)[0] while True: action = np.argmax(probs) if action not in game.possible_moves(board): probs[action] = -np.inf else: break board, won = game.move(board, action, current) if dump: print(game.render(board)) if len(game.possible_moves(board)) == 0: return None if won: break current = 'O' if current == 'X' else 'X' return best if current == 'O' else ann
def expectimax(game, depth, value_function): """ Searches the game tree down to given depth to find the maximum expected value of value_function. value_function takes the game at the leaf nodes and returns a number value. Returns tuple (value, move) with the expected value and the maximizing move. """ # base case: reached depth if depth == 0: return value_function(game), 'null' possible = possible_moves(game) # base case: no more moves if not possible: return value_function(game), 'null' # get the possible outcomes of each possible move expanded = [(move, move_made_all(game, move)) for move in possible] move_value = [] # calculate expected value of each possible move for move, games in expanded: value = sum(p * expectimax(g, depth - 1, value_function)[0] for p, g in games) move_value.append((value, move)) return max(move_value)
def get_move_randomly(active_player, board): piece_location_options = locations_of_pieces_with_valid_moves( active_player, board) if not piece_location_options: raise GameOver() location_of_piece_to_move = random.choice(piece_location_options) move_options = possible_moves(location_of_piece_to_move, active_player, board) return random.choice(move_options)
def get_move_from_stdin(active_player, board): piece_location_options = locations_of_pieces_with_valid_moves( active_player, board) if not piece_location_options: raise GameOver() location_of_piece_to_move = get_choice_from_stdin(piece_location_options, pretty_location_str) move_options = possible_moves(location_of_piece_to_move, active_player, board) return get_choice_from_stdin(move_options, pretty_move_str)
def best_move_silvia(board): moves = possible_moves(board) move_std = dict(zip(moves, [0] * len(moves))) for move in moves: new_board, _ = move_made((board, 0), move) move_std[move] = get_neighbor_devsum(new_board) move = min(move_std, key=move_std.get) return move
def ai_mode(number_of_games=1): """ Just let the AI play a number of times without showing the UI. """ scores = [] for i in range(number_of_games): board, score = new_game(4) possible = possible_moves(board) while possible: move = game_ai.expectimax_move((board, score), 'gradient') score += make_move(board, move) possible = possible_moves(board) scores.append(score) print("Game {0}: Score = {1}".format(i+1, score)) print() print("Mean score = " + str(sum(scores)/float(len(scores))))
def main(playmode): view = GameView() board, score = new_game(4) view.draw(board, score) clock = pygame.time.Clock() while True: clock.tick(20) # limit fps redraw = False # get move from player for event in pygame.event.get(): if event.type == QUIT: print("Exiting...") return if event.type == KEYDOWN and playmode: if event.key == K_LEFT: score += make_move(board, 'left') redraw = True if event.key == K_RIGHT: score += make_move(board, 'right') redraw = True if event.key == K_UP: score += make_move(board, 'up') redraw = True if event.key == K_DOWN: score += make_move(board, 'down') redraw = True if redraw: view.draw(board, score) # get move from ai if not playmode: best_move = game_ai.expectimax_move((board, score), 'gradient') # make the move and redraw score += make_move(board, best_move) view.draw(board, score) pygame.time.wait(0) # check if it is game over if len(possible_moves(board)) == 0: print("Game over! Score: " + str(score) + " Max square: " + str(max_square(board))) print("Starting new game...\n") pygame.time.wait(3000) pygame.event.clear() board, score = new_game(4) view.draw(board, score)
def ai_mode(number_of_games=1): """ Just let the AI play a number of times without showing the UI. """ scores = [] for i in range(number_of_games): board, score = new_game(4) possible = possible_moves(board) while possible: move = game_ai.expectimax_move((board, score), 'gradient') score += make_move(board, move) possible = possible_moves(board) scores.append(score) print("Game {0}: Score = {1}".format(i + 1, score)) print() print("Mean score = " + str(sum(scores) / float(len(scores))))
def main(playmode): view = GameView() board, score = new_game(4) view.draw(board,score) clock = pygame.time.Clock() while True: clock.tick(20) # limit fps redraw = False # get move from player for event in pygame.event.get(): if event.type == QUIT: print("Exiting...") return if event.type == KEYDOWN and playmode: if event.key == K_LEFT: score += make_move(board, 'left') redraw = True if event.key == K_RIGHT: score += make_move(board, 'right') redraw = True if event.key == K_UP: score += make_move(board, 'up') redraw = True if event.key == K_DOWN: score += make_move(board, 'down') redraw = True if redraw: view.draw(board, score) # get move from ai if not playmode: best_move = game_ai.expectimax_move((board, score), 'gradient') # make the move and redraw score += make_move(board, best_move) view.draw(board, score) pygame.time.wait(0) # check if it is game over if len(possible_moves(board)) == 0: print("Game over! Score: " + str(score) + " Max square: " + str(max_square(board))) print("Starting new game...\n") pygame.time.wait(3000) pygame.event.clear() board, score = new_game(4) view.draw(board, score)
def get_move_from_stdin_old_style(active_player, board): location_of_piece_to_move = None reason_cant_move = "Select a piece to move." while reason_cant_move: print(reason_cant_move) try: location_of_piece_to_move = parse_location_from_str(input("> ")) reason_cant_move = reason_piece_at_location_cant_move( location_of_piece_to_move, active_player, board) except InvalidLocationString: reason_cant_move = "That's not a valid square. Try something like \"h6\"..." options = possible_moves(location_of_piece_to_move, active_player, board) return get_choice_from_stdin(options, pretty_move_str)
def max_score_search(game, depth, val): """ Simple AI that searches the game tree down a given depth and returns the maximum value of the leaf nodes at level depth. Value is given by the function val(game) Signature: game, int depth, function val => int score """ if depth == 0: return val(game) new_games = [move_made(game, move) for move in possible_moves(game)] if len(new_games) == 0: return 0 return max(max_score_search(g, depth - 1, val) for g in new_games)
def best_move(game, method='score'): """ val should be function game -> int """ board, score = game if method == 'score': def val(g): return g[1] elif method == 'empty': val = empty_squares elif method == 'gradient': val = gradient_value else: print('Invalid method given to best_move function') exit(1) if score < 10000: depth = 4 elif score < 20000: depth = 5 elif score < 30000: depth = 7 else: depth = 7 moves = possible_moves(board) # dict with score for each move move_score = dict(zip(moves, [0] * len(moves))) # search for max score for each move for move in moves: move_score[move] += max_score_search(move_made(game, move), depth, val) move = max(move_score, key=move_score.get) return move