Данаил обнови решението на 28.11.2022 23:49 (преди около 2 години)
+base_figures = {'r': 5, 'n': 3, 'b': 3, 'q': 9, 'k': 4, 'p': 1}
+
+
+class ChessException(Exception):
+ def __init__(self, message):
Можеш да минеш и само с един pass
в тялото на класа, защото този инициализатор реално не прави нищо.
+ super().__init__(message)
+
+
+def calculate_score(figures, fen):
По-добре тази функция да е в класа, който я използва.
+ score = 0
+ for figure in figures:
+ score += fen.count(figure)*figures[figure]
Прието е около *
да се слагат интервали.
+
+ return score
+
+
+class ChessPosition:
+ def __init__(self, fen):
+ self.fen = fen
+ self.desk = self.__build_desk(fen)
+
+ def __build_desk(self, fen):
+ rows = fen.split('/')
+ rowCounter = 8
Моля използвай snake_case
за имена на променливи.
+ desk = {}
+
+ for row in rows:
+ for col in row:
+ char = col
+ if col >= '0' and col <= '9':
Можеш и '0' <= col <= '9'
+ char = "".join(int(col)*['0'])
+ if rowCounter not in desk:
+ desk[rowCounter] = ""
+ desk[rowCounter] = desk.get(rowCounter, "") + char
+ rowCounter -= 1
+
+ self.__verify_desk(desk, fen)
+ return desk
+
+ def __verify_desk(self, desk, fen):
+ if fen.count('K') != 1 or fen.count('k') != 1:
+ raise ChessException("kings")
+
+ def is_invalid_pos(x, y):
+ if x < 0 or y < 1 or x > 7 or y > 8:
+ return 0
+ return desk[y][x].lower() == 'k'
+
+ for row in desk:
+ row_index = desk[row].lower().find('k')
+
+ if row_index == -1:
+ continue
+
+ if is_invalid_pos(row_index, row+1) or is_invalid_pos(row_index, row-1) \
Избягвай пренасяне на редове с наклонена черта на всяка цена. Тук би могъл да дефинираш няколко променливи, или да разцепиш if
-а на няколко парчета.
+ or is_invalid_pos(row_index-1, row) or is_invalid_pos(row_index-1, row+1) or is_invalid_pos(row_index-1, row-1)\
+ or is_invalid_pos(row_index+1, row) or is_invalid_pos(row_index+1, row + 1) or is_invalid_pos(row_index+1, row-1):
+ raise ChessException("kings")
+
+ if 'p' in desk[1].lower() or 'p' in desk[8].lower():
+ raise ChessException("pawns")
+
+ def get_white_score(self):
+ return calculate_score({k.upper(): v for k, v in base_figures.items()}, self.fen)
+
+ def get_black_score(self):
+ return calculate_score(base_figures, self.fen)
+
+ 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 __str__(self):
+ return self.fen
+
+ def __len__(self):
+ figure_count = 0
+ for figure in base_figures:
+ figure_count += self.fen.lower().count(figure)
+
+ return figure_count
+
+ def __getitem__(self, key):
+ figures_on_row = self.desk[int(key[1])]
+ figure = figures_on_row[ord(key[0].upper())-ord('A')]
+ return None if figure == '0' else figure
+
+
+class ChessScore:
+ def __init__(self, figures):
+ self.figures = figures
+ self.score = calculate_score(
+ base_figures, ''.join(str(x) for x in figures))
Не виждам причина да правиш списъка на стринг. Във функцията, която извикваш, така или иначе обхождаш колекция, независимо каква е тя.
+
+ def __int__(self):
+ return self.score
+
+ def __add__(self, chess_score):
+ return self.score + chess_score.score
+
+ def __gt__(self, chess_score):
+ return self.score > chess_score.score
+
+ def __lt__(self, chess_score):
+ return self.score < chess_score.score
+
+ def __le__(self, chess_score):
+ return self.score <= chess_score.score
+
+ def __eq__(self, chess_score):
+ return self.score == chess_score.score
+
+ def __ne__(self, chess_score):
+ return self.score != chess_score.score
+
+ def __sub__(self, chess_score):
+ return self.score - chess_score.score
Можеш да минеш и само с един
pass
в тялото на класа, защото този инициализатор реално не прави нищо.По-добре тази функция да е в класа, който я използва.
Прието е около
*
да се слагат интервали.Моля използвай
snake_case
за имена на променливи.Можеш и
'0' <= col <= '9'
Избягвай пренасяне на редове с наклонена черта на всяка цена. Тук би могъл да дефинираш няколко променливи, или да разцепиш
if
-а на няколко парчета.Не виждам причина да правиш списъка на стринг. Във функцията, която извикваш, така или иначе обхождаш колекция, независимо каква е тя.