Решение на Морски шах от Добринка Табакова

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

Към профила на Добринка Табакова

Резултати

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

Код

import re
class TicTacToeBoard:
ALPHA_KEYS = {"A": 0, "B": 1, "C": 2}
NUM_KEYS = {"3": 2, "2": 1, "1": 0}
PLAYER_X = 'X'
PLAYER_O = 'O'
BOARD_SIZE = 3
def __init__(self):
self.board = [[" " for i in range(0, self.BOARD_SIZE)]
for i in range(0, self.BOARD_SIZE)]
self.next_player = None
self.moves_counter = 0
self._game_status = "Game in progress."
self.win_combinations = []
self.win_combinations += [[(i, j) for i in range(0, self.BOARD_SIZE)]
for j in range(0, self.BOARD_SIZE)]
self.win_combinations += [[(i, j) for j in range(0, self.BOARD_SIZE)]
for i in range(0, self.BOARD_SIZE)]
self.win_combinations += [[(i, i) for i in range(0, self.BOARD_SIZE)]]
self.win_combinations += [[(i, self.BOARD_SIZE-i-1)
for i in range(0, self.BOARD_SIZE)]]
def __str__(self):
devider = "\n -------------\n"
result = "{}".format(devider)
for i in reversed(range(0, 3)):
result += "{} ".format(str(i+1))
for j in range(0, 3):
result += "| {} ".format(self.board[i][j])
result += "|{}".format(devider)
result += " A B C \n"
return result
def __setitem__(self, key, value):
if not self._check_valid_key(key):
raise InvalidKey("Invalid key!")
if not self._check_valid_value(value):
raise InvalidValue("Invalid value!")
indexes = self._calculate_indexes(key)
if self.board[indexes[0]][indexes[1]] != " ":
raise InvalidMove("Invalid move!")
if not self._check_your_turn(value):
raise NotYourTurn
self.board[indexes[0]][indexes[1]] = value
self._update_game_status(indexes[0], indexes[1], value)
def __getitem__(self, key):
if not self._check_valid_key(key):
raise InvalidKey("Invalid key!")
indexes = self._calculate_indexes(key)
return self.board[indexes[0]][indexes[1]]
def _calculate_indexes(self, key):
row = self.ALPHA_KEYS[key[0]]
col = self.NUM_KEYS[key[1]]
return (row, col)
def game_status(self):
return self._game_status
def _update_game_status(self, row, col, player):
self.moves_counter += 1
for combination in self.win_combinations:
filtered_combination = [pos for pos in combination
if self.board[pos[0]][pos[1]] == player]
if len(filtered_combination) == self.BOARD_SIZE:
self._game_status = "{} wins!".format(player)
return
if self.moves_counter == 9:
self._game_status = "Draw!"
def _check_valid_key(self, key):
return re.match(r'(^([ABC][123])$)', key)
def _check_valid_value(self, value):
return re.match(r'(^[XO]$)', value)
def _check_your_turn(self, player):
if self.next_player is None or self.next_player == player:
if player == self.PLAYER_X:
self.next_player = self.PLAYER_O
else:
self.next_player = self.PLAYER_X
return True
return False
class InvalidKey(Exception):
pass
class InvalidValue(Exception):
pass
class InvalidMove(Exception):
pass
class NotYourTurn(Exception):
pass

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

..E.....
======================================================================
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-1ged0gf/test.py", line 57, in test_input_format
    o['A1'] = None
  File "/tmp/d20130415-29081-1ged0gf/solution.py", line 44, in __setitem__
    if not self._check_valid_value(value):
  File "/tmp/d20130415-29081-1ged0gf/solution.py", line 88, in _check_valid_value
    return re.match(r'(^[XO]$)', value)
  File "/opt/python3.3/lib/python3.3/re.py", line 156, in match
    return _compile(pattern, flags).match(string)
TypeError: expected string or buffer

----------------------------------------------------------------------
Ran 8 tests in 0.092s

FAILED (errors=1)

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

Добринка обнови решението на 15.04.2013 01:03 (преди около 11 години)

+import re
+
+
+class TicTacToeBoard:
+ ALPHA_KEYS = {"A": 0, "B": 1, "C": 2}
+ NUM_KEYS = {"3": 2, "2": 1, "1": 0}
+ PLAYER_X = 'X'
+ PLAYER_O = 'O'
+
+ def __init__(self):
+ self.board = [[" " for i in range(0, 3)] for i in range(0, 3)]
+ self.next_player = None
+
+ def __str__(self):
+ result = ""
+ devider = "\n -------------\n"
+ result += devider
+ for i in reversed(range(0, 3)):
+ result += str(i+1) + " "
+ for j in range(0, 3):
+ result += "| " + self.board[i][j] + " "
+
+ result += "|"
+ result += devider
+
+ result += " A B C \n"
+ return result
+
+ def __setitem__(self, key, value):
+ if not self._check_valid_key(key):
+ raise InvalidKey("Invalid key!")
+
+ if not self._check_valid_value(value):
+ raise InvalidValue("Invalid value!")
+
+ indexes = self._calculate_indexes(key)
+ if self.board[indexes[0]][indexes[1]] != " ":
+ raise InvalidMove("Invalid move!")
+
+ if not self._check_your_turn(value):
+ raise NotYourTurn
+
+ self.board[indexes[0]][indexes[1]] = value
+
+ def __getitem__(self, key):
+ if not self._check_valid_key(key):
+ raise InvalidKey("Invalid key!")
+
+ indexes = self._calculate_indexes(key)
+ return self.board[indexes[0]][indexes[1]]
+
+ def _calculate_indexes(self, key):
+ i = self.ALPHA_KEYS[key[0]]
+ j = self.NUM_KEYS[key[1]]
+ return (j, i)
+
+ def game_status(self):
+ if self._check_win(self.PLAYER_X):
+ return "X wins!"
+ if self._check_win(self.PLAYER_O):
+ return "O wins!"
+ if self._check_draw():
+ return "Draw!"
+ return "Game in progress."
+
+ def _check_draw(self):
+ for i in range(0, 3):
+ for j in range(0, 3):
+ if self.board[i][j] == " ":
+ return False
+
+ return True
+
+ def _check_win(self, player):
+ return (self._check_win_rows(player) or
+ self._check_win_cols(player) or
+ self._check_win_diag(player) or
+ self._check_win_antidiag(player))
+
+ def _check_win_rows(self, player):
+ win = True
+ for i in range(0, 3):
+ for j in range(0, 3):
+ if self.board[i][j] != player:
+ win = False
+ break
+ if win:
+ return win
+ return win
+
+ def _check_win_cols(self, player):
+ win = True
+ for i in range(0, 3):
+ for j in range(0, 3):
+ if self.board[j][i] != player:
+ win = False
+ break
+ if win:
+ return win
+ return win
+
+ def _check_win_diag(self, player):
+ win = True
+ for i in range(0, 3):
+ if self.board[i][i] != player:
+ win = False
+ break
+ return win
+
+ def _check_win_antidiag(self, player):
+ win = True
+ for i in range(0, 3):
+ if self.board[i][2-i] != player:
+ win = False
+ break
+ return win
+
+ def _check_valid_key(self, key):
+ return re.match(r'(^([ABC][123])$)', key)
+
+ def _check_valid_value(self, value):
+ return re.match(r'(^[XO]$)', value)
+
+ def _check_your_turn(self, player):
+ if self.next_player is None or self.next_player == player:
+ if player == self.PLAYER_X:
+ self.next_player = self.PLAYER_O
+ else:
+ self.next_player = self.PLAYER_X
+ return True
+
+ return False
+
+
+class InvalidKey(Exception):
+ pass
+
+
+class InvalidValue(Exception):
+ pass
+
+
+class InvalidMove(Exception):
+ pass
+
+
+class NotYourTurn(Exception):
+ pass

Дай по-подходящи имена на променливите: i, j

Влагането е зло. Опитвай да решаваш задачи с по-малко нива на влагане.

Всичките ти _check_win_... методи изглеждат ужасяващо подобни. Можеш да направиш един вместо четири абстрахирайки се от проверяваните полета.

__str__ методът ти може да се възползва от форматиране на низове за четимост и пригледност.

Добринка обнови решението на 15.04.2013 15:06 (преди около 11 години)

import re
class TicTacToeBoard:
ALPHA_KEYS = {"A": 0, "B": 1, "C": 2}
NUM_KEYS = {"3": 2, "2": 1, "1": 0}
PLAYER_X = 'X'
PLAYER_O = 'O'
+ BOARD_SIZE = 3
def __init__(self):
- self.board = [[" " for i in range(0, 3)] for i in range(0, 3)]
+ self.board = [[" " for i in range(0, self.BOARD_SIZE)]
+ for i in range(0, self.BOARD_SIZE)]
self.next_player = None
+ self.moves_counter = 0
+ self._game_status = "Game in progress."
+ self.win_combinations = []
+ self.win_combinations += [[(i, j) for i in range(0, self.BOARD_SIZE)]
+ for j in range(0, self.BOARD_SIZE)]
+ self.win_combinations += [[(i, j) for j in range(0, self.BOARD_SIZE)]
+ for i in range(0, self.BOARD_SIZE)]
+ self.win_combinations += [[(i, i) for i in range(0, self.BOARD_SIZE)]]
+ self.win_combinations += [[(i, self.BOARD_SIZE-i-1)
+ for i in range(0, self.BOARD_SIZE)]]
+
def __str__(self):
- result = ""
devider = "\n -------------\n"
- result += devider
+ result = "{}".format(devider)
for i in reversed(range(0, 3)):
- result += str(i+1) + " "
+ result += "{} ".format(str(i+1))
for j in range(0, 3):
- result += "| " + self.board[i][j] + " "
+ result += "| {} ".format(self.board[i][j])
- result += "|"
- result += devider
+ result += "|{}".format(devider)
result += " A B C \n"
return result
def __setitem__(self, key, value):
if not self._check_valid_key(key):
raise InvalidKey("Invalid key!")
if not self._check_valid_value(value):
raise InvalidValue("Invalid value!")
indexes = self._calculate_indexes(key)
if self.board[indexes[0]][indexes[1]] != " ":
raise InvalidMove("Invalid move!")
if not self._check_your_turn(value):
raise NotYourTurn
self.board[indexes[0]][indexes[1]] = value
+ self._update_game_status(indexes[0], indexes[1], value)
def __getitem__(self, key):
if not self._check_valid_key(key):
raise InvalidKey("Invalid key!")
indexes = self._calculate_indexes(key)
return self.board[indexes[0]][indexes[1]]
def _calculate_indexes(self, key):
- i = self.ALPHA_KEYS[key[0]]
- j = self.NUM_KEYS[key[1]]
- return (j, i)
+ row = self.ALPHA_KEYS[key[0]]
+ col = self.NUM_KEYS[key[1]]
+ return (row, col)
def game_status(self):
- if self._check_win(self.PLAYER_X):
- return "X wins!"
- if self._check_win(self.PLAYER_O):
- return "O wins!"
- if self._check_draw():
- return "Draw!"
- return "Game in progress."
+ return self._game_status
- def _check_draw(self):
- for i in range(0, 3):
- for j in range(0, 3):
- if self.board[i][j] == " ":
- return False
+ def _update_game_status(self, row, col, player):
+ self.moves_counter += 1
+ for combination in self.win_combinations:
+ filtered_combination = [pos for pos in combination
+ if self.board[pos[0]][pos[1]] == player]
+ if len(filtered_combination) == self.BOARD_SIZE:
+ self._game_status = "{} wins!".format(player)
+ return
- return True
-
- def _check_win(self, player):
- return (self._check_win_rows(player) or
- self._check_win_cols(player) or
- self._check_win_diag(player) or
- self._check_win_antidiag(player))
-
- def _check_win_rows(self, player):
- win = True
- for i in range(0, 3):
- for j in range(0, 3):
- if self.board[i][j] != player:
- win = False
- break
- if win:
- return win
- return win
-
- def _check_win_cols(self, player):
- win = True
- for i in range(0, 3):
- for j in range(0, 3):
- if self.board[j][i] != player:
- win = False
- break
- if win:
- return win
- return win
-
- def _check_win_diag(self, player):
- win = True
- for i in range(0, 3):
- if self.board[i][i] != player:
- win = False
- break
- return win
-
- def _check_win_antidiag(self, player):
- win = True
- for i in range(0, 3):
- if self.board[i][2-i] != player:
- win = False
- break
- return win
+ if self.moves_counter == 9:
+ self._game_status = "Draw!"
def _check_valid_key(self, key):
return re.match(r'(^([ABC][123])$)', key)
def _check_valid_value(self, value):
return re.match(r'(^[XO]$)', value)
def _check_your_turn(self, player):
if self.next_player is None or self.next_player == player:
if player == self.PLAYER_X:
self.next_player = self.PLAYER_O
else:
self.next_player = self.PLAYER_X
return True
return False
class InvalidKey(Exception):
pass
class InvalidValue(Exception):
pass
class InvalidMove(Exception):
pass
class NotYourTurn(Exception):
pass