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

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

Към профила на Мартин Маринов

Резултати

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

Код

import re
from collections import OrderedDict
from itertools import chain
class InvalidValue(Exception):
pass
class InvalidKey(Exception):
pass
class InvalidMove(Exception):
pass
class NotYourTurn(Exception):
pass
class TicTacToeBoard:
VALID_VALUES = ('X', 'O')
WINNING_COMBINATIONS = (('X', 'X', 'X'),
('O', 'O', 'O'))
NUMBER_OF_SQUARES = 9
def __init__(self):
self._dictBoard = OrderedDict.fromkeys(('A', 'B', 'C'))
for char in self._dictBoard:
self._dictBoard[char] = [' ', ' ', ' ']
self._is_finished = False
self._winner = None
self._last_move = None
self._moves_counter = 0
def __getitem__(self, key):
char, digit = self.__class__.cleaned_key(key)
return self._dictBoard[char][digit]
def __setitem__(self, key, value):
self._validate_move(key, value)
char, digit = self.__class__.cleaned_key(key)
self._dictBoard[char][digit] = value
self._last_move = value
self._moves_counter += 1
if not self._is_finished:
self._resolve_status()
def game_status(self):
if self._is_finished:
if self._winner:
return "{} wins!".format(self._winner)
else:
return "Draw!"
return 'Game in progress.'
def __str__(self):
return ('\n -------------\n' +
'3 | {0[2]} | {1[2]} | {2[2]} |\n' +
' -------------\n' +
'2 | {0[1]} | {1[1]} | {2[1]} |\n' +
' -------------\n' +
'1 | {0[0]} | {1[0]} | {2[0]} |\n' +
' -------------\n' +
' A B C \n').format(*self._columns)
@staticmethod
def cleaned_key(key):
if not isinstance(key, str) or not re.match('[A-C][1-3]', key):
raise InvalidKey()
char, digit = list(key)
digit = int(digit) - 1
return (char, digit)
@property
def _rows(self):
return tuple(zip(*self._columns))
@property
def _columns(self):
return tuple(tuple(self._dictBoard[char]) for char in self._dictBoard)
@property
def _diagonals(self):
return (tuple(col[i] for i, col in enumerate(self._columns)),
tuple(col[i] for i, col in enumerate(reversed(self._columns))))
def _resolve_status(self):
for triple in chain(self._columns, self._rows, self._diagonals):
if triple in self.WINNING_COMBINATIONS:
self._is_finished = True
self._winner = triple[0]
return
if self._moves_counter == self.NUMBER_OF_SQUARES:
self._is_finished = True
def _validate_move(self, key, value):
char, digit = self.__class__.cleaned_key(key)
if not value in self.VALID_VALUES:
raise InvalidValue()
if self._dictBoard[char][digit] != ' ':
raise InvalidMove()
if self._last_move == value:
raise NotYourTurn()

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

........
----------------------------------------------------------------------
Ran 8 tests in 0.205s

OK

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

Мартин обнови решението на 14.04.2013 13:39 (преди около 11 години)

+import re
+from collections import OrderedDict
+from itertools import chain
+
+
+class InvalidValue(Exception):
+ pass
+
+
+class InvalidKey(Exception):
+ pass
+
+
+class InvalidMove(Exception):
+ pass
+
+
+class NotYourTurn(Exception):
+ pass
+
+
+def validates_key(fn):
+ def wrapped(key):
+ if not isinstance(key, str) or not re.match('[A-C][1-3]', key):
+ raise InvalidKey()
+ return fn(key)
+ return wrapped
+
+
+class TicTacToeBoard:
+
+ VALID_VALUES = ('X', 'O')
+ WINNING_COMBINATIONS = (('X', 'X', 'X'),
+ ('O', 'O', 'O'))
+ NUMBER_OF_SQUARES = 9
+
+ def __init__(self):
+ self._dictBoard = OrderedDict.fromkeys(('A', 'B', 'C'))
+ for char in self._dictBoard:
+ self._dictBoard[char] = [' ', ' ', ' ']
+ self._is_finished = False
+ self._winner = None
+ self._last_move = None
+ self._moves_counter = 0
+
+ def __getitem__(self, key):
+ char, digit = self.__class__.cleaned_key(key)
+ return self._dictBoard[char][digit]
+
+ def __setitem__(self, key, value):
+ self._validate_move(key, value)
+ char, digit = self.__class__.cleaned_key(key)
+ self._dictBoard[char][digit] = value
+ self._last_move = value
+ self._moves_counter += 1
+ if not self._is_finished:
+ self._resolve_status()
+
+ def game_status(self):
+ if self._is_finished:
+ if self._winner:
+ return "{} wins!".format(self._winner)
+ else:
+ return "Draw!"
+ return 'Game in progress.'
+
+ def __str__(self):
+ return ('\n -------------\n' +
+ '3 | {0[2]} | {1[2]} | {2[2]} |\n' +
+ ' -------------\n' +
+ '2 | {0[1]} | {1[1]} | {2[1]} |\n' +
+ ' -------------\n' +
+ '1 | {0[0]} | {1[0]} | {2[0]} |\n' +
+ ' -------------\n' +
+ ' A B C \n').format(*self._columns)
+
+ @staticmethod
+ @validates_key
+ def cleaned_key(key):
+ char, digit = list(key)
+ digit = int(digit) - 1
+ return (char, digit)
+
+ @property
+ def _rows(self):
+ return tuple(zip(*self._columns))
+
+ @property
+ def _columns(self):
+ return tuple(tuple(self._dictBoard[char]) for char in self._dictBoard)
+
+ @property
+ def _diagonals(self):
+ return ([col[i] for i, col in enumerate(self._columns)],
+ [col[i] for i, col in enumerate(reversed(self._columns))])
+
+ def _resolve_status(self):
+ for triple in chain(self._columns, self._rows, self._diagonals):
+ if triple in self.WINNING_COMBINATIONS:
+ self._is_finished = True
+ self._winner = triple[0]
+ return
+ if self._moves_counter == self.NUMBER_OF_SQUARES:
+ self._is_finished = True
+
+ def _validate_move(self, key, value):
+ char, digit = self.__class__.cleaned_key(key)
+ if not value in self.VALID_VALUES:
+ raise InvalidValue()
+ if self._dictBoard[char][digit] != ' ':
+ raise InvalidMove()
+ if self._last_move == value:
+ raise NotYourTurn()

Мартин обнови решението на 14.04.2013 14:30 (преди около 11 години)

import re
from collections import OrderedDict
from itertools import chain
class InvalidValue(Exception):
pass
class InvalidKey(Exception):
pass
class InvalidMove(Exception):
pass
class NotYourTurn(Exception):
pass
-def validates_key(fn):
- def wrapped(key):
- if not isinstance(key, str) or not re.match('[A-C][1-3]', key):
- raise InvalidKey()
- return fn(key)
- return wrapped
-
-
class TicTacToeBoard:
VALID_VALUES = ('X', 'O')
WINNING_COMBINATIONS = (('X', 'X', 'X'),
('O', 'O', 'O'))
NUMBER_OF_SQUARES = 9
def __init__(self):
self._dictBoard = OrderedDict.fromkeys(('A', 'B', 'C'))
for char in self._dictBoard:
self._dictBoard[char] = [' ', ' ', ' ']
self._is_finished = False
self._winner = None
self._last_move = None
self._moves_counter = 0
def __getitem__(self, key):
char, digit = self.__class__.cleaned_key(key)
return self._dictBoard[char][digit]
def __setitem__(self, key, value):
self._validate_move(key, value)
char, digit = self.__class__.cleaned_key(key)
self._dictBoard[char][digit] = value
self._last_move = value
self._moves_counter += 1
if not self._is_finished:
self._resolve_status()
def game_status(self):
if self._is_finished:
if self._winner:
return "{} wins!".format(self._winner)
else:
return "Draw!"
return 'Game in progress.'
def __str__(self):
return ('\n -------------\n' +
'3 | {0[2]} | {1[2]} | {2[2]} |\n' +
' -------------\n' +
'2 | {0[1]} | {1[1]} | {2[1]} |\n' +
' -------------\n' +
'1 | {0[0]} | {1[0]} | {2[0]} |\n' +
' -------------\n' +
' A B C \n').format(*self._columns)
@staticmethod
- @validates_key
def cleaned_key(key):
+ if not isinstance(key, str) or not re.match('[A-C][1-3]', key):
+ raise InvalidKey()
char, digit = list(key)
digit = int(digit) - 1
return (char, digit)
@property
def _rows(self):
return tuple(zip(*self._columns))
@property
def _columns(self):
return tuple(tuple(self._dictBoard[char]) for char in self._dictBoard)
@property
def _diagonals(self):
return ([col[i] for i, col in enumerate(self._columns)],
[col[i] for i, col in enumerate(reversed(self._columns))])
def _resolve_status(self):
for triple in chain(self._columns, self._rows, self._diagonals):
if triple in self.WINNING_COMBINATIONS:
self._is_finished = True
self._winner = triple[0]
return
if self._moves_counter == self.NUMBER_OF_SQUARES:
self._is_finished = True
def _validate_move(self, key, value):
char, digit = self.__class__.cleaned_key(key)
if not value in self.VALID_VALUES:
raise InvalidValue()
if self._dictBoard[char][digit] != ' ':
raise InvalidMove()
if self._last_move == value:
raise NotYourTurn()

Мартин обнови решението на 14.04.2013 21:42 (преди около 11 години)

import re
from collections import OrderedDict
from itertools import chain
class InvalidValue(Exception):
pass
class InvalidKey(Exception):
pass
class InvalidMove(Exception):
pass
class NotYourTurn(Exception):
pass
class TicTacToeBoard:
VALID_VALUES = ('X', 'O')
WINNING_COMBINATIONS = (('X', 'X', 'X'),
('O', 'O', 'O'))
NUMBER_OF_SQUARES = 9
def __init__(self):
self._dictBoard = OrderedDict.fromkeys(('A', 'B', 'C'))
for char in self._dictBoard:
self._dictBoard[char] = [' ', ' ', ' ']
self._is_finished = False
self._winner = None
self._last_move = None
self._moves_counter = 0
def __getitem__(self, key):
char, digit = self.__class__.cleaned_key(key)
return self._dictBoard[char][digit]
def __setitem__(self, key, value):
self._validate_move(key, value)
char, digit = self.__class__.cleaned_key(key)
self._dictBoard[char][digit] = value
self._last_move = value
self._moves_counter += 1
if not self._is_finished:
self._resolve_status()
def game_status(self):
if self._is_finished:
if self._winner:
return "{} wins!".format(self._winner)
else:
return "Draw!"
return 'Game in progress.'
def __str__(self):
return ('\n -------------\n' +
'3 | {0[2]} | {1[2]} | {2[2]} |\n' +
' -------------\n' +
'2 | {0[1]} | {1[1]} | {2[1]} |\n' +
' -------------\n' +
'1 | {0[0]} | {1[0]} | {2[0]} |\n' +
' -------------\n' +
' A B C \n').format(*self._columns)
@staticmethod
def cleaned_key(key):
if not isinstance(key, str) or not re.match('[A-C][1-3]', key):
raise InvalidKey()
char, digit = list(key)
digit = int(digit) - 1
return (char, digit)
@property
def _rows(self):
return tuple(zip(*self._columns))
@property
def _columns(self):
return tuple(tuple(self._dictBoard[char]) for char in self._dictBoard)
@property
def _diagonals(self):
- return ([col[i] for i, col in enumerate(self._columns)],
- [col[i] for i, col in enumerate(reversed(self._columns))])
+ return (tuple(col[i] for i, col in enumerate(self._columns)),
+ tuple(col[i] for i, col in enumerate(reversed(self._columns))))
def _resolve_status(self):
for triple in chain(self._columns, self._rows, self._diagonals):
if triple in self.WINNING_COMBINATIONS:
self._is_finished = True
self._winner = triple[0]
return
if self._moves_counter == self.NUMBER_OF_SQUARES:
self._is_finished = True
def _validate_move(self, key, value):
char, digit = self.__class__.cleaned_key(key)
if not value in self.VALID_VALUES:
raise InvalidValue()
if self._dictBoard[char][digit] != ' ':
raise InvalidMove()
if self._last_move == value:
raise NotYourTurn()