Skip to content

Commit 4d138a3

Browse files
committed
Finish HackerRank Tic-Tac-Toe Min-Max challenge
1 parent 5652b2b commit 4d138a3

File tree

3 files changed

+88
-2
lines changed

3 files changed

+88
-2
lines changed

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
out
2-
*.class
32
__pycache__
3+
.vscode
4+
*.class
45
*.swp
5-
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# README
2+
3+
[https://www.hackerrank.com/challenges/tic-tac-toe](https://www.hackerrank.com/challenges/tic-tac-toe)
4+
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#!/usr/bin/env python
2+
3+
import sys
4+
5+
# Map from max player -> values for winners. If X' is the max player, then
6+
# a tie with '_' winning is better than 'O' winning but worse than 'X' winning.
7+
VALUES = {'X': {'O': 0, '_': 1, 'X': 2},
8+
'O': {'X': 0, '_': 1, 'O': 2}}
9+
10+
11+
def main():
12+
player = raw_input()
13+
board = [list(raw_input()) for _ in range(3)]
14+
r, c = minimax(board, player, player)[1]
15+
print('%s %s' % (r, c))
16+
17+
18+
def minimax(board, curr_player, max_player):
19+
'''Runs min-max on the board.'''
20+
if finished(board):
21+
w = winner(board)
22+
return VALUES[max_player][w], None
23+
24+
if curr_player == 'X':
25+
value, next_player = VALUES[max_player]['O'], 'O'
26+
else:
27+
value, next_player = VALUES[max_player]['X'], 'X'
28+
29+
move = None
30+
31+
for r, c in options(board):
32+
board[r][c] = curr_player
33+
value_ = minimax(board, next_player, max_player)[0]
34+
board[r][c] = '_'
35+
if (curr_player == max_player and value_ >= value) or \
36+
(curr_player != max_player and value_ <= value):
37+
value, move = value_, (r, c)
38+
39+
return value, move
40+
41+
42+
def options(board):
43+
'''Returns a generator of available moves.'''
44+
for r in range(3):
45+
for c in range(3):
46+
if board[r][c] == '_':
47+
yield (r, c)
48+
49+
50+
def finished(board):
51+
'''Returns if the game is finished or not.'''
52+
if winner(board) != '_':
53+
return True
54+
for r in board:
55+
for x in r:
56+
if x == '_':
57+
return False
58+
return True
59+
60+
61+
def winner(board):
62+
'''Returns the current winner, if one exists.'''
63+
for i in range(3):
64+
# Check rows...
65+
if board[i][0] != '_' and board[i][0] == board[i][1] == board[i][2]:
66+
return board[i][0]
67+
# Check cols...
68+
if board[0][i] != '_' and board[0][i] == board[1][i] == board[2][i]:
69+
return board[0][i]
70+
71+
# Check diags...
72+
if board[0][0] != '_' and board[0][0] == board[1][1] == board[2][2]:
73+
return board[0][0]
74+
75+
if board[2][0] != '_' and board[2][0] == board[1][1] == board[0][2]:
76+
return board[2][0]
77+
78+
return '_'
79+
80+
81+
if __name__ == '__main__':
82+
main()

0 commit comments

Comments
 (0)