Skip to content

Instantly share code, notes, and snippets.

@tomtheisen
Created November 27, 2012 18:54
Show Gist options
  • Save tomtheisen/4156236 to your computer and use it in GitHub Desktop.
Save tomtheisen/4156236 to your computer and use it in GitHub Desktop.
HackerRank Tic Tac Toe
#!/bin/python
outcomes = lambda: expando
outcomes.inProgress = "0 in progress"
outcomes.lose = "1 lose"
outcomes.tie = "2 tie"
outcomes.win = "3 win"
getNextPlayer = {"X": "O", "O": "X"}.get
cells = [(r,c) for r in range(3) for c in range(3)]
lines = [
[(0,0),(0,1),(0,2)],
[(1,0),(1,1),(1,2)],
[(2,0),(2,1),(2,2)],
[(0,0),(1,0),(2,0)],
[(0,1),(1,1),(2,1)],
[(0,2),(1,2),(2,2)],
[(0,0),(1,1),(2,2)],
[(2,0),(1,1),(0,2)],
]
def getMoves(player, board):
return [(r,c) for (r,c) in cells if board[r][c] == "_"]
def makeMove(player, board, move):
moved = board[:]
moved[move[0]] = moved[move[0]][:]
moved[move[0]][move[1]] = player
return moved
def isWinning(player, board):
return any(all(board[r][c] == player for (r,c) in line) for line in lines)
def getStatus(player, board):
if isWinning(player, board): return outcomes.win
elif isWinning(getNextPlayer(player), board): return outcomes.lose
elif any("_" in row for row in board): return outcomes.inProgress
else: return outcomes.tie
def getBestMove(player, board):
moves = getMoves(player, board)
if len(moves) in [1, 9]: return moves[0]
boards = {move: makeMove(player, board, move) for move in moves}
for move in moves:
if isWinning(player, boards[move]): return move
outcomes = {move: getOutcome(player, boards[move]) for move in moves}
best = max(outcomes.values())
for move in moves:
if outcomes[move] == best: return move
# find the worst outcome assuming i just made a move
def getOutcome(player, board):
opponent = getNextPlayer(player)
moves = getMoves(opponent, board)
status = getStatus(player, board)
if not moves or status == outcomes.win: return status
return min(getOpponentOutcome(opponent, makeMove(opponent, board, move)) for move in moves)
# find the best outcome assuming my opponent just made a move
def getOpponentOutcome(opponent, board):
player = getNextPlayer(opponent)
moves = getMoves(player, board)
status = getStatus(player, board)
if not moves or status == outcomes.lose: return status
return max(getOutcome(player, makeMove(player, board, move)) for move in moves)
def nextMove(player, board):
move = getBestMove(player, board)
print move[0], move[1]
#If player is X, I'm the first player.
#If player is O, I'm the second player.
player = raw_input()
#Read the board now. The board is a 3x3 array filled with X, O or _.
board = []
for i in xrange(0, 3):
board.append(list(raw_input()))
nextMove(player,board)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment