Айше обнови решението на 29.11.2022 13:25 (преди почти 2 години)
+import string
+
+PIECES = [
+ 'R',
+ 'N',
+ 'B',
+ 'Q',
+ 'K',
+ 'P'
+]
+
+ROW_TO_INDEX = {
+ '1': 7,
+ '2': 6,
+ '3': 5,
+ '4': 4,
+ '5': 3,
+ '6': 2,
+ '7': 1,
+ '8': 0
+}
+
+COLUMN_TO_INDEX = {
+ 'A': 0,
+ 'B': 1,
+ 'C': 2,
+ 'D': 3,
+ 'E': 4,
+ 'F': 5,
+ 'G': 6,
+ 'H': 7
+}
+
+PIECES_TO_SCORE = {
+ 'r': 5,
+ 'n': 3,
+ 'b': 3,
+ 'q': 9,
+ 'k': 4,
+ 'p': 1
+}
+
+class ChessException(Exception):
Можеш да минеш и само с един pass
в тялото на класа, защото този инициализатор реално не прави нищо.
+ def __init__(self, message):
+ self.message = message
+ super().__init__(self.message)
+
+
+class ChessPosition:
+ def __init__(self, fen):
+ board = self._generate_board(fen)
+ self._fen = fen
+ self._board = board
+ self._validate()
+
+ def __str__(self):
+ return self._fen
+
+ def __len__(self):
+ return len(list(filter(lambda symbol: symbol != '-' , ''.join(self._board))))
Не мисля, че е нужно да join
-ваш. self._board
е итерабъл така или иначе. Дано не греша, но ми се струва, че е едномерен масив и ще е все едно.
Aко не го джойнна, тъй като е масив от стрингове няма ли да итерирам по самите стрингове (което в моя случай отговаря на ред от дъската)? В случая аз искам да итерирам по символите, т.е. отделните квадратчета на дъската
+
+ def __getitem__(self, position):
+ column = COLUMN_TO_INDEX[position[0]]
+ row = ROW_TO_INDEX[position[1]]
+
+ if self._board[row][column] != '-':
+ return self._board[row][column]
+ else:
+ return None
+
+ def _neighbouring_in_column(self, row, column):
Има и по-лесни начини да се справиш с кошийството. Когато отключим решенията, може да погледнеш останалите имплементации.
+ return (
+ column < 7 and
+ self._board[row][column].lower() == self._board[row][column + 1].lower() and
+ self._board[row][column].lower() == 'k'
+ )
+
+ def _neighbouring_in_row(self, row, column):
+ return (
+ row < 7 and
+ self._board[row][column].lower() == self._board[row + 1][column].lower() and
+ self._board[row][column].lower() == 'k'
+ )
+
+ def _neighbouring_in_first_diagonal(self, row, column):
+ return (
+ row < 7 and
+ column < 7 and
+ self._board[row][column].lower() == self._board[row + 1][column + 1].lower() and
+ self._board[row][column].lower() == 'k'
+ )
+
+ def _neighbouring_in_second_diagonal(self, row, column):
+ return (
+ row > 0 and
+ column > 0 and
+ self._board[row][column].lower() == self._board[row - 1][column - 1].lower()
+ and self._board[row][column].lower() == 'k'
+ )
+
+ def _kings_neighbours(self, row, column):
+ return (
+ self._neighbouring_in_column(row, column) or
+ self._neighbouring_in_row(row, column) or
+ self._neighbouring_in_first_diagonal(row, column) or
+ self._neighbouring_in_second_diagonal(row, column)
+ )
+
+ def _invalid_kings_number(self):
+ return self._fen.count('k') != 1 or self._fen.count('K') != 1
+
+ def _invalid_pawns(self):
+ return 'p' in self._board[0] or 'P' in self._board[7]
+
+ def _validate(self):
+ for row in range(len(self._board)):
+ for column in range(len(self._board[row])):
+ if self._kings_neighbours(row, column):
+ raise ChessException('kings')
+
+ elif self._invalid_kings_number():
+ raise ChessException('kings')
+
+ elif self._invalid_pawns():
+ raise ChessException('pawns')
+
+ def _generate_board(self, fen):
+ rows = fen.split('/')
+ return [self._get_row(row) for row in rows]
+
+ def _get_row(self, row):
+ if len(row) == 8:
+ return row
+
+ result = ''
+ for symbol in row:
+ if symbol.upper() in PIECES:
+ result += symbol
+ else:
+ result += int(symbol)*'-'
Прието е около *
да се слагат интервали.
+
+ return result
+
+ def get_white_score(self):
+ whites = [symbol.lower() for symbol in list(filter(lambda row: row in string.ascii_uppercase,''.join(self._board)))]
string.ascii_uppercase
можеш да замениш с something.isupper()
+ return ChessScore(whites)
+
+ def get_black_score(self):
+ blacks = list(filter(lambda row: row in string.ascii_lowercase, ''.join(self._board)))
+ return ChessScore(blacks)
+
+ def black_is_winning(self):
+ return self.get_black_score() > self.get_white_score()
+
+ def white_is_winning(self):
+ return self.get_white_score() > self.get_black_score()
+
+ def is_equal(self):
+ return self.get_black_score() == self.get_white_score()
+
+
+class ChessScore:
+ def __init__(self, figures):
+ self.score = sum([PIECES_TO_SCORE[figure] for figure in figures])
+
+ 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 __ne__(self, other):
+ return self.score != other.score
+
+ def __gt__(self, other):
+ return self.score > other.score
+
+ def __ge__(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
в тялото на класа, защото този инициализатор реално не прави нищо.Не мисля, че е нужно да
join
-ваш.self._board
е итерабъл така или иначе. Дано не греша, но ми се струва, че е едномерен масив и ще е все едно.Aко не го джойнна, тъй като е масив от стрингове няма ли да итерирам по самите стрингове (което в моя случай отговаря на ред от дъската)? В случая аз искам да итерирам по символите, т.е. отделните квадратчета на дъската
Има и по-лесни начини да се справиш с кошийството. Когато отключим решенията, може да погледнеш останалите имплементации.