"""
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)
Comments