def _run(*args): idx, p1, p2, moves = args[0] game = Board(p1, p2) for m in moves: game.apply_move(m) winner, move_history, termination = game.play(time_limit=TIME_LIMIT) return (idx, winner == p1, len(move_history)), termination
def play_round(cpu_agent, test_agents, win_counts, num_matches): """Compare the test agents to the cpu agent in "fair" matches. "Fair" matches use random starting locations and force the agents to play as both first and second player to control for advantages resulting from choosing better opening moves or having first initiative to move. """ timeout_count = 0 forfeit_count = 0 move_count = 0 pool = Pool(NUM_PROCS) for _ in range(num_matches): # initialize all games with a random move and response init_moves = [] init_game = Board("p1", "p2") for _ in range(2): move = random.choice(init_game.get_legal_moves()) init_moves.append(move) init_game.apply_move(move) games = sum([[(2 * i, cpu_agent.player, agent.player, init_moves), (2 * i + 1, agent.player, cpu_agent.player, init_moves)] for i, agent in enumerate(test_agents)], []) # play all games and tally the results for result, termination in pool.imap_unordered(_run, games): game = games[result[0]] winner = game[1] if result[1] else game[2] move_count += result[2] win_counts[winner] += 1 if termination == "timeout": timeout_count += 1 elif winner not in test_agents and termination == "forfeit": forfeit_count += 1 return timeout_count, forfeit_count, move_count
import time from isolation import Board from sample_players import GreedyPlayer from game_agent import CustomPlayer player_1 = CustomPlayer() player_2 = GreedyPlayer() #player_2 = RandomPlayer() print(player_1, player_2) test_game = Board(player_1, player_2) start = time.time() winner, moves, reason = test_game.play() end = time.time() #print (winner) if reason == "timeout": print("Forfeit due to timeout.") for move in moves: print(move) print( 'Play Summary : Time taken = {0}, number of move = {1}, winner= {2}, Reason ={3}' .format(end - start, len(moves), winner, reason))
valid_choice = False while not valid_choice: try: index = int(input('Select move index:')) valid_choice = 0 <= index < len(legal_moves) if not valid_choice: print('Illegal move! Try again.') except ValueError: print('Invalid index! Try again.') return legal_moves[index] if __name__ == "__main__": from isolation import Board # create an isolation board (by default 7x7) player1 = HumanPlayer1() player2 = HumanPlayer2() game = Board(player1, player2) winner, history, outcome = game.play(time_limit=1000000) print("\nWinner: {}\nOutcome: {}".format(winner, outcome)) print(game.to_string()) print("Move history:\n{!s}".format(history)) print("\n{}".format(game.is_winner(game.inactive_player)))
def try_moves(moves): g = Board(p1, p2, w, w) for move in moves: g.apply_move(move) move_start = curr_time_millis() time_left = lambda: TIME_LIMIT - (curr_time_millis() - move_start) print(g.to_string()) active_p = g.active_player p_l_m = g.get_legal_moves(active_p) p_res = active_p.get_move(g, p_l_m, time_left) # p1_pos = [(i, j) for i in range(w//2+1) for j in range(i, w//2+1)] # p1_pos = [(i, i) for i in range(w//2)] # for p1_move in p1_pos: # for p2_move in [(i, j) for i in range(w) for j in range(i, w) if (i, j) != p1_move]: # try_moves([p1_move, p2_move]) # # # p1_pos = [(i, w//2) for i in range(w//2)] # for p1_move in p1_pos: # for p2_move in [(i, j) for i in range(w) for j in range(w//2+1) if (i, j) != p1_move]: # try_moves([p1_move, p2_move]) # # p1_pos = [(w//2, w//2)] # for p1_move in p1_pos: # for p2_move in [(i, j) for i in range(w//2) for j in range(i, w//2+1) if (i, j) != p1_move]: # try_moves([p1_move, p2_move]) # # p1_pos = [(i, j) for i in range(w//2) for j in range(i, w//2) if i != j] # for p1_move in p1_pos: # for p2_move in [(i, j) for i in range(w) for j in range(w) if (i, j) != p1_move]: # try_moves([p1_move, p2_move]) # for i in range(5): # for j in range(5): # if (i, j) == (0, 1): continue # g2 = g.copy() # g2.apply_move((i, j)) # print(g2.to_string()) # p1_l_m = g2.get_legal_moves(p1) # p1_res = p1.get_move(g2, p1_l_m, time_left) # print(p1_res) # p1_l_m = g.get_legal_moves(p1) # p1_res = p1.get_move(g, p1_l_m, time_left) # print(p1_res) # p2_l_m = g.get_legal_moves(p2) # p2_res = p2.get_move(g, p2_l_m, time_left) # print(p2_res) # p1_move = (0, 2) #p2_moves = [(a, b) for a in range(5) for b in range(3) if (a, b) != p1_move] #p2_moves = [(a, b) for a in range(3) for b in range(3) if (a, b) != p1_move] # p2_moves = [(1, 3)] # p1_wins = [] # p2_wins = [] # for p2_move in p2_moves: # g = Board(p1, p2, 5, 5) # g.apply_move(p1_move) # g.apply_move(p2_move) # # res = g.play(time_limit=TIME_LIMIT) # print(res) # move_start = curr_time_millis() # time_left = lambda : TIME_LIMIT - (curr_time_millis() - move_start) # p1_l_m = g.get_legal_moves(p1) # p1_res = p1.get_move(g, p1_l_m, time_left) # if p1_res == (-1, -1): # p2_wins.append(p2_move) # print('in game: p1 lose!') # else: # g.apply_move(p1_res) # move_start = curr_time_millis() # time_left = lambda: TIME_LIMIT - (curr_time_millis() - move_start) # p2_l_m = g.get_legal_moves(p2) # p2_res = p2.get_move(g, p2_l_m, time_left) # if p2_res == (-1, -1): # p1_wins.append(p1_move) # print('in game: p1 win!') # else: # print('terrible! did not search to the end!!!!!! in game: ') # print(g.to_string()) # # print(p1_wins) # print(p2_wins)
from isolation import Board from sample_players import GreedyPlayer from game_agent import MinimaxPlayer from game_agent import AlphaBetaPlayer p1 = AlphaBetaPlayer() #p2 = MinimaxPlayer() p2 = GreedyPlayer() game = Board(p1, p2) game.apply_move((3, 3)) game.apply_move((0, 5)) print(game.get_legal_moves()) winner, history, outcome = game.play() print("\nWinner: {}, Outcome: {}".format(winner, outcome)) print(game.to_string()) print("History:\n{!s}".format(history))
if not valid_choice: print('Illegal move! Try again.') except ValueError: print('Invalid index! Try again.') return legal_moves[index] if __name__ == "__main__": from isolation import Board # create an isolation board (by default 7x7) player1 = RandomPlayer() player2 = GreedyPlayer() game = Board(player1, player2) # place player 1 on the board at row 2, column 3, then place player 2 on # the board at row 0, column 5; display the resulting board state. Note # that the .apply_move() method changes the calling object in-place. game.apply_move((2, 3)) game.apply_move((0, 5)) print(game.to_string()) # players take turns moving on the board, so player1 should be next to move assert(player1 == game.active_player) # get a list of the legal moves available to the active player print(game.get_legal_moves()) # get a successor of the current state by making a copy of the board and
def alphabeta(self, game: Board, depth: int, alpha: float = float("-inf"), beta: float = float("inf"), maximizing_player: bool = True) -> Tuple[float, Move]: """Implement minimax search with alpha-beta pruning as described in the lectures. Parameters ---------- game : isolation.Board An instance of the Isolation game `Board` class representing the current game state depth : int Depth is an integer representing the maximum number of plies to search in the game tree before aborting alpha : float Alpha limits the lower bound of search on minimizing layers beta : float Beta limits the upper bound of search on maximizing layers maximizing_player : bool Flag indicating whether the current search depth corresponds to a maximizing layer (True) or a minimizing layer (False) Returns ------- float The score for the current search branch tuple(int, int) The best move for the current branch; (-1, -1) for no legal moves Notes ----- (1) You MUST use the `self.score()` method for board evaluation to pass the project unit tests; you cannot call any other evaluation function directly. """ if self.time_left() < self.timer_threshold: raise Timeout() best_move = (-1, -1) best_score = alpha if maximizing_player else beta if depth is 0: return self.score(game, self), best_move for move in game.get_legal_moves(): future_game = game.forecast_move(move) score, _ = self.alphabeta(future_game, depth - 1, alpha, beta, not maximizing_player) if maximizing_player: if score > best_score: best_score, best_move = score, move if best_score >= beta: return best_score, best_move alpha = max(alpha, best_score) else: if score < best_score: best_score, best_move = score, move if best_score <= alpha: return best_score, best_move beta = min(beta, best_score) return best_score, best_move
v = _v move = m if v >= beta: return v, move alpha = max(alpha, v) return v, move # used for testing if __name__ == "__main__": from isolation import Board p1 = AlphaBetaPlayer(score_fn=custom_score_5) p2 = MinimaxPlayer(score_fn=custom_score) game = Board(p1, p2, width=7, height=7) winner, history, _ = game.play(time_limit=150) # game.apply_move((1, 2)) # game.apply_move((2, 2)) # game.apply_move((2, 3)) # game.apply_move((2, 4)) # game.apply_move((3, 1)) # game.apply_move((3, 3)) # game.apply_move((3, 4)) # game.apply_move((3, 6)) # game.apply_move((4, 3)) # game.apply_move((4, 4)) # game.apply_move((4, 5)) # game.apply_move((5, 2)) # game.apply_move((5, 3))
custom_score_2, custom_score_3) from tournament import play_matches,play_round,update from time import time import timeit from copy import copy NUM_MATCHES = 5 # number of matches against each opponent TIME_LIMIT = 150 # number of milliseconds before timeout Agent = namedtuple("Agent", ["player", "name"]) Agent1 = Agent(AlphaBetaPlayer(score_fn=open_move_score), "MM_Open") #Agent1 = Agent(MinimaxPlayer(score_fn=open_move_score), "MM_Open") #Agent2 = Agent(RandomPlayer(), "Random") Agent2 = Agent(AlphaBetaPlayer(score_fn=improved_score), "AB_Improved") game = Board(Agent1.player, Agent2.player,9,9) #game._board_state = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 51] #game._board_state = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 32] #game._board_state = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 51] game._board_state = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 51] print(game.to_string()) legal_player_moves = game.get_legal_moves() legal_player_moves.sort() print("legal_player_moves:",legal_player_moves) move_history = [] time_limit = 150
from isolation import Board from sample_players import GreedyPlayer from game_agent import AlphaBetaPlayer player1 = AlphaBetaPlayer() player2 = AlphaBetaPlayer() game = Board(player1, player2, 9, 9) print(game.to_string()) game._board_state = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 49 ] print(game.to_string()) assert (player1 == game.active_player) print(game.get_legal_moves()) # new_game = game.forecast_move((1, 1)) # assert(new_game.to_string() != game.to_string()) # print("\nOld state:\n{}".format(game.to_string())) # print("\nNew state:\n{}".format(new_game.to_string())) winner, history, outcome = game.play() print("\nWinner: {}\nOutcome: {}".format(winner, outcome)) print(game.to_string()) # print("Move history:\n{!s}".format(history))
# TODO: finish this function! return best_move, best_val # The following are some basic tests you can use to sanity-check your code. You will also be provided with a test server to which you will be able to submit your agents as mentioned in the instructions doc. Good luck! # In[ ]: """Example test you can run to make sure your AI does better than random.""" from isolation import Board if __name__ == "__main__": r = RandomPlayer() h = CustomPlayer() game = Board(h,r) game.play_isolation() # In[ ]: """Example test you can run to make sure your basic evaluation function works.""" from isolation import Board if __name__ == "__main__": sample_board = Board(RandomPlayer(),RandomPlayer()) # setting up the board as though we've been playing sample_board.move_count = 3 sample_board.__active_player__ = 0 # player 1 = 0, player 2 = 1
import itertools import random import warnings from collections import namedtuple from isolation import Board from game_agent import MinimaxPlayer from isolation import Board from sample_players import improved_score player1 = MinimaxPlayer(search_depth=100) player2 = MinimaxPlayer(search_depth=100) game = Board(player1, player2) def timer(): return 10.0 while game.get_legal_moves() != 0: print("I did a turn") # DO this stuff player = game.active_player move = player.get_move(game, timer) game.apply_move(move) print(game.to_string())
def main(): try: sample_board = Board(RandomPlayer(), RandomPlayer()) # setting up the board as though we've been playing sample_board.move_count = 4 sample_board.__board_state__ = [[11, 0, 0, 0, 21, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 22, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 12, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0]] sample_board.__last_queen_move__ = { sample_board.queen_11: (0, 0), sample_board.queen_12: (4, 5), sample_board.queen_21: (0, 4), sample_board.queen_22: (2, 2) } test = sample_board.get_legal_moves() h = OpenMoveEvalFn() print 'OpenMoveEvalFn Test: This board has a score of %s.' % ( h.score(sample_board)) except NotImplementedError: print 'OpenMoveEvalFn Test: Not implemented' except: print 'OpenMoveEvalFn Test: ERROR OCCURRED' print traceback.format_exc() try: """Example test to make sure your minimax works, using the OpenMoveEvalFunction evaluation function. This can be used for debugging your code with different model Board states. Especially important to check alphabeta pruning""" # create dummy 5x5 board p1 = RandomPlayer() p2 = HumanPlayer() b = Board(p1, p2, 5, 5) b.__board_state__ = [[0, 0, 0, 0, 0], [0, 0, 0, 22, 0], [0, 0, 0, 11, 0], [0, 0, 0, 21, 12], [0, 0, 0, 0, 0]] b.__last_queen_move__["queen11"] = (2, 3) b.__last_queen_move__["queen12"] = (3, 4) b.__last_queen_move__["queen21"] = (3, 3) b.__last_queen_move__["queen22"] = (1, 3) b.move_count = 4 output_b = b.copy() legal_moves = b.get_legal_moves() winner, move_history, termination = b.play_isolation() print 'Minimax Test: Runs Successfully' # Uncomment to see example game print game_as_text(winner, move_history, termination, output_b) except NotImplementedError: print 'Minimax Test: Not Implemented' except: print 'Minimax Test: ERROR OCCURRED' print traceback.format_exc() """Example test you can run to make sure your AI does better than random.""" try: r = RandomPlayer() h = CustomPlayer() game = Board(r, h, 7, 7) output_b = game.copy() winner, move_history, termination = game.play_isolation() print game_as_text(winner, move_history, termination, output_b) if 'CustomPlayer' in str(winner): print 'CustomPlayer Test: CustomPlayer Won' else: print 'CustomPlayer Test: CustomPlayer Lost' # Uncomment to see game # print game_as_text(winner, move_history, termination, output_b) except NotImplementedError: print 'CustomPlayer Test: Not Implemented' except: print 'CustomPlayer Test: ERROR OCCURRED' print traceback.format_exc()
def setUp(self): pg.display.set_mode = Mock(wraps=pg.Surface) pg.display.set_caption = Mock() pg.display.update = Mock() self.board = Board()
## import timeit time_millis = lambda: 1000 * timeit.default_timer() move_start = time_millis() time_left = lambda: player1.TIMER_THRESHOLD - (time_millis() - move_start) # from isolation import Board # create an isolation board (by default 7x7) player2 = MinimaxPlayer(search_depth=10, score_fn=custom_score, timeout=10.) player1 = AlphaBetaPlayer(search_depth=10, score_fn=custom_score, timeout=10.) game = Board(player1, player2) # place player 1 on the board at row 2, column 3, then place player 2 on # the board at row 0, column 5; display the resulting board state. Note # that the .apply_move() method changes the calling object in-place. game.apply_move((2, 3)) game.apply_move((0, 5)) # assert (player1 == game.active_player) # get a list of the legal moves available to the active player print(game.get_legal_moves()) # get a successor of the current state by making a copy of the board and # applying a move. Notice that this does NOT change the calling object # (unlike .apply_move()).
TIME_LIMIT = 20 curr_time_millis = lambda: 1000 * timeit.default_timer() move_start = curr_time_millis() time_left = lambda: TIME_LIMIT - (curr_time_millis() - move_start) move = my_agent.player.get_move(game, game.get_legal_moves(my_agent.player),time_left) # winner, history, outcome = game.play() # print("\nWinner: {}\nOutcome: {}".format(winner, outcome)) # print(game.to_string()) # print(history) print(move) """ game = Board(my_agent.player, adversary.player, 7, 7) print(game.to_string()) moves_by_turn = [[(2, 2), (6, 1)], [(3, 4), (5, 3)], [(4, 2), (4, 1)], [(2, 3), (6, 0)], [(4, 4), (5, 2)], [(3, 2), (3, 3)], [(2, 4), (1, 2)], [(4, 3), (0, 0)], [(3, 5), (2, 1)], [(1, 4), (0, 2)], [(2, 6), (1, 0)], [(4, 5), (3, 1)], [(6, 4), (5, 0)], [(5, 6), (6, 2)], [(-1, -1)]] turn_count = 0 TIME_LIMIT = 1000 for turn in moves_by_turn: turn_count = turn_count + 1 p1_move = turn[0] p2_move = turn[1] if len(turn) == 2 else None
best_score = v best_move = move alpha = max(alpha, best_score) return best_move if __name__ == "__main__": from isolation import Board # create an isolation board (by default 7x7) # player1 = RandomPlayer() # player2 = GreedyPlayer() # game = Board(player1, player2) player1 = AlphaBetaPlayer() player2 = RandomPlayer() game = Board(player1, player2) # place player 1 on the board at row 2, column 3, then place player 2 on # the board at row 0, column 5; display the resulting board state. Note # that the .apply_move() method changes the calling object in-place. # game.apply_move((2, 3)) # game.apply_move((0, 5)) # print(game.to_string()) # players take turns moving on the board, so player1 should be next to move assert (player1 == game.active_player) # get a list of the legal moves available to the active player # print(game.get_legal_moves()) # get a successor of the current state by making a copy of the board and
class AlphaBetaIsolationTest(unittest.TestCase): """Unit tests for isolation agents""" def setUp(self): reload(game_agent) self.player1 = AlphaBetaPlayer(search_depth=2, score_fn=null_score, timeout=10.) self.player2 = AlphaBetaPlayer(search_depth=2, score_fn=null_score, timeout=10.) self.game = Board(self.player1, self.player2) def test_board_state(self): print(""" AssertionError: Failed to cut off search -- expanded too many nodes. (i.e., your agent did not prune at this node, but a correct alpha beta search did prune at this node when following the same expansion order that your agent followed.) Alpha: 4.0 Beta: 3.0 Game tree evaluation order: [(2, 1), (3, 0)] [(5, 6)] Nodes are shown with each layer sorted in the order the nodes were expanded during search. All nodes in each successive layer are children of the furthest-right node in the parent layer above it. Test Case Details: ------------------ Heuristic: open_move_score Depth limit: 2 Initial Board State: 0 1 2 3 4 5 6 7 8 0 | | | | | | | | | | 1 | | | | | | | | | | 2 | | | | - | - | | | | | 3 | | | - | - | - | - | - | | | 4 | | | 1 | - | - | - | - | | | 5 | | | - | | - | - | | | | 6 | | | - | - | | - | - | | | 7 | | | | | | 2 | | | | 8 | | | | | | | | | | game._board_state: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 22] """) self.game.set_board_state([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 22 ]) print(self.game.to_string()) self.game.play(rounds=1) # for debugging: # self.game.play(time_limit=9999000, rounds=1) print(self.game.to_string()) # which heuristic? & possibility to set alpha, beta directly! :( # self.assertIn(self.game.get_player_location(self.player1), [(2, 1), (3, 0)], "Failed to cut off search -- expanded too many nodes.") def test_board_state_2(self): print(""" AssertionError: Failed to cut off search -- expanded too many nodes. (i.e., your agent did not prune at this node, but a correct alpha beta search did prune at this node when following the same expansion order that your agent followed.) Alpha: 3.0 Beta: 2.0 Game tree evaluation order: [(0, 2), (0, 4)] [(4, 5)] Nodes are shown with each layer sorted in the order the nodes were expanded during search. All nodes in each successive layer are children of the furthest-right node in the parent layer above it. Test Case Details: ------------------ Heuristic: open_move_score Depth limit: 2 Initial Board State: 0 1 2 3 4 5 6 7 8 0 | | | | | | | | | | 1 | | | | | | | | | | 2 | | | - | 1 | | - | | | | 3 | | | | | | | | | | 4 | | | - | - | - | | - | | | 5 | | | - | | - | - | | | | 6 | | | | - | 2 | | | | | 7 | | | | | | | | | | 8 | | | | | | | | | | game._board_state: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 29] """) self.game.set_board_state([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 29 ]) print(self.game.to_string()) self.game.play(rounds=1) # for debugging: # self.game.play(time_limit=9999000, rounds=1) print(self.game.to_string())
if __name__ == "__main__": from isolation import Board win = False win_count = 0 game_count = 0 while True: # weights = [0.34395085588117713, 0.031064823225326332] # if not win: # weights = np.random.rand(2).tolist() # create an isolation board (by default 7x7) player1 = AlphaBetaPlayer(score_fn=improved_score) player2 = AlphaBetaPlayer(score_fn=custom_score) game = Board(player1, player2) # place player 1 on the board at row 2, column 3, then place player 2 on # the board at row 0, column 5; display the resulting board state. Note # that the .apply_move() method changes the calling object in-place. p1_start = choice(game.get_legal_moves()) # p1_start = (5, 2) print(p1_start) game.apply_move(p1_start) p2_start = choice(game.get_legal_moves()) # p2_start = (0, 5) print(p2_start) game.apply_move(p2_start) print(game.to_string()) # players take turns moving on the board, so player1 should be next to move
beta=float("inf"), maximizing_player=True): deeper = 1 best_move = (-1, -1) if maximizing_player: best_val = -float("inf") else: best_val = float("inf") while deeper <= max_depth: move, val, time_expired = self.alphabeta(game, deeper, alpha, beta, maximizing_player) if time_expired or deeper > game.height * game.width - game.move_count: print 'Time has expired' print 'current depth' print str(deeper - 1) return best_move, best_val else: best_move = move best_val = val deeper += 1 return best_move, best_val ## Gameplay setup and testing (confirm agent preforms better than random player) if __name__ == '__main__': from isolation import Board r = RandomPlayer() h = CustomPlayer() game = Board(h, r) game.play_isolation()
''' Serves as a testbed for game_agent ''' from isolation import Board from game_agent import * from sample_players import * import math # player1 = MinimaxPlayer() player2 = MinimaxPlayer() player1 = AlphaBetaPlayer() #player2 = AlphaBetaPlayer() game = Board(player1, player2) moves = game.get_legal_moves() # for move in moves(): # print('move : ', move) # game.forecast_move(move) game.apply_move((3, 3)) game.apply_move((3, 5)) own_location = game.get_player_location(player1) opp_location = game.get_player_location(player2) own_moves = game.get_legal_moves(player1) opp_moves = game.get_legal_moves(player2) print('own_moves: ', own_moves)
def __init__(self): self.human_player = None # it's the human player self.ia_player = CustomPlayer(method='alphabeta', iterative=False, score_fn=custom_score_knight_tour) self.board = Board(self.human_player, self.ia_player)
# game.apply_move((2, 3)) # game.apply_move((0, 5)) # # winner, history, outcome = game.play() #play(self, time_limit=TIME_LIMIT_MILLIS) # #player1.minimax(game,3) # # print("\nWinner: {}\nOutcome: {}".format(winner, outcome)) # print(game.to_string()) # print("Move history:\n{!s}".format(history)) p1wins = 0 p2wins = 0 for i in range(10): game = Board(player1, player2) #STARTING LOCATIONS FOR BOTH PLAYERS - FIXED #game.apply_move((2, 3)) #game.apply_move((0, 5)) #RANDOM STARTING LOCATIONS p1startx = randint(0, 6) p1starty = randint(0, 6) game.apply_move((p1startx, p1starty)) p2startx = randint(0, 6) p2starty = randint(0, 6) while ((p1startx == p2startx) and (p1starty == p2starty)): p2startx = randint(0, 6) p2starty = randint(0, 6) winner, history, outcome = game.play() print("winner=", str(winner))
from sample_players import (RandomPlayer, open_move_score, improved_score, center_score) from game_agent import (MinimaxPlayer, AlphaBetaPlayer, custom_score, custom_score_2, custom_score_3) from tournament import play_matches,play_round,update from time import time NUM_MATCHES = 5 # number of matches against each opponent TIME_LIMIT = 150 # number of milliseconds before timeout Agent = namedtuple("Agent", ["player", "name"]) NUM_MATCHES = 1 t0 = time() for i in range(NUM_MATCHES): #Agent1 = Agent(AlphaBetaPlayer(score_fn=open_move_score), "MM_Open") Agent1 = Agent(MinimaxPlayer(score_fn=open_move_score), "MM_Open") #Agent2 = Agent(RandomPlayer(), "Random") Agent2 = Agent(AlphaBetaPlayer(score_fn=improved_score), "AB_Improved") game = Board(Agent1.player, Agent2.player) # initialize all games with a random move and response for _ in range(2): move = random.choice(game.get_legal_moves()) game.apply_move(move) #print(game.to_string()) # play all games and tally the results winner, log, termination = game.play() # real thing happens here print(game.to_string()) print("winner:",winner, "opponet failed due to", termination) print("total time: ", time()-t0)
# | | | - | | 2 | | - | # # [[(0, 4), (4, 5)], [(2, 3), (6, 6)], [(0, 2), (5, 4)], [(1, 0), (4, 2)], [(2, 2), (5, 0)], [(0, 1), (6, 2)], [(1, 3), (4, 1)], [(3, 2), (3, 3)], [(2, 4), (1, 2)], [(4, 3), (3, 1)], [(3, 5), (5, 2)], [(1, 4), (6, 4)], [(-1, -1)]] DIR = [(1, 2), (2, 1), (-1, 2), (-2, 1), (1, -2), (2, -1), (-1, -2), (-2, -1)] CUSTOM_ARGS = {"method": 'alphabeta', 'iterative': True} curr_time_millis = lambda: 1000 * timeit.default_timer() p2 = CustomPlayer(score_fn=custom_score, **CUSTOM_ARGS) p1 = CustomPlayer(score_fn=improved_score, **CUSTOM_ARGS) #p2 = HumanPlayer() w = 7 g = Board(p1, p2, w, w) moves = [[(5, 1), (2, 6)], [(3, 0), (0, 5)], [(1, 1), (1, 3)], [(0, 3), (2, 1)], [(1, 5), (3, 3)], [(2, 3), (5, 2)], [(3, 1), (4, 0)], [(1, 0), (3, 2)], [(0, 2), (2, 4)], [(1, 4), (4, 3)], [(2, 2), (3, 5)], [(0, 1), (5, 4)], [(2, 0), (4, 6)], [(4, 1), (2, 5)]] for (move1, move2) in moves: g.apply_move(move1) if move2: g.apply_move(move2) print(g.to_string()) res = g.play(TIME_LIMIT)
def main(): # print "" # try: # sample_board = Board(RandomPlayer(), RandomPlayer()) # # setting up the board as though we've been playing # sample_board.move_count = 2 # sample_board.__board_state__ = [ # ["Q1", " ", " ", " ", " ", " ", " "], # [" ", " ", " ", " ", " ", " ", " "], # [" ", " ", " ", " ", " ", " ", " "], # [" ", " ", " ", "Q2", " ", " ", " "], # [" ", " ", " ", " ", " ", " ", " "], # [" ", " ", " ", " ", " ", " ", " "], # [" ", " ", " ", " ", " ", " ", " "] # ] # sample_board.__last_queen_move__ = {sample_board.__queen_1__: (0, 0, False), \ # sample_board.__queen_2__: (3, 3, False)} # test = sample_board.get_legal_moves() # h = OpenMoveEvalFn() # print 'OpenMoveEvalFn Test: This board has a score of %s.' % (h.score(sample_board)) # except NotImplementedError: # print 'OpenMoveEvalFn Test: Not implemented' # except: # print 'OpenMoveEvalFn Test: ERROR OCCURRED' # print traceback.format_exc() # # print "" # try: # """Example test to make sure # your minimax works, using the # OpenMoveEvalFunction evaluation function. # This can be used for debugging your code # with different model Board states. # Especially important to check alphabeta # pruning""" # # create dummy 5x5 board # b = Board(RandomPlayer(), HumanPlayer(), 5, 5) # # b.__board_state__ = [ # [" ", " ", " ", " ", " "], # [" ", " ", " ", " ", " "], # [" ", " ", " ", "Q1", " "], # [" ", " ", " ", "Q2", " "], # [" ", " ", " ", " ", " "] # ] # b.__last_queen_move__[b.__queen_1__] = (2, 3, False) # b.__last_queen_move__[b.__queen_2__] = (3, 3, False) # b.move_count = 2 # # output_b = b.copy() # legal_moves = b.get_legal_moves() # winner, move_history, termination = b.play_isolation( # time_limit=100000, print_moves=True) # print 'Minimax Test: Runs Successfully' # # Uncomment to see example game # # insert in reverse order # # initial_turn = [(2, 3, False), (3, 3, False)] # # move_history.insert(0, initial_turn) # # print game_as_text(winner, move_history, termination, output_b) # except NotImplementedError: # print 'Minimax Test: Not Implemented' # except: # print 'Minimax Test: ERROR OCCURRED' # print traceback.format_exc() """Example test you can run to make sure your AI does better than random.""" cnt = 0 for i in range(0, 1): try: r = RandomPlayer() h = CustomPlayer(2) game = Board(r, h, 7, 7) output_b = game.copy() winner, move_history, termination = game.play_isolation( time_limit=1000, print_moves=True) if winner == 'CustomPlayer - Q2': cnt += 1 print "\n", winner, " has won. Reason: ", termination # Uncomment to see game # print game_as_text(winner, move_history, termination, output_b) except NotImplementedError: print 'CustomPlayer Test: Not Implemented' except: print 'CustomPlayer Test: ERROR OCCURRED' print traceback.format_exc() print "Win Rate ", float(cnt * 1.0 / 100.0)
def minimaxTest(yourAgent, minimax_fn): """Example test to make sure your minimax works, using the OpenMoveEvalFunction evaluation function. This can be used for debugging your code with different model Board states. Especially important to check alphabeta pruning""" # create dummy 5x5 board print("Now running the Minimax test.") print() try: def time_left(): # For these testing purposes, let's ignore timeouts return 10000 player = yourAgent() #using as a dummy player to create a board sample_board = Board(player, RandomPlayer()) # setting up the board as though we've been playing board_state = [[" ", "X", " ", "X", " ", " ", " "], [" ", " ", " ", " ", " ", "X", " "], ["X", " ", " ", " ", " ", "Q1", " "], [" ", "X", " ", "Q2", " ", " ", "X"], [" ", " ", "X", " ", " ", " ", " "], [" ", " ", " ", "X", " ", "X", " "], [" ", " ", "X", " ", " ", "X", " "]] sample_board.set_state(board_state, p1_turn=True) test_pass = True expected_depth_scores = [(1, 7), (2, -6), (3, 1), (4, -1), (5, 2)] for depth, exp_score in expected_depth_scores: move, score = minimax_fn(player, sample_board, time_left, depth=depth, my_turn=True) print(score) if exp_score != score: print("Minimax failed for depth: ", depth) test_pass = True else: print("Minimax passed for depth: ", depth) if test_pass: player = yourAgent() sample_board = Board(RandomPlayer(), player) # setting up the board as though we've been playing board_state = [[" ", "X", " ", " ", "X", " ", "X"], [" ", " ", "X", "X", " ", "Q2", " "], ["X", " ", " ", " ", " ", " ", " "], [" ", " ", " ", " ", " ", "X", "X"], [" ", "X", "Q1", " ", "X", " ", " "], ["X", " ", " ", " ", " ", " ", " "], ["X", " ", " ", " ", "X", " ", "X"]] sample_board.set_state(board_state, p1_turn=False) test_pass = True expected_depth_scores = [(1, 3), (2, -8), (3, 3), (4, -5), (5, -2)] for depth, exp_score in expected_depth_scores: move, score = minimax_fn(player, sample_board, time_left, depth=depth, my_turn=True) print(score) if exp_score != score: print("Minimax failed for depth: ", depth) test_pass = False else: print("Minimax passed for depth: ", depth) if test_pass: print("Minimax Test: Runs Successfully!") else: print("Minimax Test: Failed") except NotImplementedError: print('Minimax Test: Not implemented') except: print('Minimax Test: ERROR OCCURRED') print(traceback.format_exc())
from isolation import Board player1 = RandomPlayer() # search algorithm, hacks, heuristic function player2 = GreedyPlayer() # minimax with alpha-beta pruning, # my_moves game = Board(player1, player2) #initialize the model of the Board """ 1. Initialize game board and maintain player order = pass player1, player2 2. Get legal moves for current player and algorithm it! 3. Maintain the player order 4. Print the game board 5. Repeat until game ends """ #-----------# def minimax(self, game, depth, maximizing_player=True): if maximizing_player==True: eval_func = max score, best_move = float('-inf'), (-1,-1) else: eval_func = min score, best_move = float('inf'), (-1,-1) if depth == 0: #base case of recursion return self.scoring_func(game, player), (-1,-1) for move in game.get_legal_moves(): new_game = game.forecast(move)
class TestGUI(unittest.TestCase): def setUp(self): self.board = Board() pg.display.set_mode = Mock(wraps=pg.Surface) pg.display.set_caption = Mock() pg.display.update = Mock() self.ui = GUI() def tearDown(self): if pg.get_init(): pg.quit() def test_pg_init(self): self.assertTrue(pg.get_init()) def test_display(self): self.ui.display(self.board) ann_pos = self.board.get_ann_pos() ann_screen_pos = self.ui.board2screen(ann_pos, self.board.size()) ann = self.ui.screen.subsurface( pg.Rect(*ann_screen_pos, *self.ui.cell_size)).copy() ann_new_pos = ann_pos[0], ann_pos[1] + 1 ann_screen_new_pos = self.ui.board2screen(ann_new_pos, self.board.size()) old_ann = self.ui.screen.subsurface( pg.Rect(*ann_screen_new_pos, *self.ui.cell_size)).copy() self.board.move_ann(*ann_new_pos) self.assertNotEqual(ann.get_buffer().raw, old_ann.get_buffer().raw) self.ui.display(self.board) new_ann = self.ui.screen.subsurface( pg.Rect(*ann_screen_new_pos, *self.ui.cell_size)).copy() self.assertEqual(ann.get_buffer().raw, new_ann.get_buffer().raw) def test_draw(self): pg.event.post(pg.event.Event(pg.QUIT, dict())) self.ui.draw() self.assertFalse(pg.get_init()) def test_ann_won(self): pg.event.post(pg.event.Event(pg.QUIT, dict())) self.ui.ann_won() self.assertFalse(pg.get_init()) def test_bob_won(self): pg.event.post(pg.event.Event(pg.QUIT, dict())) self.ui.bob_won() self.assertFalse(pg.get_init()) def test_info_img(self): empty_info = self.ui.info.copy() pos = self.ui.display_info_img(self.ui.WAIT_ICON) wait_info = self.ui.info.copy() self.assertNotEqual(empty_info.get_buffer().raw, wait_info.get_buffer().raw) w, h = self.ui.WAIT_ICON.get_width(), self.ui.WAIT_ICON.get_height() icon = self.ui.info.subsurface(pg.Rect(*pos, w, h)).copy() for i in range(w): for j in range(h): pixel2 = self.ui.WAIT_ICON.get_at((i, j)) if pixel2.a == 255: pixel1 = icon.get_at((i, j)) self.assertEqual(pixel1, pixel2) def test_info_text(self): empty_info = self.ui.info.copy() self.ui.display_info_text("Test") info = self.ui.info.copy() self.assertNotEqual(empty_info.get_buffer().raw, info.get_buffer().raw) def test_reser_info(self): empty_info = self.ui.info.copy() self.ui.reset_info() info = self.ui.info.copy() self.assertNotEqual(empty_info.get_buffer().raw, info.get_buffer().raw)
except ValueError: print('Invalid index! Try again.') return legal_moves[index] if __name__ == "__main__": from isolation import Board # create an isolation board (by default 7x7) #player1 = RandomPlayer() #player1 = game_agent.CustomPlayer() player1 = RandomPlayer() #player2 = GreedyPlayer() player2 = HumanPlayer() game = Board(player1, player2, height=7, width=7) # place player 1 on the board at row 2, column 3, then place player 2 on # the board at row 0, column 5; display the resulting board state. Note # that .apply_move() changes the calling object game.apply_move((2, 2)) game.apply_move((2, 1)) print(game.to_string()) # players take turns moving on the board, so player1 should be next to move assert (player1 == game.active_player) # get a list of the legal moves available to the active player #print(game.get_legal_moves()) # get a successor of the current state by making a copy of the board and
if not valid_choice: print('Illegal move! Try again.') except ValueError: print('Invalid index! Try again.') return legal_moves[index] if __name__ == "__main__": from isolation import Board # create an isolation board (by default 7x7) player1 = RandomPlayer() player2 = GreedyPlayer() game = Board(player1, player2) # place player 1 on the board at row 2, column 3, then place player 2 on # the board at row 0, column 5; display the resulting board state. Note # that the .apply_move() method changes the calling object in-place. game.apply_move((2, 3)) game.apply_move((0, 5)) print(game.to_string()) # players take turns moving on the board, so player1 should be next to move assert (player1 == game.active_player) # get a list of the legal moves available to the active player print(game.get_legal_moves()) # get a successor of the current state by making a copy of the board and
if not valid_choice: print('Illegal move! Try again.') except ValueError: print('Invalid index! Try again.') return legal_moves[index] if __name__ == "__main__": from isolation import Board # create an isolation board (by default 7x7) player1 = game_agent.AlphaBetaPlayer() # my minimax player player2 = GreedyPlayer() # sample greedy player game = Board(player1, player2) game.apply_move((0, 0)) game.apply_move((6, 6)) print(game.to_string()) # players take turns moving on the board, so player1 should be next to move assert (player1 == game.active_player) # play the remainder of the game automatically -- outcome can be "illegal # move", "timeout", or "forfeit" winner, history, outcome = game.play() print("\nWinner: {}\nOutcome: {}".format(winner, outcome)) print(game.to_string()) print("Move history:\n{!s}".format(history))
@author: richard ''' import random from isolation import Board from sample_players import HumanPlayer from sample_players import improved_score from game_agent import CustomPlayer if __name__ == '__main__': human = HumanPlayer() computer = CustomPlayer(score_fn=improved_score, method='alphabeta') # Randomize who goes first if (random.randint(0, 1)): print("You are player 'O'") game = Board(human, computer) else: print("You are player 'X'") game = Board(computer, human) # Randominze first moves for each player for _ in range(2): game.apply_move(random.choice(game.get_legal_moves())) # Start playing! winner, _, reason = game.play() if winner == human: print("You won!!!", reason) else: print("You lost!!!", reason)
if not valid_choice: print('Illegal move! Try again.') except ValueError: print('Invalid index! Try again.') return legal_moves[index] if __name__ == "__main__": from isolation import Board # create an isolation board (by default 7x7) player1 = AlphaBetaPlayer() player2 = GreedyPlayer() game = Board(player1, player2) # place player 1 on the board at row 2, column 3, then place player 2 on # the board at row 0, column 5; display the resulting board state. Note # that the .apply_move() method changes the calling object in-place. game.apply_move((randint(0, 6), randint(0, 6))) game.apply_move((randint(0, 6), randint(0, 6))) print(game.to_string(symbols=['M', 'G'])) # players take turns moving on the board, so player1 should be next to move assert (player1 == game.active_player) # get a list of the legal moves available to the active player print(game.active_player) print(game.get_legal_moves())
def utility_alphabeta(self, game, causing_move, max_player): if game.is_winner(self): return float("inf") if game.is_opponent_winner(self): return float("-inf") if max_player: return self.eval_fn.score_max(game, causing_move) else: return self.eval_fn.score_min(game, causing_move) def utility(self, game): if game.is_winner(self): return float("inf") if game.is_opponent_winner(self): return float("-inf") return self.eval_fn.score(game) """Test""" from isolation import Board if __name__ == "__main__": r = CustomPlayer() h = CustomPlayer() game = Board(h, r) game.play_isolation()
if not valid_choice: print('Illegal move! Try again.') except ValueError: print('Invalid index! Try again.') return legal_moves[index] if __name__ == "__main__": from isolation import Board # create an isolation board (by default 7x7) player1 = MinimaxPlayer() player2 = GreedyPlayer() game = Board(player1, player2) # place player 1 on the board at row 2, column 3, then place player 2 on # the board at row 0, column 5; display the resulting board state. Note # that the .apply_move() method changes the calling object in-place. game.apply_move((2, 3)) game.apply_move((0, 5)) print(game.to_string()) # players take turns moving on the board, so player1 should be next to move assert(player1 == game.active_player) # get a list of the legal moves available to the active player print(game.get_legal_moves()) # get a successor of the current state by making a copy of the board and