""" Monte Carlo Tic-Tac-Toe Player """ #http://www.codeskulptor.org/#user43_s5eXtEgisZ8i3UR_7.py import random import poc_ttt_gui import poc_ttt_provided as provided #import user43_pWrohuXpCeEdo0y_45 as simple_test # Constants for Monte Carlo simulator # You may change the values of these constants as desired, but # do not change their names. NTRIALS = 1000 # Number of trials to run SCORE_CURRENT = 1.0 # Score for squares played by the current player SCORE_OTHER = 5.0 # Score for squares played by the other player # Add your functions here. def mc_trial(board, player): """ Takes a board and the player whose move it is. Completes the board with random moves, alternating players """ trial_player = player while not board.check_win(): move_space = random.choice(board.get_empty_squares()) board.move(move_space[0], move_space[1], trial_player) trial_player = provided.switch_player(trial_player) if not board.check_win(): print "Error- unfinished game returned" return else: return def add_score(scores, grid): """ adds each element of grid to the corresponding element of scores """ # print "Adding " # print grid # print "to " # print scores #account for possibilty of empty list instead of list of 0's #test program feeds [], not sure about hidden TTTBoard program if scores == []: return grid score_row = 0 score_col = 0 for grid_row in grid: for grid_point in grid_row: scores[score_row][score_col] += grid_point score_col += 1 score_row+= 1 score_col = 0 return scores def mc_update_scores(scores, board, player): """ Takes grid of scores (nested list), completed board, and the machine player. Appends scores with a score grid for the board. """ #create empty score matching board dimensions grid = [[0 for dummy_dim in range(board.get_dim())] for dummy_dim in range(board.get_dim())] game_state = board.check_win() if game_state == provided.DRAW: # print "DRAW" scores = add_score(scores, grid) # print "MC Update Score returning " # print scores return elif game_state == player: #print "WIN" player_value = SCORE_CURRENT opponent_value = -SCORE_OTHER elif game_state == provided.switch_player(player): #print "LOSE" player_value = -SCORE_CURRENT opponent_value = SCORE_OTHER #print "Player value: " + str(player_value) #print "Opponent value: " + str(opponent_value) new_score = [] row_index = 0 for dummy_row in grid: new_score_row = [] for col_index in range(board.get_dim()): if board.square(row_index, col_index) == provided.EMPTY: new_score_row.append(0) elif board.square(row_index, col_index) == player: new_score_row.append(player_value) elif board.square(row_index, col_index) == provided.switch_player(player): new_score_row.append(opponent_value) else: print "Error, unknown value in square " + str(row_index) + "," + str(col_index) new_score.append(new_score_row) row_index += 1 #print new_score scores = add_score(scores, new_score) if not game_state: print "Error- incomplete game sent to mc_update_scores function." print "Printing incomplete board:" print board return # print "MC Update Score returning " # print scores return def get_best_move(board, scores): """ Given a board/score, returns a random open square with score >= the max score. """ empty_squares = board.get_empty_squares() # print "All open moves: " # print empty_squares if empty_squares == []: print "Error: board full, no move available" return max_empty_squares = [] max_score = scores[empty_squares[0][0]][empty_squares[0][1]] #print "Starting with max score of " + str(max_score) for square in empty_squares: if scores[square[0]][square[1]] == max_score: max_empty_squares.append(square) elif scores[square[0]][square[1]] > max_score: max_score = scores[square[0]][square[1]] max_empty_squares = [square] random.shuffle(max_empty_squares) # print "Possible moves culled to include: " # print max_empty_squares return max_empty_squares[0] def mc_move(board, player, trials): """ returns a tuple indicating the best move for machine given a board, which player the machine is and the # of trials to simulate """ scores = [[0.0 for dummy_dim in range(board.get_dim())] for dummy_dim in range(board.get_dim())] for dummy_num in range(trials): test_board = board.clone() mc_trial(test_board, player) mc_update_scores(scores, test_board, player) next_move = get_best_move(board, scores) #instructions say to return next_move, not to MAKE the move #commenting out code that makes the move #board.move(next_move[0], next_move[1], player) #print board return next_move #simple_test.run_suite_mc_trial(mc_trial) #simple_test.run_suite_add_score(add_score) #simple_test.run_suite_mc_update_scores(mc_update_scores) #simple_test.run_suite_get_best_move(get_best_move) #simple_test.run_suite_mc_move(mc_move) #my_board = provided.TTTBoard(3) #player = provided.PLAYERX #my_board.move(0,0,provided.PLAYERO) # #print my_board #print "Player is " + str(player) #print ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>" #print "" #mc_trial(my_board, player) #print my_board #print "Player is " + str(player) #mc_update_scores([], my_board, player) # Test game with the console or the GUI. Uncomment whichever # you prefer. Both should be commented out when you submit # for testing to save time. provided.play_game(mc_move, NTRIALS, False) poc_ttt_gui.run_gui(4, provided.PLAYERO, mc_move, NTRIALS, False)