Решение на Шахматни фенове от Йоанна Кръстева

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

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

Резултати

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

Код

import re
chess_positions = ["A8", "B8", "C8", "D8", "E8", "F8", "G8", "H8",
"A7", "B7", "C7", "D7", "E7", "F7", "G7", "H7",
"A6", "B6", "C6", "D6", "E6", "F6", "G6", "H6",
"A5", "B5", "C5", "D5", "E5", "F5", "G5", "H5",
"A4", "B4", "C4", "D4", "E4", "F4", "G4", "H4",
"A3", "B3", "C3", "D3", "E3", "F3", "G3", "H3",
"A2", "B2", "C2", "D2", "E2", "F2", "G2", "H2",
"A1", "B1", "C1", "D1", "E1", "F1", "G1", "H1"
]
columns_as_letters = {
1: "A",
2: "B",
3: "C",
4: "D",
5: "E",
6: "F",
7: "G",
8: "H",
}
rows_in_chess = {
0: 8,
1: 7,
2: 6,
3: 5,
4: 4,
5: 3,
6: 2,
7: 1
}
figure_scores = {
"r": 5,
"n": 3,
"b": 3,
"q": 9,
"k": 4,
"p": 1
}
class ChessException(Exception):
pass
def generator(king):
all_possible_neighbors = [[king[0] - 1, king[1] - 1], [king[0] - 1, king[1]],
[king[0] - 1, king[1] + 1], [king[0], king[1] + 1],
[king[0] + 1, king[1] + 1], [king[0] + 1, king[1]],
[king[0] + 1, king[1] - 1], [king[0], king[1] - 1]]
return all_possible_neighbors
def assign_fen_to_dict(fen, chess_dictionary):
columns = fen.split('/')
united = ''.join(columns)
dict_index = 0
for index, char in enumerate(united):
if char.isalpha():
chess_dictionary[chess_positions[dict_index]] = char
dict_index += 1
elif char.isdigit():
for i in range(int(char)):
chess_dictionary[chess_positions[dict_index + i]] = None
dict_index += int(char)
def check_kings_neighbors(sorted_kings):
for king in sorted_kings:
for neighbour in generator(king):
if neighbour in sorted_kings:
raise ChessException("kings")
def validate_fen(fen_match):
if fen_match:
fen_list = fen_match.groups()
fen = fen_list[0].split("/")
pawns_error = False
number_of_white_kings, number_of_black_kings = 0, 0
kings_data = []
if len(fen) != 8:
raise ChessException("Eight (8) rows expected in position part of fen: {0}".format(repr(fen)))
for row_index, row in enumerate(fen):
columns = 0
prev_digit, prev_figure = False, False
for char in row:
if char.isdigit():
if prev_digit:
raise ChessException("There are two subsequent digits"
" in position part of fen: {0}".format(repr(fen)))
columns += int(char)
prev_digit = True
prev_figure = False
elif char.isalpha():
columns += 1
prev_digit = False
prev_figure = True
if char == "k":
number_of_black_kings += 1
kings_data.append([rows_in_chess[row_index], columns])
elif char == "K":
number_of_white_kings += 1
kings_data.append([rows_in_chess[row_index], columns])
elif (char == "p" or char == "P") and (row_index == 0 or row_index == 7):
pawns_error = True
else:
raise ChessException("Invalid character in position: {0}".format(repr(fen)))
if columns != 8:
raise ChessException("Eight(8) columns expected per row "
"in position part of fen: {0}".format(repr(fen)))
sorted_kings = sorted(kings_data, key=lambda element: element[0])
check_kings_neighbors(sorted_kings)
if number_of_white_kings > 1 or number_of_white_kings < 1 \
or number_of_black_kings > 1 or number_of_black_kings < 1:
raise ChessException("kings")
elif pawns_error:
raise ChessException("pawns")
else:
raise ChessException(
"Passed FEN does NOT match this example: pppppppp/pppppppp/8/8/8/8/PPPPPPPP/pppppppp")
class ChessPosition:
def __init__(self, fen_definition: str): # create modules for each functionality
self.fen_definition = fen_definition
fen_match = re.match('^(((?:[rnbqkpRNBQKP1-8]+/){7})[rnbqkpRNBQKP1-8]+)$', fen_definition)
self.chess_dictionary = {}
assign_fen_to_dict(fen_definition, self.chess_dictionary)
validate_fen(fen_match)
def get_white_score(self):
white_figures = []
for figure in self.fen_definition:
if figure in ["P", "N", "B", "R", "Q", "K"]:
white_figures.append(figure.lower())
return ChessScore(white_figures)
def get_black_score(self):
black_figures = []
for figure in self.fen_definition:
if figure in ["p", "n", "b", "r", "q", "k"]:
black_figures.append(figure)
return ChessScore(black_figures)
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_white_score() == self.get_black_score()
def __len__(self):
length = 0
for char in self.fen_definition:
if char.isalpha():
length += 1
return length
def __repr__(self):
return self.fen_definition
def __str__(self):
return self.fen_definition
def __getitem__(self, items: str):

Ако предварително си парснеш позицията в някакъв речник, ще си спестиш всички главоболия около тези цикли с ръчно инкрементиране на индекси. Много по-лесно би станало.

Е, да, определено кодът тук е по-добре. Ако дефинираш речника динамично, ще е още по-добре, защото сега има шанс за грешка, но определено сега е по-добре.

if items in self.chess_dictionary:
return self.chess_dictionary[items]
else:
raise ChessException("Invalid column or row!")
class ChessScore:
def __init__(self, figures):
score = 0
for figure in figures:
if figure not in ["p", "n", "b", "r", "q", "k"]:
raise ChessException("Invalid figure passed when calculating ChessScore")
self.figures = figures
for figure in self.figures:
score += figure_scores[figure.lower()]
self.score = score
def __int__(self):
return self.score
def __lt__(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 __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 __le__(self, other):
return self.score <= other.score
def __repr__(self):
return self.score
def __str__(self):
return f"{self.score}"

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

.................
----------------------------------------------------------------------
Ran 17 tests in 0.177s

OK

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

Йоанна обнови решението на 27.11.2022 23:41 (преди почти 2 години)

+import re
+import unittest
+
+
+columns_as_letters = {
+ 1: "A",
+ 2: "B",
+ 3: "C",
+ 4: "D",
+ 5: "E",
+ 6: "F",
+ 7: "G",
+ 8: "H",
+}
+
+rows_in_chess = {
+ 0: 8,
+ 1: 7,
+ 2: 6,
+ 3: 5,
+ 4: 4,
+ 5: 3,
+ 6: 2,
+ 7: 1
+}
+
+figure_scores = {
+ "r": 5,
+ "n": 3,
+ "b": 3,
+ "q": 9,
+ "k": 4,
+ "p": 1
+}
+
+
+def generator(king):
+ all_possible_neighbors = [[king[0] - 1, king[1] - 1], [king[0] - 1, king[1]],
+ [king[0] - 1, king[1] + 1], [king[0], king[1] + 1],
+ [king[0] + 1, king[1] + 1], [king[0] + 1, king[1]],
+ [king[0] + 1, king[1] - 1], [king[0], king[1] - 1]]
+ return all_possible_neighbors
+
+
+class ChessException(Exception):
+ def __init__(self, fen_string):
+ self.fen_string = fen_string
+
+
+class ChessPosition:
+ def __init__(self, fen_definition: str):
+ self.fen_definition = fen_definition
+ fen_match = re.match('\s*^(((?:[rnbqkpRNBQKP1-8]+/){7})[rnbqkpRNBQKP1-8]+)$', fen_definition)
+
+ if fen_match:
+ fen_list = fen_match.groups()
+ fen = fen_list[0].split("/")
+ pawns_error = False
+ number_of_white_kings, number_of_black_kings = 0, 0
+ kings_data = []
+ if len(fen) != 8:
+ raise ChessException("Eight (8) rows expected in position part of fen: {0}".format(repr(fen)))
+ for row_index, row in enumerate(fen):
+ columns = 0
+ prev_digit, prev_figure = False, False
+ for char in row:
+ if char in ["1", "2", "3", "4", "5", "6", "7", "8"]:
+ if prev_digit:
+ raise ChessException("There are two subsequent digits"
+ " in position part of fen: {0}".format(repr(fen)))
+ columns += int(char)
+ prev_digit = True
+ prev_figure = False
+ elif char in ["p", "n", "b", "r", "q", "k", "P", "N", "B", "R", "Q", "K"]:
+ columns += 1
+ prev_digit = False
+ prev_figure = True
+ if char == "k":
+ number_of_black_kings += 1
+ kings_data.append([rows_in_chess[row_index], columns])
+ elif char == "K":
+ number_of_white_kings += 1
+ kings_data.append([rows_in_chess[row_index], columns])
+ elif (char == "p" or char == "P") and (row_index == 0 or row_index == 7):
+ pawns_error = True
+
+ else:
+ raise ChessException("Invalid character in position: {0}".format(repr(fen)))
+
+ if columns != 8:
+ raise ChessException("Eight(8) columns expected per row "
+ "in position part of fen: {0}".format(repr(fen)))
+
+ sorted_kings = sorted(kings_data, key=lambda element: element[0])
+ for king in sorted_kings:
+ for neighbour in generator(king):
+ if neighbour in sorted_kings:
+ raise ChessException("kings")
+
+ if number_of_white_kings > 1 or number_of_white_kings < 1 \
+ or number_of_black_kings > 1 or number_of_black_kings < 1:
+ raise ChessException("kings")
+ elif pawns_error:
+ raise ChessException("pawns")
+
+ else:
+ raise ChessException(
+ "Passed FEN does NOT match this example: pppppppp/pppppppp/8/8/8/8/PPPPPPPP/pppppppp")
+
+ def get_white_score(self):
+ white_figures = []
+ for figure in self.fen_definition:
+ if figure in ["P", "N", "B", "R", "Q", "K"]:
+ white_figures.append(figure)
+ return ChessScore(white_figures)
+
+ def get_black_score(self):
+ black_figures = []
+ for figure in self.fen_definition:
+ if figure in ["p", "n", "b", "r", "q", "k"]:
+ black_figures.append(figure)
+ return ChessScore(black_figures)
+
+ 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_white_score() == self.get_black_score()
+
+ def __len__(self):
+ length = 0
+ for char in self.fen_definition:
+ if char in ["p", "n", "b", "r", "q", "k", "P", "N", "B", "R", "Q", "K"]:
+ length += 1
+ return length
+
+ def __repr__(self):
+ return f"{self.fen_definition}"
+
+ def __str__(self):
+ return f"FEN: {self.fen_definition}"
+
+ def __getitem__(self, items: str):
+ line = 8
+ index = 0
+ column_index = 0
+ for char in self.fen_definition:
+ if char == '/':
+ line -= 1
+ if line != int(items[1]):
+ index += 1
+ elif line == int(items[1]):
+ if line != 8:
+ index += 1
+ for i, letter in enumerate(self.fen_definition[index:]):
+ if letter.isdigit():
+ column_index += int(letter)
+ else:
+ column_index += 1
+ if column_index < 8 and columns_as_letters[column_index] == items[0]:
+ return letter
+ return None
+
+
+class ChessScore:
+ score = 0
+
+ def __init__(self, figures):
+ for figure in figures:
+ if figure not in ["p", "n", "b", "r", "q", "k", "P", "N", "B", "R", "Q", "K"]:
+ raise ChessException("Invalid figure passed when calculating ChessScore")
+ self.figures = figures
+ for figure in self.figures:
+ self.score += figure_scores[figure.lower()]
+
+ def __int__(self):
+ return self.score
+
+ def __lt__(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 __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 __le__(self, other):
+ return self.score <= other.score
+
+ def __repr__(self):
+ return self.score
+
+ def __str__(self):
+ return f"{self.score}"
+
+"""
+try:
+ ChessPosition('bbbbbbbb/pkpppKpp/PPpPPPPP/4p3/pPPPPPPP/PPPPPPPP/PPPPPPPP/RNBQQBNR')
+except ChessException as ce:
+ print(ce)
+
+some_pieces2 = ['k', 'r', 'q']
+score2 = ChessScore(some_pieces2)
+print(score2)
+
+
+class TestChess(unittest.TestCase):
+
+ def test_access_example1(self):
+ chess_position = ChessPosition('bbbbbbbb/pkpppKpp/PPpPPPPP/4p3/pPPPPPPP/PPPPPPPP/PPPPPPPP/RNBQQBNR')
+ self.assertEqual(chess_position['E2'], 'P')
+
+ def test_access_example2(self):
+ chess_position = ChessPosition('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR')
+ self.assertEqual(chess_position['D8'], 'q')
+
+ def test_access_example3(self):
+ chess_position = ChessPosition('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR')
+ self.assertEqual(chess_position['E1'], 'K')
+
+ def test_access_example4(self):
+ chess_position = ChessPosition('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR')
+ self.assertEqual(chess_position['I1'], None)
+
+ def test_access_example5(self):
+ chess_position = ChessPosition('rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR')
+ self.assertEqual(chess_position['E4'], 'P')
+
+ def test_calculating_score_example1(self):
+ some_pieces1 = ['r', 'b']
+ score1 = ChessScore(some_pieces1)
+ self.assertEqual(int(score1), 8)
+
+ def test_calculating_score_example2(self):
+ some_pieces = ['k', 'r', 'q']
+ score = ChessScore(some_pieces)
+ self.assertEqual(int(score), 18)
+
+ def test_len_fen_example1(self):
+ chess_position = ChessPosition('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR')
+ self.assertEqual(len(chess_position), 32)
+
+ def test_len_fen_example2(self):
+ chess_position = ChessPosition('rnbqkbnr/pppppppp/4P3/8/8/8/PPPPPPPP/RNBQKBNR')
+ self.assertEqual(len(chess_position), 33)
+
+ def test_lt_operator_example1(self):
+ some_pieces3 = ['k', 'r', 'q']
+ score3 = ChessScore(some_pieces3)
+ some_pieces4 = ['k', 'r', 'q', 'q', 'p']
+ score4 = ChessScore(some_pieces4)
+ self.assertEqual(score3 < score4, True)
+
+ def test_gt_operator_example1(self):
+ some_pieces5 = ['k', 'r', 'q', 'q', 'q', 'q', 'q']
+ score5 = ChessScore(some_pieces5)
+ some_pieces6 = ['k', 'r', 'q', 'q', 'p']
+ score6 = ChessScore(some_pieces6)
+ self.assertEqual(score5 > score6, True)
+
+ def test_ne_operator_example1(self):
+ some_pieces7 = ['k', 'r', 'q', 'q', 'q', 'q', 'q']
+ score7 = ChessScore(some_pieces7)
+ some_pieces8 = ['k', 'r', 'q', 'q', 'p']
+ score8 = ChessScore(some_pieces8)
+ self.assertEqual(score7 != score8, True)
+
+ def test_eq_operator_example1(self):
+ some_pieces9 = ['k', 'r', 'q', 'q', 'q', 'q', 'q']
+ score9 = ChessScore(some_pieces9)
+ some_pieces10 = ['k', 'r', 'q', 'q', 'p']
+ score10 = ChessScore(some_pieces10)
+ self.assertEqual(score9 == score10, False)
+
+ def test_ge_operator_example1(self):
+ some_pieces11 = ['k', 'r', 'q', 'q', 'p']
+ score11 = ChessScore(some_pieces11)
+ some_pieces12 = ['k', 'r', 'q', 'q', 'p']
+ score12 = ChessScore(some_pieces12)
+ self.assertEqual(score11 >= score12, True)
+
+ def test_add_operator_example1(self):
+ some_pieces13 = ['k', 'r', 'q', 'q', 'p']
+ score13 = ChessScore(some_pieces13)
+ some_pieces14 = ['k', 'r', 'q', 'q', 'p']
+ score14 = ChessScore(some_pieces14)
+ self.assertEqual(score13 + score14, 56)
+
+ def test_sub_operator_example1(self):
+ some_pieces15 = ['k', 'r', 'q', 'q', 'p']
+ score15 = ChessScore(some_pieces15)
+ some_pieces16 = ['k', 'r', 'q', 'q', 'p']
+ score16 = ChessScore(some_pieces16)
+ self.assertEqual(score15 - score16, 0)
+
+ def test_get_white_score_example1(self):
+ chess_position = ChessPosition('bbbbbbbb/pPpkpPpp/QBpRNKPP/4p3/pppppppp/pppppppp/pppppppp/rrrrrrrr')
+ scores = chess_position.get_white_score()
+ self.assertEqual(int(scores), 28)
+
+ def test_get_black_score_example1(self):
+ chess_position = ChessPosition('bbbbbbbb/pPpkpPpp/QBpRNKPP/4p3/pppppppp/pppppppp/pppppppp/rrrrrrrr')
+ scores = chess_position.get_black_score()
+ self.assertEqual(int(scores), 99)
+
+ def test_white_is_winning_example1(self):
+ chess_position = ChessPosition('bbbbbbbb/pPpkpPpp/QBpRNKPP/4p3/pppppppp/pppppppp/pppppppp/rrrrrrrr')
+ self.assertEqual(chess_position.white_is_winning(), False)
+
+ def test_black_is_winning_example1(self):
+ chess_position = ChessPosition('bbbbbbbb/pPpkpPpp/QBpRNKPP/4p3/pppppppp/pppppppp/pppppppp/rrrrrrrr')
+ self.assertEqual(chess_position.black_is_winning(), True)
+
+ def test_is_equal_example1(self):
+ chess_position = ChessPosition('bbbbbbbb/pPpkpPpp/QBpRNKPP/4p3/pppppppp/pppppppp/pppppppp/rrrrrrrr')
+ self.assertEqual(chess_position.is_equal(), False)
+
+
+if __name__ == '__main__':
+ unittest.main()
+"""

Йоанна обнови решението на 27.11.2022 23:44 (преди почти 2 години)

import re
-import unittest
columns_as_letters = {
1: "A",
2: "B",
3: "C",
4: "D",
5: "E",
6: "F",
7: "G",
8: "H",
}
rows_in_chess = {
0: 8,
1: 7,
2: 6,
3: 5,
4: 4,
5: 3,
6: 2,
7: 1
}
figure_scores = {
"r": 5,
"n": 3,
"b": 3,
"q": 9,
"k": 4,
"p": 1
}
def generator(king):
all_possible_neighbors = [[king[0] - 1, king[1] - 1], [king[0] - 1, king[1]],
[king[0] - 1, king[1] + 1], [king[0], king[1] + 1],
[king[0] + 1, king[1] + 1], [king[0] + 1, king[1]],
[king[0] + 1, king[1] - 1], [king[0], king[1] - 1]]
return all_possible_neighbors
class ChessException(Exception):
def __init__(self, fen_string):
self.fen_string = fen_string
class ChessPosition:
def __init__(self, fen_definition: str):
self.fen_definition = fen_definition
fen_match = re.match('\s*^(((?:[rnbqkpRNBQKP1-8]+/){7})[rnbqkpRNBQKP1-8]+)$', fen_definition)
if fen_match:
fen_list = fen_match.groups()
fen = fen_list[0].split("/")
pawns_error = False
number_of_white_kings, number_of_black_kings = 0, 0
kings_data = []
if len(fen) != 8:
raise ChessException("Eight (8) rows expected in position part of fen: {0}".format(repr(fen)))
for row_index, row in enumerate(fen):
columns = 0
prev_digit, prev_figure = False, False
for char in row:
if char in ["1", "2", "3", "4", "5", "6", "7", "8"]:
if prev_digit:
raise ChessException("There are two subsequent digits"
" in position part of fen: {0}".format(repr(fen)))
columns += int(char)
prev_digit = True
prev_figure = False
elif char in ["p", "n", "b", "r", "q", "k", "P", "N", "B", "R", "Q", "K"]:
columns += 1
prev_digit = False
prev_figure = True
if char == "k":
number_of_black_kings += 1
kings_data.append([rows_in_chess[row_index], columns])
elif char == "K":
number_of_white_kings += 1
kings_data.append([rows_in_chess[row_index], columns])
elif (char == "p" or char == "P") and (row_index == 0 or row_index == 7):
pawns_error = True
else:
raise ChessException("Invalid character in position: {0}".format(repr(fen)))
if columns != 8:
raise ChessException("Eight(8) columns expected per row "
"in position part of fen: {0}".format(repr(fen)))
sorted_kings = sorted(kings_data, key=lambda element: element[0])
for king in sorted_kings:
for neighbour in generator(king):
if neighbour in sorted_kings:
raise ChessException("kings")
if number_of_white_kings > 1 or number_of_white_kings < 1 \
or number_of_black_kings > 1 or number_of_black_kings < 1:
raise ChessException("kings")
elif pawns_error:
raise ChessException("pawns")
else:
raise ChessException(
"Passed FEN does NOT match this example: pppppppp/pppppppp/8/8/8/8/PPPPPPPP/pppppppp")
def get_white_score(self):
white_figures = []
for figure in self.fen_definition:
if figure in ["P", "N", "B", "R", "Q", "K"]:
white_figures.append(figure)
return ChessScore(white_figures)
def get_black_score(self):
black_figures = []
for figure in self.fen_definition:
if figure in ["p", "n", "b", "r", "q", "k"]:
black_figures.append(figure)
return ChessScore(black_figures)
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_white_score() == self.get_black_score()
def __len__(self):
length = 0
for char in self.fen_definition:
if char in ["p", "n", "b", "r", "q", "k", "P", "N", "B", "R", "Q", "K"]:
length += 1
return length
def __repr__(self):
return f"{self.fen_definition}"
def __str__(self):
return f"FEN: {self.fen_definition}"
def __getitem__(self, items: str):
line = 8
index = 0
column_index = 0
for char in self.fen_definition:
if char == '/':
line -= 1
if line != int(items[1]):
index += 1
elif line == int(items[1]):
if line != 8:
index += 1
for i, letter in enumerate(self.fen_definition[index:]):
if letter.isdigit():
column_index += int(letter)
else:
column_index += 1
if column_index < 8 and columns_as_letters[column_index] == items[0]:
return letter
return None
class ChessScore:
score = 0
def __init__(self, figures):
for figure in figures:
if figure not in ["p", "n", "b", "r", "q", "k", "P", "N", "B", "R", "Q", "K"]:
raise ChessException("Invalid figure passed when calculating ChessScore")
self.figures = figures
for figure in self.figures:
self.score += figure_scores[figure.lower()]
def __int__(self):
return self.score
def __lt__(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 __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 __le__(self, other):
return self.score <= other.score
def __repr__(self):
return self.score
def __str__(self):
return f"{self.score}"
-"""
-try:
- ChessPosition('bbbbbbbb/pkpppKpp/PPpPPPPP/4p3/pPPPPPPP/PPPPPPPP/PPPPPPPP/RNBQQBNR')
-except ChessException as ce:
- print(ce)
-
-some_pieces2 = ['k', 'r', 'q']
-score2 = ChessScore(some_pieces2)
-print(score2)
-
-
-class TestChess(unittest.TestCase):
-
- def test_access_example1(self):
- chess_position = ChessPosition('bbbbbbbb/pkpppKpp/PPpPPPPP/4p3/pPPPPPPP/PPPPPPPP/PPPPPPPP/RNBQQBNR')
- self.assertEqual(chess_position['E2'], 'P')
-
- def test_access_example2(self):
- chess_position = ChessPosition('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR')
- self.assertEqual(chess_position['D8'], 'q')
-
- def test_access_example3(self):
- chess_position = ChessPosition('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR')
- self.assertEqual(chess_position['E1'], 'K')
-
- def test_access_example4(self):
- chess_position = ChessPosition('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR')
- self.assertEqual(chess_position['I1'], None)
-
- def test_access_example5(self):
- chess_position = ChessPosition('rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR')
- self.assertEqual(chess_position['E4'], 'P')
-
- def test_calculating_score_example1(self):
- some_pieces1 = ['r', 'b']
- score1 = ChessScore(some_pieces1)
- self.assertEqual(int(score1), 8)
-
- def test_calculating_score_example2(self):
- some_pieces = ['k', 'r', 'q']
- score = ChessScore(some_pieces)
- self.assertEqual(int(score), 18)
-
- def test_len_fen_example1(self):
- chess_position = ChessPosition('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR')
- self.assertEqual(len(chess_position), 32)
-
- def test_len_fen_example2(self):
- chess_position = ChessPosition('rnbqkbnr/pppppppp/4P3/8/8/8/PPPPPPPP/RNBQKBNR')
- self.assertEqual(len(chess_position), 33)
-
- def test_lt_operator_example1(self):
- some_pieces3 = ['k', 'r', 'q']
- score3 = ChessScore(some_pieces3)
- some_pieces4 = ['k', 'r', 'q', 'q', 'p']
- score4 = ChessScore(some_pieces4)
- self.assertEqual(score3 < score4, True)
-
- def test_gt_operator_example1(self):
- some_pieces5 = ['k', 'r', 'q', 'q', 'q', 'q', 'q']
- score5 = ChessScore(some_pieces5)
- some_pieces6 = ['k', 'r', 'q', 'q', 'p']
- score6 = ChessScore(some_pieces6)
- self.assertEqual(score5 > score6, True)
-
- def test_ne_operator_example1(self):
- some_pieces7 = ['k', 'r', 'q', 'q', 'q', 'q', 'q']
- score7 = ChessScore(some_pieces7)
- some_pieces8 = ['k', 'r', 'q', 'q', 'p']
- score8 = ChessScore(some_pieces8)
- self.assertEqual(score7 != score8, True)
-
- def test_eq_operator_example1(self):
- some_pieces9 = ['k', 'r', 'q', 'q', 'q', 'q', 'q']
- score9 = ChessScore(some_pieces9)
- some_pieces10 = ['k', 'r', 'q', 'q', 'p']
- score10 = ChessScore(some_pieces10)
- self.assertEqual(score9 == score10, False)
-
- def test_ge_operator_example1(self):
- some_pieces11 = ['k', 'r', 'q', 'q', 'p']
- score11 = ChessScore(some_pieces11)
- some_pieces12 = ['k', 'r', 'q', 'q', 'p']
- score12 = ChessScore(some_pieces12)
- self.assertEqual(score11 >= score12, True)
-
- def test_add_operator_example1(self):
- some_pieces13 = ['k', 'r', 'q', 'q', 'p']
- score13 = ChessScore(some_pieces13)
- some_pieces14 = ['k', 'r', 'q', 'q', 'p']
- score14 = ChessScore(some_pieces14)
- self.assertEqual(score13 + score14, 56)
-
- def test_sub_operator_example1(self):
- some_pieces15 = ['k', 'r', 'q', 'q', 'p']
- score15 = ChessScore(some_pieces15)
- some_pieces16 = ['k', 'r', 'q', 'q', 'p']
- score16 = ChessScore(some_pieces16)
- self.assertEqual(score15 - score16, 0)
-
- def test_get_white_score_example1(self):
- chess_position = ChessPosition('bbbbbbbb/pPpkpPpp/QBpRNKPP/4p3/pppppppp/pppppppp/pppppppp/rrrrrrrr')
- scores = chess_position.get_white_score()
- self.assertEqual(int(scores), 28)
-
- def test_get_black_score_example1(self):
- chess_position = ChessPosition('bbbbbbbb/pPpkpPpp/QBpRNKPP/4p3/pppppppp/pppppppp/pppppppp/rrrrrrrr')
- scores = chess_position.get_black_score()
- self.assertEqual(int(scores), 99)
-
- def test_white_is_winning_example1(self):
- chess_position = ChessPosition('bbbbbbbb/pPpkpPpp/QBpRNKPP/4p3/pppppppp/pppppppp/pppppppp/rrrrrrrr')
- self.assertEqual(chess_position.white_is_winning(), False)
-
- def test_black_is_winning_example1(self):
- chess_position = ChessPosition('bbbbbbbb/pPpkpPpp/QBpRNKPP/4p3/pppppppp/pppppppp/pppppppp/rrrrrrrr')
- self.assertEqual(chess_position.black_is_winning(), True)
-
- def test_is_equal_example1(self):
- chess_position = ChessPosition('bbbbbbbb/pPpkpPpp/QBpRNKPP/4p3/pppppppp/pppppppp/pppppppp/rrrrrrrr')
- self.assertEqual(chess_position.is_equal(), False)
-
-
-if __name__ == '__main__':
- unittest.main()
-"""

Йоанна обнови решението на 28.11.2022 00:13 (преди почти 2 години)

import re
columns_as_letters = {
1: "A",
2: "B",
3: "C",
4: "D",
5: "E",
6: "F",
7: "G",
8: "H",
}
rows_in_chess = {
0: 8,
1: 7,
2: 6,
3: 5,
4: 4,
5: 3,
6: 2,
7: 1
}
figure_scores = {
"r": 5,
"n": 3,
"b": 3,
"q": 9,
"k": 4,
"p": 1
}
def generator(king):
all_possible_neighbors = [[king[0] - 1, king[1] - 1], [king[0] - 1, king[1]],
[king[0] - 1, king[1] + 1], [king[0], king[1] + 1],
[king[0] + 1, king[1] + 1], [king[0] + 1, king[1]],
[king[0] + 1, king[1] - 1], [king[0], king[1] - 1]]
return all_possible_neighbors
class ChessException(Exception):
def __init__(self, fen_string):
self.fen_string = fen_string
class ChessPosition:
def __init__(self, fen_definition: str):

Доста логика в инициализатора - парсване, валидиране...
Бих те посъветвал малко да го разделиш на парчета в отделни методи, за да се поддържа по-лесно. Дори това да е с цената да циклиш повече пъти, качеството на кода ще се повиши.

self.fen_definition = fen_definition
fen_match = re.match('\s*^(((?:[rnbqkpRNBQKP1-8]+/){7})[rnbqkpRNBQKP1-8]+)$', fen_definition)
if fen_match:
fen_list = fen_match.groups()

Ако мачваш само един група, малко е безсмислено да използваш групи. Реално regex-а го позлваш само за да валидираш, че инпута съдържа само валидни символи в точно 8 реда. НО, тренираш regex, така че няма да се оплаквам.

fen = fen_list[0].split("/")
pawns_error = False
number_of_white_kings, number_of_black_kings = 0, 0
kings_data = []
if len(fen) != 8:
raise ChessException("Eight (8) rows expected in position part of fen: {0}".format(repr(fen)))
for row_index, row in enumerate(fen):
columns = 0
prev_digit, prev_figure = False, False
for char in row:
if char in ["1", "2", "3", "4", "5", "6", "7", "8"]:
if prev_digit:
raise ChessException("There are two subsequent digits"
" in position part of fen: {0}".format(repr(fen)))
columns += int(char)
prev_digit = True
prev_figure = False
elif char in ["p", "n", "b", "r", "q", "k", "P", "N", "B", "R", "Q", "K"]:
columns += 1
prev_digit = False
prev_figure = True
if char == "k":
number_of_black_kings += 1
kings_data.append([rows_in_chess[row_index], columns])
elif char == "K":
number_of_white_kings += 1
kings_data.append([rows_in_chess[row_index], columns])
elif (char == "p" or char == "P") and (row_index == 0 or row_index == 7):
pawns_error = True
else:
raise ChessException("Invalid character in position: {0}".format(repr(fen)))
if columns != 8:
raise ChessException("Eight(8) columns expected per row "
"in position part of fen: {0}".format(repr(fen)))
sorted_kings = sorted(kings_data, key=lambda element: element[0])
for king in sorted_kings:
for neighbour in generator(king):
if neighbour in sorted_kings:
raise ChessException("kings")
if number_of_white_kings > 1 or number_of_white_kings < 1 \
or number_of_black_kings > 1 or number_of_black_kings < 1:
raise ChessException("kings")
elif pawns_error:
raise ChessException("pawns")
else:
raise ChessException(
"Passed FEN does NOT match this example: pppppppp/pppppppp/8/8/8/8/PPPPPPPP/pppppppp")
def get_white_score(self):
white_figures = []
for figure in self.fen_definition:
if figure in ["P", "N", "B", "R", "Q", "K"]:
- white_figures.append(figure)
+ white_figures.append(figure.lower())
return ChessScore(white_figures)
def get_black_score(self):
black_figures = []
for figure in self.fen_definition:
if figure in ["p", "n", "b", "r", "q", "k"]:
black_figures.append(figure)
return ChessScore(black_figures)
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_white_score() == self.get_black_score()
def __len__(self):
length = 0
for char in self.fen_definition:
if char in ["p", "n", "b", "r", "q", "k", "P", "N", "B", "R", "Q", "K"]:
length += 1
return length
def __repr__(self):
return f"{self.fen_definition}"
def __str__(self):
return f"FEN: {self.fen_definition}"
def __getitem__(self, items: str):

Ако предварително си парснеш позицията в някакъв речник, ще си спестиш всички главоболия около тези цикли с ръчно инкрементиране на индекси. Много по-лесно би станало.

line = 8
index = 0
column_index = 0
for char in self.fen_definition:
if char == '/':
line -= 1
if line != int(items[1]):
index += 1
elif line == int(items[1]):
if line != 8:
index += 1
for i, letter in enumerate(self.fen_definition[index:]):
if letter.isdigit():
column_index += int(letter)
else:
column_index += 1
if column_index < 8 and columns_as_letters[column_index] == items[0]:
return letter
return None
class ChessScore:
score = 0

Това е атрибут на класа, а ти ще го използваш като атрибут на иснтанцията. За да работи правилно, трябва да го инициализираш в __init__. Иначе всички инстанции на класа ще го споделят.

def __init__(self, figures):
for figure in figures:
- if figure not in ["p", "n", "b", "r", "q", "k", "P", "N", "B", "R", "Q", "K"]:
+ if figure not in ["p", "n", "b", "r", "q", "k"]:
raise ChessException("Invalid figure passed when calculating ChessScore")
self.figures = figures
for figure in self.figures:
self.score += figure_scores[figure.lower()]
def __int__(self):
return self.score
def __lt__(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 __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 __le__(self, other):
return self.score <= other.score
def __repr__(self):
return self.score
def __str__(self):
return f"{self.score}"
-

Йоанна обнови решението на 29.11.2022 02:17 (преди почти 2 години)

import re
+chess_positions = ["A8", "B8", "C8", "D8", "E8", "F8", "G8", "H8",
+ "A7", "B7", "C7", "D7", "E7", "F7", "G7", "H7",
+ "A6", "B6", "C6", "D6", "E6", "F6", "G6", "H6",
+ "A5", "B5", "C5", "D5", "E5", "F5", "G5", "H5",
+ "A4", "B4", "C4", "D4", "E4", "F4", "G4", "H4",
+ "A3", "B3", "C3", "D3", "E3", "F3", "G3", "H3",
+ "A2", "B2", "C2", "D2", "E2", "F2", "G2", "H2",
+ "A1", "B1", "C1", "D1", "E1", "F1", "G1", "H1"
+ ]
columns_as_letters = {
1: "A",
2: "B",
3: "C",
4: "D",
5: "E",
6: "F",
7: "G",
8: "H",
}
rows_in_chess = {
0: 8,
1: 7,
2: 6,
3: 5,
4: 4,
5: 3,
6: 2,
7: 1
}
figure_scores = {
"r": 5,
"n": 3,
"b": 3,
"q": 9,
"k": 4,
"p": 1
}
+chess_dictionary = {}
+
+class ChessException(Exception):
+ pass
+
+
def generator(king):
all_possible_neighbors = [[king[0] - 1, king[1] - 1], [king[0] - 1, king[1]],
[king[0] - 1, king[1] + 1], [king[0], king[1] + 1],
[king[0] + 1, king[1] + 1], [king[0] + 1, king[1]],
[king[0] + 1, king[1] - 1], [king[0], king[1] - 1]]
return all_possible_neighbors
-class ChessException(Exception):
- def __init__(self, fen_string):
- self.fen_string = fen_string
+def assign_fen_to_dict(fen):
+ columns = fen.split('/')
+ united = ''.join(columns)
+ dict_index = 0
+ for index, char in enumerate(united):
+ if char.isalpha():
+ chess_dictionary[chess_positions[dict_index]] = char
+ dict_index += 1
+ elif char.isdigit():
+ for i in range(int(char)):
+ chess_dictionary[chess_positions[dict_index + i]] = None
+ dict_index += int(char)
-class ChessPosition:
- def __init__(self, fen_definition: str):
- self.fen_definition = fen_definition
- fen_match = re.match('\s*^(((?:[rnbqkpRNBQKP1-8]+/){7})[rnbqkpRNBQKP1-8]+)$', fen_definition)
+def check_kings_neighbors(sorted_kings):
+ for king in sorted_kings:
+ for neighbour in generator(king):
+ if neighbour in sorted_kings:
+ raise ChessException("kings")
- if fen_match:
- fen_list = fen_match.groups()
- fen = fen_list[0].split("/")
- pawns_error = False
- number_of_white_kings, number_of_black_kings = 0, 0
- kings_data = []
- if len(fen) != 8:
- raise ChessException("Eight (8) rows expected in position part of fen: {0}".format(repr(fen)))
- for row_index, row in enumerate(fen):
- columns = 0
- prev_digit, prev_figure = False, False
- for char in row:
- if char in ["1", "2", "3", "4", "5", "6", "7", "8"]:
- if prev_digit:
- raise ChessException("There are two subsequent digits"
- " in position part of fen: {0}".format(repr(fen)))
- columns += int(char)
- prev_digit = True
- prev_figure = False
- elif char in ["p", "n", "b", "r", "q", "k", "P", "N", "B", "R", "Q", "K"]:
- columns += 1
- prev_digit = False
- prev_figure = True
- if char == "k":
- number_of_black_kings += 1
- kings_data.append([rows_in_chess[row_index], columns])
- elif char == "K":
- number_of_white_kings += 1
- kings_data.append([rows_in_chess[row_index], columns])
- elif (char == "p" or char == "P") and (row_index == 0 or row_index == 7):
- pawns_error = True
- else:
- raise ChessException("Invalid character in position: {0}".format(repr(fen)))
+def validate_fen(fen_match):
+ if fen_match:
+ fen_list = fen_match.groups()
+ fen = fen_list[0].split("/")
+ pawns_error = False
+ number_of_white_kings, number_of_black_kings = 0, 0
+ kings_data = []
+ if len(fen) != 8:
+ raise ChessException("Eight (8) rows expected in position part of fen: {0}".format(repr(fen)))
+ for row_index, row in enumerate(fen):
+ columns = 0
+ prev_digit, prev_figure = False, False
+ for char in row:
+ if char.isdigit():
+ if prev_digit:
+ raise ChessException("There are two subsequent digits"
+ " in position part of fen: {0}".format(repr(fen)))
+ columns += int(char)
+ prev_digit = True
+ prev_figure = False
+ elif char.isalpha():
+ columns += 1
+ prev_digit = False
+ prev_figure = True
+ if char == "k":
+ number_of_black_kings += 1
+ kings_data.append([rows_in_chess[row_index], columns])
+ elif char == "K":
+ number_of_white_kings += 1
+ kings_data.append([rows_in_chess[row_index], columns])
+ elif (char == "p" or char == "P") and (row_index == 0 or row_index == 7):
+ pawns_error = True
- if columns != 8:
- raise ChessException("Eight(8) columns expected per row "
- "in position part of fen: {0}".format(repr(fen)))
+ else:
+ raise ChessException("Invalid character in position: {0}".format(repr(fen)))
- sorted_kings = sorted(kings_data, key=lambda element: element[0])
- for king in sorted_kings:
- for neighbour in generator(king):
- if neighbour in sorted_kings:
- raise ChessException("kings")
+ if columns != 8:
+ raise ChessException("Eight(8) columns expected per row "
+ "in position part of fen: {0}".format(repr(fen)))
- if number_of_white_kings > 1 or number_of_white_kings < 1 \
- or number_of_black_kings > 1 or number_of_black_kings < 1:
- raise ChessException("kings")
- elif pawns_error:
- raise ChessException("pawns")
+ sorted_kings = sorted(kings_data, key=lambda element: element[0])
+ check_kings_neighbors(sorted_kings)
- else:
- raise ChessException(
- "Passed FEN does NOT match this example: pppppppp/pppppppp/8/8/8/8/PPPPPPPP/pppppppp")
+ if number_of_white_kings > 1 or number_of_white_kings < 1 \
+ or number_of_black_kings > 1 or number_of_black_kings < 1:
+ raise ChessException("kings")
+ elif pawns_error:
+ raise ChessException("pawns")
+ else:
+ raise ChessException(
+ "Passed FEN does NOT match this example: pppppppp/pppppppp/8/8/8/8/PPPPPPPP/pppppppp")
+
+
+class ChessPosition:
+
+ def __init__(self, fen_definition: str): # create modules for each functionality
+ self.fen_definition = fen_definition
+ fen_match = re.match('^(((?:[rnbqkpRNBQKP1-8]+/){7})[rnbqkpRNBQKP1-8]+)$', fen_definition)
+ assign_fen_to_dict(fen_definition)
+ validate_fen(fen_match)
+
def get_white_score(self):
white_figures = []
for figure in self.fen_definition:
if figure in ["P", "N", "B", "R", "Q", "K"]:
white_figures.append(figure.lower())
return ChessScore(white_figures)
def get_black_score(self):
black_figures = []
for figure in self.fen_definition:
if figure in ["p", "n", "b", "r", "q", "k"]:
black_figures.append(figure)
return ChessScore(black_figures)
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_white_score() == self.get_black_score()
def __len__(self):
length = 0
for char in self.fen_definition:
- if char in ["p", "n", "b", "r", "q", "k", "P", "N", "B", "R", "Q", "K"]:
+ if char.isalpha():
length += 1
return length
def __repr__(self):
- return f"{self.fen_definition}"
+ return self.fen_definition
def __str__(self):
- return f"FEN: {self.fen_definition}"
+ return self.fen_definition
def __getitem__(self, items: str):

Е, да, определено кодът тук е по-добре. Ако дефинираш речника динамично, ще е още по-добре, защото сега има шанс за грешка, но определено сега е по-добре.

- line = 8
- index = 0
- column_index = 0
- for char in self.fen_definition:
- if char == '/':
- line -= 1
- if line != int(items[1]):
- index += 1
- elif line == int(items[1]):
- if line != 8:
- index += 1
- for i, letter in enumerate(self.fen_definition[index:]):
- if letter.isdigit():
- column_index += int(letter)
- else:
- column_index += 1
- if column_index < 8 and columns_as_letters[column_index] == items[0]:
- return letter
- return None
+ if items in chess_dictionary:
+ return chess_dictionary[items]
+ else:
+ raise ChessException("Invalid column or row!")
class ChessScore:
- score = 0
def __init__(self, figures):
+ score = 0
for figure in figures:
if figure not in ["p", "n", "b", "r", "q", "k"]:
raise ChessException("Invalid figure passed when calculating ChessScore")
self.figures = figures
for figure in self.figures:
- self.score += figure_scores[figure.lower()]
+ score += figure_scores[figure.lower()]
+ self.score = score
def __int__(self):
return self.score
def __lt__(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 __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 __le__(self, other):
return self.score <= other.score
def __repr__(self):
return self.score
def __str__(self):
return f"{self.score}"
+

Йоанна обнови решението на 29.11.2022 15:11 (преди почти 2 години)

import re
chess_positions = ["A8", "B8", "C8", "D8", "E8", "F8", "G8", "H8",
"A7", "B7", "C7", "D7", "E7", "F7", "G7", "H7",
"A6", "B6", "C6", "D6", "E6", "F6", "G6", "H6",
"A5", "B5", "C5", "D5", "E5", "F5", "G5", "H5",
"A4", "B4", "C4", "D4", "E4", "F4", "G4", "H4",
"A3", "B3", "C3", "D3", "E3", "F3", "G3", "H3",
"A2", "B2", "C2", "D2", "E2", "F2", "G2", "H2",
"A1", "B1", "C1", "D1", "E1", "F1", "G1", "H1"
]
columns_as_letters = {
1: "A",
2: "B",
3: "C",
4: "D",
5: "E",
6: "F",
7: "G",
8: "H",
}
rows_in_chess = {
0: 8,
1: 7,
2: 6,
3: 5,
4: 4,
5: 3,
6: 2,
7: 1
}
figure_scores = {
"r": 5,
"n": 3,
"b": 3,
"q": 9,
"k": 4,
"p": 1
}
-chess_dictionary = {}
-
class ChessException(Exception):
pass
def generator(king):
all_possible_neighbors = [[king[0] - 1, king[1] - 1], [king[0] - 1, king[1]],
[king[0] - 1, king[1] + 1], [king[0], king[1] + 1],
[king[0] + 1, king[1] + 1], [king[0] + 1, king[1]],
[king[0] + 1, king[1] - 1], [king[0], king[1] - 1]]
return all_possible_neighbors
-def assign_fen_to_dict(fen):
+def assign_fen_to_dict(fen, chess_dictionary):
columns = fen.split('/')
united = ''.join(columns)
dict_index = 0
for index, char in enumerate(united):
if char.isalpha():
chess_dictionary[chess_positions[dict_index]] = char
dict_index += 1
elif char.isdigit():
for i in range(int(char)):
chess_dictionary[chess_positions[dict_index + i]] = None
dict_index += int(char)
def check_kings_neighbors(sorted_kings):
for king in sorted_kings:
for neighbour in generator(king):
if neighbour in sorted_kings:
raise ChessException("kings")
def validate_fen(fen_match):
if fen_match:
fen_list = fen_match.groups()
fen = fen_list[0].split("/")
pawns_error = False
number_of_white_kings, number_of_black_kings = 0, 0
kings_data = []
if len(fen) != 8:
raise ChessException("Eight (8) rows expected in position part of fen: {0}".format(repr(fen)))
for row_index, row in enumerate(fen):
columns = 0
prev_digit, prev_figure = False, False
for char in row:
if char.isdigit():
if prev_digit:
raise ChessException("There are two subsequent digits"
" in position part of fen: {0}".format(repr(fen)))
columns += int(char)
prev_digit = True
prev_figure = False
elif char.isalpha():
columns += 1
prev_digit = False
prev_figure = True
if char == "k":
number_of_black_kings += 1
kings_data.append([rows_in_chess[row_index], columns])
elif char == "K":
number_of_white_kings += 1
kings_data.append([rows_in_chess[row_index], columns])
elif (char == "p" or char == "P") and (row_index == 0 or row_index == 7):
pawns_error = True
else:
raise ChessException("Invalid character in position: {0}".format(repr(fen)))
if columns != 8:
raise ChessException("Eight(8) columns expected per row "
"in position part of fen: {0}".format(repr(fen)))
sorted_kings = sorted(kings_data, key=lambda element: element[0])
check_kings_neighbors(sorted_kings)
if number_of_white_kings > 1 or number_of_white_kings < 1 \
or number_of_black_kings > 1 or number_of_black_kings < 1:
raise ChessException("kings")
elif pawns_error:
raise ChessException("pawns")
else:
raise ChessException(
"Passed FEN does NOT match this example: pppppppp/pppppppp/8/8/8/8/PPPPPPPP/pppppppp")
class ChessPosition:
def __init__(self, fen_definition: str): # create modules for each functionality
self.fen_definition = fen_definition
fen_match = re.match('^(((?:[rnbqkpRNBQKP1-8]+/){7})[rnbqkpRNBQKP1-8]+)$', fen_definition)
- assign_fen_to_dict(fen_definition)
+ self.chess_dictionary = {}
+ assign_fen_to_dict(fen_definition, self.chess_dictionary)
validate_fen(fen_match)
def get_white_score(self):
white_figures = []
for figure in self.fen_definition:
if figure in ["P", "N", "B", "R", "Q", "K"]:
white_figures.append(figure.lower())
return ChessScore(white_figures)
def get_black_score(self):
black_figures = []
for figure in self.fen_definition:
if figure in ["p", "n", "b", "r", "q", "k"]:
black_figures.append(figure)
return ChessScore(black_figures)
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_white_score() == self.get_black_score()
def __len__(self):
length = 0
for char in self.fen_definition:
if char.isalpha():
length += 1
return length
def __repr__(self):
return self.fen_definition
def __str__(self):
return self.fen_definition
def __getitem__(self, items: str):
- if items in chess_dictionary:
- return chess_dictionary[items]
+ if items in self.chess_dictionary:
+ return self.chess_dictionary[items]
else:
raise ChessException("Invalid column or row!")
class ChessScore:
def __init__(self, figures):
score = 0
for figure in figures:
if figure not in ["p", "n", "b", "r", "q", "k"]:
raise ChessException("Invalid figure passed when calculating ChessScore")
self.figures = figures
for figure in self.figures:
score += figure_scores[figure.lower()]
self.score = score
def __int__(self):
return self.score
def __lt__(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 __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 __le__(self, other):
return self.score <= other.score
def __repr__(self):
return self.score
def __str__(self):
return f"{self.score}"
-