# Tic Tac Toe
from myro import *
from random import choice
# game parameters
INFINITY = 100
LEVEL = 0
LEVEL = int(ask("Enter a level:"))
# pieces, default assignment
Me = 'O'
You = 'X'
def makeBoard():
"""Returns a fresh/empty board.
Empty is represented by a ' '.
"""
# a 3x3 board is represented as a list of 9 elements.
# We will use the following numbering to locate a square
# 0 | 1 | 2
# ---|---|---
# 3 | 4 | 5
# ---|---|---
# 6 | 7 | 8
return [' ',' ',' ',' ',' ',' ',' ',' ',' ']
def display(board):
"""Displays the current board.
"""
for i in range(0, 9, 3):
if i > 0:
print '---|---|---'
print " %c | %c | %c " % (board[i],board[i+1],board[i+2])
print
def opponent(player):
"""Returns the opponent piece from player. player-X -> O and vice versa.
"""
if player == "X":
return "O"
else:
return "X"
# These square triples represent wins (three in a row).
wins = [[0, 1, 2], [3, 4, 5], [6, 7, 8], # the rows
[0, 3, 6], [1, 4, 7], [2, 5, 8], # the columns
[0, 4, 8], [2, 4, 6]] # diagonals
def winner(board):
"""Returns the winning piece on the board X/O/' '/'Tie'.
X/O if either piece has won.
' ' means no winner yet.
'Tie' means all squares are full and there was no winner.
"""
for win in wins:
posWinner = board[win[0]]
if (posWinner != ' ' and
posWinner == board[win[1]] and
posWinner == board[win[2]]):
return posWinner
# No winner yet, are there empty squares left?
for i in range(9):
if board[i] == ' ':
return ' '
# The board is full and no one has three in a row
return 'Tie'
#----
def openings(board, player):
"""Return the number of possible winning positions for player on board.
"""
possWins = 0
for position in wins:
n = 0
for i in range(3):
if (board[position[i]] == player) or (board[position[i]] == ' '):
n += 1
if n == 3:
possWins += 1
return possWins
def evaluate(board):
"""Evaluates the board with respect to the player's perspective.
Returns a number.
"""
# if board is a win for player, return INFINITY
piece = winner(board)
if piece == Me:
return INFINITY
elif piece == You:
return -INFINITY
else:
return openings(board,Me) - openings(board,You)
def bestMove(board, player, moves):
"""Returns the best move of all possible moves.
The evaluate function returns a score for the player if each move
were made.
"""
scores = []
for m in moves:
b = copy(board)
b[m] = player
scores.append(lookahead(b, opponent(player), 0, LEVEL-1))
return moves[scores.index(max(scores))]
def lookahead(board, player, MAX, level):
"""Do a lookahead search on the board and return the backed up value.
"""
moves = possibleMoves(board)
if level == 0 or len(moves)==0:
return evaluate(board)
if MAX:
V = -INFINITY
for m in moves:
b = copy(board)
b[m] = player
V = max(V, lookahead(b, opponent(player), 1-MAX, level-1))
else:
V = INFINITY
for m in moves:
b = copy(board)
b[m] = player
V = min(V, lookahead(b, opponent(player), 1-MAX, level-1))
return V
def possibleMoves(board):
"""returns the set of possible moves in the game.
In this game, all empty squares are viable.
"""
return [i for i in range(9) if board[i] == ' ']
def move(board, player, user):
"""Make a move for player.
"""
if player == user: # user's move?
square = input("Enter your move: ") - 1
else: # my turn
# player is the computer, make a random choice
square = bestMove(board, player, possibleMoves(board))
#square = choice(possibleMoves(board))
# place player's piece on the chosen square
board[square] = player
def gameOver(board):
"""Returns True if game is over (someone won or it is a tie)
False o/w.
"""
return winner(board) != ' '
def play():
# Initialize board
board = makeBoard()
# Select pieces (X or O) and who goes first
if askQuestion("Do you want to move first?") == "Yes":
You = 'X'
else:
You = 'O'
# In Tic Tac Toe, X always goes first
player = 'X'
Me = opponent(You)
display(board)
# The game loop
while not gameOver(board):
move(board, player, You)
print "After %s's move..." % player
display(board)
player = opponent(player)
# game over, show outcome
winningPiece = winner(board)
if winningPiece != 'Tie':
print winningPiece, "won."
else:
print "It is a tie."