Таня обнови решението на 27.11.2022 20:37 (преди почти 2 години)
+class ChessException(Exception):
+ def __init__(self, message):
Можеш да минеш и без __init__
. Един pass
в тялото на класа е достатъчно.
+ self._message = message
+ super().__init__(self._message)
+
+class ChessScore:
+ def __init__(self, pieces):
+ score = 0
+ for piece in pieces:
+ if piece == 'r':
По-добре дефинирай това в речник, за да спестиш еднакви блокове код.
+ score += 5
+ continue
+ if piece == 'n':
+ score += 3
+ continue
+ if piece == 'b':
+ score += 3
+ continue
+ if piece == 'q':
+ score += 9
+ continue
+ if piece == 'k':
+ score += 4
+ continue
+ if piece == 'p':
+ score += 1
+ continue
+ self.score = score
+
+ def __int__(self):
+ return self.score
+
+ def __add__(self, other):
+ return self.score + other.score
+
+ def __sub__(self, other):
+ return self.score - other.score
+
+ def __lt__(self, other):
+ return self.score < other.score
+
+ def __gt__(self, other):
+ return self.score > other.score
+
+ def __le__(self, other):
+ return self.score <= other.score
+
+ def __ge__(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
+
+
+class ChessPosition:
+ def __init__(self, init_pos) -> dict:
И по-долу подсказах за това, но все пак - добре е да извадиш валидации и парсвания от инициализатора. В момента той е десетки редове. По-атомарният код се поддържа и тества много по-лесно.
+ rows = init_pos.split("/")
+ white_king = 0
+ black_king = 0
+ for letter in init_pos:
+ if letter == 'K':
+ white_king += 1
+ continue
+ if letter == 'k':
+ black_king += 1
+ continue
+
+ if white_king != 1 or black_king != 1:
+ raise ChessException("kings")
+
+ for i, row in enumerate(rows):
+ for j, pos in enumerate(row):
+ if pos == 'k':
Тук виждам два идентични блока, които можеш да изнесеш в helper метод, за да спестиш повторение.
Освен това ще си спестиш имената на променливите ii
, jj
.
+ from_j = 0 if j - 1 < 0 else j - 1
+ to_j = len(row) - 1 if len(row) - 1 < j + 1 else j + 1
+ from_i = 0 if i - 1 < 0 else i - 1
+ to_i = len(row) - 1 if len(row) - 1 < i + 1 else i + 1
+ for ii in range(from_i, to_i + 1):
+ for jj in range(from_j, to_j + 1):
+ if ii == i and jj == j:
+ continue
+ if rows[ii][jj] == "K":
+ raise ChessException("kings")
+ if pos == 'K':
+ from_j = 0 if j - 1 < 0 else j - 1
+ to_j = len(row) - 1 if len(row) - 1 < j + 1 else j + 1
+ from_i = 0 if i - 1 < 0 else i - 1
+ to_i = len(row) - 1 if len(row) - 1 < i + 1 else i + 1
+ for ii in range(from_i, to_i + 1):
+ for jj in range(from_j, to_j + 1):
+ if ii == i and jj == j:
+ continue
+ if rows[ii][jj] == "k":
+ raise ChessException("kings")
+
+ for letter in row[0]:
+ if letter == 'P' or letter == 'p':
Може и letter.lower() == 'p'
+ raise ChessException("pawns")
+ for letter in row[0]:
+ if letter == 'P' or letter == 'p':
+ raise ChessException("pawns")
+ allowed_values = ['r', 'n', 'b', 'q', 'k', 'p', 'R', 'N', 'B', 'Q', 'K', 'P']
+ sanitized_rows = []
+ for row in range(len(rows)):
+ current_row = []
+ for col in range(len(rows[row])):
+ if rows[row][col] in allowed_values:
+ current_row.append(rows[row][col])
+ else:
+ current_row.extend([None] * int(rows[row][col]))
+ sanitized_rows.append(current_row)
+ mapped_pieces = {}
+
+ cols = ["A", "B", "C", "D", "E", "F", "J", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
Повече от 8 колони няма да имаш.
+ for row in range(len(sanitized_rows)):
+ for col in range(len(rows[row])):
+ key_value =cols[col] + str(row + 1)
Липсващ интервал след равното.
+
+ mapped_pieces[key_value] = sanitized_rows[row][col]
+
+ self.pos = init_pos
+ self.rows = rows
+ self.mapped_pieces = mapped_pieces
+
+ def __getitem__(self, key):
+ return self.mapped_pieces[key]
+
+ def __str__(self):
+ return self.pos
+
+ def __len__(self):
+ len_ = 0
+ allowed_values = ['r', 'n', 'b', 'q', 'k', 'p', 'R', 'N', 'B', 'Q', 'K', 'P']
+ for letter in self.pos:
+ if letter in allowed_values:
+ len_ += 1
+ return len_
+
+ def get_black_score(self) -> ChessScore:
+ blacks = ['r', 'n', 'b', 'q', 'k', 'p']
+ black_pieces = []
+ for letter in self.pos:
+ if letter in blacks:
+ black_pieces.append(letter)
+
+ return ChessScore(black_pieces)
+
+ def get_white_score(self) -> ChessScore:
+ whites = ['R', 'N', 'B', 'Q', 'K', 'P']
+ white_pieces = []
+ for letter in self.pos:
+ if letter in whites:
+ white_pieces.append(letter)
+
+ return ChessScore([x.lower() for x in white_pieces])
+
+ def white_is_winning(self):
+ return self.get_black_score() < self.get_white_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()
+
Можеш да минеш и без
__init__
. Единpass
в тялото на класа е достатъчно.По-добре дефинирай това в речник, за да спестиш еднакви блокове код.
И по-долу подсказах за това, но все пак - добре е да извадиш валидации и парсвания от инициализатора. В момента той е десетки редове. По-атомарният код се поддържа и тества много по-лесно.
Тук виждам два идентични блока, които можеш да изнесеш в helper метод, за да спестиш повторение.
Освен това ще си спестиш имената на променливите
ii
,jj
.Може и
letter.lower() == 'p'
Повече от 8 колони няма да имаш.
Липсващ интервал след равното.