Решение на Шахматни фенове от Георги

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

Към профила на Георги

Резултати

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

Код

import random
class ChessException(Exception):
pass
class ChessScore:
"""Represent the score associated with a set of Chess pieces."""
SCORES = {'r': 5,
'n': 3,
'b': 3,
'k': 4,
'q': 9,
'p': 1}
def __init__(self, pieces):
"""Initializator."""
self._pieces = pieces
self._score = 0
self._calculate_score()
@staticmethod
def __type_checked(fun):
"""Decorator for type checking in other methods."""
def decorated(this, other):
if type(this) is not type(other):
raise TypeError("Invalid operation on "
f"{type(this)} and {type(other)}.")
return fun(this, other)
return decorated
def _calculate_score(self):
"""Calculate score as number."""
for piece in self._pieces:
# KeyErrors just get propagated
self._score += self.SCORES[piece]
def __int__(self):
"""Integer representation."""
return self._score
@__type_checked
def __eq__(self, other):
"""Equal comparison."""
return self._score == other._score
@__type_checked
def __lt__(self, other):
"""Less than comparison."""
return self._score < other._score
@__type_checked
def __gt__(self, other):
"""Greater than comparison."""
return self._score > other._score
@__type_checked
def __le__(self, other):
"""Less or equal comparison."""
return self._score <= other._score
@__type_checked
def __ge__(self, other):
"""Creater or equal comparison."""
return self._score >= other._score
@__type_checked
def __add__(self, other):
"""Sum of two scores."""
return self._score + other._score
@__type_checked
def __sub__(self, other):
"""Subtraction of two scores."""
return self._score - other._score
class ChessPosition:
"""Represent a Chess position."""
COLS = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
def __init__(self, fen):
"""Initializator."""
self._fen = fen
self._parsed = {}
self._white_score = self._assign_score(str.isupper)
self._black_score = self._assign_score(str.islower)
self._parse_fen()
self._validate()
def _parse_fen(self):
"""Parse fen into easy to use dictionary."""
for row, row_label in zip(self._fen.split('/')[::-1], range(1, 9)):
self._parsed[row_label] = {}
col_index = 0
for square in row:
if square.isdigit():
for _ in range(int(square)):
self._parsed[row_label][self.COLS[col_index]] = None
col_index += 1
else:
self._parsed[row_label][self.COLS[col_index]] = square
col_index += 1
def _validate(self):
"""Validate the input fen."""
self._validate_king_count()
self._validate_king_position()
self._validate_pawns_position()
def _validate_king_count(self):
"""Validate correct number of kings."""
if self._fen.count('k') != 1 or self._fen.count('K') != 1:
raise ChessException('kings')
def _validate_king_position(self):
"""Validate correct position of kings."""
positions = {'k': None, 'K': None}
for row_index, (row_label, row) in enumerate(self._parsed.items()):
for col_index, (col_label, square) in enumerate(row.items()):
if square and square.lower() == 'k':
positions[square] = (row_index, col_index)
offset_x = abs(positions['K'][1] - positions['k'][1])
offset_y = abs(positions['K'][0] - positions['k'][0])
if offset_x in (0, 1) and offset_y in (0, 1):
raise ChessException('kings')
def _validate_pawns_position(self):
"""Validate correct position of pawns."""
rows = list(self._parsed[1].values()) + list(self._parsed[8].values())
if 'p' in rows or 'P' in rows:
raise ChessException('pawns')
def _assign_score(self, filter_fun):
"""Assign a ChessScore instance for particular type of pieces."""
return ChessScore(list(map(str.lower, filter(filter_fun, self._fen))))
def get_white_score(self):
"""Return white score object."""
return self._white_score
def get_black_score(self):
"""Return black score object."""
return self._black_score
def white_is_winning(self):
"""Return bool of whether white is winning."""
return self._white_score > self._black_score
def black_is_winning(self):
"""Return bool of whether black is winning."""
return self._black_score > self._white_score
def is_equal(self):
"""Return bool of whether the game is equal."""
return self._black_score == self._white_score
def __str__(self):
"""String representation of the position."""
return self._fen
def __len__(self):
"""Number of pieces in the position."""
return len(list(filter(str.isalpha, self._fen)))
def __getitem__(self, coordinates):
"""Get a piece from coordinates."""
col, row = coordinates[0], coordinates[1]
return self._parsed[int(row)][col]

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

.................
----------------------------------------------------------------------
Ran 17 tests in 0.162s

OK

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

Георги обнови решението на 18.11.2022 00:31 (преди над 1 година)

+import random
+
+
+class ChessException(Exception):
+ pass
+
+
+class ChessScore:
+ """Represent the score associated with a set of Chess pieces."""
+
+ SCORES = {'r': 5,
+ 'n': 3,
+ 'b': 3,
+ 'k': 4,
+ 'q': 9,
+ 'p': 1}
+
+ def __init__(self, pieces):
+ """Initializator."""
+ self._pieces = pieces
+ self._score = 0
+ self._calculate_score()
+
+ @staticmethod
+ def __type_checked(fun):
+ """Decorator for type checking in other methods."""
+ def decorated(this, other):
+ if type(this) is not type(other):
+ raise TypeError("Invalid operation on "
+ f"{type(this)} and {type(other)}.")
+ return fun(this, other)
+ return decorated
+
+ def _calculate_score(self):
+ """Calculate score as number."""
+ for piece in self._pieces:
+ # KeyErrors just get propagated
+ self._score += self.SCORES[piece]
+
+ def __int__(self):
+ """Integer representation."""
+ return self._score
+
+ @__type_checked
+ def __eq__(self, other):
+ """Equal comparison."""
+ return self._score == other._score
+
+ @__type_checked
+ def __lt__(self, other):
+ """Less than comparison."""
+ return self._score < other._score
+
+ @__type_checked
+ def __gt__(self, other):
+ """Greater than comparison."""
+ return self._score > other._score
+
+ @__type_checked
+ def __le__(self, other):
+ """Less or equal comparison."""
+ return self._score <= other._score
+
+ @__type_checked
+ def __ge__(self, other):
+ """Creater or equal comparison."""
+ return self._score >= other._score
+
+ @__type_checked
+ def __add__(self, other):
+ """Sum of two scores."""
+ return self._score + other._score
+
+ @__type_checked
+ def __sub__(self, other):
+ """Subtraction of two scores."""
+ return self._score - other._score
+
+
+class ChessPosition:
+ """Represent a Chess position."""
+
+ COLS = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
+
+ def __init__(self, fen):
+ """Initializator."""
+ self._fen = fen
+ self._parsed = {}
+ self._white_score = self._assign_score(str.isupper)
+ self._black_score = self._assign_score(str.islower)
+ self._parse_fen()
+ self._validate()
+
+ def _parse_fen(self):
+ """Parse fen into easy to use dictionary."""
+ for row, row_label in zip(self._fen.split('/')[::-1], range(1, 9)):
+ self._parsed[row_label] = {}
+ col_index = 0
+ for square in row:
+ if square.isdigit():
+ for _ in range(int(square)):
+ self._parsed[row_label][self.COLS[col_index]] = None
+ col_index += 1
+ else:
+ self._parsed[row_label][self.COLS[col_index]] = square
+ col_index += 1
+
+ def _validate(self):
+ """Validate the input fen."""
+ self._validate_king_count()
+ self._validate_king_position()
+ self._validate_pawns_position()
+
+ def _validate_king_count(self):
+ """Validate correct number of kings."""
+ if self._fen.count('k') != 1 or self._fen.count('K') != 1:
+ raise ChessException('kings')
+
+ def _validate_king_position(self):
+ """Validate correct position of kings."""
+ positions = {'k': None, 'K': None}
+ for row_index, (row_label, row) in enumerate(self._parsed.items()):
+ for col_index, (col_label, square) in enumerate(row.items()):
+ if square and square.lower() == 'k':
+ positions[square] = (row_index, col_index)
+ offset_x = abs(positions['K'][1] - positions['k'][1])
+ offset_y = abs(positions['K'][0] - positions['k'][0])
+ if offset_x in (0, 1) and offset_y in (0, 1):
+ raise ChessException('kings')
+
+ def _validate_pawns_position(self):
+ """Validate correct position of pawns."""
+ rows = list(self._parsed[1].values()) + list(self._parsed[8].values())
+ if 'p' in rows or 'P' in rows:
+ raise ChessException('pawns')
+
+ def _assign_score(self, filter_fun):
+ """Assign a ChessScore instance for particular type of pieces."""
+ return ChessScore(list(map(str.lower, filter(filter_fun, self._fen))))
+
+ def get_white_score(self):
+ """Return white score object."""
+ return self._white_score
+
+ def get_black_score(self):
+ """Return black score object."""
+ return self._black_score
+
+ def white_is_winning(self):
+ """Return bool of whether white is winning."""
+ return self._white_score > self._black_score
+
+ def black_is_winning(self):
+ """Return bool of whether black is winning."""
+ return self._black_score > self._white_score
+
+ def is_equal(self):
+ """Return bool of whether the game is equal."""
+ return self._black_score == self._white_score
+
+ def __str__(self):
+ """String representation of the position."""
+ return self._fen
+
+ def __len__(self):
+ """Number of pieces in the position."""
+ return len(list(filter(str.isalpha, self._fen)))
+
+ def __getitem__(self, coordinates):
+ """Get a piece from coordinates."""
+ col, row = coordinates[0], coordinates[1]
+ return self._parsed[int(row)][col]