Рая обнови решението на 29.11.2022 14:34 (преди почти 2 години)
+import itertools
+
+
+class ChessException(Exception):
Можеш да минеш и само с един pass
в тялото на класа, защото този инициализатор реално не прави нищо.
+
+ def __init__(self, message):
+ self._message = message
+ super().__init__(message)
+
+
+class ChessPosition:
+
+ def __init__(self, fen):
+ self._fen = fen
+ self._chessboard = {}
+ chessboard_rows = fen.split('/')
+ chessboard_rows.reverse()
+
+ pawn_invalid_position = False
+ white_kings_count = 0
+ black_kings_count = 0
+
+ for row_number, row in enumerate(chessboard_rows, start=1):
+ col = 'A'
+ for figure in row:
+ increment_col_by = 1
+
+ if(figure.isdigit()):
Моля не слагай интервали около условието на if
.
+ increment_col_by = int(figure)
+ else:
+ position = col + str(row_number)
+ self._chessboard[position] = figure
+
+ if(row_number in [1, 8] and figure.casefold() == 'p'):
+ pawn_invalid_position = True
+
+ if(figure == 'k'):
+ black_kings_count += 1
+ black_king_position = position
+
+ if(figure == 'K'):
+ white_kings_count += 1
+ white_king_position = position
+
+ col = chr(ord(col) + increment_col_by)
+
+ self.__is_valid_kings_count(white_kings_count, black_kings_count)
По-удачно име би било 'validate_kings_count'. 'is_valid...' предполага, че връщаш булева стойност, а ти не го правиш. Освен това, по-добре само с една долна черта. https://fmi.py-bg.net/tips/2
+ self.__is_valid_kings_position(white_king_position, black_king_position)
+
+ if(pawn_invalid_position):
+ raise ChessException("pawns")
+
+ def get_white_score(self):
+ allowed = {"R", "B", "K", "N", "Q", "P"}
+ return self.__get_score(allowed)
+
+ def get_black_score(self):
+ allowed = {"r", "b", "k", "n", "q", "p"}
+ return self.__get_score(allowed)
+
+ def white_is_winning(self):
+ return self.get_white_score() > self.get_black_score()
+
+ def black_is_winning(self):
+ return self.get_black_score() > self.get_white_score()
+
+ def is_equal(self):
+ return self.get_white_score() == self.get_black_score()
+
+ def __str__(self):
+ return self._fen
+
+ def __len__(self):
+ return len(self._chessboard)
+
+ def __getitem__(self, key):
+ return self._chessboard[key] if key in self._chessboard else None
+
+ def __get_score(self, allowed):
+ figures = []
+ for figure in self._chessboard.values():
+ if figure in allowed:
+ figures.append(figure.casefold())
+
+ return ChessScore(figures)
+
+ def __is_valid_kings_position(self, white_king_position, black_king_position):
+ black_king_col, black_king_row = [*black_king_position]
+ forbidden_cols = [chr(ord(black_king_col) - 1), black_king_col, chr(ord(black_king_col) + 1)]
+ forbidden_rows = [str(int(black_king_row) - 1), black_king_row, str(int(black_king_row) + 1)]
+ forbidden_positions = [''.join(pair) for pair in list(itertools.product(forbidden_cols, forbidden_rows))]
+
+ if(white_king_position in forbidden_positions):
+ raise ChessException("kings")
+
+ def __is_valid_kings_count(self, white_kings_count, black_kings_count):
+ if(white_kings_count != 1 or black_kings_count != 1):
+ raise ChessException("kings")
+
+
+class ChessScore:
+
+ _figure_points = {
+ 'r': 5,
+ 'n': 3,
+ 'b': 3,
+ 'q': 9,
+ 'k': 4,
+ 'p': 1,
+ }
+
+ def __init__(self, figures):
+ self._score = 0
+ for figure in figures:
+ self._score += self._figure_points[figure.casefold()]
+
+ 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 __nq__(self, other):
+ return self._score != other._score
+
+ def __gt__(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
Можеш да минеш и само с един
pass
в тялото на класа, защото този инициализатор реално не прави нищо.