Решение на Шахматни фенове от Тина Томова

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

Към профила на Тина Томова

Резултати

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

Код

white_figures = {'R': 5, 'N': 3, 'B': 3, 'K': 4, 'Q': 9, 'P': 1}
black_figures = {'r': 5, 'n': 3, 'b': 3, 'k': 4, 'q': 9, 'p': 1}
class ChessException(Exception):
pass
class ChessPosition:
def __init__(self, fen):
self.fen = fen
self.fen_to_list = fen.split('/')
for _ in range(8):
row = self.fen_to_list[0]
for figure in row:
if figure.isdigit():
index_of_digit = row.index(figure)
row = row[:index_of_digit] + int(figure) * '1' + row[index_of_digit+1:]
self.fen_to_list.append(row)
self.fen_to_list.pop(0)
self.kings_count()
self.kings_position()
self.pawns_position()
def kings_count(self):
white_king = 0
black_king = 0
for figure in self.fen:
if figure == 'k':
black_king += 1
if figure == 'K':
white_king += 1
if white_king != 1 or black_king != 1:
raise ChessException("kings")
def kings_position(self):
row_k = [self.fen_to_list.index(row) for row in self.fen_to_list if 'k' in row][0]
column_k = [row.index('k') for row in self.fen_to_list if 'k' in row][0]
row_K = [self.fen_to_list.index(row) for row in self.fen_to_list if 'K' in row][0]
column_K = [row.index('K') for row in self.fen_to_list if 'K' in row][0]
vector_length = (row_K - row_k) ** 2 + (column_K - column_k) ** 2
if vector_length <= 2:
raise ChessException("kings")
def pawns_position(self):
if 'p' in self.fen_to_list[0] or 'P' in self.fen_to_list[0]:
raise ChessException('pawns')
if 'p' in self.fen_to_list[7] or 'P' in self.fen_to_list[7]:
raise ChessException("pawns")
def get_black_score(self):
points = 0
for figure in self.fen:
if figure in black_figures.keys():
points += black_figures[figure]
return points
def get_white_score(self):
points = 0
for figure in self.fen:
if figure in white_figures.keys():
points += white_figures[figure]
return points
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()
def __str__(self):
return self.fen
def __len__(self):
figures = 0
for figure in self.fen:
if figure in ('r', 'R', 'n', 'N', 'b', 'B', 'q', 'Q', 'k', 'K', 'p', 'P'):
figures += 1
return figures
def __getitem__(self, idx):
column = idx[0]
row = idx[1]
item = self.fen_to_list[8 - int(row)][ord(column) - 65]
if item == '1':
return None
return item
class ChessScore:
def __init__(self, figures):
self.score = 0
for figure in figures:
points += black_figures[figure]
def __int__(self):
return self.score
def __eq__(self, other):
return self.score == other.score
def __ne__(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 __gt__(self, other):
return self.score > other.score
def __ge__(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

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

....F.......FEEEE
======================================================================
ERROR: test_basic_arithmetic (test.TestChessScore)
Test additiona and subtraction of ChessScores.
----------------------------------------------------------------------
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
UnboundLocalError: local variable 'points' referenced before assignment

======================================================================
ERROR: test_comparison (test.TestChessScore)
Test correct comparison on a pair of scores.
----------------------------------------------------------------------
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
UnboundLocalError: local variable 'points' referenced before assignment

======================================================================
ERROR: test_correct_mapping_of_pieces (test.TestChessScore)
Test correct mapping for each piece.
----------------------------------------------------------------------
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
UnboundLocalError: local variable 'points' referenced before assignment

======================================================================
ERROR: test_correct_sum_of_pieces (test.TestChessScore)
Test correct sum for random pieces.
----------------------------------------------------------------------
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
UnboundLocalError: local variable 'points' referenced before assignment

======================================================================
FAIL: test_get_white_score (test.TestChessPosition)
Test get_white_score.
----------------------------------------------------------------------
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
AssertionError: 4 is not an instance of <class 'solution.ChessScore'>

======================================================================
FAIL: test_white_is_winning (test.TestChessPosition)
Test white_is_winning.
----------------------------------------------------------------------
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
AssertionError: 4 is not an instance of <class 'solution.ChessScore'>

----------------------------------------------------------------------
Ran 17 tests in 0.164s

FAILED (failures=2, errors=4)

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

Тина обнови решението на 28.11.2022 23:19 (преди почти 2 години)

+class ChessException(Exception):
+ def __init__(self, message):
+ self._message = message
+ super().__init__(self._message)
+
+
+class ChessPosition:
+ def __init__(self, fen):
+ self.fen = fen
+ self.fen_to_list = fen.split('/')
+ white_king = 0
+ black_king = 0
+
+ for _ in range(8):
+ row = self.fen_to_list[0]
+ for figure in row:
+ if figure.isdigit():
+ index_of_digit = row.index(figure)
+ row = row[:index_of_digit] + str(int(figure)*'1') + row[index_of_digit+1:]

Не е нужно да кастваш към стринг след умножението. Освен това, прието е да има интервали около *, освен ако не е в израз с няколко оператора, които са с различен приоритет за прилагане.

+ self.fen_to_list.append(row)
+ self.fen_to_list.pop(0)
+
+ for figure in fen:
+ if figure == 'k':
+ black_king += 1
+ if figure == 'K':
+ white_king += 1
+ if white_king != 1 or black_king != 1:
+ raise ChessException("kings")
+
+ for row in self.fen_to_list:
+ if 'kK' in row or 'Kk' in row:
+ raise ChessException('kings')
+ for idx in range(0, 7):

Този цикъл плаче за рефакториране. Би могла да направиш проверката доста по-кратко, ако предварително вземеш позицията на царете като координатна двойка (x, y) и изчислиш разстоянието между тях.

+ position_k = 1
+ position_K = 1
+ if 'k' in self.fen_to_list[idx] and 'K' in self.fen_to_list[idx+1]:
+ for figure in self.fen_to_list[idx]:
+ if figure == 'k':
+ break
+ if figure.isdigit():
+ position_k += int(figure)
+ else:
+ position_k += 1
+ for figure in self.fen_to_list[idx+1]:
+ if figure == 'K':
+ break
+ if figure.isdigit():
+ position_K += int(figure)
+ else:
+ position_K += 1
+ if position_K == position_k or position_K == position_k-1 or position_K == position_k+1:
+ raise ChessException('kings')
+ if 'K' in self.fen_to_list[idx] and 'k' in self.fen_to_list[idx+1]:
+ for figure in self.fen_to_list[idx]:
+ if figure == 'K':
+ break
+ if figure.isdigit():
+ position_K += int(figure)
+ else:
+ position_K += 1
+ for figure in self.fen_to_list[idx+1]:
+ if figure == 'k':
+ break
+ if figure.isdigit():
+ position_k += int(figure)
+ else:
+ position_k += 1
+ if position_K == position_k or position_K == position_k-1 or position_K == position_k+1:
+ raise ChessException('kings')
+
+ if 'p' in self.fen_to_list[0] or 'P' in self.fen_to_list[0]:
+ raise ChessException('pawns')
+ if 'p' in self.fen_to_list[7] or 'P' in self.fen_to_list[7]:
+ raise ChessException('pawns')
+
+ def get_white_score(self):
+ points = 43
+ for figure in self.fen:
+ if figure == 'r':
+ points -= 5
+ if figure == 'n' or figure == 'b':
+ points -= 3
+ if figure == 'q':
+ points -= 9
+ if figure == 'k':
+ points -= 4
+ if figure == 'p':
+ points -= 1
+ return points
+
+ def get_black_score(self):
+ points = 43
+ for figure in self.fen:
+ if figure == 'R':
+ points -= 5
+ if figure == 'N' or figure == 'B':
+ points -= 3
+ if figure == 'Q':
+ points -= 9
+ if figure == 'K':
+ points -= 4
+ if figure == 'P':
+ points -= 1
+ return points
+
+ 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()
+
+ def __str__(self):
+ return self.fen
+
+ def __len__(self):
+ figures = 0
+ for figure in self.fen:
+ if figure in ('r', 'R', 'n', 'N', 'b', 'B', 'q', 'Q', 'k', 'K', 'p', 'P'):
+ figures += 1
+ return figures
+
+ def __getitem__(self, idx):
+ column = idx[0]
+ row = idx[1]
+ if self.fen_to_list[8-int(row)][ord(column)-65] == '1':

Това self.fen_to_list[8-int(row)][ord(column)-65] го ползваш два пъти, а е доста дълго, така че по-добре да го запазиш в променлива. Освен това, прието е да имаш интервали около -.

+ return None
+ return self.fen_to_list[8-int(row)][ord(column)-65]
+
+
+class ChessScore:
+ def __init__(self, figures):
+ self.score = 0
+ for figure in figures:
+ if figure == 'r':
+ self.score += 5
+ if figure == 'n' or figure == 'b':
+ self.score += 3
+ if figure == 'q':
+ self.score += 9
+ if figure == 'k':
+ self.score += 4
+ if figure == 'p':
+ self.score += 1
+
+ def __int__(self):
+ return self.score
+
+ def __eq__(self, other):
+ return self.score == other.score
+
+ def __ne__(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 __gt__(self, other):
+ return self.score > other.score
+
+ def __ge__(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

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

+white_figures = {'R': 5, 'N': 3, 'B': 3, 'K': 4, 'Q': 9, 'P': 1}
+black_figures = {'r': 5, 'n': 3, 'b': 3, 'k': 4, 'q': 9, 'p': 1}
+
+
class ChessException(Exception):
- def __init__(self, message):
- self._message = message
- super().__init__(self._message)
+ pass
class ChessPosition:
def __init__(self, fen):
self.fen = fen
self.fen_to_list = fen.split('/')
- white_king = 0
- black_king = 0
for _ in range(8):
row = self.fen_to_list[0]
for figure in row:
if figure.isdigit():
index_of_digit = row.index(figure)
- row = row[:index_of_digit] + str(int(figure)*'1') + row[index_of_digit+1:]
+ row = row[:index_of_digit] + int(figure) * '1' + row[index_of_digit+1:]
self.fen_to_list.append(row)
self.fen_to_list.pop(0)
- for figure in fen:
+ self.kings_count()
+ self.kings_position()
+ self.pawns_position()
+
+ def kings_count(self):
+ white_king = 0
+ black_king = 0
+ for figure in self.fen:
if figure == 'k':
black_king += 1
if figure == 'K':
white_king += 1
if white_king != 1 or black_king != 1:
raise ChessException("kings")
-
- for row in self.fen_to_list:
- if 'kK' in row or 'Kk' in row:
- raise ChessException('kings')
- for idx in range(0, 7):
- position_k = 1
- position_K = 1
- if 'k' in self.fen_to_list[idx] and 'K' in self.fen_to_list[idx+1]:
- for figure in self.fen_to_list[idx]:
- if figure == 'k':
- break
- if figure.isdigit():
- position_k += int(figure)
- else:
- position_k += 1
- for figure in self.fen_to_list[idx+1]:
- if figure == 'K':
- break
- if figure.isdigit():
- position_K += int(figure)
- else:
- position_K += 1
- if position_K == position_k or position_K == position_k-1 or position_K == position_k+1:
- raise ChessException('kings')
- if 'K' in self.fen_to_list[idx] and 'k' in self.fen_to_list[idx+1]:
- for figure in self.fen_to_list[idx]:
- if figure == 'K':
- break
- if figure.isdigit():
- position_K += int(figure)
- else:
- position_K += 1
- for figure in self.fen_to_list[idx+1]:
- if figure == 'k':
- break
- if figure.isdigit():
- position_k += int(figure)
- else:
- position_k += 1
- if position_K == position_k or position_K == position_k-1 or position_K == position_k+1:
- raise ChessException('kings')
+ def kings_position(self):
+ row_k = [self.fen_to_list.index(row) for row in self.fen_to_list if 'k' in row][0]
+ column_k = [row.index('k') for row in self.fen_to_list if 'k' in row][0]
+ row_K = [self.fen_to_list.index(row) for row in self.fen_to_list if 'K' in row][0]
+ column_K = [row.index('K') for row in self.fen_to_list if 'K' in row][0]
+ vector_length = (row_K - row_k) ** 2 + (column_K - column_k) ** 2
+ if vector_length <= 2:
+ raise ChessException("kings")
+
+ def pawns_position(self):
if 'p' in self.fen_to_list[0] or 'P' in self.fen_to_list[0]:
raise ChessException('pawns')
if 'p' in self.fen_to_list[7] or 'P' in self.fen_to_list[7]:
- raise ChessException('pawns')
+ raise ChessException("pawns")
- def get_white_score(self):
- points = 43
+ def get_black_score(self):
+ points = 0
for figure in self.fen:
- if figure == 'r':
- points -= 5
- if figure == 'n' or figure == 'b':
- points -= 3
- if figure == 'q':
- points -= 9
- if figure == 'k':
- points -= 4
- if figure == 'p':
- points -= 1
+ if figure in black_figures.keys():
+ points += black_figures[figure]
return points
- def get_black_score(self):
- points = 43
+ def get_white_score(self):
+ points = 0
for figure in self.fen:
- if figure == 'R':
- points -= 5
- if figure == 'N' or figure == 'B':
- points -= 3
- if figure == 'Q':
- points -= 9
- if figure == 'K':
- points -= 4
- if figure == 'P':
- points -= 1
+ if figure in white_figures.keys():
+ points += white_figures[figure]
return points
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()
def __str__(self):
return self.fen
def __len__(self):
figures = 0
for figure in self.fen:
if figure in ('r', 'R', 'n', 'N', 'b', 'B', 'q', 'Q', 'k', 'K', 'p', 'P'):
figures += 1
return figures
def __getitem__(self, idx):
column = idx[0]
row = idx[1]
- if self.fen_to_list[8-int(row)][ord(column)-65] == '1':
+ item = self.fen_to_list[8 - int(row)][ord(column) - 65]
+ if item == '1':
return None
- return self.fen_to_list[8-int(row)][ord(column)-65]
+ return item
class ChessScore:
def __init__(self, figures):
self.score = 0
for figure in figures:
- if figure == 'r':
- self.score += 5
- if figure == 'n' or figure == 'b':
- self.score += 3
- if figure == 'q':
- self.score += 9
- if figure == 'k':
- self.score += 4
- if figure == 'p':
- self.score += 1
+ points += black_figures[figure]
def __int__(self):
return self.score
def __eq__(self, other):
return self.score == other.score
def __ne__(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 __gt__(self, other):
return self.score > other.score
def __ge__(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
+ return self.score - other.score