Created
September 12, 2014 19:57
-
-
Save lwiecek/af4b9e2d2584e429b7de to your computer and use it in GitHub Desktop.
This file contains 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
import random | |
class Game(object): | |
N = 3 | |
def __init__(self, ai=None): | |
self.board = [] | |
for i in range(Game.N): | |
self.board.append([' '] * Game.N) | |
self.current_player = 'X' | |
self.ai = ai | |
self.moves = 0 | |
self.game_over = None | |
self.show_board() | |
self.check_ai_move() | |
def show_board(self): | |
human = ('(human)' if self.is_current_player_human() else '') | |
print 'current player:', self.current_player, human | |
for row in range(Game.N): | |
for col in range(Game.N): | |
print '[' + self.board[row][col] + ']', | |
def move_is_allowed(self, row, col, player): | |
return ( | |
(not self.game_over) and | |
(row >= 0 and col >= 0 and row < Game.N and col < Game.N) and | |
(self.board[row][col] == ' ') and (self.current_player == player) | |
) | |
def play(self, row, col, player): | |
self.moves += 1 | |
if not self.move_is_allowed(row, col, player): | |
print player, 'move ( row: ', row, ', col', col, ') is not allowed.' | |
return | |
self.board[row][col] = player.upper() | |
self.show_board() | |
game_over = self.check_game_over() | |
if game_over: | |
print 'game over:', game_over | |
self.game_over = game_over | |
return | |
self.switch_player() | |
self.check_ai_move() | |
def switch_player(self): | |
self.current_player = 'O' if self.current_player == 'X' else 'X' | |
def is_current_player_human(self): | |
return (not self.ai) or (self.current_player not in self.ai) | |
def check_ai_move(self): | |
if self.is_current_player_human(): | |
return | |
while True: | |
row, col = random.randint(0, Game.N - 1), random.randint(0, Game.N - 1) | |
if self.move_is_allowed(row, col, self.current_player): | |
self.play(row, col, self.current_player) | |
break | |
def check_game_over(self): | |
checks = [] | |
for row in range(Game.N): | |
checks.append((row * Game.N, 1)) | |
for col in range(Game.N): | |
checks.append((col, Game.N)) | |
checks.append((0, Game.N + 1)) # diag left-top -> right-bottom | |
checks.append((Game.N - 1, Game.N - 1)) # diag right-top -> left-bottom | |
for start, offset in checks: | |
winner = self.check_line(start, offset) | |
if winner: | |
return winner + ' won' | |
if self.moves == Game.N * Game.N: | |
return 'draw' | |
return None | |
# row: offset = 1, col: offset = N, diag: offset = N + 1, offset = N - 1 | |
def check_line(self, start, offset): | |
pos = start | |
count_x = 0 | |
count_o = 0 | |
for i in range(Game.N): | |
row = pos / Game.N | |
col = pos % Game.N | |
pos += offset | |
count_x += int(self.board[row][col] == 'X') | |
count_o += int(self.board[row][col] == 'O') | |
if count_x == Game.N: | |
return 'X' | |
if count_o == Game.N: | |
return 'O' | |
return None | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment