Решение на Шахматни фенове от Петър Тодоров

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

Към профила на Петър Тодоров

Резултати

  • 9 точки от тестове
  • 0 бонус точки
  • 9 точки общо
  • 16 успешни тест(а)
  • 1 неуспешни тест(а)

Код

points = {'p':1, 'b':3, 'n':3, 'k':4, 'r':5, 'q':9}
class ChessException(Exception):
def __init__(self, message):
pass
class ChessPosition:
def __init__(self, FEN):
self.pos = FEN
self.rows = FEN.split('/')
if not self.pos.count('k') == 1 or not self.pos.count('K') == 1 or self.taxicab_kings() == 2:
raise ChessException("kings")
if 'p' in self.rows[7] + self.rows[0] or 'P' in self.rows[7] + self.rows[0]:
raise ChessException("pawns")
def __str__(self):
return self.pos
def __len__(self):
return sum([1 if c.isalpha() else 0 for c in self.pos])
def __getitem__(self, position):
col = ord(position[0]) - 64
row = 8 - int(position[1])
sum = 0
for i in self.rows[row]:
sum += 1 if i.isalpha() else int(i)
if sum == col:
return i
return None
def taxicab_kings(self):
k = self.find_king("k")
K = self.find_king("K")
dist = [k[0] - K[0], k[1] - K[1]]
return sum([-1 <= d <= 1 for d in dist])
def find_king(self, king):
col = 1
for row in self.rows:
if king in row:
i = 0
while not row[i] == king:
col += int(row[i]) if row[i].isdigit() else 1
i += 1
return self.rows.index(row) + 1, col
def get_white_score(self):
return ChessScore([c.lower() for c in self.pos if c.isalpha() and c.isupper()])
def get_black_score(self):
return ChessScore([c for c in self.pos if c.isalpha() and c.islower()])
def white_is_winning(self):
return self.get_white_score() > self.get_black_score()
def is_equal(self):
return self.get_white_score() == self.get_black_score()
def black_is_winning(self):
return self.get_white_score() < self.get_black_score()
class ChessScore:
def __init__(self, str):
self.points = sum([points[c] for c in str])
def __int__(self):
return self.points
def __lt__(self, other):
return self.points < other.points
def __le__(self, other):
return self.points <= other.points
def __eq__(self, other):
return self.points == other.points
def __ne__(self, other):
return not self == other
def __gt__(self, other):
return not self <= other
def __add__(self, other):
return self.points + other.points
def __sub__(self, other):
return self.points - other.points

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

.....F...........
======================================================================
FAIL: 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
AssertionError: '2' != None

----------------------------------------------------------------------
Ran 17 tests in 0.163s

FAILED (failures=1)

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

Петър обнови решението на 28.11.2022 18:51 (преди почти 2 години)

+points = {'p':1, 'b':3, 'n':3, 'k':4, 'r':5, 'q':9}
+
+
+def find_pos(row, k_pos):
+ if "K" not in row:
+ return 0
+ K_pos = 1
+ for i in row:
+ if i == "K":
+ break
+ K_pos += ord(i) - 48 if i.isdigit() else 1
+ ind = [-1,0,1]
+ return sum([K_pos + i == k_pos for i in ind])
+
+
+class ChessException(BaseException):

Правилният подход е да наследяващ Exception.
PEP8: "Derive exceptions from Exception rather than BaseException. Direct inheritance from BaseException is reserved for exceptions where catching them is almost always the wrong thing to do."

+ def __init__(self, message):
+ self.message = message
+ super().__init__(self.message)
+
+ def __str__(self):
+ return f'{self.message}'
+
+
+class ChessPosition:
+ def __init__(self, FEN):
+ self.pos = FEN
+ self.rows = FEN.split('/')
+ if not self.pos.count('k') == 1 or not self.pos.count('K') == 1 or self.find_first_king() > 0:
+ raise ChessException("kings")
+ if 'p' in self.rows[7] + self.rows[0] or 'P' in self.rows[7] + self.rows[0]:#ne stana s list compr
+ raise ChessException("pawns")
+
+ def __str__(self):
+ return self.pos
+
+ def __len__(self):
+ return sum([1 if c.isalpha() else 0 for c in self.pos])
+
+ def __getitem__(self, position):
+ col = ord(position[0]) - 64
+ row = ord(position[1]) - 49
+ sum = 0
+ for i in self.rows[row]:
+ sum += 1 if i.isalpha() else ord(i) - 48
+ if sum == col:
+ return i
+ return None
+
+
+ def find_first_king(self):

Честно закано това не го разбирам. Имам да прегледам още 30 домашни, така че няма да влизам в детайлите, но щом не мога да го разбера за 30 секунди, значи е пропоръчително да се рефакторира. Не казвам да го правиш сега, защото срокът е къс, но го имай предвид.

Да, признавам че го написах доста немарливо, но смятах че не е толкова зле. Така де, промених начина, по който търся дали два царя са един до друг и мисля, че се получи доста по-добре. Ще може ли да му хвърлите един поглед, макар и след крайния срок.

+ index = 1
+ for i in range(8):
+ if "k" in self.rows[i]:
+ j = 0
+ while not self.rows[i][j] == 'k':
+ index += ord(self.rows[i][j]) - 48 if self.rows[i][j].isdigit() else 1
+ j += 1
+ r = []
+ if i > 0:
+ r.append(i - 1)
+ if i < 7:
+ r.append(i + 1)
+ return sum([find_pos(self.rows[row], index) for row in r])
+
+ def get_white_score(self):
+ return ChessScore([c for c in self.pos if 64 < ord(c) <= 90])
+
+ def get_black_score(self):
+ return ChessScore([c for c in self.pos if 96 < ord(c) < 123])
+
+ def white_is_winning(self):
+ return self.get_white_score() > self.get_black_score()
+
+ def is_equal(self):
+ return self.get_white_score() == self.get_black_score()
+
+ def black_is_winning(self):
+ return self.get_white_score() < self.get_black_score()
+
+
+class ChessScore:
+ def __init__(self, str):
+ self.points = sum([points[c] for c in str])
+
+ def __int__(self):
+ return self.points
+
+ def __lt__(self, other):
+ return self.points < other.points
+
+ def __le__(self, other):
+ return self.points <= other.points
+
+ def __eq__(self, other):
+ return self.points == other.points
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __gt__(self, other):
+ return not self <= other
+
+ def __add__(self, other):
+ return self.points + other.points
+
+ def __sub__(self, other):
+ return self.points - other.points

Петър обнови решението на 29.11.2022 14:30 (преди почти 2 години)

points = {'p':1, 'b':3, 'n':3, 'k':4, 'r':5, 'q':9}
-def find_pos(row, k_pos):
- if "K" not in row:
- return 0
- K_pos = 1
- for i in row:
- if i == "K":
- break
- K_pos += ord(i) - 48 if i.isdigit() else 1
- ind = [-1,0,1]
- return sum([K_pos + i == k_pos for i in ind])
-
-
-class ChessException(BaseException):
+class ChessException(Exception):
def __init__(self, message):
- self.message = message
- super().__init__(self.message)
+ pass
- def __str__(self):
- return f'{self.message}'
-
class ChessPosition:
def __init__(self, FEN):
self.pos = FEN
self.rows = FEN.split('/')
- if not self.pos.count('k') == 1 or not self.pos.count('K') == 1 or self.find_first_king() > 0:
+ if not self.pos.count('k') == 1 or not self.pos.count('K') == 1 or self.taxicab_kings() == 2:
raise ChessException("kings")
- if 'p' in self.rows[7] + self.rows[0] or 'P' in self.rows[7] + self.rows[0]:#ne stana s list compr
+ if 'p' in self.rows[7] + self.rows[0] or 'P' in self.rows[7] + self.rows[0]:
raise ChessException("pawns")
def __str__(self):
return self.pos
def __len__(self):
return sum([1 if c.isalpha() else 0 for c in self.pos])
def __getitem__(self, position):
col = ord(position[0]) - 64
- row = ord(position[1]) - 49
+ row = 8 - int(position[1])
sum = 0
for i in self.rows[row]:
- sum += 1 if i.isalpha() else ord(i) - 48
+ sum += 1 if i.isalpha() else int(i)
if sum == col:
return i
return None
+ def taxicab_kings(self):
+ k = self.find_king("k")
+ K = self.find_king("K")
+ dist = [k[0] - K[0], k[1] - K[1]]
+ return sum([-1 <= d <= 1 for d in dist])
- def find_first_king(self):
- index = 1
- for i in range(8):
- if "k" in self.rows[i]:
- j = 0
- while not self.rows[i][j] == 'k':
- index += ord(self.rows[i][j]) - 48 if self.rows[i][j].isdigit() else 1
- j += 1
- r = []
- if i > 0:
- r.append(i - 1)
- if i < 7:
- r.append(i + 1)
- return sum([find_pos(self.rows[row], index) for row in r])
+ def find_king(self, king):
+ col = 1
+ for row in self.rows:
+ if king in row:
+ i = 0
+ while not row[i] == king:
+ col += int(row[i]) if row[i].isdigit() else 1
+ i += 1
+ return self.rows.index(row) + 1, col
+
def get_white_score(self):
- return ChessScore([c for c in self.pos if 64 < ord(c) <= 90])
+ return ChessScore([c.lower() for c in self.pos if c.isalpha() and c.isupper()])
def get_black_score(self):
- return ChessScore([c for c in self.pos if 96 < ord(c) < 123])
+ return ChessScore([c for c in self.pos if c.isalpha() and c.islower()])
def white_is_winning(self):
return self.get_white_score() > self.get_black_score()
def is_equal(self):
return self.get_white_score() == self.get_black_score()
def black_is_winning(self):
return self.get_white_score() < self.get_black_score()
class ChessScore:
def __init__(self, str):
self.points = sum([points[c] for c in str])
def __int__(self):
return self.points
def __lt__(self, other):
return self.points < other.points
def __le__(self, other):
return self.points <= other.points
def __eq__(self, other):
return self.points == other.points
def __ne__(self, other):
return not self == other
def __gt__(self, other):
return not self <= other
def __add__(self, other):
return self.points + other.points
def __sub__(self, other):
return self.points - other.points