Решение на Шахматни фенове от Александра Павлова

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

Към профила на Александра Павлова

Резултати

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

Код

POINTS = {'q': 9, 'r': 5, 'k': 4, 'n': 3, 'b': 3, 'p': 1}
class ChessException(Exception):
pass
class ChessPosition:
def __init__(self, fen):
self.fen = self.__fen_checker(fen)
def get_white_score(self):
return ChessScore(self.__separate_lower_upper(self.fen)[1])
def get_black_score(self):
return ChessScore(self.__separate_lower_upper(self.fen)[0])
def white_is_winning(self):
return int(self.get_white_score()) > int(self.get_black_score())
def black_is_winning(self):
return int(self.get_black_score()) > int(self.get_white_score())
def is_equal(self):
return int(self.get_white_score()) == int(self.get_black_score())
def __len__(self):
return len([x for x in self.fen if x.isalpha()])
def __getitem__(self, item):
if self.__fen_table_as_dict(self.fen)[item].isalpha():
return self.__fen_table_as_dict(self.fen)[item]
return None
def __repr__(self):
return self.fen
def __fen_checker(self, fen):
if fen.count('k') == 0 or fen.count('K') == 0:
raise ChessException('kings')
elif fen.count('k') > 1 or fen.count('K') > 1:
raise ChessException('kings')
elif not self.__king_pos_checker(fen):
raise ChessException('kings')
for idx, row in enumerate(self.__fen_table_as_matrix(fen)):
if (idx == 0 or idx == 7) and (row.count('p') > 0 or row.count('P') > 0):
raise ChessException('paws')
return fen
def __king_pos_checker(self, fen):
table = self.__fen_table_as_matrix(fen)
for i, r in enumerate(table):
for j, c in enumerate(r):
if c == 'k' or c == 'K':
return self.__is_king_alone(table, i, j)
@staticmethod
def __fen_table_as_matrix(fen):
table, rows = [], [list(x) for x in fen.split('/')]
for row in rows:
line = []
for ch in row:
line.extend(' ' * int(ch)) if ch.isdigit() else line.append(ch)
table.append(line)
return table
@staticmethod
def __is_king_alone(table, r, c):
moves = (
(r - 1, c - 1),
(r - 1, c),
(r - 1, c + 1),
(r, c - 1),
(r, c + 1),
(r + 1, c - 1),
(r + 1, c),
(r + 1, c + 1)
)
for move in moves:
if 0 <= move[0] < len(table) and 0 <= move[1] < len(table):
if table[move[0]][move[1]] == table[r][c]:
return False
return True
@staticmethod
def __separate_lower_upper(fen):
return [ch for ch in fen if ch.islower()], [ch for ch in fen if ch.isupper()]
@staticmethod
def __fen_table_as_dict(fen):
table, rows = {}, [list(x) for x in fen.split('/')]
idx = 8
for row in rows:
num = 65
for ch in row:
if ch.isdigit():
for i in range(int(ch)):
table[f'{chr(num)}{idx}'] = ''
num += 1
else:
table[f'{chr(num)}{idx}'] = ch
num += 1
idx -= 1
return table
class ChessScore:
def __init__(self, arguments: list):
self.arguments = arguments
def __int__(self):
return sum(POINTS[x.lower()] for x in self.arguments)
def __add__(self, other):
return int(self) + int(other)
def __sub__(self, other):
return int(self) - int(other)
def __lt__(self, other):
return int(self) < int(other)
def __ge__(self, other):
return int(self) >= int(other)
def __eq__(self, other):
return int(self) == int(other)

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

.E.......F.F.....
======================================================================
ERROR: test_against_touching_kings (test.TestChessPosition)
Test for kings next to each other.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/storage/deedee/data/rails/pyfmi-2022/releases/20221115154139/lib/language/python/runner.py", line 67, in thread
    raise result
Exception: No exception raised on: k7/K7/8/8/8/8/8/8

======================================================================
FAIL: test_pawns_position (test.TestChessPosition)
Test for incorrect pawns.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/storage/deedee/data/rails/pyfmi-2022/releases/20221115154139/lib/language/python/runner.py", line 67, in thread
    raise result
AssertionError: 'paws' != 'pawns'
- paws
+ pawns
?    +


======================================================================
FAIL: test_validation_conflict (test.TestChessPosition)
Test for correct Exception on multiple validation fails.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/storage/deedee/data/rails/pyfmi-2022/releases/20221115154139/lib/language/python/runner.py", line 67, in thread
    raise result
AssertionError: 'paws' != 'kings'
- paws
+ kings


----------------------------------------------------------------------
Ran 17 tests in 0.172s

FAILED (failures=2, errors=1)

История (4 версии и 6 коментара)

Александра обнови решението на 26.11.2022 19:14 (преди над 1 година)

+POINTS = {'q': 9, 'r': 5, 'k': 4, 'n': 3, 'b': 3, 'p': 1}
+
+
+class ChessException(Exception):
+ pass
+
+
+class ChessPosition:
+
+ def __init__(self, fen):
+ self.fen = self.__fen_checker(fen)
+
+ def get_white_score(self):
+ return ChessScore(self.__separate_lower_upper(fen)[1])
+
+ def get_black_score(self):
+ return ChessScore(self.__separate_lower_upper(fen)[0])
+
+ def white_is_winning(self):
+ if self.get_white_score().__int__() > self.get_black_score().__int__():
+ return True
+ return False
+
+ def black_is_winning(self):
+ if self.get_black_score().__int__() > self.get_white_score().__int__():
+ return True
+ return False
+
+ def is_equal(self):
+ if self.get_white_score().__int__() == self.get_black_score().__int__():
+ return True
+ return False
+
+ def __len__(self):
+ return len([x for x in self.fen if x.isalpha()])
+
+ def __repr__(self):
+ return self.fen
+
+ def __fen_checker(self, fen):
+ if fen.count('k') > 1 or fen.count('K') > 1:
+ raise ChessException('kings')
+ elif not self.__king_pos_checker(fen):
+ raise ChessException('kings')
+ for idx, row in enumerate(self.__fen_table_as_matrix(fen)):
+ if (idx == 0 or idx == 7) and (row.count('p') > 0 or row.count('P') > 0):
+ raise ChessException('paws')
+ return fen
+
+ def __king_pos_checker(self, fen):
+ table = self.__fen_table_as_matrix(fen)
+ for i, r in enumerate(table):
+ for j, c in enumerate(r):
+ if c == 'k' or c == 'K':
+ return self.__is_king_alone(table, i, j)
+
+ @staticmethod
+ def __fen_table_as_matrix(fen):
+ table = []
+ rows = [x for x in fen.split('/')]
+ for row in rows:
+ table.append(list(row))
+ return table
+
+ @staticmethod
+ def __is_king_alone(table, r, c):
+ moves = [
+ (r - 1, c - 1),
+ (r - 1, c),
+ (r - 1, c + 1),
+ (r, c - 1),
+ (r, c + 1),
+ (r + 1, c - 1),
+ (r + 1, c),
+ (r + 1, c + 1)
+ ]
+ for move in moves:
+ if 0 <= move[0] < len(table) and 0 <= move[1] < len(table):
+ if table[move[0]][move[1]] == table[r][c]:
+ return False
+ return True
+
+ @staticmethod
+ def __separate_lower_upper(fen):
+ return [ch for ch in fen if ch.islower()], [ch for ch in fen if ch.isupper()]
+
+ """
+ Това го оставям, заради: position['E2'] # Трябва да връща дефиниция на фигурата,
+ която се намира на съответната комбинация от колона и ред, дефинирана като `str`. В
+ този пример искам фигурата, която седи на ред "2", колона "E". Ако приемем, че това
+ е първоначалната шахматна позиция, на това поле седи бяла пешка, така че очакваният
+ отговор е "P". Ако на въпросното поле няма никаква фигура, очакваният резултат е None.
+ (Не знам как да го използвам).
+ """
+ @staticmethod
+ def fen_table_as_dict(fen):
+ table = {}
+ rows = [list(x) for x in fen.split('/')]
+ idx = 1
+ for row in rows:
+ num = 65
+ for pos in row:
+ if pos.isdigit():
+ for i in range(int(pos)):
+ table[f'{chr(num)}{idx}'] = ''
+ num += 1
+ else:
+ table[f'{chr(num)}{idx}'] = pos
+ num += 1
+ idx += 1
+
+ return table
+
+
+class ChessScore:
+
+ def __init__(self, arguments: list):
+ self.arguments = arguments
+
+ def __int__(self):
+ return sum(POINTS[x.lower()] for x in self.arguments)
+
+ def __add__(self, other):
+ return self.__int__() + other.__int__()
+
+ def __sub__(self, other):
+ return self.__int__() - other.__int__()
+
+ def __lt__(self, other):
+ return self.__int__() < other.__int__()
+
+ def __ge__(self, other):
+ return self.__int__() >= other.__int__()
+
+ def __eq__(self, other):
+ return self.__int__() == other.__int__()

Имам въпрос, който много ме мъчи. Според примерите, които сте дали ( print(position) # Трябва да принтира символния низ на "FEN"-а, който е получен при инициализация.

position['E2'] # Трябва да връща дефиниция на фигурата, която се намира на съответната комбинация от колона и ред, дефинирана като str. В този пример искам фигурата, която седи на ред "2", колона "E". Ако приемем, че това е първоначалната шахматна позиция, на това поле седи бяла пешка, така че очакваният отговор е "P". Ако на въпросното поле няма никаква фигура, очакваният резултат е None. ), position хем е стринг, хем речник, от това което аз разбрах. Та въпросът ми е правилно ли разбирам нещата, и ако да, как да направя обекта да е две различни неща едновременно?

Току що се появи същия въпрос и във форума. Има дъндър методи, които могат да направят класа ти да поддържа тази функционалност. Можеш да прегледаш лекциите или документация в интернет

Александра обнови решението на 27.11.2022 11:26 (преди над 1 година)

POINTS = {'q': 9, 'r': 5, 'k': 4, 'n': 3, 'b': 3, 'p': 1}
class ChessException(Exception):
pass
class ChessPosition:
def __init__(self, fen):
self.fen = self.__fen_checker(fen)
def get_white_score(self):
return ChessScore(self.__separate_lower_upper(fen)[1])
def get_black_score(self):
return ChessScore(self.__separate_lower_upper(fen)[0])
def white_is_winning(self):
- if self.get_white_score().__int__() > self.get_black_score().__int__():
- return True
- return False
+ return self.get_white_score().__int__() > self.get_black_score().__int__()
def black_is_winning(self):
- if self.get_black_score().__int__() > self.get_white_score().__int__():
- return True
- return False
+ return self.get_black_score().__int__() > self.get_white_score().__int__()
def is_equal(self):
- if self.get_white_score().__int__() == self.get_black_score().__int__():
- return True
- return False
+ return self.get_white_score().__int__() == self.get_black_score().__int__()
def __len__(self):
return len([x for x in self.fen if x.isalpha()])
+ def __getitem__(self, item):
+ return self.__fen_table_as_dict(fen)[item]
+
def __repr__(self):
return self.fen
def __fen_checker(self, fen):
if fen.count('k') > 1 or fen.count('K') > 1:
raise ChessException('kings')
elif not self.__king_pos_checker(fen):
raise ChessException('kings')
for idx, row in enumerate(self.__fen_table_as_matrix(fen)):
if (idx == 0 or idx == 7) and (row.count('p') > 0 or row.count('P') > 0):
raise ChessException('paws')
return fen
def __king_pos_checker(self, fen):
table = self.__fen_table_as_matrix(fen)
for i, r in enumerate(table):
for j, c in enumerate(r):
if c == 'k' or c == 'K':
return self.__is_king_alone(table, i, j)
@staticmethod
def __fen_table_as_matrix(fen):
- table = []
- rows = [x for x in fen.split('/')]
+ table, rows = [], [x for x in fen.split('/')]
for row in rows:
table.append(list(row))
return table
@staticmethod
def __is_king_alone(table, r, c):
- moves = [
+ moves = (
(r - 1, c - 1),
(r - 1, c),
(r - 1, c + 1),
(r, c - 1),
(r, c + 1),
(r + 1, c - 1),
(r + 1, c),
(r + 1, c + 1)
- ]
+ )
for move in moves:
if 0 <= move[0] < len(table) and 0 <= move[1] < len(table):
if table[move[0]][move[1]] == table[r][c]:
return False
return True
@staticmethod
def __separate_lower_upper(fen):
return [ch for ch in fen if ch.islower()], [ch for ch in fen if ch.isupper()]
- """
- Това го оставям, заради: position['E2'] # Трябва да връща дефиниция на фигурата,
- която се намира на съответната комбинация от колона и ред, дефинирана като `str`. В
- този пример искам фигурата, която седи на ред "2", колона "E". Ако приемем, че това
- е първоначалната шахматна позиция, на това поле седи бяла пешка, така че очакваният
- отговор е "P". Ако на въпросното поле няма никаква фигура, очакваният резултат е None.
- (Не знам как да го използвам).
- """
@staticmethod
- def fen_table_as_dict(fen):
- table = {}
- rows = [list(x) for x in fen.split('/')]
- idx = 1
+ def __fen_table_as_dict(fen):
+ table, rows = {}, [list(x) for x in fen.split('/')]
+ idx = 8
for row in rows:
num = 65
- for pos in row:
- if pos.isdigit():
- for i in range(int(pos)):
+ for ch in row:
+ if ch.isdigit():
+ for i in range(int(ch)):
table[f'{chr(num)}{idx}'] = ''
num += 1
else:
- table[f'{chr(num)}{idx}'] = pos
+ table[f'{chr(num)}{idx}'] = ch
num += 1
- idx += 1
-
+ idx -= 1
return table
class ChessScore:
def __init__(self, arguments: list):
self.arguments = arguments
def __int__(self):
return sum(POINTS[x.lower()] for x in self.arguments)
def __add__(self, other):
return self.__int__() + other.__int__()
def __sub__(self, other):
return self.__int__() - other.__int__()
def __lt__(self, other):
return self.__int__() < other.__int__()
def __ge__(self, other):
return self.__int__() >= other.__int__()
def __eq__(self, other):
return self.__int__() == other.__int__()

Александра обнови решението на 28.11.2022 15:03 (преди над 1 година)

POINTS = {'q': 9, 'r': 5, 'k': 4, 'n': 3, 'b': 3, 'p': 1}
class ChessException(Exception):
pass
class ChessPosition:
def __init__(self, fen):
self.fen = self.__fen_checker(fen)
def get_white_score(self):
- return ChessScore(self.__separate_lower_upper(fen)[1])
+ return ChessScore(self.__separate_lower_upper(self.fen)[1])
def get_black_score(self):
- return ChessScore(self.__separate_lower_upper(fen)[0])
+ return ChessScore(self.__separate_lower_upper(self.fen)[0])
def white_is_winning(self):
- return self.get_white_score().__int__() > self.get_black_score().__int__()
+ return int(self.get_white_score()) > int(self.get_black_score())
def black_is_winning(self):
- return self.get_black_score().__int__() > self.get_white_score().__int__()
+ return int(self.get_black_score()) > int(self.get_white_score())
def is_equal(self):
- return self.get_white_score().__int__() == self.get_black_score().__int__()
+ return int(self.get_white_score()) == int(self.get_black_score())
def __len__(self):
return len([x for x in self.fen if x.isalpha()])
def __getitem__(self, item):
- return self.__fen_table_as_dict(fen)[item]
+ if self.__fen_table_as_dict(self.fen)[item].isalpha():
+ return self.__fen_table_as_dict(self.fen)[item]
+ return None
def __repr__(self):
return self.fen
def __fen_checker(self, fen):
- if fen.count('k') > 1 or fen.count('K') > 1:
+ if fen.count('k') == 0 or fen.count('K') == 0:
raise ChessException('kings')
+ elif fen.count('k') > 1 or fen.count('K') > 1:
+ raise ChessException('kings')
elif not self.__king_pos_checker(fen):
raise ChessException('kings')
for idx, row in enumerate(self.__fen_table_as_matrix(fen)):
if (idx == 0 or idx == 7) and (row.count('p') > 0 or row.count('P') > 0):
raise ChessException('paws')
return fen
def __king_pos_checker(self, fen):
table = self.__fen_table_as_matrix(fen)
for i, r in enumerate(table):
for j, c in enumerate(r):
if c == 'k' or c == 'K':
return self.__is_king_alone(table, i, j)
@staticmethod
def __fen_table_as_matrix(fen):
- table, rows = [], [x for x in fen.split('/')]
+ table, rows = [], [list(x) for x in fen.split('/')] if '/' in fen else [list(x) for x in fen]
for row in rows:
table.append(list(row))
return table
@staticmethod
def __is_king_alone(table, r, c):
moves = (
(r - 1, c - 1),
(r - 1, c),
(r - 1, c + 1),
(r, c - 1),
(r, c + 1),
(r + 1, c - 1),
(r + 1, c),
(r + 1, c + 1)
)
for move in moves:
if 0 <= move[0] < len(table) and 0 <= move[1] < len(table):
if table[move[0]][move[1]] == table[r][c]:
return False
return True
@staticmethod
def __separate_lower_upper(fen):
return [ch for ch in fen if ch.islower()], [ch for ch in fen if ch.isupper()]
@staticmethod
def __fen_table_as_dict(fen):
table, rows = {}, [list(x) for x in fen.split('/')]
idx = 8
for row in rows:
num = 65
for ch in row:
if ch.isdigit():
for i in range(int(ch)):
table[f'{chr(num)}{idx}'] = ''
num += 1
else:
table[f'{chr(num)}{idx}'] = ch
num += 1
idx -= 1
return table
class ChessScore:
def __init__(self, arguments: list):
self.arguments = arguments
def __int__(self):
return sum(POINTS[x.lower()] for x in self.arguments)
def __add__(self, other):
- return self.__int__() + other.__int__()
+ return int(self) + int(other)
def __sub__(self, other):
- return self.__int__() - other.__int__()
+ return int(self) - int(other)
def __lt__(self, other):
- return self.__int__() < other.__int__()
+ return int(self) < int(other)
def __ge__(self, other):
- return self.__int__() >= other.__int__()
+ return int(self) >= int(other)
def __eq__(self, other):
- return self.__int__() == other.__int__()
+ return int(self) == int(other)

Александра обнови решението на 28.11.2022 22:43 (преди над 1 година)

POINTS = {'q': 9, 'r': 5, 'k': 4, 'n': 3, 'b': 3, 'p': 1}
class ChessException(Exception):
pass
class ChessPosition:
def __init__(self, fen):
self.fen = self.__fen_checker(fen)
def get_white_score(self):
return ChessScore(self.__separate_lower_upper(self.fen)[1])
def get_black_score(self):
return ChessScore(self.__separate_lower_upper(self.fen)[0])
def white_is_winning(self):
return int(self.get_white_score()) > int(self.get_black_score())
def black_is_winning(self):
return int(self.get_black_score()) > int(self.get_white_score())
def is_equal(self):
return int(self.get_white_score()) == int(self.get_black_score())
def __len__(self):
return len([x for x in self.fen if x.isalpha()])
def __getitem__(self, item):
if self.__fen_table_as_dict(self.fen)[item].isalpha():
return self.__fen_table_as_dict(self.fen)[item]
return None
def __repr__(self):
return self.fen
def __fen_checker(self, fen):
if fen.count('k') == 0 or fen.count('K') == 0:
raise ChessException('kings')
elif fen.count('k') > 1 or fen.count('K') > 1:
raise ChessException('kings')
elif not self.__king_pos_checker(fen):
raise ChessException('kings')
for idx, row in enumerate(self.__fen_table_as_matrix(fen)):
if (idx == 0 or idx == 7) and (row.count('p') > 0 or row.count('P') > 0):
raise ChessException('paws')
return fen
def __king_pos_checker(self, fen):
table = self.__fen_table_as_matrix(fen)
for i, r in enumerate(table):
for j, c in enumerate(r):
if c == 'k' or c == 'K':
return self.__is_king_alone(table, i, j)
@staticmethod
def __fen_table_as_matrix(fen):
- table, rows = [], [list(x) for x in fen.split('/')] if '/' in fen else [list(x) for x in fen]
+ table, rows = [], [list(x) for x in fen.split('/')]
for row in rows:
- table.append(list(row))
+ line = []
+ for ch in row:
+ line.extend(' ' * int(ch)) if ch.isdigit() else line.append(ch)
+ table.append(line)
return table
@staticmethod
def __is_king_alone(table, r, c):
moves = (
(r - 1, c - 1),
(r - 1, c),
(r - 1, c + 1),
(r, c - 1),
(r, c + 1),
(r + 1, c - 1),
(r + 1, c),
(r + 1, c + 1)
)
for move in moves:
if 0 <= move[0] < len(table) and 0 <= move[1] < len(table):
if table[move[0]][move[1]] == table[r][c]:
return False
return True
@staticmethod
def __separate_lower_upper(fen):
return [ch for ch in fen if ch.islower()], [ch for ch in fen if ch.isupper()]
@staticmethod
def __fen_table_as_dict(fen):
table, rows = {}, [list(x) for x in fen.split('/')]
idx = 8
for row in rows:
num = 65
for ch in row:
if ch.isdigit():
for i in range(int(ch)):
table[f'{chr(num)}{idx}'] = ''
num += 1
else:
table[f'{chr(num)}{idx}'] = ch
num += 1
idx -= 1
return table
class ChessScore:
def __init__(self, arguments: list):
self.arguments = arguments
def __int__(self):
return sum(POINTS[x.lower()] for x in self.arguments)
def __add__(self, other):
return int(self) + int(other)
def __sub__(self, other):
return int(self) - int(other)
def __lt__(self, other):
return int(self) < int(other)
def __ge__(self, other):
return int(self) >= int(other)
def __eq__(self, other):
return int(self) == int(other)