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

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

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

Резултати

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

Код

from re import findall
ROW_TO_IDX_MAPPING = {
'1': 7,
'2': 6,
'3': 5,
'4': 4,
'5': 3,
'6': 2,
'7': 1,
'8': 0
}
COLUMN_TO_IDX_MAPPING = {
'A': 0,
'B': 1,
'C': 2,
'D': 3,
'E': 4,
'F': 5,
'G': 6,
'H': 7
}
PIECE_TO_SCORE_MAPPING = {
'r': 5,
'n': 3,
'b': 3,
'q': 9,
'k': 4,
'p': 1
}
class ChessException(Exception):
pass
class ChessScore:
def __init__(self, pieces):
self._score = 0
for piece in pieces:
self._score += PIECE_TO_SCORE_MAPPING[piece]
def __int__(self):
return self._score
def __lt__(self, other):
return self._score < other._score
def __le__(self, other):
return self._score <= other._score
def __eq__(self, other):
return self._score == other._score
def __ge__(self, other):
return self._score >= other._score
def __gt__(self, other):
return self._score > other._score
def __ne__(self, other):
return self._score != other._score
def __add__(self, other):
return self._score + other._score
def __sub__(self, other):
return self._score - other._score
class ChessPosition:
def __init__(self, fen):
if not ChessPosition.kings_are_unique(fen):
raise ChessException('kings')
if ChessPosition.kings_are_neighbors(fen):
raise ChessException('kings')
if not ChessPosition.pawns_are_on_allowed_rows(fen):
raise ChessException('pawns')
self._fen = fen
def __str__(self):
return self._fen
def __len__(self):
count = 0
for symbol in self._fen:
if symbol.isalpha():
count += 1
return count
def __getitem__(self, position):
column_idx = COLUMN_TO_IDX_MAPPING[position[0]]
row_idx = ROW_TO_IDX_MAPPING[position[1]]
translated = ChessPosition.translated_fen(self._fen).split('/')
piece = translated[row_idx][column_idx]
return piece if piece != '-' else None
def get_white_score(self):
white_pieces = findall(r'[RNBQKP]', self._fen)
return ChessScore([symbol.lower() for symbol in white_pieces])
def get_black_score(self):
black_pieces = findall(r'[rnbqkp]', self._fen)
return ChessScore(black_pieces)
def white_is_winning(self):
if self.get_white_score() > self.get_black_score():
return True
return False
def black_is_winning(self):
if self.get_black_score() > self.get_white_score():
return True
return False
def is_equal(self):
if self.get_white_score() == self.get_black_score():
return True
return False
@staticmethod
def translated_fen(fen):
rows = fen.split('/')
translated_rows = [''.join(
[c.replace(c, '-'*int(c)) if c.isdigit() else c for c in row]) for row in rows]
return '/'.join(translated_rows)
@staticmethod
def position_of_piece(rows, piece):
row_idx = -1
column_idx = -1
for current_idx, row in enumerate(rows):
symbol_idx = row.find(piece)
if symbol_idx != -1:
row_idx = current_idx
column_idx = symbol_idx
break
return row_idx, column_idx
@staticmethod
def kings_are_unique(fen):
white_kings_count = fen.count('K')
black_kings_count = fen.count('k')
return white_kings_count == 1 and black_kings_count == 1
@staticmethod
def kings_are_neighbors(fen):
rows = ChessPosition.translated_fen(fen).split('/')
white_r, white_c = ChessPosition.position_of_piece(rows, 'K')
black_r, black_c = ChessPosition.position_of_piece(rows, 'k')
if white_r == black_r and white_c in (black_c - 1, black_c + 1):
return True
if white_r in (black_r - 1, black_r + 1) and white_c in (black_c - 1, black_c, black_c + 1):
return True
return False
@staticmethod
def pawns_are_on_allowed_rows(fen):
rows = ChessPosition.translated_fen(fen).split('/')
if ('P' in rows[0] or 'p' in rows[0] or 'P' in rows[7] or 'p' in rows[7]):
return False
return True

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

.................
----------------------------------------------------------------------
Ran 17 tests in 0.170s

OK

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

Георги обнови решението на 28.11.2022 23:26 (преди над 1 година)

+from re import findall
+
+ROW_TO_IDX_MAPPING = {
+ '1': 7,
+ '2': 6,
+ '3': 5,
+ '4': 4,
+ '5': 3,
+ '6': 2,
+ '7': 1,
+ '8': 0
+}
+
+COLUMN_TO_IDX_MAPPING = {
+ 'A': 0,
+ 'B': 1,
+ 'C': 2,
+ 'D': 3,
+ 'E': 4,
+ 'F': 5,
+ 'G': 6,
+ 'H': 7
+}
+
+PIECE_TO_SCORE_MAPPING = {
+ 'r': 5,
+ 'n': 3,
+ 'b': 3,
+ 'q': 9,
+ 'k': 4,
+ 'p': 1
+}
+
+
+def locate_symbol(strings, symbol):
+ r = -1
+ c = -1
+
+ for idx, str in enumerate(strings):
+ res = str.find(symbol)
+
+ if res != -1:
+ r = idx
+ c = res
+ break
+
+ return r, c
+
+
+def translated_fen(fen):
+ rows = fen.split('/')
+
+ translated_rows = [''.join(
+ [c.replace(c, '-'*int(c)) if c.isdigit() else c for c in row]) for row in rows]
+
+ return '/'.join(translated_rows)
+
+
+def kings_are_unique(fen):
+ white_kings_count = fen.count('K')
+ black_kings_count = fen.count('k')
+
+ if white_kings_count != 1 or black_kings_count != 1:
+ return False
+
+ return True
+
+
+def kings_are_neighbors(fen):
+ rows = translated_fen(fen).split('/')
+
+ white_r, white_c = locate_symbol(rows, 'K')
+ black_r, black_c = locate_symbol(rows, 'k')
+
+ if white_r == black_r and white_c in (black_c - 1, black_c + 1):
+ return True
+
+ if white_r in (black_r - 1, black_r + 1) and white_c in (black_c - 1, black_c, black_c + 1):
+ return True
+
+ return False
+
+
+def pawns_are_on_allowed_rows(fen):
+ rows = translated_fen(fen).split('/')
+
+ if ('P' in rows[0] or 'p' in rows[0] or 'P' in rows[7] or 'p' in rows[7]):
+ return False
+
+ return True
+
+
+class ChessException(Exception):
+ def __init__(self, message):
+ self._message = message
+ super().__init__(self._message)
+
+
+class ChessScore:
+ def __init__(self, pieces):
+ self._score = 0
+
+ for piece in pieces:
+ self._score += PIECE_TO_SCORE_MAPPING[piece]
+
+ def __int__(self):
+ return self._score
+
+ def __lt__(self, other):
+ if self._score < other._score:
+ return True
+
+ return False
+
+ def __le__(self, other):
+ if self._score <= other._score:
+ return True
+
+ return False
+
+ def __eq__(self, other):
+ if self._score == other._score:
+ return True
+
+ return False
+
+ def __ge__(self, other):
+ if self._score >= other._score:
+ return True
+
+ return False
+
+ def __gt__(self, other):
+ if self._score > other._score:
+ return True
+
+ return False
+
+ def __ne__(self, other):
+ if self._score != other._score:
+ return True
+
+ return False
+
+ def __add__(self, other):
+ return self._score + other._score
+
+ def __sub__(self, other):
+ return self._score - other._score
+
+
+class ChessPosition:
+ def __init__(self, fen):
+ if not kings_are_unique(fen):
+ raise ChessException('kings')
+
+ if kings_are_neighbors(fen):
+ raise ChessException('kings')
+
+ if not pawns_are_on_allowed_rows(fen):
+ raise ChessException('pawns')
+
+ self._fen = fen
+
+ def __str__(self):
+ return self._fen
+
+ def __len__(self):
+ count = 0
+
+ for symbol in self._fen:
+ if symbol.isalpha():
+ count += 1
+
+ return count
+
+ def __getitem__(self, position):
+ column_idx = COLUMN_TO_IDX_MAPPING[position[0]]
+ row_idx = ROW_TO_IDX_MAPPING[position[1]]
+
+ translated = translated_fen(self._fen).split('/')
+ piece = translated[row_idx][column_idx]
+
+ return piece if piece != '-' else None
+
+ def get_white_score(self):
+ white_pieces = findall(r'[RNBQKP]', self._fen)
+ return ChessScore([symbol.lower() for symbol in white_pieces])
+
+ def get_black_score(self):
+ black_pieces = findall(r'[rnbqkp]', self._fen)
+ return ChessScore(black_pieces)
+
+ def white_is_winning(self):
+ if self.get_white_score() > self.get_black_score():
+ return True
+
+ return False
+
+ def black_is_winning(self):
+ if self.get_black_score() > self.get_white_score():
+ return True
+
+ return False
+
+ def is_equal(self):
+ if self.get_white_score() == self.get_black_score():
+ return True
+
+ return False

Георги обнови решението на 29.11.2022 12:28 (преди над 1 година)

from re import findall
ROW_TO_IDX_MAPPING = {
'1': 7,
'2': 6,
'3': 5,
'4': 4,
'5': 3,
'6': 2,
'7': 1,
'8': 0
}
COLUMN_TO_IDX_MAPPING = {
'A': 0,
'B': 1,
'C': 2,
'D': 3,
'E': 4,
'F': 5,
'G': 6,
'H': 7
}
PIECE_TO_SCORE_MAPPING = {
'r': 5,
'n': 3,
'b': 3,
'q': 9,
'k': 4,
'p': 1
}
-def locate_symbol(strings, symbol):
- r = -1
- c = -1
-
- for idx, str in enumerate(strings):
- res = str.find(symbol)
-
- if res != -1:
- r = idx
- c = res
- break
-
- return r, c
-
-
-def translated_fen(fen):
- rows = fen.split('/')
-
- translated_rows = [''.join(
- [c.replace(c, '-'*int(c)) if c.isdigit() else c for c in row]) for row in rows]
-
- return '/'.join(translated_rows)
-
-
-def kings_are_unique(fen):
- white_kings_count = fen.count('K')
- black_kings_count = fen.count('k')
-
- if white_kings_count != 1 or black_kings_count != 1:
- return False
-
- return True
-
-
-def kings_are_neighbors(fen):
- rows = translated_fen(fen).split('/')
-
- white_r, white_c = locate_symbol(rows, 'K')
- black_r, black_c = locate_symbol(rows, 'k')
-
- if white_r == black_r and white_c in (black_c - 1, black_c + 1):
- return True
-
- if white_r in (black_r - 1, black_r + 1) and white_c in (black_c - 1, black_c, black_c + 1):
- return True
-
- return False
-
-
-def pawns_are_on_allowed_rows(fen):
- rows = translated_fen(fen).split('/')
-
- if ('P' in rows[0] or 'p' in rows[0] or 'P' in rows[7] or 'p' in rows[7]):
- return False
-
- return True
-
-
class ChessException(Exception):
- def __init__(self, message):
- self._message = message
- super().__init__(self._message)
+ pass
class ChessScore:
def __init__(self, pieces):
self._score = 0
for piece in pieces:
self._score += PIECE_TO_SCORE_MAPPING[piece]
def __int__(self):
return self._score
def __lt__(self, other):
- if self._score < other._score:
- return True
+ return self._score < other._score
- return False
-
def __le__(self, other):
- if self._score <= other._score:
- return True
+ return self._score <= other._score
- return False
-
def __eq__(self, other):
- if self._score == other._score:
- return True
+ return self._score == other._score
- return False
-
def __ge__(self, other):
- if self._score >= other._score:
- return True
+ return self._score >= other._score
- return False
-
def __gt__(self, other):
- if self._score > other._score:
- return True
+ return self._score > other._score
- return False
-
def __ne__(self, other):
- if self._score != other._score:
- return True
+ return self._score != other._score
- return False
-
def __add__(self, other):
return self._score + other._score
def __sub__(self, other):
return self._score - other._score
class ChessPosition:
def __init__(self, fen):
- if not kings_are_unique(fen):
+ if not ChessPosition.kings_are_unique(fen):
raise ChessException('kings')
- if kings_are_neighbors(fen):
+ if ChessPosition.kings_are_neighbors(fen):
raise ChessException('kings')
- if not pawns_are_on_allowed_rows(fen):
+ if not ChessPosition.pawns_are_on_allowed_rows(fen):
raise ChessException('pawns')
self._fen = fen
def __str__(self):
return self._fen
def __len__(self):
count = 0
for symbol in self._fen:
if symbol.isalpha():
count += 1
return count
def __getitem__(self, position):
column_idx = COLUMN_TO_IDX_MAPPING[position[0]]
row_idx = ROW_TO_IDX_MAPPING[position[1]]
- translated = translated_fen(self._fen).split('/')
+ translated = ChessPosition.translated_fen(self._fen).split('/')
piece = translated[row_idx][column_idx]
return piece if piece != '-' else None
def get_white_score(self):
white_pieces = findall(r'[RNBQKP]', self._fen)
return ChessScore([symbol.lower() for symbol in white_pieces])
def get_black_score(self):
black_pieces = findall(r'[rnbqkp]', self._fen)
return ChessScore(black_pieces)
def white_is_winning(self):
if self.get_white_score() > self.get_black_score():
return True
return False
def black_is_winning(self):
if self.get_black_score() > self.get_white_score():
return True
return False
def is_equal(self):
if self.get_white_score() == self.get_black_score():
return True
return False
+
+ @staticmethod
+ def translated_fen(fen):
+ rows = fen.split('/')
+
+ translated_rows = [''.join(
+ [c.replace(c, '-'*int(c)) if c.isdigit() else c for c in row]) for row in rows]
+
+ return '/'.join(translated_rows)
+
+ @staticmethod
+ def position_of_piece(rows, piece):
+ row_idx = -1
+ column_idx = -1
+
+ for current_idx, row in enumerate(rows):
+ symbol_idx = row.find(piece)
+
+ if symbol_idx != -1:
+ row_idx = current_idx
+ column_idx = symbol_idx
+ break
+
+ return row_idx, column_idx
+
+ @staticmethod
+ def kings_are_unique(fen):
+ white_kings_count = fen.count('K')
+ black_kings_count = fen.count('k')
+
+ return white_kings_count == 1 and black_kings_count == 1
+
+ @staticmethod
+ def kings_are_neighbors(fen):
+ rows = ChessPosition.translated_fen(fen).split('/')
+
+ white_r, white_c = ChessPosition.position_of_piece(rows, 'K')
+ black_r, black_c = ChessPosition.position_of_piece(rows, 'k')
+
+ if white_r == black_r and white_c in (black_c - 1, black_c + 1):
+ return True
+
+ if white_r in (black_r - 1, black_r + 1) and white_c in (black_c - 1, black_c, black_c + 1):
+ return True
+
+ return False
+
+ @staticmethod
+ def pawns_are_on_allowed_rows(fen):
+ rows = ChessPosition.translated_fen(fen).split('/')
+
+ if ('P' in rows[0] or 'p' in rows[0] or 'P' in rows[7] or 'p' in rows[7]):
+ return False
+
+ return True
  • Премахнати излишни if проверки при предефиниране на оператори за сравнение в класа ChessScore, както и в помощната функция kings_are_neighbors.
  • Опростена дефиниция на изключението ChessException.
  • Помощните функции (translated_fen, position_of_piece, kings_are_unique, kings_are_neighbors, pawns_are_on_allowed_rows) са преместени като @staticmethods в класа ChessPosition.
  • По-описателни имена на някои променливи.