Last active
August 29, 2015 13:57
-
-
Save bitoffdev/9623820 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Board(list): | |
def __init__(self): | |
for i in range(9): | |
self.append('-') | |
def isWin(self): | |
''' | |
Returns true if either player is winning else returns false | |
''' | |
# check if any of the rows has winning combination | |
for i in range(3): | |
if len(set(self[i*3:i*3+3])) == 1 and self[i*3] != '-': return True | |
# check if any of the Columns has winning combination | |
for i in range(3): | |
if self[i]==self[i+3]==self[i+6] and self[i] != '-': | |
return True | |
# check diagonals | |
if self[0] is self[4] and self[4] is self[8] and self[4] is not '-': | |
return True | |
if self[2]==self[4]==self[6] and self[4] is not '-': | |
return True | |
return False | |
def __str__(self): | |
return ''.join( (str(i) if self[i]=='-' else self[i]) + ('\n' if i%3==2 else ' | ') for i in range(len(self))) | |
class Player(object): | |
def __init__(self, piece, cpu): | |
self.piece = piece | |
self.cpu = cpu | |
def move(self, board): | |
if self.cpu: | |
print "CPU (%s) is moving ..."%(self.piece) | |
return AIMove(board, self.piece)[1] | |
else: | |
while True: | |
coords = raw_input('Player\'s move (%s): '%self.piece) | |
return int(coords) | |
def AIMove(board, player): | |
""" | |
Arguments: | |
board: list containing X,- and O | |
player: one character string 'X' or 'O' | |
Returns: | |
willwin: 1 if 'X' is winning, 0 if the game is draw and -1 if 'O' is winning | |
nextmove: best player move else -1 if game is over | |
""" | |
#Return early if blank board | |
if len(set(board)) == 1: return 0,4 | |
#Check for winner | |
if board.isWin() : | |
if player is 'X': return -1,-1 | |
else: return 1,-1 | |
#Check for tie | |
if board.count('-') == 0: return 0,-1 | |
#Get possible moves | |
possible_moves = [] | |
for i in range(len(board)): | |
if board[i] == '-': | |
possible_moves.append(i) | |
#determine next player | |
nextplayer = 'X' if player=='O' else 'O' | |
#Iterate over possible moves using minimax algorithm | |
results = [] | |
for i in possible_moves: | |
board[i] = player | |
result, move = AIMove(board,nextplayer) | |
results.append(result) | |
board[i] = '-' | |
if player == 'X': | |
max_result = max(results) | |
return max_result, possible_moves[results.index(max_result)] | |
else: | |
min_result=min(results) | |
return min_result, possible_moves[results.index(min_result)] | |
def play(): | |
print ">>> Welcome to Boss Tic Tac Toe! <<<" | |
gameboard = Board() | |
players = [Player('X', False), Player('O', True)] | |
current_player = 0 | |
print str(gameboard) | |
while not gameboard.isWin(): | |
gameboard[players[current_player].move(gameboard)] = players[current_player].piece | |
print str(gameboard) | |
current_player += 1 | |
if current_player > 1: current_player = 0 | |
play() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment