Иван обнови решението на 15.04.2013 10:38 (преди над 11 години)
+from collections import defaultdict
+import re
+
+
+class InvalidMove(Exception):
+ pass
+
+
+class InvalidValue(Exception):
+ pass
+
+
+class InvalidKey(Exception):
+ pass
+
+
+class NotYourTurn(Exception):
+ pass
+
+
+class TicTacToeBoard:
+
+ empty_board = '\n -------------\n' +\
+ '3 | {A3} | {B3} | {C3} |\n' +\
+ ' -------------\n' +\
+ '2 | {A2} | {B2} | {C2} |\n' +\
+ ' -------------\n' +\
+ '1 | {A1} | {B1} | {C1} |\n' +\
+ ' -------------\n' +\
+ ' A B C \n'
+
+ def __init__(self):
+ self.board = defaultdict(lambda: ' ')
+ self.status = 'Game in progress.'
+ self.last_player = ''
+ self.moves = 0
+
+ def __str__(self):
+ return self.empty_board.format(**self.board)
+
+ def __setitem__(self, key, value):
+ if not re.match(r'^[A-C][1-3]$', key):
+ raise InvalidKey
+ if self.board[key] != self.board.default_factory():
+ raise InvalidMove
+ if not re.match(r'(X|O)$', value):
+ raise InvalidValue
+ if self.last_player == value:
+ raise NotYourTurn
+
+ self.board[key] = value
+ self.last_player = value
+ self.moves += 1
+ self.__check_status()
+
+ def __getitem__(self, key):
+ if not re.match(r'^[A-C][1-3]$', key):
+ raise InvalidKey
+ if self.board[key] != self.board.default_factory():
+ return self.board[key]
+ return ''
+
+ def __check_for_winner(self, x_coords, y_coords, combine_func):
+ for x in x_coords:
+ sequence = ''
+ for y in y_coords:
+ sequence += self.board[combine_func(x, y)]
+ match = re.match(r'^(O|X)\1\1$', sequence)
+ if match:
+ self.status = match.groups()[0] + ' wins!'
+
+ def __check_status(self):
+ letters = ['A', 'B', 'C']
+ indexes = ['1', '2', '3']
+ self.__check_for_winner(letters, indexes, lambda x, y: x+y)
+ self.__check_for_winner(indexes, letters, lambda x, y: y+x)
+ diagonal = list(map(str.__add__, letters, indexes))
+ self.__check_for_winner([''], diagonal, lambda x, y: y)
+ other_diagonal = list(map(str.__add__, letters, indexes[::-1]))
+ self.__check_for_winner([''], other_diagonal, lambda x, y: y)
+ if self.status == 'Game in progress.' and self.moves == 9:
+ self.status = 'Draw!'
+
+ def game_status(self):
+ return self.status