Решение на Шахматни фенове от Таня Сейкова

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

Към профила на Таня Сейкова

Резултати

  • 8 точки от тестове
  • 0 бонус точки
  • 8 точки общо
  • 13 успешни тест(а)
  • 4 неуспешни тест(а)

Код

class ChessException(Exception):
def __init__(self, message):
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':
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"]
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()

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

.E...E..EE.......
======================================================================
ERROR: test_against_touching_kings (test.TestChessPosition)
Test for kings next to each other.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/storage/deedee/data/rails/pyfmi-2022/releases/20221115154139/lib/language/python/runner.py", line 67, in thread
    raise result
IndexError: string index out of range

======================================================================
ERROR: test_getitem (test.TestChessPosition)
Test getitem functionality.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/storage/deedee/data/rails/pyfmi-2022/releases/20221115154139/lib/language/python/runner.py", line 67, in thread
    raise result
IndexError: string index out of range

======================================================================
ERROR: test_len (test.TestChessPosition)
Test number of pieces for a position.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/storage/deedee/data/rails/pyfmi-2022/releases/20221115154139/lib/language/python/runner.py", line 67, in thread
    raise result
IndexError: string index out of range

======================================================================
ERROR: test_pawns_position (test.TestChessPosition)
Test for incorrect pawns.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/storage/deedee/data/rails/pyfmi-2022/releases/20221115154139/lib/language/python/runner.py", line 67, in thread
    raise result
IndexError: string index out of range

----------------------------------------------------------------------
Ran 17 tests in 0.156s

FAILED (errors=4)

История (1 версия и 7 коментара)

Таня обнови решението на 27.11.2022 20:37 (преди почти 2 години)

+class ChessException(Exception):
+ def __init__(self, message):
+ 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':
+ 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"]
+ 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()
+