Решение на Шахматни фенове от Йоан Бабулков

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

Към профила на Йоан Бабулков

Резултати

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

Код

cols = "ABCDEFGH"
rows = ["1", "2", "3", "4", "5", "6", "7", "8"]
fig_to_score = {"r": 5, "n": 3, "b": 3, "q": 9, "k": 4, "p": 1}
POSITIONS_COUNT = 64
POSITIONS_PER_ROW = 8
def flat_map(lst):
res = []
for x in lst:
res.extend(x)
return res
class ChessException(Exception):
pass
class ChessPosition:
def __init__(self, fen_str):
self.fen = fen_str
fen_str = fen_str.split("/")
self.figures = flat_map([figure for figure in
list(
map(
self.__fill_with_empty_spaces,
fen_str
))])
self.positions = {(col + str(row)): self.figures[POSITIONS_COUNT - POSITIONS_PER_ROW * row + ind]
for row in range(1, 9)
for ind, col in enumerate(cols)
}
kings = [k for k, v in self.positions.items() if v in "Kk"]
if len(kings) != 2 or kings[0] == kings[1] or self.__are_adjacent(kings[0], kings[1]):
raise ChessException("kings")
pawns = [k for k, v in self.positions.items() if v in "Pp"]
if [pawn for pawn in pawns if pawn[1] in ["1", "8"]]:
raise ChessException("pawns")
def __fill_with_empty_spaces(self, row):
return flat_map(["_" for _ in range(int(figure))] if figure.isnumeric() else figure for figure in row)
def __are_adjacent(self, f_figure, s_figure):
f_col, f_row = [i for i in f_figure]
s_col, s_row = [i for i in s_figure]
if cols.index(f_col) == cols.index(s_col):
return rows.index(f_row) in [rows.index(s_row) - 1, rows.index(s_row) + 1]
if rows.index(f_row) == rows.index(s_row):
return cols.index(f_col) in [cols.index(s_col) - 1, cols.index(s_col) + 1]
return rows.index(f_row) in [rows.index(s_row) - 1, rows.index(s_row) + 1] \
and cols.index(f_col) in [cols.index(s_col) - 1, cols.index(s_col) + 1]
def __len__(self):
return len([figure for figure in self.figures if figure != "_"])
def __getitem__(self, item):
return None if self.positions[item] == "_" else self.positions[item]
def __repr__(self):
return self.fen
def get_white_score(self):
return ChessScore([figure for figure in self.figures if figure.isupper()])
def get_black_score(self):
return ChessScore([figure for figure in self.figures if figure.islower()])
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()
class ChessScore:
def __init__(self, figs):
self.score = sum([fig_to_score[fig.lower()] for fig in figs])
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 __le__(self, other):
return self.score <= other.score
def __eq__(self, other):
return self.score == other.score
def __gt__(self, other):
return self.score > other.score
def __ne__(self, other):
return self.score != other.score
def __int__(self):
return self.score

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

.................
----------------------------------------------------------------------
Ran 17 tests in 0.176s

OK

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

Йоан обнови решението на 28.11.2022 22:46 (преди над 1 година)

+from itertools import chain
+
+cols = "ABCDEFGH"
+rows = ["1", "2", "3", "4", "5", "6", "7", "8"]
+fig_to_score = {"r": 5, "n": 3, "b": 3, "q": 9, "k": 4, "p": 1}
+
+
+class ChessException(Exception):
+ def __init__(self, message):
+ self._message = message
+ super().__init__(self._message)
+
+
+def are_adjacent(f_figure, s_figure):
+ f_col, f_row = [i for i in f_figure]
+ s_col, s_row = [i for i in s_figure]
+
+ if cols.index(f_col) == cols.index(s_col):
+ return rows.index(f_row) in [rows.index(s_row) - 1, rows.index(s_row) + 1]
+
+ if rows.index(f_row) == rows.index(s_row):
+ return cols.index(f_col) in [rows.index(s_col) - 1, rows.index(s_col) + 1]
+
+ return rows.index(f_row) in [rows.index(s_row) - 1, rows.index(s_row) + 1] \
+ and cols.index(f_col) in [cols.index(s_col) - 1, cols.index(s_col) + 1]
+
+
+class ChessPosition:
+ def __init__(self, fen_str):
+ self.fen = fen_str
+ fen_str = fen_str.split("/")
+ self.figures = list(chain(*list(figure for figure in
+ list(
+ map(
+ lambda row: list(
+ chain(*list(
+ ["None" for _ in range(int(figure))]

Не знам дали това няма да накара нещо друго да гръмне, но бих използвал None като сингълтън, а не като стринг. Предполагам после правиш операции върху списъка, оачквайки всичко да е стринг, но в такъв случай бих използвал друг символ - например _.

+ if figure.isnumeric()
+ else figure for figure in row))),
+ fen_str
+ )))))
+
+ self.positions = {(col + str(row + 1)): self.figures[56 - 8 * row + ind]
+ for row in range(0, 8)
+ for ind, col in enumerate(cols)
+ }
+
+ kings = [k for k, v in self.positions.items() if v in "Kk"]
+ if len(kings) != 2 or kings[0] == kings[1] or are_adjacent(kings[0], kings[1]):
+ raise ChessException("kings")
+
+ pawns = [k for k, v in self.positions.items() if v in "Pp"]
+ if [pawn for pawn in pawns if pawn[1] in [1, 8]]:
+ raise ChessException("pawns")
+
+ def __len__(self):
+ return len([figure for figure in self.figures if figure != "None"])
+
+ def __getitem__(self, item):
+ return self.positions[item]
+
+ def __repr__(self):
+ return self.fen
+
+ def get_white_score(self):
+ return ChessScore([figure for figure in self.figures if figure.isupper()])
+
+ def get_black_score(self):
+ return ChessScore([figure for figure in self.figures if figure.islower()])
+
+ 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()
+
+
+class ChessScore:
+ def __init__(self, figs):
+ self.score = sum([fig_to_score[fig.lower()] for fig in figs])
+
+ 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 __le__(self, other):
+ return self.score <= other.score
+
+ def __eq__(self, other):
+ return self.score == other.score
+
+ def __gt__(self, other):
+ return self.score > other.score
+
+ def __ne__(self, other):
+ return self.score != other.score
+
+ def __int__(self):
+ return self.score

Йоан обнови решението на 29.11.2022 17:22 (преди над 1 година)

-from itertools import chain
-
cols = "ABCDEFGH"
rows = ["1", "2", "3", "4", "5", "6", "7", "8"]
fig_to_score = {"r": 5, "n": 3, "b": 3, "q": 9, "k": 4, "p": 1}
+POSITIONS_COUNT = 64
+POSITIONS_PER_ROW = 8
-class ChessException(Exception):
- def __init__(self, message):
- self._message = message
- super().__init__(self._message)
+def flat_map(lst):
+ res = []
+ for x in lst:
+ res.extend(x)
+ return res
-def are_adjacent(f_figure, s_figure):
- f_col, f_row = [i for i in f_figure]
- s_col, s_row = [i for i in s_figure]
+class ChessException(Exception):
+ pass
- if cols.index(f_col) == cols.index(s_col):
- return rows.index(f_row) in [rows.index(s_row) - 1, rows.index(s_row) + 1]
- if rows.index(f_row) == rows.index(s_row):
- return cols.index(f_col) in [rows.index(s_col) - 1, rows.index(s_col) + 1]
-
- return rows.index(f_row) in [rows.index(s_row) - 1, rows.index(s_row) + 1] \
- and cols.index(f_col) in [cols.index(s_col) - 1, cols.index(s_col) + 1]
-
-
class ChessPosition:
def __init__(self, fen_str):
self.fen = fen_str
fen_str = fen_str.split("/")
- self.figures = list(chain(*list(figure for figure in
- list(
- map(
- lambda row: list(
- chain(*list(
- ["None" for _ in range(int(figure))]
- if figure.isnumeric()
- else figure for figure in row))),
- fen_str
- )))))
+ self.figures = flat_map([figure for figure in
+ list(
+ map(
+ self.__fill_with_empty_spaces,
+ fen_str
+ ))])
- self.positions = {(col + str(row + 1)): self.figures[56 - 8 * row + ind]
- for row in range(0, 8)
+ self.positions = {(col + str(row)): self.figures[POSITIONS_COUNT - POSITIONS_PER_ROW * row + ind]
+ for row in range(1, 9)
for ind, col in enumerate(cols)
}
kings = [k for k, v in self.positions.items() if v in "Kk"]
- if len(kings) != 2 or kings[0] == kings[1] or are_adjacent(kings[0], kings[1]):
+ if len(kings) != 2 or kings[0] == kings[1] or self.__are_adjacent(kings[0], kings[1]):
raise ChessException("kings")
pawns = [k for k, v in self.positions.items() if v in "Pp"]
- if [pawn for pawn in pawns if pawn[1] in [1, 8]]:
+ if [pawn for pawn in pawns if pawn[1] in ["1", "8"]]:
raise ChessException("pawns")
+ def __fill_with_empty_spaces(self, row):
+ return flat_map(["_" for _ in range(int(figure))] if figure.isnumeric() else figure for figure in row)
+
+ def __are_adjacent(self, f_figure, s_figure):
+ f_col, f_row = [i for i in f_figure]
+ s_col, s_row = [i for i in s_figure]
+
+ if cols.index(f_col) == cols.index(s_col):
+ return rows.index(f_row) in [rows.index(s_row) - 1, rows.index(s_row) + 1]
+
+ if rows.index(f_row) == rows.index(s_row):
+ return cols.index(f_col) in [cols.index(s_col) - 1, cols.index(s_col) + 1]
+
+ return rows.index(f_row) in [rows.index(s_row) - 1, rows.index(s_row) + 1] \
+ and cols.index(f_col) in [cols.index(s_col) - 1, cols.index(s_col) + 1]
+
def __len__(self):
- return len([figure for figure in self.figures if figure != "None"])
+ return len([figure for figure in self.figures if figure != "_"])
def __getitem__(self, item):
- return self.positions[item]
+ return None if self.positions[item] == "_" else self.positions[item]
def __repr__(self):
return self.fen
def get_white_score(self):
return ChessScore([figure for figure in self.figures if figure.isupper()])
def get_black_score(self):
return ChessScore([figure for figure in self.figures if figure.islower()])
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()
class ChessScore:
def __init__(self, figs):
self.score = sum([fig_to_score[fig.lower()] for fig in figs])
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 __le__(self, other):
return self.score <= other.score
def __eq__(self, other):
return self.score == other.score
def __gt__(self, other):
return self.score > other.score
def __ne__(self, other):
return self.score != other.score
def __int__(self):
- return self.score
+ return self.score