Решение на Шахматни фенове от Весела Петрова

Обратно към всички решения

Към профила на Весела Петрова

Резултати

  • 10 точки от тестове
  • 0 бонус точки
  • 10 точки общо
  • 17 успешни тест(а)
  • 0 неуспешни тест(а)

Код

class ChessException(Exception):
pass
class ChessPosition:
def __init__(self, fen):
rows = fen.split('/')
rows.reverse()
if self.has_adjacent_kings(rows):
raise ChessException("kings")
elif not self.check_kings(rows):
raise ChessException("kings")
elif self.check_pawns(rows):
raise ChessException("pawns")
self._fen = fen
self._white_score = self.get_white_score()
self._black_score = self.get_black_score()
@staticmethod
def has_adjacent_kings(rows):
board = []
for index, row in enumerate(rows):
positions = [*(''.join([figure if not figure.isdigit() else " " * int(figure) for figure in row]))]
board.append(positions)
for row_index, row in enumerate(board):
for col_index, col in enumerate(row):
if col == " ":
continue
if col == "k":
if row_index != 0:
if board[row_index - 1][col_index] == "K" or (
col_index != 0 and board[row_index - 1][col_index - 1] == "K") or (
col_index != 7 and board[row_index - 1][col_index + 1] == "K"):
return True
if row_index != 7:
if board[row_index + 1][col_index] == "K" or (
col_index != 0 and board[row_index + 1][col_index - 1] == "K") or (
col_index != 7 and board[row_index + 1][col_index + 1] == "K"):
return True
if col_index != 0:
if board[row_index][col_index - 1] == "K":
return True
if col_index != 7:
if board[row_index][col_index + 1] == "K":
return True
return False
@staticmethod
def check_kings(rows):
is_white_king_available = False
is_black_king_available = False
white_king_count = 0
black_king_count = 0
for index, row in enumerate(rows):
if "K" in row:
is_white_king_available = True
white_king_count += 1
if "k" in row:
is_black_king_available = True
black_king_count += 1
if not is_black_king_available or not is_white_king_available or white_king_count > 1 or black_king_count > 1:
return False
return True
@staticmethod
def check_pawns(rows):
for row in rows[0] + rows[-1]:
if "P" in row or "p" in row:
return True
return False
def get_white_score(self):
white_figures_on_the_board = [figure for figure in self._fen if figure.isupper()]
return ChessScore(white_figures_on_the_board)
def get_black_score(self):
black_figures_on_the_board = [figure for figure in self._fen if figure.islower()]
return ChessScore(black_figures_on_the_board)
def white_is_winning(self):

По-удачно би било, да. Освен това, добра идея е предварително да присвоиш в атрибут на инстанциите самите ChessScore обекти, за да не се налага да ги инициализираш при всяко използване на метод. Имайки ги като атрибути на инстанцията, просто ги сравняваш. Те самите вече са подготвени за сравнение, поради изискванията на задачата.

return self._white_score > self._black_score
def black_is_winning(self):
return self._white_score < self._black_score
def is_equal(self):
return self._white_score == self._black_score
def __str__(self):
return self._fen
def __len__(self):
return len(''.join([figure for figure in self._fen if figure.isalpha()]))
def __getitem__(self, pos):

Бих дефинирал един речник предварително, базиран на самия fen, за да мога тук просто да потърся ключ, съвпадащ с pos. Реално този речник би ти свършил чудесна работа и за останалите методи.

letters_to_nums = {
"A": 0,
"B": 1,
"C": 2,
"D": 3,
"E": 4,
"F": 5,
"G": 6,
"H": 7
}
board = []
rows = self._fen.split('/')
rows.reverse()
for index, row in enumerate(rows):
positions = [*(''.join([figure if not figure.isdigit() else " " * int(figure) for figure in row]))]
board.append(positions)
return board[int(pos[1]) - 1][letters_to_nums[pos[0]]] if board[int(pos[1]) - 1][
letters_to_nums[pos[0]]] != " " else None
class ChessScore:
def __init__(self, figures):
self._figures = figures
def __int__(self):
scores = {
"R": 5,
"N": 3,
"B": 3,
"Q": 9,
"K": 4,
"P": 1
}
sum_scores = 0
for figure in self._figures:
sum_scores += scores[figure.upper()]
return sum_scores
def __lt__(self, second_instance):
return int(self) < int(second_instance)
def __le__(self, second_instance):
return int(self) <= int(second_instance)
def __gt__(self, second_instance):
return int(self) > int(second_instance)
def __ge__(self, second_instance):
return int(self) >= int(second_instance)
def __eq__(self, second_instance):
return int(self) == int(second_instance)
def __ne__(self, second_instance):
return int(self) != int(second_instance)
def __add__(self, second_instance):
return int(self) + int(second_instance)
def __sub__(self, second_instance):
return int(self) - int(second_instance)

Лог от изпълнението

.................
----------------------------------------------------------------------
Ran 17 tests in 0.158s

OK

История (2 версии и 10 коментара)

Весела обнови решението на 29.11.2022 14:36 (преди почти 2 години)

+class ChessException(Exception):
+ pass
+
+
+def has_adjacent_kings(rows):
+ board = []
+
+ for index, row in enumerate(rows):
+ positions = [*(''.join([figure if not figure.isdigit() else " " * int(figure) for figure in row]))]
+ board.append(positions)
+
+ for rowIndex, row in enumerate(board):
+ for colIndex, col in enumerate(row):
+ if col == " ":
+ continue
+ if col == "k":
+ if rowIndex != 0:
+ if board[rowIndex - 1][colIndex] == "K" or (
+ colIndex != 0 and board[rowIndex - 1][colIndex - 1] == "K") or (
+ colIndex != 7 and board[rowIndex - 1][colIndex + 1] == "K"):
+ return True
+ if rowIndex != 7:
+ if board[rowIndex + 1][colIndex] == "K" or (
+ colIndex != 0 and board[rowIndex + 1][colIndex - 1] == "K") or (
+ colIndex != 7 and board[rowIndex + 1][colIndex + 1] == "K"):
+ return True
+ if colIndex != 0:
+ if board[rowIndex][colIndex - 1] == "K":
+ return True
+ if colIndex != 7:
+ if board[rowIndex][colIndex + 1] == "K":
+ return True
+ return False
+
+
+def check_kings(rows):
+ is_white_king_available = False
+ is_black_king_available = False
+ white_king_count = 0
+ black_king_count = 0
+
+ for index, line in enumerate(rows):
+ if "K" in line:
+ is_white_king_available = True
+ white_king_count += 1
+ if "k" in line:
+ is_black_king_available = True
+ black_king_count += 1
+
+ if not is_black_king_available or not is_white_king_available or white_king_count > 1 or black_king_count > 1:
+ return False
+ return True
+
+
+def check_pawns(rows):
+ for index, line in enumerate(rows):
+ if ("P" in line or "p" in line) and (index == 0 or index == 7):
+ return True
+ return False
+
+
+class ChessPosition:
+ def __init__(self, fen):
+ rows = fen.split('/')
+ rows.reverse()
+
+ if has_adjacent_kings(rows):
+ raise ChessException("kings")
+ elif not check_kings(rows):
+ raise ChessException("kings")
+ elif check_pawns(rows):
+ raise ChessException("pawns")
+ self._fen = fen
+
+ def get_white_score(self):
+ white_figures_on_the_board = [figure for figure in self._fen if figure.isupper()]
+ white_score = ChessScore(white_figures_on_the_board)
+ return int(white_score)
+
+ def get_black_score(self):
+ black_figures_on_the_board = [figure for figure in self._fen if figure.islower()]
+ black_score = ChessScore(black_figures_on_the_board)
+ return int(black_score)
+
+ def white_is_winning(self):

По-удачно би било, да. Освен това, добра идея е предварително да присвоиш в атрибут на инстанциите самите ChessScore обекти, за да не се налага да ги инициализираш при всяко използване на метод. Имайки ги като атрибути на инстанцията, просто ги сравняваш. Те самите вече са подготвени за сравнение, поради изискванията на задачата.

+ white_figures_on_the_board = [figure for figure in self._fen if figure.isupper()]
+ black_figures_on_the_board = [figure for figure in self._fen if figure.islower()]
+ white_score = ChessScore(white_figures_on_the_board)
+ black_score = ChessScore(black_figures_on_the_board)
+ return white_score > black_score
+
+ def black_is_winning(self):
+ white_figures_on_the_board = [figure for figure in self._fen if figure.isupper()]
+ black_figures_on_the_board = [figure for figure in self._fen if figure.islower()]
+ white_score = ChessScore(white_figures_on_the_board)
+ black_score = ChessScore(black_figures_on_the_board)
+ return white_score < black_score
+
+ def is_equal(self):
+ white_figures_on_the_board = [figure for figure in self._fen if figure.isupper()]
+ black_figures_on_the_board = [figure for figure in self._fen if figure.islower()]
+ white_score = ChessScore(white_figures_on_the_board)
+ black_score = ChessScore(black_figures_on_the_board)
+ return white_score == black_score
+
+ def __str__(self):
+ return self._fen
+
+ def __len__(self):
+ return len(''.join([figure for figure in self._fen if not figure.isdigit()]).replace('/', ''))
+
+ def __getitem__(self, pos):

Бих дефинирал един речник предварително, базиран на самия fen, за да мога тук просто да потърся ключ, съвпадащ с pos. Реално този речник би ти свършил чудесна работа и за останалите методи.

+ letters_to_nums = {
+ "A": 0,
+ "B": 1,
+ "C": 2,
+ "D": 3,
+ "E": 4,
+ "F": 5,
+ "G": 6,
+ "H": 7
+ }
+
+ board = []
+ rows = self._fen.split('/')
+ rows.reverse()
+
+ for index, line in enumerate(rows):
+ positions = [*(''.join([figure if not figure.isdigit() else " " * int(figure) for figure in line]))]
+ board.append(positions)
+
+ return board[int(pos[1]) - 1][letters_to_nums[pos[0]]] if board[int(pos[1]) - 1][
+ letters_to_nums[pos[0]]] != " " else None
+
+
+class ChessScore:
+ def __init__(self, figures):
+ self._figures = figures
+
+ def sum_of_scores(self):
+ scores = {
+ "R": 5,
+ "N": 3,
+ "B": 3,
+ "Q": 9,
+ "K": 4,
+ "P": 1
+ }
+ sum_scores = 0
+
+ for figure in self._figures:
+ sum_scores += scores[figure.upper()]
+
+ return sum_scores
+
+ __int__ = sum_of_scores
+
+ def __lt__(self, second_instance):
+ return int(self) < int(second_instance)
+
+ def __le__(self, second_instance):
+ return int(self) <= int(second_instance)
+
+ def __gt__(self, second_instance):
+ return int(self) > int(second_instance)
+
+ def __ge__(self, second_instance):
+ return int(self) >= int(second_instance)
+
+ def __eq__(self, second_instance):
+ return int(self) == int(second_instance)
+
+ def __ne__(self, second_instance):
+ return int(self) != int(second_instance)
+
+ def __add__(self, second_instance):
+ return int(self) + int(second_instance)
+
+ def __sub__(self, second_instance):
+ return int(self) - int(second_instance)

Весела обнови решението на 29.11.2022 15:53 (преди почти 2 години)

class ChessException(Exception):
pass
-def has_adjacent_kings(rows):
- board = []
-
- for index, row in enumerate(rows):
- positions = [*(''.join([figure if not figure.isdigit() else " " * int(figure) for figure in row]))]
- board.append(positions)
-
- for rowIndex, row in enumerate(board):
- for colIndex, col in enumerate(row):
- if col == " ":
- continue
- if col == "k":
- if rowIndex != 0:
- if board[rowIndex - 1][colIndex] == "K" or (
- colIndex != 0 and board[rowIndex - 1][colIndex - 1] == "K") or (
- colIndex != 7 and board[rowIndex - 1][colIndex + 1] == "K"):
- return True
- if rowIndex != 7:
- if board[rowIndex + 1][colIndex] == "K" or (
- colIndex != 0 and board[rowIndex + 1][colIndex - 1] == "K") or (
- colIndex != 7 and board[rowIndex + 1][colIndex + 1] == "K"):
- return True
- if colIndex != 0:
- if board[rowIndex][colIndex - 1] == "K":
- return True
- if colIndex != 7:
- if board[rowIndex][colIndex + 1] == "K":
- return True
- return False
-
-
-def check_kings(rows):
- is_white_king_available = False
- is_black_king_available = False
- white_king_count = 0
- black_king_count = 0
-
- for index, line in enumerate(rows):
- if "K" in line:
- is_white_king_available = True
- white_king_count += 1
- if "k" in line:
- is_black_king_available = True
- black_king_count += 1
-
- if not is_black_king_available or not is_white_king_available or white_king_count > 1 or black_king_count > 1:
- return False
- return True
-
-
-def check_pawns(rows):
- for index, line in enumerate(rows):
- if ("P" in line or "p" in line) and (index == 0 or index == 7):
- return True
- return False
-
-
class ChessPosition:
def __init__(self, fen):
rows = fen.split('/')
rows.reverse()
- if has_adjacent_kings(rows):
+ if self.has_adjacent_kings(rows):
raise ChessException("kings")
- elif not check_kings(rows):
+ elif not self.check_kings(rows):
raise ChessException("kings")
- elif check_pawns(rows):
+ elif self.check_pawns(rows):
raise ChessException("pawns")
self._fen = fen
+ self._white_score = self.get_white_score()
+ self._black_score = self.get_black_score()
+ @staticmethod
+ def has_adjacent_kings(rows):
+ board = []
+
+ for index, row in enumerate(rows):
+ positions = [*(''.join([figure if not figure.isdigit() else " " * int(figure) for figure in row]))]
+ board.append(positions)
+
+ for row_index, row in enumerate(board):
+ for col_index, col in enumerate(row):
+ if col == " ":
+ continue
+ if col == "k":
+ if row_index != 0:
+ if board[row_index - 1][col_index] == "K" or (
+ col_index != 0 and board[row_index - 1][col_index - 1] == "K") or (
+ col_index != 7 and board[row_index - 1][col_index + 1] == "K"):
+ return True
+ if row_index != 7:
+ if board[row_index + 1][col_index] == "K" or (
+ col_index != 0 and board[row_index + 1][col_index - 1] == "K") or (
+ col_index != 7 and board[row_index + 1][col_index + 1] == "K"):
+ return True
+ if col_index != 0:
+ if board[row_index][col_index - 1] == "K":
+ return True
+ if col_index != 7:
+ if board[row_index][col_index + 1] == "K":
+ return True
+ return False
+
+ @staticmethod
+ def check_kings(rows):
+ is_white_king_available = False
+ is_black_king_available = False
+ white_king_count = 0
+ black_king_count = 0
+
+ for index, row in enumerate(rows):
+ if "K" in row:
+ is_white_king_available = True
+ white_king_count += 1
+ if "k" in row:
+ is_black_king_available = True
+ black_king_count += 1
+
+ if not is_black_king_available or not is_white_king_available or white_king_count > 1 or black_king_count > 1:
+ return False
+ return True
+
+ @staticmethod
+ def check_pawns(rows):
+ for row in rows[0] + rows[-1]:
+ if "P" in row or "p" in row:
+ return True
+ return False
+
def get_white_score(self):
white_figures_on_the_board = [figure for figure in self._fen if figure.isupper()]
- white_score = ChessScore(white_figures_on_the_board)
- return int(white_score)
+ return ChessScore(white_figures_on_the_board)
def get_black_score(self):
black_figures_on_the_board = [figure for figure in self._fen if figure.islower()]
- black_score = ChessScore(black_figures_on_the_board)
- return int(black_score)
+ return ChessScore(black_figures_on_the_board)
def white_is_winning(self):
- white_figures_on_the_board = [figure for figure in self._fen if figure.isupper()]
- black_figures_on_the_board = [figure for figure in self._fen if figure.islower()]
- white_score = ChessScore(white_figures_on_the_board)
- black_score = ChessScore(black_figures_on_the_board)
- return white_score > black_score
+ return self._white_score > self._black_score
def black_is_winning(self):
- white_figures_on_the_board = [figure for figure in self._fen if figure.isupper()]
- black_figures_on_the_board = [figure for figure in self._fen if figure.islower()]
- white_score = ChessScore(white_figures_on_the_board)
- black_score = ChessScore(black_figures_on_the_board)
- return white_score < black_score
+ return self._white_score < self._black_score
def is_equal(self):
- white_figures_on_the_board = [figure for figure in self._fen if figure.isupper()]
- black_figures_on_the_board = [figure for figure in self._fen if figure.islower()]
- white_score = ChessScore(white_figures_on_the_board)
- black_score = ChessScore(black_figures_on_the_board)
- return white_score == black_score
+ return self._white_score == self._black_score
def __str__(self):
return self._fen
def __len__(self):
- return len(''.join([figure for figure in self._fen if not figure.isdigit()]).replace('/', ''))
+ return len(''.join([figure for figure in self._fen if figure.isalpha()]))
def __getitem__(self, pos):
letters_to_nums = {
"A": 0,
"B": 1,
"C": 2,
"D": 3,
"E": 4,
"F": 5,
"G": 6,
"H": 7
}
board = []
rows = self._fen.split('/')
rows.reverse()
- for index, line in enumerate(rows):
- positions = [*(''.join([figure if not figure.isdigit() else " " * int(figure) for figure in line]))]
+ for index, row in enumerate(rows):
+ positions = [*(''.join([figure if not figure.isdigit() else " " * int(figure) for figure in row]))]
board.append(positions)
return board[int(pos[1]) - 1][letters_to_nums[pos[0]]] if board[int(pos[1]) - 1][
letters_to_nums[pos[0]]] != " " else None
class ChessScore:
def __init__(self, figures):
self._figures = figures
- def sum_of_scores(self):
+ def __int__(self):
scores = {
"R": 5,
"N": 3,
"B": 3,
"Q": 9,
"K": 4,
"P": 1
}
sum_scores = 0
for figure in self._figures:
sum_scores += scores[figure.upper()]
return sum_scores
-
- __int__ = sum_of_scores
def __lt__(self, second_instance):
return int(self) < int(second_instance)
def __le__(self, second_instance):
return int(self) <= int(second_instance)
def __gt__(self, second_instance):
return int(self) > int(second_instance)
def __ge__(self, second_instance):
return int(self) >= int(second_instance)
def __eq__(self, second_instance):
return int(self) == int(second_instance)
def __ne__(self, second_instance):
return int(self) != int(second_instance)
def __add__(self, second_instance):
return int(self) + int(second_instance)
def __sub__(self, second_instance):
return int(self) - int(second_instance)