Калоян обнови решението на 14.04.2013 16:41 (преди над 11 години)
+class InvalidValue(Exception):
+ def __init__(self, value):
+ super(InvalidValue, self).__init__()
+ self.value = value
+
+
+class NotYourTurn(Exception):
+ def __init__(self):
+ super(NotYourTurn, self).__init__()
+
+
+class InvalidMove(Exception):
+ def __init__(self):
+ super(InvalidMove, self).__init__()
+
+
+class InvalidKey(Exception):
+ def __init__(self):
+ super(InvalidKey, self).__init__()
+
+
+class TicTacToeBoard:
+ def __init__(self):
+ self.status = "Game in progress."
+ self.last_turn = " "
+ self.moves_played = 0
+ self.board = [[" "]*3 for x in range(3)]
+
+ def __str__(self):
+ string = (
+ "\n -------------\n" +
+ "3 | " + self.board[0][2] +
+ " | " + self.board[1][2] +
+ " | " + self.board[2][2] +
+ " |\n" +
+ " -------------\n" +
+ "2 | " + self.board[0][1] +
+ " | " + self.board[1][1] +
+ " | " + self.board[2][1] +
+ " |\n" +
+ " -------------\n" +
+ "1 | " + self.board[0][0] +
+ " | " + self.board[1][0] +
+ " | " + self.board[2][0] +
+ " |\n" +
+ " -------------\n"
+ " A B C \n")
+
+ return string
+
+ def _read_coords(self, coords):
+ if len(coords) > 2:
+ raise InvalidKey()
+ return
+
+ try:
+ x = ord(coords[0]) - ord("A")
+ y = int(coords[1]) - 1
+ except Exception:
+ raise InvalidKey()
+ return
+
+ if x not in range(3) or y not in range(3):
+ raise InvalidKey()
+ return
+
+ return (x, y)
+
+ def __getitem__(self, coords):
+ c = self._read_coords(coords)
+ return self.board[c[0]][c[1]]
+
+ def __setitem__(self, coords, value):
+ if value not in ("X", "O"):
+ raise InvalidValue(value)
+ return
+
+ if value == self.last_turn:
+ raise NotYourTurn()
+ return
+
+ self.last_turn = value
+
+ c = self._read_coords(coords)
+
+ if self.board[c[0]][c[1]] != " ":
+ raise InvalidMove()
+ return
+
+ self.board[c[0]][c[1]] = value
+
+ self.moves_played += 1
+
+ if self.status == "Game in progress.":
+ self.status = self._check_game_status()
+
+ def _check_game_status(self):
+ for x in range(3):
+ if self.board[x][0] == self.board[x][1] == self.board[x][2] != " ":
+ return self.board[x][0] + " wins!"
+
+ for y in range(3):
+ if self.board[0][y] == self.board[1][y] == self.board[2][y] != " ":
+ return self.board[0][y] + " wins!"
+
+ if self.board[0][0] == self.board[1][1] == self.board[2][2] != " ":
+ return self.board[1][1] + " wins!"
+
+ if self.board[2][0] == self.board[1][1] == self.board[0][2] != " ":
+ return self.board[1][1] + " wins!"
+
+ if self.moves_played == 9:
+ return "Draw!"
+
+ return "Game in progress."
+
+ def game_status(self):
+ return self.status
По-добрата практика е съобщението при изключение е да се подава като аргумент:
raise NotYourTurn("It's not your turn!")
Ако наследяваш Exception не е нужно да добавяш value
атрибут. Неговия конструктор има атрибут args
и str(exception)
връща първият аргумент подаден на конструктора.
освен това е малко странно че използваш вътре числено индексиране на board. (board[0][x]
).
Няма ли да ти е по-лесно ако използваш dict за board?