Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
First solution in Uncategorized category for Xs and Os Champion by Moff
class CrossesAndNoughts(object):
def __init__(self, field, player):
self.empty_cell = '.'
self.first_player = 'X'
self.second_player = 'O'
self.field = field
self.side = 1 if player == 'X' else -1
def __str__(self):
return '\n'.join(''.join(row) for row in self.field)
def move(self, cell):
self.field[cell // 3][cell % 3] = self.first_player if self.side == 1 else self.second_player
self.side *= -1
def back(self, cell):
self.field[cell // 3][cell % 3] = self.empty_cell
self.side *= -1
def check_list(self, array):
if all(x == self.first_player for x in array):
return 1
elif all(x == self.second_player for x in array):
return 2
else:
return 0
def winner(self):
result = 0
for row in range(3):
result = max(result, self.check_list([self.field[row][col] for col in range(3)]))
for col in range(3):
result = max(result, self.check_list([self.field[row][col] for row in range(3)]))
result = max(result, self.check_list([self.field[i][i] for i in range(3)]))
result = max(result, self.check_list([self.field[i][2 - i] for i in range(3)]))
return result
def is_draw(self):
return self.winner() == 0 and self.possible_moves == []
@property
def possible_moves(self):
return [i for i in range(9) if self.field[i // 3][i % 3] == self.empty_cell]
def assess(self):
winner = self.winner()
if winner != 0:
return 3 - 2 * winner
if self.is_draw():
return 0
if self.side == 1:
return self.assess_max()
else:
return self.assess_min()
def assess_max(self):
score = -float('inf')
for m in self.possible_moves:
self.move(m)
score = max(self.assess(), score)
self.back(m)
return score
def assess_min(self):
score = float('inf')
for m in self.possible_moves:
self.move(m)
score = min(self.assess(), score)
self.back(m)
return score
def x_and_o(field, player):
game = CrossesAndNoughts(list(map(list, field)), player)
draw = None
for i in game.possible_moves:
game.move(i)
if game.assess() == 0:
draw = divmod(i, 3)
if game.assess() * game.side == -1:
return divmod(i, 3)
game.back(i)
return draw
Aug. 27, 2015