Tic Tac Toe - Code V3
From RoboWiki
Return back to project page: Tic Tac Toe - Fedor Agarshev
Python code for the Tic Tac Toe project:
from hub import light_matrix, port, button, light, speaker
import motor,time, color_sensor
motor_up = port.F
motor_down = port.B
head_colorsensor = port.D
motor_up_speed = 1000
motor_down_speed = 200
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 = [[-1, -1, -1], [-1, -1, -1], [-1, -1, -1]]
number_of_moves = 0
def play(self):
light_matrix.clear()
light_matrix.show_image(3) #image HAPPY
while True:
while not button.pressed(button.RIGHT): # Wait for the right button to be pressed
pass
time.sleep_ms(2000)
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:
light_matrix.write('I WIN!!!')
time.sleep_ms(2000)
return
elif win == -10:
light_matrix.write('You WIN!!!')
time.sleep_ms(2000)
return
elif not isMovesLeft(self.tic_tac_toe_matrix):
light_matrix.write('Draw')
time.sleep_ms(2000)
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:
light_matrix.write('I WIN!!!')
time.sleep_ms(2000)
return
elif win == -10:
light_matrix.write('You WIN!!!')
time.sleep_ms(2000)
return
elif not isMovesLeft(self.tic_tac_toe_matrix):
light_matrix.write('Draw')
time.sleep_ms(2000)
return
def show_light_matrix(self):
light_matrix.clear()
for line in range(3):
for column in range(3):
if self.tic_tac_toe_matrix[line][column] == player:
light_matrix.set_pixel(line, column, 80)
elif self.tic_tac_toe_matrix[line][column] == robot:
light_matrix.set_pixel(line, column, 100)
def get_new_tic_tac_toe_matrix(self):
light_matrix.clear()
new_tic_tac_toe_matrix = [[-1, -1, -1], [-1, -1, -1], [-1, -1, -1]]
self.number_of_moves = 0
for line in range(3):
for column in range(3):
color = color_sensor.color(head_colorsensor)
print(color)
if color == 0:
new_tic_tac_toe_matrix[line][column] = player
light_matrix.set_pixel(line, column, 80)
self.number_of_moves +=1
elif color == 1:
new_tic_tac_toe_matrix[line][column] = robot
light_matrix.set_pixel(line, column, 100)
self.number_of_moves +=1
else:
light_matrix.set_pixel(line, column, 0)
if column == 0:
motor.run_for_degrees(motor_up, self.degree_for_move_one_row1 * -1, motor_up_speed)
time.sleep_ms(1000)
elif column == 1:
motor.run_for_degrees(motor_up, self.degree_for_move_one_row2 * -1, motor_up_speed)
time.sleep_ms(1000)
motor.run_for_degrees(motor_up, self.degree_for_move_one_row1 + self.degree_for_move_one_row2, motor_up_speed)
time.sleep_ms(1000)
if line != 2:
motor.run_for_degrees(motor_down, self.degree_for_move_one_line * -1, motor_down_speed)
time.sleep_ms(1000)
motor.run_for_degrees(motor_down, self.degree_for_move_one_line + self.degree_for_move_one_line, motor_down_speed)
time.sleep_ms(1000)
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] == -1:
return 0,0
elif self.tic_tac_toe_matrix[2][0] == -1:
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] == -1:
return 2,2
elif self.tic_tac_toe_matrix[2][0] == -1:
return 2,0
else :
return 0, 2
return findBestMove(self.tic_tac_toe_matrix)
def show_move(self, line, column):
while not button.pressed(button.LEFT):
for i in range(5, 10):
light_matrix.set_pixel(line, column, 10 * i)
time.sleep_ms(250)
for i in range(0, 5):
light_matrix.set_pixel(line, column, 100 - 10 * i)
time.sleep_ms(250)
self.tic_tac_toe_matrix[line][column] = robot
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] == -1):
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] == -1):
# 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] = -1
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] == -1):
# 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] = -1
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] == -1):
# Make the move
board[i][j] = robot
# compute evaluation function for this
# move.
moveVal = minimax(board, 0, False)
# Undo the move
board[i][j] = -1
# 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()