Деян обнови решението на 09.04.2013 12:52 (преди над 11 години)
+import re
+
+
+class InvalidKey(Exception):
+ pass
+
+
+class InvalidMove(Exception):
+ pass
+
+
+class InvalidValue(Exception):
+ pass
+
+
+class NotYourTurn(Exception):
+ pass
+
+
+class TicTacToeBoard:
+ lines = [['A1', 'A2', 'A3'],
+ ['B1', 'B2', 'B3'],
+ ['C1', 'C2', 'C3'],
+ ['A1', 'B1', 'C1'],
+ ['A2', 'B2', 'C2'],
+ ['A3', 'B3', 'C3'],
+ ['A1', 'B2', 'C3'],
+ ['A3', 'B2', 'C1']]
+
+ def __init__(self):
+ self.data = {}
+ self.last_move = None
+ self.winner = None
+
+ def __getitem__(self, field):
+ if not re.match(r'^[A-Z][1-3]$', field):
+ raise InvalidKey
+ elif field not in self.data:
+ return ' '
+ else:
+ return self.data[field]
+
+ def __setitem__(self, field, value):
+ if not re.match(r'^[A-Z][1-3]$', field):
+ raise InvalidKey
+ elif field in self.data:
+ raise InvalidMove
+ elif value not in ['X', 'O']:
+ raise InvalidValue
+ elif value == self.last_move:
+ raise NotYourTurn
+ else:
+ self.data[field] = value
+ self.last_move = value
+ if self.is_winning_move(field, value):
+ self.winner = value
+
+ def is_winning_move(self, field, value):
+ """Check if this move formed a line"""
+ # Get lines that include this field and all
+ # cells in them are filled by this player
+ lines = filter(lambda line: field in line
+ and all(map(lambda cell: self[cell] == value, line)),
+ self.lines)
+ return len(list(lines)) > 0
+
+ def game_status(self):
+ if self.winner is not None:
+ return "%s wins!" % self.winner
+ elif len(self.data) >= 9:
+ return 'Draw!'
+ else:
+ return 'Game in progress.'
+
+ def __str__(self):
+ horizontal_line = ' ' + '-' * 13 + '\n'
+ result = '\n' + horizontal_line
+ for row in [3, 2, 1]:
+ cells = map(lambda c: self[c + str(row)], ['A', 'B', 'C'])
+ result += str(row) + ' | ' + ' | '.join(cells) + ' |\n'
+ result += horizontal_line
+ result += ' A B C \n'
+ return result
Защо хващаш всички букви с r'^[A-Z][1-3]$'
, при положение, че няма поле Y2, примерно?
Да, объркал съм се - трябва да е A-C.