Георги обнови решението на 29.11.2022 01:17 (преди почти 2 години)
+white_piece_points = {
+ 'R': 5,
+ 'N': 3,
+ 'B': 3,
+ 'Q': 9,
+ 'K': 4,
+ 'P': 1
+}
+
+black_piece_points = {
+ 'r': 5,
+ 'n': 3,
+ 'b': 3,
+ 'q': 9,
+ 'k': 4,
+ 'p': 1
+}
+
+
+class ChessException(Exception):
Можеш да минеш и само с един pass
в тялото на класа, защото този инициализатор реално не прави нищо.
+
+ def __init__(self, message: str = "Raised a chess excpetion"):
+ super().__init__(message)
+
+
+class ChessPosition():
Скобите тук са излишни.
+
+ def __init__(self, FEN):
Прието е главните букви да значат константа, така че аргументът ти трябва да е с малки букви.
+ board = self._init_board(FEN)
+
+ if not self._is_king_init_valid(FEN, board):
+ raise ChessException('kings')
+
+ if not self._is_pawn_init_valid(board):
+ raise ChessException('pawns')
+
+ self._board = board
+ self._FEN = FEN
+
+ def _init_board(self, FEN):
+
+ board = []
+ rows = FEN.split('/')
+
+ for row in reversed(rows):
+ row_to_append = []
+ for symbol in row:
+ if symbol >= '1' and symbol <= '8':
+ row_to_append += ['0'] * int(symbol)
+ else:
+ row_to_append.append(symbol)
+ board.append(row_to_append)
+
+ return board
+
+ def _is_king_init_valid(self, FEN, board):
+
+ if FEN.count('k') != 1 or FEN.count('K') != 1:
+ return False
+
+ black_king_row, black_king_col = (0, 0)
+ for row_number, row in enumerate(board):
+ if 'K' in row:
+ column_number = row.index('K')
+ black_king_row, black_king_col = row_number, column_number
+ break
+
+ for i in [-1, 0, 1]:
+ for j in [-1, 0, 1]:
+ if (black_king_row + i > 7) or (
Отварящите скоби трябва да са на новия ред при подобни пренасяния.
+ black_king_row + i < 0) or (
+ black_king_col + j > 7) or (
+ black_king_col + j < 0) or (
+ i == 0 and j == 0):
+ continue
+ if board[black_king_row + i][black_king_col + j] == 'k':
+ return False
+
+ return True
+
+ def _is_pawn_init_valid(self, board):
+
+ for pawn in ['p', 'P']:
+ if pawn in board[0] or pawn in board[7]:
+ return False
+
+ return True
+
+ def get_white_score(self):
+
+ score = 0
+
+ for row in range(8):
+ for col in range(8):
+ piece = self._board[row][col]
+ if piece in white_piece_points:
+ score += white_piece_points[piece]
+
+ return score
+
+ def get_black_score(self):
+
+ score = 0
+
+ for row in range(8):
+ for col in range(8):
+ piece = self._board[row][col]
+ if piece in black_piece_points:
+ score += black_piece_points[piece]
+
+ return score
+
+ 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_black_score() == self.get_white_score()
+
+ def __repr__(self):
+ return self._FEN
+
+ def __len__(self):
+ count_pieces = 0
+ for row in range(8):
+ for col in range(8):
+ piece = self._board[row][col]
+ if piece != '0':
+ count_pieces += 1
+ return count_pieces
+
+ def __getitem__(self, position):
+ col = ord(position[0]) - ord('A')
+ row = int(position[1]) - 1
+ piece = self._board[row][col]
+ return None if piece == '0' else piece
+
+
+class ChessScore():
+
+ def __init__(self, pieces):
+ self._pieces = pieces
+
+ def _is_white_piece(self, piece):
+ return piece in white_piece_points
+
+ def _is_black_piece(self, piece):
+ return piece in black_piece_points
+
+ def _calculate_score(self):
Няма причина да изчисляваш черните и белите отделно. Този клас получава списък от фигури с малки букви.
+ white_pieces_scores = [white_piece_points[piece] for piece in filter(self._is_white_piece, self._pieces)]
+ black_pieces_scores = [black_piece_points[piece] for piece in filter(self._is_black_piece, self._pieces)]
+ return sum(white_pieces_scores) + sum(black_pieces_scores)
+
+ def __eq__(self, other):
+ return self._calculate_score() == other._calculate_score()
Вместо всяки път да изчисляваш наново, по-добре изчисли при инициализация и запази в атрибут на инстанцията.
+
+ def __lt__(self, other):
+ return self._calculate_score() < other._calculate_score()
+
+ def __le__(self, other):
+ return self._calculate_score() <= other._calculate_score()
+
+ def __gt__(self, other):
+ return self._calculate_score() > other._calculate_score()
+
+ def __ge__(self, other):
+ return self._calculate_score() >= other._calculate_score()
+
+ def __add__(self, other):
+ return self._calculate_score() + other._calculate_score()
+
+ def __sub__(self, other):
+ return self._calculate_score() - other._calculate_score()
Не знам дали и друг път не съм го коментирал, но имаш доста излишни празни редове, които нарушават логическата обособеност на отделните методи и кодът се следи трудно.
Можеш да минеш и само с един
pass
в тялото на класа, защото този инициализатор реално не прави нищо.