Николай обнови решението на 11.04.2013 01:34 (преди над 11 години)
+import re
+
+
+class InvalidMove(Exception):
+ pass
+
+
+class InvalidValue(Exception):
+ pass
+
+
+class InvalidKey(Exception):
+ pass
+
+
+class NotYourTurn(Exception):
+ pass
+
+
+class TicTacToeBoard:
+ BOARD_SIZE = 3
+
+ KEY_CHECKER = re.compile(r'^[A-C][1-3]$')
+ VALUE_CHECKER = re.compile(r'^[O|X]$')
+
+ def __init__(self):
+ self.board = [[' ', ' ', ' '],
+ [' ', ' ', ' '],
+ [' ', ' ', ' ']]
+
+ self.row_points = [0, 0, 0]
+ self.column_points = [0, 0, 0]
+ self.main_diagonal_points = 0
+ self.second_diagonal_points = 0
+
+ self.status = "Game in progress."
+ self.is_game_in_progress = True
+ self.remaning_cells = TicTacToeBoard.BOARD_SIZE ** 2
+
+ self.last_played_turn = '?'
+
+ @staticmethod
+ def is_valid_key(key):
+ return TicTacToeBoard.KEY_CHECKER.match(key)
+
+ @staticmethod
+ def is_valid_value(value):
+ return TicTacToeBoard.VALUE_CHECKER.match(value)
+
+ def is_valid_turn(self, curr_turn):
+ return self.last_played_turn != curr_turn
+
+ @staticmethod
+ def get_turn_weight(turn):
+ return 1 if turn == 'X' else -1
+
+ def update_board_points(self, row, col, turn):
+ self.row_points[row] += TicTacToeBoard.get_turn_weight(turn)
+ self.column_points[col] += TicTacToeBoard.get_turn_weight(turn)
+
+ if row == col:
+ self.main_diagonal_points += TicTacToeBoard.get_turn_weight(turn)
+
+ if row + col == TicTacToeBoard.BOARD_SIZE - 1:
+ self.second_diagonal_points += TicTacToeBoard.get_turn_weight(turn)
+
+ def is_winning_move(self, row, col):
+ return abs(self.row_points[row]) == TicTacToeBoard.BOARD_SIZE or\
+ abs(self.column_points[col]) == TicTacToeBoard.BOARD_SIZE or\
+ abs(self.main_diagonal_points) == TicTacToeBoard.BOARD_SIZE or\
+ abs(self.second_diagonal_points) == TicTacToeBoard.BOARD_SIZE
+
+ def __setitem__(self, key, value):
+ if not TicTacToeBoard.is_valid_key(key):
+ raise InvalidKey("Invalid key: " + key)
+
+ if not TicTacToeBoard.is_valid_value(value):
+ raise InvalidValue("Invalid value: " + value)
+
+ if not self.is_valid_turn(value):
+ raise NotYourTurn("It is not turn of {}".format(value))
+
+ col = ord(key[0]) - ord('A')
+ row = ord(key[1]) - ord('1')
+
+ if self.board[row][col] != ' ':
+ raise InvalidMove("Cell {} is already occupied".format(key))
+
+ self.board[row][col] = value
+ self.last_played_turn = value
+ self.remaning_cells = self.remaning_cells - 1
+
+ self.update_board_points(row, col, value)
+
+ if self.is_game_in_progress:
+ if self.is_winning_move(row, col):
+ self.status = "{} wins!".format(value)
+ self.is_game_in_progress = False
+ elif self.remaning_cells == 0:
+ self.status = "Draw!"
+ self.is_game_in_progress = False
+
+ def game_status(self):
+ return self.status
+
+ def __str__(self):
+ return "\n -------------\n" +\
+ "3 | {0} | {1} | {2} |\n".format(
+ self.board[2][0], self.board[2][1], self.board[2][2]) +\
+ " -------------\n" +\
+ "2 | {0} | {1} | {2} |\n".format(
+ self.board[1][0], self.board[1][1], self.board[1][2]) +\
+ " -------------\n" +\
+ "1 | {0} | {1} | {2} |\n".format(
+ self.board[0][0], self.board[0][1], self.board[0][2]) +\
+ " -------------\n" +\
+ " A B C \n"
Изпускаш случаи при проверката на входните данни. Казали сме ви да тествате входните данни в случая => не сте сигурни, че ще получите стринг, като стойност на клетка ;)