Минчо обнови решението на 24.11.2022 18:10 (преди около 2 години)
+import re
+
+
+class ChessException(Exception):
+ def __init__(self, message=""):
Можеш да минеш и без този __init__
. Реално в него не правиш нищо. Така или иначе получаваш същия резултат.7
+ self._message = message
+ super().__init__(self._message)
+
+
+class ChessPosition:
Бих извадил валидациите в отделни методи. Сега инициализаторът ти е доста претрупан.
+ def __init__(self, fen):
+ self._whites = re.findall("[A-Z]", fen)
+ self._blacks = re.findall("[a-z]", fen)
+ self._fen = fen
+ self._board = []
+ lst_of_lines = fen.split("/")
+
+ if fen.count("k") > 1 or fen.count("K") > 1:
А ако няма никакви царе? Покриваш ли го по-долу? Просто питам, още не съм стигнал до там, но очаквам тази проверка да е тук.
+ raise ChessException("kings")
+
+ for lst in lst_of_lines:
+ tmp_lst = []
+ for piece in lst:
+ if re.findall("[a-zA-Z]", piece):
+ tmp_lst.append(piece)
+ elif re.findall("[1-8]", piece):
+ tmp_lst.extend(["_" for _ in range(int(piece))])
+ self._board.append(tmp_lst)
+ self._board.reverse()
+
+ y_cord = 0
+ for row in self._board:
Ако предварително намериш къде са царете, излислиш разстоянието между тях, и тогава го сравниш с 0, 1, ще спестип доста главоболия.
+ if row.count("k") > 0:
+ x_cord_left = (
+ row.index("k") - 1 if row.index("k") - 1 >= 0 else row.index("k")
+ )
+ x_cord_right = (
+ row.index("k") + 2 if row.index("k") + 2 <= 7 else row.index("k")
+ )
+ y_cord_up = y_cord - 1 if y_cord - 1 >= 0 else y_cord
+ y_cord_down = y_cord + 1 if y_cord + 1 <= 7 else y_cord
+ if (
Моля виж как се подреждат подобни неща.
+ "K" in self._board[y_cord_down][x_cord_left:x_cord_right]
+ or "K" in self._board[y_cord][x_cord_left:x_cord_right]
+ or "K" in self._board[y_cord_up][x_cord_left:x_cord_right]
+ ):
+ raise ChessException("kings")
+ else:
+ y_cord += 1
+
+ if (
+ lst_of_lines[0].count("p") > 0
+ or lst_of_lines[0].count("P") > 0
+ or lst_of_lines[7].count("p") > 0
+ or lst_of_lines[7].count("P") > 0
+ ):
+ raise ChessException("pawns")
+
+ def _print_b(self):
+ for lst in self._board:
+ print(lst)
+
+ def __str__(self):
+ return self._fen
+
+ def __len__(self):
+ return len(self._blacks) + len(self._whites)
+
+ def __getitem__(self, key):
+ x_comp, y_comp = key
+ if 1 < int(y_comp) or int(y_comp) > 7:
+ raise IndexError
+ x_comp = x_comp.upper()
+ translate = {"A": 0, "B": 1, "C": 2, "D": 3, "E": 4, "F": 5, "G": 6, "H": 7}
+ x_comp = translate[x_comp]
+ y_comp = int(y_comp) - 1
+ piece = self._board[y_comp][x_comp]
+ if piece == "_":
+ return "None"
"None"
е различно от None
.
+ else:
+ return piece
+
+ def get_white_score(self):
+ return ChessScore(self._whites)
Не е нужно при всяко извикване на метода да реинициализираш ChessScore
. По-добре го пази като атрибут на инстанцията на класа.
+
+ def get_black_score(self):
+ return ChessScore(self._blacks)
+
+ def white_is_winning(self):
+ return ChessScore(self._whites) > ChessScore(self._blacks)
+
+ def black_is_winning(self):
+ return ChessScore(self._blacks) > ChessScore(self._whites)
+
+ def is_equal(self):
+ return ChessScore(self._whites) == ChessScore(self._blacks)
+
+
+class ChessScore:
+ def __init__(self, figures):
+ self.score = 0
+ self._fig_to_int = {"r": 5, "n": 3, "b": 3, "k": 4, "q": 9, "p": 1,
+ "R": 5, "N": 3, "B": 3, "K": 4, "Q": 9, "P": 1}
+ for fig in figures:
+ fig = fig
+ self.score += self._fig_to_int[fig]
+
+ 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 __add__(self, other):
+ return self.score + other.score
+
+ def __sub__(self, other):
+ return self.score - other.score
+
+ def __int__(self):
+ return self.score
Можеш да минеш и без този
__init__
. Реално в него не правиш нищо. Така или иначе получаваш същия резултат.7Бих извадил валидациите в отделни методи. Сега инициализаторът ти е доста претрупан.
Ако предварително намериш къде са царете, излислиш разстоянието между тях, и тогава го сравниш с 0, 1, ще спестип доста главоболия.
Моля виж как се подреждат подобни неща.
https://peps.python.org/pep-0008/#multiline-if-statements