Радослав обнови решението на 11.04.2013 15:52 (преди над 11 години)
+import re
+
+
+class InvalidMove(Exception):
+ pass
+
+
+class InvalidValue(Exception):
+ pass
+
+
+class InvalidKey(Exception):
+ pass
+
+
+class NotYourTurn(Exception):
+ pass
+
+
+class TicTacToeBoard:
+ X_SIGN = 'X'
+ O_SIGN = 'O'
+ EMPTY_SIGN = ' '
+ STATUS_DRAW = 'Draw!'
+ STATUS_X_WINS = 'X wins!'
+ STATUS_O_WINS = 'O wins!'
+ STATUS_GAME_IN_PROGRESS = 'Game in progress.'
+ VALID_COORDINATE = r'^[ABC][123]$'
+ VALID_SIGN = r'^[' + X_SIGN + O_SIGN + r']$'
+ LINE = ' -------------'
+ COLUMNS = {'A': 0, 'B': 1, 'C': 2}
+
+ def __init__(self):
+ self._board = [None] * 3
+ for row in range(3):
+ self._board[row] = [self.EMPTY_SIGN] * 3
+ self._last_played = None
+
+ def _get_board_coords(self, key):
+ row = 3 - int(key[1])
+ col = self.COLUMNS[key[0]]
+ return row, col
+
+ def __getitem__(self, key):
+ if re.match(self.VALID_COORDINATE, key) is None:
+ raise InvalidKey
+ row, col = self._get_board_coords(key)
+ return self._board[row][col]
+
+ def __setitem__(self, key, value):
+ if self._last_played is not None and self._last_played == value:
+ raise NotYourTurn
+ if re.match(self.VALID_COORDINATE, key) is None:
+ raise InvalidKey
+ if re.match(self.VALID_SIGN, value) is None:
+ raise InvalidValue
+ if self[key] != self.EMPTY_SIGN:
+ raise InvalidMove
+
+ self._last_played = value
+ row, col = self._get_board_coords(key)
+ self._board[row][col] = value
+
+ def __str__(self):
+ result = '\n'
+ for row in range(3):
+ result += self.LINE + '\n'
+ result += str(3 - row) + ' '
+ for col in range(3):
+ result += '| ' + self._board[row][col] + ' '
+ result += '|\n'
+
+ result += self.LINE + '\n'
+ result += ' ' * 4 + 'A' + ' ' * 3 + 'B' + ' ' * 3 + 'C' + ' \n'
+ return result
+
+ def _list_wins(self, list_):
+ win_list_x = [self.X_SIGN] * 3
+ win_list_o = [self.O_SIGN] * 3
+
+ if list_ == win_list_x:
+ return self.STATUS_X_WINS
+ elif list_ == win_list_o:
+ return self.STATUS_O_WINS
+
+ def game_status(self):
+ for row in self._board:
+ win_test = self._list_wins(row)
+ if win_test is not None:
+ return win_test
+
+ cols = [[row[col] for row in self._board] for col in range(3)]
+
+ for col in cols:
+ win_test = self._list_wins(col)
+ if win_test is not None:
+ return win_test
+
+ diagonals = [[], []]
+ for row in range(3):
+ diagonals[0] += self._board[row][row]
+ diagonals[1] += self._board[row][2 - row]
+
+ for diagonal in diagonals:
+ win_test = self._list_wins(diagonal)
+ if win_test is not None:
+ return win_test
+
+ for row in self._board:
+ if self.EMPTY_SIGN in row:
+ return self.STATUS_GAME_IN_PROGRESS
+
+ return self.STATUS_DRAW
+1 точка за това че използваш константи за статусите на играта. По принцип това е много по-добър начин от измислянето на някакви низове :)
пробвай да направиш __str__
метода си по-четлив. С format
или %
например.