Георги обнови решението на 12.04.2013 15:28 (преди над 11 години)
+from collections import OrderedDict
+import re
+
+
+class InvalidMove(Exception):
+ def __init__(self):
+ self.message = 'The attemted move is invalid!'
+
+
+class InvalidValue(Exception):
+ def __init__(self):
+ self.message = 'The value is invalid!'
+
+
+class InvalidKey(Exception):
+ def __init__(self):
+ self.message = 'The key is invalid!'
+
+
+class NotYourTurn(Exception):
+ def __init__(self):
+ self.message = 'It is not your turn!'
+
+
+class TicTacToeBoard:
+ def __init__(self):
+ self.last_move = ' '
+ self.board_status = 'Game in progress.'
+ self.line_board = str()
+ self.board_positions = OrderedDict()
+ self.board_positions['A1'] = ' '
+ self.board_positions['A2'] = ' '
+ self.board_positions['A3'] = ' '
+ self.board_positions['B1'] = ' '
+ self.board_positions['B2'] = ' '
+ self.board_positions['B3'] = ' '
+ self.board_positions['C1'] = ' '
+ self.board_positions['C2'] = ' '
+ self.board_positions['C3'] = ' '
+
+ def __setitem__(self, value, result):
+ if value not in self.board_positions.keys():
+ raise InvalidKey
+ elif result != 'O' and result != 'X':
+ raise InvalidValue
+ elif self.board_positions[value] != ' ':
+ raise InvalidMove
+ elif self.last_move == result:
+ raise NotYourTurn
+ else:
+ self.board_positions[value] = result
+ self.last_move = result
+
+ def __getitem__(self, value):
+ return self.board_positions[value]
+
+ def __str__(self):
+ return('\n -------------\n' +
+ '3 | {} | {} | {} |\n'.format(self.board_positions['A3'],
+ self.board_positions['B3'],
+ self.board_positions['C3']) +
+ ' -------------\n' +
+ '2 | {} | {} | {} |\n'.format(self.board_positions['A2'],
+ self.board_positions['B2'],
+ self.board_positions['C2']) +
+ ' -------------\n' +
+ '1 | {} | {} | {} |\n'.format(self.board_positions['A1'],
+ self.board_positions['B1'],
+ self.board_positions['C1']) +
+ ' -------------\n' +
+ ' A B C \n'
+ )
+
+ def game_status(self):
+ for p in self.board_positions.values():
+ self.line_board += str(p)
+
+ if self.board_status != 'Game in progress.':
+ pass
+
+ else:
+ self.win_status0 = re.search(r'(\w)[\w\s][\w\s]\1[\w\s][\w\s]\1',
+ self.line_board)
+ self.win_status1 = re.search(r'[\w\s][\w\s](\w)[\w\s]\1[\w\s]\1[\w\s][\w\s]',
+ self.line_board)
+ self.win_status2 = re.search(r'(\w)[\w\s][\w\s][\w\s]\1[\w\s][\w\s][\w\s]\1',
+ self.line_board)
+ self.win_status3 = re.search(r'^(\w)\1\1', self.line_board)
+ self.win_status4 = re.search(r'[\w\s][\w\s][\w\s](\w)\1\1[\w\s][\w\s][\w\s]',
+ self.line_board)
+ self.win_status5 = re.search(r'(\w)\1\1$',
+ self.line_board)
+
+ if self.win_status0:
+ self.board_status = str(self.win_status0.group()[0]) + ' wins!'
+ elif self.win_status1:
+ self.board_status = str(self.win_status1.group()[2]) + ' wins!'
+ elif self.win_status2:
+ self.board_status = str(self.win_status2.group()[0]) + ' wins!'
+ elif self.win_status3:
+ self.board_status = str(self.win_status3.group()[0]) + ' wins!'
+ elif self.win_status4:
+ self.board_status = str(self.win_status4.group()[3]) + ' wins!'
+ elif self.win_status5:
+ self.board_status = str(self.win_status5.group()[0]) + ' wins!'
+
+ if (self.board_status != 'X wins!' or self.board_status != 'O wins!')\
+ and not re.search(r'\s', self.line_board):
+ self.board_status = 'Draw!'
+ return self.board_status
По-добрата практика е съобщението при изключение е да се подава като аргумент:
raise NotYourTurn("It's not your turn!")
Ако наследяваш Exception не е нужно да добавяш message
атрибут. Неговия конструктор има атрибут args
и str(exception)
връща първият аргумент подаден на конструктора.
Забавно е, че ползваш регулярни изрази в game_status
, ама в случая това само ти пречи. Да не говорим, че самият израз е кофти. Въобще, пробвай се да пренапишеш game_status
, ама без повторенията :)