Tic Tac Toe - Code
From RoboWiki
Return back to project page: Tic Tac Toe - Fedor Agarshev
Python code for the Tic Tac Toe project:
from spike import PrimeHub, LightMatrix, Button, StatusLight, ForceSensor, MotionSensor, Speaker, ColorSensor, App, DistanceSensor, Motor, MotorPair
from spike.control import wait_for_seconds, wait_until, Timer
hub = PrimeHub()
hub.light_matrix.show_image('HAPPY')
wait_for_seconds(2)
motor_up = Motor('F')
motor_down = Motor('B')
head_colorsensor = ColorSensor('D')
motor_up.set_default_speed(100)
motor_down.set_default_speed(10)
player = 0
robot = 1
class TikTakToeWithRobot:
degree_for_move_one_line = 30
degree_for_move_one_row1 = 250
degree_for_move_one_row2 = 225
whose_move = ''
robot_chip_color = 'violet'
player_chip_color = 'black'
tic_tac_toe_matrix = [['', '', ''], ['', '', ''], ['', '', '']]
number_of_moves = 0
def play(self):
hub.light_matrix.off()
while True:
hub.right_button.wait_until_pressed()
new_tic_tac_toe_matrix = self.get_new_tic_tac_toe_matrix()
self.check_tic_tac_toe_matrix_for_player_move(new_tic_tac_toe_matrix)
self.show_light_matrix()
print(self.tic_tac_toe_matrix)
win = evaluate(self.tic_tac_toe_matrix)
if win == 10:
hub.light_matrix.write('I WIN!!!')
return
elif win == -10:
hub.light_matrix.write('You WIN!!!')
return
elif not isMovesLeft(self.tic_tac_toe_matrix):
hub.light_matrix.write('Draw')
return
# if self.win_check():
# return
line_move, column_move = self.get_move()
self.show_move(line_move, column_move)
self.show_light_matrix()
win = evaluate(self.tic_tac_toe_matrix)
if win == 10:
hub.light_matrix.write('I WIN!!!')
return
elif win == -10:
hub.light_matrix.write('You WIN!!!')
return
elif not isMovesLeft(self.tic_tac_toe_matrix):
hub.light_matrix.write('Draw')
return
# if self.win_check():
# return
def show_light_matrix(self):
hub.light_matrix.off()
for line in range(3):
for column in range(3):
if self.tic_tac_toe_matrix[line][column] == player:
hub.light_matrix.set_pixel(line, column, 80)
elif self.tic_tac_toe_matrix[line][column] == robot:
hub.light_matrix.set_pixel(line, column, 100)
def get_new_tic_tac_toe_matrix(self):
new_tic_tac_toe_matrix = [['', '', ''], ['', '', ''], ['', '', '']]
self.number_of_moves = 0
for line in range(3):
for column in range(3):
color = head_colorsensor.get_color()
print(color)
if color == "black":
new_tic_tac_toe_matrix[line][column] = player
hub.light_matrix.set_pixel(line, column, 80)
self.number_of_moves +=1
elif color == "violet":
new_tic_tac_toe_matrix[line][column] = robot
hub.light_matrix.set_pixel(line, column, 100)
self.number_of_moves +=1
else:
hub.light_matrix.set_pixel(line, column, 0)
if column == 0:
motor_up.run_for_degrees(self.degree_for_move_one_row1 * -1)
elif column == 1:
motor_up.run_for_degrees(self.degree_for_move_one_row2 * -1)
motor_up.run_for_degrees(self.degree_for_move_one_row1 + self.degree_for_move_one_row2)
if line != 2:
motor_down.run_for_degrees(self.degree_for_move_one_line * -1)
motor_down.run_to_position(340)
return new_tic_tac_toe_matrix
def check_tic_tac_toe_matrix_for_player_move(self, new_tic_tac_toe_matrix):
self.tic_tac_toe_matrix = new_tic_tac_toe_matrix
return
def get_move(self):
if self.number_of_moves == 0:
return 0,0
elif self.number_of_moves == 1:
# if self.tic_tac_toe_matrix[0][0] == player or self.tic_tac_toe_matrix[0][2] == player or self.tic_tac_toe_matrix[2][0] == player or self.tic_tac_toe_matrix[2][2] == player:
# return 2,1
# else:
if self.tic_tac_toe_matrix[0][0] == '':
return 0,0
elif self.tic_tac_toe_matrix[2][0] == '':
return 2,0
elif self.number_of_moves == 2:
if self.tic_tac_toe_matrix[1][1] == player:
return 2,2
if self.tic_tac_toe_matrix[0][1] == player or self.tic_tac_toe_matrix[1][0] == player or self.tic_tac_toe_matrix[1][2] == player or self.tic_tac_toe_matrix[2][1] == player:
return 1,1
else:
if self.tic_tac_toe_matrix[2][2] == '':
return 2,2
elif self.tic_tac_toe_matrix[2][0] == '':
return 2,0
else :
return 0, 2
return findBestMove(self.tic_tac_toe_matrix)
def show_move(self, line, column):
while not hub.left_button.was_pressed():
for i in range(5, 10):
hub.light_matrix.set_pixel(line, column, 10 * i)
wait_for_seconds(0.25)
for i in range(0, 5):
hub.light_matrix.set_pixel(line, column, 100 - 10 * i)
wait_for_seconds(0.25)
self.tic_tac_toe_matrix[line][column] = robot
hub.light_matrix.set_pixel(line, column, 100)
return
# This function returns true if there are moves
# remaining on the board. It returns false if
# there are no moves left to play.
def isMovesLeft(board):
for i in range(3):
for j in range(3):
if (board[i][j] == ''):
return True
return False
# This is the evaluation function as discussed
# in the previous article ( http://goo.gl/sJgv68 )
def evaluate(b):
# Checking for Rows for 1 or 0 victory.
for row in range(3):
if (b[row][0] == b[row][1] and b[row][1] == b[row][2]):
if (b[row][0] == robot):
return 10
elif (b[row][0] == player):
return -10
# Checking for Columns for 1 or 0 victory.
for col in range(3):
if (b[0][col] == b[1][col] and b[1][col] == b[2][col]):
if (b[0][col] == robot):
return 10
elif (b[0][col] == player):
return -10
# Checking for Diagonals for 1 or 0 victory.
if (b[0][0] == b[1][1] and b[1][1] == b[2][2]):
if (b[0][0] == robot):
return 10
elif (b[0][0] == player):
return -10
if (b[0][2] == b[1][1] and b[1][1] == b[2][0]):
if (b[0][2] == robot):
return 10
elif (b[0][2] == player):
return -10
# Else if none of them have won then return 0
return 0
# This is the minimax function. It considers all
# the possible ways the game can go and returns
# the value of the board
def minimax(board, depth, isMax):
score = evaluate(board)
# If Maximizer has won the game return his/her
# evaluated score
if (score == 10):
return score
# If Minimizer has won the game return his/her
# evaluated score
if (score == -10):
return score
# If there are no more moves and no winner then
# it is a tie
if (isMovesLeft(board) == False):
return 0
# If this maximizer's move
if (isMax):
best = -1000
# Traverse all cells
for i in range(3):
for j in range(3):
# Check if cell is empty
if (board[i][j] == ''):
# Make the move
board[i][j] = robot
# Call minimax recursively and choose
# the maximum value
best = max(best, minimax(board,
depth + 1,
not isMax))
# Undo the move
board[i][j] = ''
return best
# If this minimizer's move
else:
best = 1000
# Traverse all cells
for i in range(3):
for j in range(3):
# Check if cell is empty
if (board[i][j] == ''):
# Make the move
board[i][j] = player
# Call minimax recursively and choose
# the minimum value
best = min(best, minimax(board, depth + 1, not isMax))
# Undo the move
board[i][j] = ''
return best
# This will return the best possible move for the player
def findBestMove(board):
bestVal = -1000
bestMove = (-1, -1)
# Traverse all cells, evaluate minimax function for
# all empty cells. And return the cell with optimal
# value.
for i in range(3):
for j in range(3):
# Check if cell is empty
if (board[i][j] == ''):
# Make the move
board[i][j] = robot
# compute evaluation function for this
# move.
moveVal = minimax(board, 0, False)
# Undo the move
board[i][j] = ''
# If the value of the current move is
# more than the best value, then update
# best/
print("The value of the Move is :", moveVal, "for", i, j)
if (moveVal > bestVal):
bestMove = (i, j)
bestVal = moveVal
print("The value of the best Move is :", bestVal)
print()
return bestMove
game = TikTakToeWithRobot()
game.play()