Решение на Шахматни фенове от Огнян Йончев
Резултати
- 5 точки от тестове
- 0 бонус точки
- 5 точки общо
- 9 успешни тест(а)
- 8 неуспешни тест(а)
Код
Лог от изпълнението
..EEEFE.EE..E.... ====================================================================== ERROR: test_black_is_winning (test.TestChessPosition) Test black_is_winning. ---------------------------------------------------------------------- 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 solution.ChessException: kings ====================================================================== ERROR: test_get_black_score (test.TestChessPosition) Test get_black_score. ---------------------------------------------------------------------- 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 solution.ChessException: kings ====================================================================== ERROR: test_get_white_score (test.TestChessPosition) Test get_white_score. ---------------------------------------------------------------------- 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 solution.ChessException: kings ====================================================================== ERROR: test_is_equal (test.TestChessPosition) Test is_equal. ---------------------------------------------------------------------- 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 solution.ChessException: kings ====================================================================== ERROR: test_len (test.TestChessPosition) Test number of pieces for a position. ---------------------------------------------------------------------- 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 IndexError: string index out of range ====================================================================== ERROR: 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 IndexError: string index out of range ====================================================================== ERROR: test_white_is_winning (test.TestChessPosition) Test white_is_winning. ---------------------------------------------------------------------- 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 solution.ChessException: kings ====================================================================== FAIL: test_getitem (test.TestChessPosition) Test getitem functionality. ---------------------------------------------------------------------- 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: None != 'K' ---------------------------------------------------------------------- Ran 17 tests in 0.168s FAILED (failures=1, errors=7)
История (5 версии и 9 коментара)
Огнян обнови решението на 29.11.2022 11:08 (преди почти 2 години)
Огнян обнови решението на 29.11.2022 12:04 (преди почти 2 години)
Огнян обнови решението на 29.11.2022 13:00 (преди почти 2 години)
Можеш да минеш и само с един pass
в тялото на класа, защото този инициализатор реално не прави нищо.
Според мен е по-добре с една долна черта: https://fmi.py-bg.net/team
Освен това, моля слагай __init__
на първо място.
Бих запазаил резултатът от този метод като атрибут на инстанцията, за да не минаваш всеки път през този метод, когато ти трябва да работиш с дъската.
return fen.count('k') == 1 and fen.count('K') == 1
Можеш да си вземеш конкретните позиции на двата царя (след като вече си се убедил, че са точно два) и да изчлислиш разстоянието между тях. Това ще ти спести цялият този код, който според мен е прекалено сложен и дълъг.
i_row in (0, 7)
Моля не слагай скоби около условията на if
.
Един от малкото хора, които са се сетили да се застраховат, че other
е от същия тип - поздравления! Като отключим решенията, можеш да видиш как съм дефинирал тази застраховка чрез декоратор, за да спестя дублиране на код.
Огнян обнови решението на 29.11.2022 17:18 (преди почти 2 години)
тук съм оправил сложния метод
chess_figures = { 'r': 5, 'n': 3, 'b': 3, 'q': 9, 'k': 4, 'p': 1, }
class ChessException(Exception): def init(self, message='Wrong chess.'): self.message = message super().init(self.message)
class ChessPosition: def init(self, fen): self.fen = fen self.converted = self.convert_fen(fen) if (self.kings_amount() or self.kings_positions()): raise ChessException('kings') elif (self.pawns_positions()): raise ChessException('pawns')
def __convert_fen(self, fen):
# Convert fen to 8x8 chess with spaces.
new_fen = []
old_fen = fen.split('/')
for row in old_fen:
new_row = ''
for figure in row:
if figure.isalpha():
new_row += figure
else:
new_row += ''.join('_'*int(figure))
new_fen.append(new_row)
return new_fen
def __kings_amount(self):
# Check if there is only two kings.
return self.fen.count('k') != 1 or self.fen.count('K') != 1
def __kings_positions(self):
# Check if the positions of the kings are correct.
black_king = []
white_king = []
for i_row, row in enumerate(self.converted):
for i_figure, figure in enumerate(row):
if figure == 'k':
black_king = [i_row, i_figure]
elif figure == 'K':
white_king = [i_row, i_figure]
return abs(black_king[0] - white_king[0]) <= 1 and abs(black_king[1] - white_king[1])
def __pawns_positions(self):
# Check if the positions of the pawns are correct.
for i_row, row in enumerate(self.converted):
for figure in row:
if figure in ('p', 'P') and i_row in (0, 7):
return True
return False
def get_white_score(self):
white_figures = []
for figure in self.fen:
if figure not in chess_figures and figure.isalpha():
white_figures.append(figure.lower())
return ChessScore(white_figures)
def get_black_score(self):
black_figures = []
for figure in self.fen:
if figure in chess_figures:
black_figures.append(figure)
return ChessScore(black_figures)
def white_is_winning(self):
return self.get_white_score() > self.get_black_score()
def black_is_winning(self):
return self.get_white_score() < self.get_black_score()
def is_equal(self):
return self.get_white_score() == self.get_black_score()
def __str__(self):
return self.fen
def __len__(self):
figures_amount = 0
for figure in self.fen:
if figure.isalpha():
figures_amount += 1
return figures_amount
def __getitem__(self, position):
letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
row = int(position[1])
col = int(letters.index(position[0]))
if self.converted[row - 1][col].isalpha():
return self.converted[row - 1][col]
else:
return None
class ChessScore: def init(self, figures): figures_value = 0 for figure in figures: if figure.lower() not in (chess_figures): raise ChessException('Wrong figures.') else: figures_value += chess_figures[figure.lower()]
self.figures = figures
self.figures_value = figures_value
def __gt__(self, other):
# Operator >
if isinstance(other, ChessScore):
return self.figures_value > other.figures_value
else:
raise NotImplemented()
def __ge__(self, other):
# Operator >=
if isinstance(other, ChessScore):
return self.figures_value >= other.figures_value
else:
raise NotImplemented()
def __lt__(self, other):
# Operator <
if isinstance(other, ChessScore):
return self.figures_value < other.figures_value
else:
raise NotImplemented()
def __le__(self, other):
# Operator <=
if isinstance(other, ChessScore):
return self.figures_value <= other.figures_value
else:
raise NotImplemented()
def __eq__(self, other):
# Operator ==
if isinstance(other, ChessScore):
return self.figures_value == other.figures_value
else:
raise NotImplemented()
def __ne__(self, other):
# Operator !=
if isinstance(other, ChessScore):
return self.figures_value != other.figures_value
else:
raise NotImplemented()
def __add__(self, other):
# Operator +
if isinstance(other, ChessScore):
return self.figures_value + other.figures_value
else:
raise NotImplemented()
def __sub__(self, other):
# Operator -
if isinstance(other, ChessScore):
return self.figures_value - other.figures_value
else:
raise NotImplemented()
def __int__(self):
return self.figures_value
def __iadd__(self, other):
# Operator +=
if isinstance(other, ChessScore):
self.figures_value += other.figures_value
return self
else:
raise NotImplemented()
def __isub__(self, other):
# Operator -=
if isinstance(other, ChessScore):
self.figures_value -= other.figures_value
return self
else:
raise NotImplemented()
Можеш да минеш и само с един
pass
в тялото на класа, защото този инициализатор реално не прави нищо.Според мен е по-добре с една долна черта: https://fmi.py-bg.net/team
Освен това, моля слагай
__init__
на първо място.Бих запазаил резултатът от този метод като атрибут на инстанцията, за да не минаваш всеки път през този метод, когато ти трябва да работиш с дъската.
Един от малкото хора, които са се сетили да се застраховат, че
other
е от същия тип - поздравления! Като отключим решенията, можеш да видиш как съм дефинирал тази застраховка чрез декоратор, за да спестя дублиране на код.