Решение на Морски шах от Филарета Йорданова

Обратно към всички решения

Към профила на Филарета Йорданова

Резултати

  • 5 точки от тестове
  • 0 бонус точки
  • 5 точки общо
  • 6 успешни тест(а)
  • 2 неуспешни тест(а)

Код

class InvalidMove(Exception):
pass
class InvalidValue(Exception):
pass
class InvalidKey(Exception):
pass
class NotYourTurn(Exception):
pass
class TicTacToeBoard:
TILES = ("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3")
MOVES = ('X', 'O')
WINNER = (("A1", "A2", "A3"), ("B1", "B2", "B3"), ("C1", "C2", "C3"),
("A1", "B1", "C1"), ("A2", "B2", "C2"), ("A3", "B3", "C3"),
("A1", "B2", "C3"), ("A3", "B2", "C1"))
def __init__(self):
self.board = dict.fromkeys(self.TILES)
self.winner = None
self.current_move = None
def set_players_turn(self, move):
self.player1 = move
if move == 'X':
self.player2 = 'O'
else:
self.player2 = 'X'
def __setitem__(self, key, value):
if self.current_move == value:
raise NotYourTurn
if value not in self.MOVES:
raise InvalidValue
if key not in self.TILES:
raise InvalidKey
if self.board[key]:
raise InvalidMove
if self.current_move:
self.current_move = value
else:
self.set_players_turn(value)
self.board[key] = value
def __getitem__(self, key):
if key in self.TILES:
return self.board[key]
def search_winner(self, move):
for triple in self.WINNER:
if all([self.board[tile] == move for tile in triple]):
self.winner = move
def game_status(self):
self.search_winner(self.player1)
if self.winner:
return "{} wins!".format(self.player1)
self.search_winner(self.player2)
if self.winner:
return "{} wins!".format(self.player2)
if None in self.board.values():
return "Game in progress."
else:
return "Draw!"
def __str__(self):
coords = {1: ("A1", "B1", "C1"),
2: ("A2", "B2", "C2"),
3: ("A3", "B3", "C3")}
ascii_board = '\n'
for row in range(7, 0, -1):
if row % 2 != 0:
ascii_board += (' ' * 2) + ('-' * 13) + '\n'
else:
i = row // 2
new_row = '{} |'.format(i)
for j in coords[i]:
if not self.board[j]:
new_row += ' |'
else:
new_row += ' {} |'.format(self.board[j])
ascii_board += new_row + '\n'
ascii_board += ' A B C \n'
return ascii_board

Лог от изпълнението

..E.F...
======================================================================
ERROR: test_input_format (test.TicTacHomeworkTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 60, in thread
    raise it.exc_info[1]
  File "lib/language/python/runner.py", line 48, in run
    self.result = func(*args, **kwargs)
  File "/tmp/d20130415-29081-10agi4d/test.py", line 57, in test_input_format
    o['A1'] = None
  File "/tmp/d20130415-29081-10agi4d/solution.py", line 38, in __setitem__
    raise NotYourTurn
solution.NotYourTurn

======================================================================
FAIL: test_overwrite_move (test.TicTacHomeworkTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 60, in thread
    raise it.exc_info[1]
  File "lib/language/python/runner.py", line 48, in run
    self.result = func(*args, **kwargs)
  File "/tmp/d20130415-29081-10agi4d/test.py", line 68, in test_overwrite_move
    o["A2"] = 'X'
AssertionError: NotYourTurn not raised

----------------------------------------------------------------------
Ran 8 tests in 0.008s

FAILED (failures=1, errors=1)

История (2 версии и 1 коментар)

Филарета обнови решението на 09.04.2013 22:59 (преди над 11 години)

+class InvalidMove(Exception):
+ def __init__(self):
+ super().__init__()
+ self.message = "This field is already set!"
+
+
+class InvalidValue(Exception):
+ def __init__(self):
+ super().__init__()
+ self.message = "You can play only with X and O!"
+
+
+class InvalidKey(Exception):
+ def __init__(self):
+ super().__init__()
+ self.message = "There is not such position on the board!"
+
+
+class NotYourTurn(Exception):
+ def __init__(self):
+ super().__init__()
+ self.message = "It is not your turn!"
+
+
+class TicTacToeBoard:
+ TILES = ("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3")
+ MOVES = ('X', 'O')
+ WINNER = (("A1", "A2", "A3"), ("B1", "B2", "B3"), ("C1", "C2", "C3"),
+ ("A1", "B1", "C1"), ("A2", "B2", "C2"), ("A3", "B3", "C3"),
+ ("A1", "B2", "C3"), ("A3", "B2", "C1"))
+
+ def __init__(self):
+ self.board = dict.fromkeys(self.TILES)
+ self.winner = None
+ self.current_move = None
+
+ def set_players_turn(self, move):
+ self.player1 = move
+ if move == 'X':
+ self.player2 = 'O'
+ else:
+ self.player2 = 'X'
+
+ def __setitem__(self, key, value):
+ if self.current_move == value:
+ raise NotYourTurn
+ if not self.current_move:
+ self.set_players_turn(value)
+ if value not in self.MOVES:
+ raise InvalidValue
+ if key not in self.TILES:
+ raise InvalidKey
+ if not self.board[key]:
+ self.board[key] = value
+ self.current_move = value
+ else:
+ raise InvalidMove
+
+ def __getitem__(self, key):
+ if key in self.TILES:
+ return self.board[key]
+
+ def search_winner(self, move):
+ for triple in self.WINNER:
+ if all([self.board[tile] == move for tile in triple]):
+ self.winner = move
+
+ def game_status(self):
+ self.search_winner(self.player1)
+ if self.winner:
+ return "{} wins!".format(self.player1)
+ self.search_winner(self.player2)
+ if self.winner:
+ return "{} wins!".format(self.player2)
+ if None in self.board.values():
+ return "Game in progress."
+ else:
+ return "Draw!"
+
+ def __str__(self):
+ coords = {1: ("A1", "B1", "C1"),
+ 2: ("A2", "B2", "C2"),
+ 3: ("A3", "B3", "C3")}
+ ascii_board = '\n'
+ for row in range(7, 0, -1):
+ if row % 2 != 0:
+ ascii_board += (' ' * 2) + ('-' * 13) + '\n'
+ else:
+ i = row // 2
+ new_row = '{} |'.format(i)
+ for j in coords[i]:
+ if not self.board[j]:
+ new_row += ' |'
+ else:
+ new_row += ' {} |'.format(self.board[j])
+ ascii_board += new_row + '\n'
+ ascii_board += ' A B C \n'
+ return ascii_board

По-добре си направи изключенията така: MyException(Exception): pass и ги възбуждай така, ако настояваш за съобщение: raise MyException('my exceptional message')

Помисли дали не можеш да преработиш __str__, така че да е по-лесен за четене и редактиране при промяна на дъската например. Hints: str.join, str.format, multiline string-ове са твои приятели

Бих препоръчал частта от __setitem__, в която проверяваш и хвърляш изключения да бъде цялата преди същината на метода и да може ясно да се вижда кои са условията за всяко изключение.

Филарета обнови решението на 10.04.2013 09:20 (преди над 11 години)

class InvalidMove(Exception):
- def __init__(self):
- super().__init__()
- self.message = "This field is already set!"
+ pass
class InvalidValue(Exception):
- def __init__(self):
- super().__init__()
- self.message = "You can play only with X and O!"
+ pass
class InvalidKey(Exception):
- def __init__(self):
- super().__init__()
- self.message = "There is not such position on the board!"
+ pass
class NotYourTurn(Exception):
- def __init__(self):
- super().__init__()
- self.message = "It is not your turn!"
+ pass
class TicTacToeBoard:
TILES = ("A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3")
MOVES = ('X', 'O')
WINNER = (("A1", "A2", "A3"), ("B1", "B2", "B3"), ("C1", "C2", "C3"),
("A1", "B1", "C1"), ("A2", "B2", "C2"), ("A3", "B3", "C3"),
("A1", "B2", "C3"), ("A3", "B2", "C1"))
def __init__(self):
self.board = dict.fromkeys(self.TILES)
self.winner = None
self.current_move = None
def set_players_turn(self, move):
self.player1 = move
if move == 'X':
self.player2 = 'O'
else:
self.player2 = 'X'
def __setitem__(self, key, value):
if self.current_move == value:
raise NotYourTurn
- if not self.current_move:
- self.set_players_turn(value)
if value not in self.MOVES:
raise InvalidValue
if key not in self.TILES:
raise InvalidKey
- if not self.board[key]:
- self.board[key] = value
+ if self.board[key]:
+ raise InvalidMove
+ if self.current_move:
self.current_move = value
else:
- raise InvalidMove
+ self.set_players_turn(value)
+ self.board[key] = value
def __getitem__(self, key):
if key in self.TILES:
return self.board[key]
def search_winner(self, move):
for triple in self.WINNER:
if all([self.board[tile] == move for tile in triple]):
self.winner = move
def game_status(self):
self.search_winner(self.player1)
if self.winner:
return "{} wins!".format(self.player1)
self.search_winner(self.player2)
if self.winner:
return "{} wins!".format(self.player2)
if None in self.board.values():
return "Game in progress."
else:
return "Draw!"
def __str__(self):
coords = {1: ("A1", "B1", "C1"),
2: ("A2", "B2", "C2"),
3: ("A3", "B3", "C3")}
ascii_board = '\n'
for row in range(7, 0, -1):
if row % 2 != 0:
ascii_board += (' ' * 2) + ('-' * 13) + '\n'
else:
i = row // 2
new_row = '{} |'.format(i)
for j in coords[i]:
if not self.board[j]:
new_row += ' |'
else:
new_row += ' {} |'.format(self.board[j])
ascii_board += new_row + '\n'
ascii_board += ' A B C \n'
return ascii_board