Решение на Шахматни фенове от Лъчезар Цветков

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

Към профила на Лъчезар Цветков

Резултати

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

Код

class ChessException(Exception):
pass
class ChessScore:
def __init__(self,figures):
self.figures=figures
self.score=0
for figure in figures:
match figure.lower():
case 'r':
self.score += 5
case 'k':
self.score += 4
case 'p':
self.score += 1
case 'n':
self.score += 3
case 'q':
self.score += 9
case 'b':
self.score += 3
def __int__(self):
return self.score
def __eq__(self, __o: object) -> bool:
return self.score == __o.score
def __ne__(self, __o: object) -> bool:
return self.score != __o.score
def __gt__(self, __o: object) -> bool:
return self.score > __o.score
def __ge__(self, __o: object) -> bool:
return self.score >= __o.score
def __lt__(self, __o: object) -> bool:
return self.score < __o.score
def __le__(self, __o: object) -> bool:
return self.score <= __o.score
def __add__(self, __o: object):
return self.score + __o.score
def __sub__(self, __o: object):
return self.score - __o.score
class ChessPosition():
arr = []

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

def __init__(self,FEN):
self.FEN = FEN
self.arr = FEN.split("/")
w_kings = 0
b_kings = 0
for string in self.arr:
for character in string:
if character == 'K' :
w_kings += 1
elif character == 'k' :
b_kings += 1
for i in range(len(self.arr)):
for j in range(len(self.arr[i])):
if self.arr[i][j] == 'k':
if i == 0 or i == len(self.arr[i]) - 1 or j == 0 or j == len(self.arr[i]) - 1:
if i != 0 and self.arr[i - 1][j] == 'K':
raise ChessException("kings")
elif i != len(self.arr[i]) - 1 and self.arr[i + 1][j] == 'K':
raise ChessException("kings")
elif j != 0 and self.arr[i][j - 1] == 'K':
raise ChessException("kings")
elif j != len(self.arr[i]) - 1 and self.arr[i][j + 1] == 'K':
raise ChessException("kings")
else:
if self.arr[i][j] == 'k':
if self.arr[i - 1][j] == 'K' or self.arr[i + 1][j] == 'K' or self.arr[i][j - 1] == 'K' or self.arr[i][j + 1] == 'K' or self.arr[i - 1][j - 1] == 'K' or self.arr[i - 1][j + 1]=='K' or self.arr[i + 1][j - 1]=='K' or self.arr[i + 1][j + 1] == 'K':
raise ChessException("kings")
# print(str(w_kings) + " " + str(b_kings))
if w_kings != 1 or b_kings != 1:
raise ChessException("kings")
for character in self.arr[0]:
if character == 'P' or character == 'p':
raise ChessException("pawns")
for character in self.arr[7]:
if character == 'P' or character == 'p':
raise ChessException("pawns")
def get_black_score(self):
bl_figs=[]
for string in self.arr:
for character in string:
if character.islower():
bl_figs.append(character)
return ChessScore(bl_figs)
def get_white_score(self):
wh_figs=[]
for string in self.arr:
for character in string:
if character.isupper():
wh_figs.append(character)
return ChessScore(wh_figs)
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 __len__(self):
num = 0
for string in self.arr:
for character in string:
if not '0' < character <= '8':
num += 1
return num
def __str__(self):
return self.FEN
def __getitem__(self, position):

Не е добре да използваш такива числа без да ги дефинираш в някаква константа, чието име показва какво представлява, или без да ги вземеш динамично по някакъв начин. В момента не е ясно какво е 48, 65, 97... Трябва ми ASCII таблица, за да го разбера.

idk = ord(position[0])
num = ord(position[1]) - 48
if idk >= 97:
if idk - 97 >= len(self.arr[8 - num]) or self.arr[8 - num][idk - 97] == '8':
return None
return self.arr[8 - num][idk - 97]
else:
if idk - 65 >= len(self.arr[8 - num]) or self.arr[8 - num][idk - 65] == '8':
return None
return self.arr[8 - num][idk - 65]

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

.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_king_count (test.TestChessPosition)
Test for missing or multiple kings.
----------------------------------------------------------------------
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

----------------------------------------------------------------------
Ran 17 tests in 0.167s

FAILED (errors=4)

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

Лъчезар обнови решението на 29.11.2022 16:30 (преди над 1 година)

+class ChessException(Exception):
+ pass
+
+class KingsError(ChessException):
+ pass
+
+class PawnsError(ChessException):
+ pass
+
+
+
+class ChessPosition():
+ arr = []
+ def __init__(self,FEN):
+ self.FEN = FEN
+
+ self.arr = FEN.split("/")
+
+ w_kings = 0
+ b_kings = 0
+
+ for string in self.arr:
+ for character in string:
+ if(character == 'K'):
+ w_kings += 1
+ if (character == 'k'):
+ b_kings +=1
+
+ try:
+ for i in range(len(self.arr)):
+ for j in range(len(self.arr[i])):
+ if(self.arr[i][j] == 'k'):
+ if i == 0 or i == len(self.arr) - 1 or j == 0 or j == len(self.arr[i]) - 1:
+ if i != 0 and self.arr[i - 1][j] == 'K':
+ raise KingsError
+
+ elif i != (len(self.arr) - 1) and self.arr[i + 1][j] == 'K':
+ raise KingsError
+
+ elif j != 0 and self.arr[i][j - 1] == 'K':
+ raise KingsError
+
+ elif j != len(self.arr[i]) - 1 and self.arr[i][j + 1] == 'K':
+ raise KingsError
+ else:
+ if(self.arr[i][j] == 'k'):
+ if self.arr[i - 1][j] == 'K' or self.arr[i + 1][j] == 'K' or self.arr[i][j - 1] == 'K' or self.arr[i][j + 1] == 'K' or self.arr[i - 1][j - 1] == 'K' or self.arr[i - 1][j + 1]=='K' or self.arr[i + 1][j - 1]=='K' or self.arr[i + 1][j + 1] == 'K':
+ raise KingsError
+
+ if w_kings == 0 or b_kings == 0 or w_kings > 1 or b_kings > 1:
+ raise KingsError
+
+ for character in self.arr[0]:
+ if character == 'P' or character == 'p':
+ raise PawnsError
+
+ except KingsError:
+ print("kings")
+
+ except PawnsError:
+ print("pawns")
+
+
+ def get_black_score(self):
+ score = 0
+ for string in self.arr:
+ for character in string:
+ if(character == 'p'):
+ score += 1
+ elif(character == 'k'):
+ score += 4
+ elif(character == 'q'):
+ score += 9
+ elif(character == 'b'):
+ score += 3
+ elif(character == 'n'):
+ score += 3
+ elif(character == 'r'):
+ score += 5
+ return score
+
+ def get_white_score(self):
+ score = 0
+ for string in self.arr:
+ for character in string:
+ if(character == 'P'):
+ score += 1
+ elif(character == 'K'):
+ score += 4
+ elif(character == 'Q'):
+ score += 9
+ elif(character == 'B'):
+ score += 3
+ elif(character == 'N'):
+ score += 3
+ elif(character == 'R'):
+ score += 5
+ return score
+
+ def white_is_winning(self):
+ if(self.get_black_score() < self.get_white_score()):
+ return True
+
+ return False
+
+ def black_is_winning(self):
+ if(self.get_black_score() > self.get_white_score()):
+ return True
+
+ return False
+
+ def is_equal(self):
+ if(self.get_black_score() == self.get_white_score()):
+ return True
+
+ return False
+
+
+ def __len__(self):
+ num = 0
+ for string in self.arr:
+ for character in string:
+ if character != '8':
+ num += 1
+
+ return num
+
+ def __str__(self):
+ return self.FEN
+
+ def __getitem__(self, position):
+ idk = ord(position[0])
+ num = ord(position[1]) - 48
+
+ if idk >= 97:
+ if idk - 97 >= len(self.arr[8 - num]) or self.arr[8 - num][idk - 97] == '8':
+ return None
+ return self.arr[8 - num][idk - 97]
+ else:
+ if idk - 65 >= len(self.arr[8 - num]) or self.arr[8 - num][idk - 65] == '8':
+ return None
+ return self.arr[8 - num][idk - 65]
+

Лъчезар обнови решението на 29.11.2022 17:53 (преди над 1 година)

class ChessException(Exception):
pass
-class KingsError(ChessException):
- pass
-class PawnsError(ChessException):
- pass
+class ChessScore:
+ def __init__(self,figures):
+ self.figures=figures
+ self.score=0
+ for figure in figures:
+ match figure.lower():
+ case 'r':
+ self.score += 5
+ case 'k':
+ self.score += 4
+ case 'p':
+ self.score += 1
+ case 'n':
+ self.score += 3
+ case 'q':
+ self.score += 9
+ case 'b':
+ self.score += 3
+ def __int__(self):
+ return self.score
+ def __eq__(self, __o: object) -> bool:
+ return self.score == __o.score
+ def __ne__(self, __o: object) -> bool:
+ return self.score != __o.score
+
+ def __gt__(self, __o: object) -> bool:
+ return self.score > __o.score
+
+ def __ge__(self, __o: object) -> bool:
+ return self.score >= __o.score
+
+ def __lt__(self, __o: object) -> bool:
+ return self.score < __o.score
+
+ def __le__(self, __o: object) -> bool:
+ return self.score <= __o.score
+
+ def __add__(self, __o: object):
+ return self.score + __o.score
+
+ def __sub__(self, __o: object):
+ return self.score - __o.score
+
+
+
class ChessPosition():
arr = []

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

def __init__(self,FEN):
self.FEN = FEN
self.arr = FEN.split("/")
w_kings = 0
b_kings = 0
for string in self.arr:
for character in string:
- if(character == 'K'):
+ if character == 'K' :
w_kings += 1
- if (character == 'k'):
- b_kings +=1
+ elif character == 'k' :
+ b_kings += 1
- try:
- for i in range(len(self.arr)):
- for j in range(len(self.arr[i])):
- if(self.arr[i][j] == 'k'):
- if i == 0 or i == len(self.arr) - 1 or j == 0 or j == len(self.arr[i]) - 1:
- if i != 0 and self.arr[i - 1][j] == 'K':
- raise KingsError
+
+ for i in range(len(self.arr)):
+ for j in range(len(self.arr[i])):
+ if self.arr[i][j] == 'k':
+ if i == 0 or i == len(self.arr[i]) - 1 or j == 0 or j == len(self.arr[i]) - 1:
+ if i != 0 and self.arr[i - 1][j] == 'K':
+ raise ChessException("kings")
- elif i != (len(self.arr) - 1) and self.arr[i + 1][j] == 'K':
- raise KingsError
+ elif i != len(self.arr[i]) - 1 and self.arr[i + 1][j] == 'K':
+ raise ChessException("kings")
- elif j != 0 and self.arr[i][j - 1] == 'K':
- raise KingsError
+ elif j != 0 and self.arr[i][j - 1] == 'K':
+ raise ChessException("kings")
- elif j != len(self.arr[i]) - 1 and self.arr[i][j + 1] == 'K':
- raise KingsError
- else:
- if(self.arr[i][j] == 'k'):
- if self.arr[i - 1][j] == 'K' or self.arr[i + 1][j] == 'K' or self.arr[i][j - 1] == 'K' or self.arr[i][j + 1] == 'K' or self.arr[i - 1][j - 1] == 'K' or self.arr[i - 1][j + 1]=='K' or self.arr[i + 1][j - 1]=='K' or self.arr[i + 1][j + 1] == 'K':
- raise KingsError
+ elif j != len(self.arr[i]) - 1 and self.arr[i][j + 1] == 'K':
+ raise ChessException("kings")
+ else:
+ if self.arr[i][j] == 'k':
+ if self.arr[i - 1][j] == 'K' or self.arr[i + 1][j] == 'K' or self.arr[i][j - 1] == 'K' or self.arr[i][j + 1] == 'K' or self.arr[i - 1][j - 1] == 'K' or self.arr[i - 1][j + 1]=='K' or self.arr[i + 1][j - 1]=='K' or self.arr[i + 1][j + 1] == 'K':
+ raise ChessException("kings")
- if w_kings == 0 or b_kings == 0 or w_kings > 1 or b_kings > 1:
- raise KingsError
+ # print(str(w_kings) + " " + str(b_kings))
+ if w_kings != 1 or b_kings != 1:
+ raise ChessException("kings")
- for character in self.arr[0]:
- if character == 'P' or character == 'p':
- raise PawnsError
+ for character in self.arr[0]:
+ if character == 'P' or character == 'p':
+ raise ChessException("pawns")
+ for character in self.arr[7]:
+ if character == 'P' or character == 'p':
+ raise ChessException("pawns")
- except KingsError:
- print("kings")
-
- except PawnsError:
- print("pawns")
+
def get_black_score(self):
- score = 0
+ bl_figs=[]
for string in self.arr:
for character in string:
- if(character == 'p'):
- score += 1
- elif(character == 'k'):
- score += 4
- elif(character == 'q'):
- score += 9
- elif(character == 'b'):
- score += 3
- elif(character == 'n'):
- score += 3
- elif(character == 'r'):
- score += 5
- return score
+ if character.islower():
+ bl_figs.append(character)
+ return ChessScore(bl_figs)
+
def get_white_score(self):
- score = 0
+ wh_figs=[]
for string in self.arr:
for character in string:
- if(character == 'P'):
- score += 1
- elif(character == 'K'):
- score += 4
- elif(character == 'Q'):
- score += 9
- elif(character == 'B'):
- score += 3
- elif(character == 'N'):
- score += 3
- elif(character == 'R'):
- score += 5
- return score
+ if character.isupper():
+ wh_figs.append(character)
+
+ return ChessScore(wh_figs)
def white_is_winning(self):
- if(self.get_black_score() < self.get_white_score()):
- return True
-
- return False
+ return self.get_black_score() < self.get_white_score()
def black_is_winning(self):
- if(self.get_black_score() > self.get_white_score()):
- return True
-
- return False
+ return self.get_black_score() > self.get_white_score()
def is_equal(self):
- if(self.get_black_score() == self.get_white_score()):
- return True
-
- return False
+ return self.get_black_score() == self.get_white_score()
def __len__(self):
num = 0
for string in self.arr:
for character in string:
- if character != '8':
+ if not '0' < character <= '8':
num += 1
return num
def __str__(self):
return self.FEN
def __getitem__(self, position):

Не е добре да използваш такива числа без да ги дефинираш в някаква константа, чието име показва какво представлява, или без да ги вземеш динамично по някакъв начин. В момента не е ясно какво е 48, 65, 97... Трябва ми ASCII таблица, за да го разбера.

idk = ord(position[0])
num = ord(position[1]) - 48
if idk >= 97:
if idk - 97 >= len(self.arr[8 - num]) or self.arr[8 - num][idk - 97] == '8':
return None
return self.arr[8 - num][idk - 97]
else:
if idk - 65 >= len(self.arr[8 - num]) or self.arr[8 - num][idk - 65] == '8':
return None
return self.arr[8 - num][idk - 65]
-
+