Решение на Шахматни фенове от Божидар Горанов

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

Към профила на Божидар Горанов

Резултати

  • 3 точки от тестове
  • 0 бонус точки
  • 3 точки общо
  • 5 успешни тест(а)
  • 12 неуспешни тест(а)

Код

import re
class ChessException(Exception):
def __init__(self, message):
super().__init__(message)
class KingException(ChessException):
def __init__(self, message="kings"):
self.message = message
super().__init__(self.message)
class PawnException(ChessException):
def __init__(self, message="pawns"):
self.message = message
super().__init__(self.message)
def exception_check(sym, fen):
coords = fen.index(sym) + 1
if coords + 1 < len(fen):
if fen[coords] == 'k' or fen[coords] == 'K':
raise KingException
if coords - 1 >= 0:
if fen[coords] == 'k' or fen[coords] == 'K':
raise KingException
if coords + 8 < len(fen):
i = coords
for i in range(coords, coords+9):
if fen[i].isdigit():
coords += int(fen[i])
if fen[i] == 'k' or fen[i] == 'K':
raise KingException
i = 0
if coords - 8 >= 0:
i = coords
for i in range(coords - 8, coords, -1):
if fen[i].isdigit():
coords -= int(fen[i])
if fen[i] == 'k' or fen[i] == 'K':
raise KingException
i = 0
if fen[coords] == 'k' or fen[coords] == 'K':
raise KingException
if coords - 9 >= 0:
i = coords
for i in range(coords - 9, coords, -1):
if fen[i].isdigit():
coords -= int(fen[i])
if fen[i] == 'k' or fen[i] == 'K':
raise KingException
i = 0
if fen[coords] == 'k' or fen[coords] == 'K':
raise KingException
if coords + 9 < len(fen):
i = coords
for i in range(coords, coords+10):
if fen[i].isdigit():
coords -= int(fen[i])
if fen[i] == 'k' or fen[i] == 'K':
raise KingException
i = 0
if fen[coords] == 'k' or fen[coords] == 'K':
raise KingException
class ChessPosition:
def __init__(self, fen):

По-добре раздели цялата тази логика на отделни методи - парсване, валидиране на царе, валидиране на пешки.. Всеки метод трябва да изпълнява само едно (възможно най-малко) нещо, за да можеш лесно да тестваш в последствие.

self.size = 0
self.fen = fen
self.fen_strings = fen.split('/')
bpieces = {'r', 'n', 'b', 'q', 'k', 'p'}
wpieces = {'R', 'N', 'B', 'Q', 'K', 'P'}
white_str = ''
black_str = ''
wking = 0
bking = 0
for sym in fen:
if sym in bpieces:
black_str += sym
self.size += 1
if sym == 'k':
exception_check(sym, fen)
bking += 1
if bking > 1:
raise KingException
elif sym in wpieces:
white_str += sym
self.size += 1
if sym == 'K':
exception_check(sym, fen)
wking += 1
if wking > 1:
raise KingException
if sym == 'p' or sym == 'P':
if sym in self.fen_strings[0] or sym in self.fen_strings[7]:
raise PawnException
if wking == 0 or bking == 0:
raise KingException
self.white = ChessScore(white_str.lower())
self.black = ChessScore(black_str)
def get_white_score(self):
return self.white
def get_black_score(self):
return self.black
def white_is_winning(self):
return self.white > self.black
def black_is_winning(self):
return self.black > self.white
def is_equal(self):
return self.black == self.white
def __getitem__(self, item):
index = re.split('(\d+)', item)
print(index[1])
row = self.fen_strings[len(self.fen_strings) - int(index[1])]
cols = ['A', 'B', 'C', 'D', 'E', 'F', 'H', 'G']
br = 0
for let in cols:
if let == index[0].upper():
if br < len(row):
return row[br]
else:
break
br += 1
return 'None'
def __str__(self):
return self.fen
def __len__(self):
return self.size
class ChessScore:
def __init__(self, pieces):
self.pieces = pieces
self.point_vals = {'r': 5, 'n': 3, 'b': 3, 'q': 9, 'k': 4, 'p': 1}
self.total = 0
@property
def score(self):
if self.total != 0:
return self.total
for piece in self.pieces:
self.total += self.point_vals[piece]
return self.total
def __int__(self):
return self.score
def __add__(self, other):
self.total = self.score + other.score
def __sub__(self, other):
self.total = 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 __eq__(self, other):
return self.score == other.score

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

.EEEEEEEEE.FEF...
======================================================================
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_black_is_winning (test.TestChessPosition)
Test black_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
IndexError: string index out of range

======================================================================
ERROR: test_get_black_score (test.TestChessPosition)
Test get_black_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
IndexError: string index out of range

======================================================================
ERROR: 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
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_is_equal (test.TestChessPosition)
Test is_equal.
----------------------------------------------------------------------
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
solution.KingException: kings

======================================================================
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

======================================================================
ERROR: 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
IndexError: string index out of range

======================================================================
FAIL: test_validation_conflict (test.TestChessPosition)
Test for correct Exception on multiple validation fails.
----------------------------------------------------------------------
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: 'pawns' != 'kings'
- pawns
+ kings


======================================================================
FAIL: 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
AssertionError: None != 7

----------------------------------------------------------------------
Ran 17 tests in 0.169s

FAILED (failures=2, errors=10)

История (3 версии и 4 коментара)

Божидар обнови решението на 26.11.2022 19:07 (преди почти 2 години)

+class ChessException(Exception):
+ pass
+
+
+class KingException(ChessException):
+ def __init__(self):
+ print("kings")

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

+
+
+class PawnException(ChessException):
+ def __init__(self):
+ print("pawns")
+
+
+class ChessPosition:
+ def __init__(self, fen):

По-добре раздели цялата тази логика на отделни методи - парсване, валидиране на царе, валидиране на пешки.. Всеки метод трябва да изпълнява само едно (възможно най-малко) нещо, за да можеш лесно да тестваш в последствие.

+ self.fen_strings = fen.split('/')
+ bpieces = {'r', 'n', 'b', 'q', 'k', 'p'}
+ wpieces = {'R', 'N', 'B', 'Q', 'K', 'P'}
+ white_str = ''
+ black_str = ''
+ wking = 0
+ bking = 0
+ for sym in fen:
+ if sym in bpieces:
+ black_str += sym
+ if sym == 'k':
+ coords = fen.index(sym)+1
+ if coords + 1 < len(fen):
+ if fen[coords] == 'k' or fen[coords] == 'K':
+ raise KingException
+ if coords-1 >= 0:
+ if fen[coords] == 'k' or fen[coords] == 'K':
+ raise KingException
+ if coords+8 < len(fen):
+ if fen[coords] == 'k' or fen[coords] == 'K':
+ raise KingException
+ if coords-8 >= 0:
+ if fen[coords] == 'k' or fen[coords] == 'K':
+ raise KingException
+
+ bking += 1
+ if bking > 1:
+ raise KingException
+ elif sym in wpieces:
+ white_str += sym
+ if sym == 'K':
+ wking += 1
+ if wking > 1:
+ raise KingException
+ if sym == 'p' or sym == 'P':
+ if sym in self.fen_strings[0] or sym in self.fen_strings[7]:
+ raise PawnException
+ #add exception if kings ar next to each other
+ if wking == 0 or bking == 0:
+ raise KingException
+
+ self.white = ChessScore(white_str)
+ self.black = ChessScore(black_str)
+
+ def get_white_score(self):
+ return self.white
+
+ def get_black_score(self):
+ return self.black
+
+ def white_is_winning(self):
+ return self.white > self.black
+
+ def black_is_winning(self):
+ return self.black > self.white
+
+ def is_equal(self):
+ return self.black == self.white
+
+
+class ChessScore:
+ def __init__(self, pieces):
+ self.pieces = pieces
+ self.point_vals = {'r': 5, 'n': 3, 'b': 3, 'q': 9, 'k': 4, 'p': 1}
+ self.total = 0
+
+ @property
+ def score(self):
+ if self.total != 0:
+ return self.total
+ for piece in self.pieces:
+ self.total += self.point_vals[piece]
+ return self.total
+
+ def __int__(self):
+ return self.score
+
+ def __add__(self, other):
+ self.total = self.score + other.score
+
+ def __sub__(self, other):
+ self.total = 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 __eq__(self, other):
+ return self.score == other.score

Божидар обнови решението на 27.11.2022 16:29 (преди почти 2 години)

+import re
+
+
class ChessException(Exception):
- pass
+ def __init__(self, message):
+ super().__init__(message)
class KingException(ChessException):
- def __init__(self):
- print("kings")
+ def __init__(self, message="kings"):
+ self.message = message
+ super().__init__(self.message)
class PawnException(ChessException):
- def __init__(self):
- print("pawns")
+ def __init__(self, message="pawns"):
+ self.message = message
+ super().__init__(self.message)
+def exception_check(sym, fen):
+ coords = fen.index(sym) + 1
+ if coords + 1 < len(fen):
+ if fen[coords] == 'k' or fen[coords] == 'K':
+ raise KingException
+ if coords - 1 >= 0:
+ if fen[coords] == 'k' or fen[coords] == 'K':
+ raise KingException
+ if coords + 8 < len(fen):
+ if fen[coords] == 'k' or fen[coords] == 'K':
+ raise KingException
+ if coords - 8 >= 0:
+ if fen[coords] == 'k' or fen[coords] == 'K':
+ raise KingException
+
+
class ChessPosition:
def __init__(self, fen):
+ self.size = 0
+ self.fen = fen
self.fen_strings = fen.split('/')
bpieces = {'r', 'n', 'b', 'q', 'k', 'p'}
wpieces = {'R', 'N', 'B', 'Q', 'K', 'P'}
white_str = ''
black_str = ''
wking = 0
bking = 0
for sym in fen:
if sym in bpieces:
black_str += sym
+ self.size += 1
if sym == 'k':
- coords = fen.index(sym)+1
- if coords + 1 < len(fen):
- if fen[coords] == 'k' or fen[coords] == 'K':
- raise KingException
- if coords-1 >= 0:
- if fen[coords] == 'k' or fen[coords] == 'K':
- raise KingException
- if coords+8 < len(fen):
- if fen[coords] == 'k' or fen[coords] == 'K':
- raise KingException
- if coords-8 >= 0:
- if fen[coords] == 'k' or fen[coords] == 'K':
- raise KingException
-
+ exception_check(sym, fen)
bking += 1
if bking > 1:
raise KingException
elif sym in wpieces:
white_str += sym
+ self.size += 1
if sym == 'K':
+ exception_check(sym, fen)
wking += 1
if wking > 1:
raise KingException
if sym == 'p' or sym == 'P':
if sym in self.fen_strings[0] or sym in self.fen_strings[7]:
raise PawnException
- #add exception if kings ar next to each other
if wking == 0 or bking == 0:
raise KingException
- self.white = ChessScore(white_str)
+ self.white = ChessScore(white_str.lower())
self.black = ChessScore(black_str)
def get_white_score(self):
return self.white
def get_black_score(self):
return self.black
def white_is_winning(self):
return self.white > self.black
def black_is_winning(self):
return self.black > self.white
def is_equal(self):
return self.black == self.white
+
+ def __getitem__(self, item):
+ index = re.split('(\d+)', item)
+ print(index[1])
+ row = self.fen_strings[len(self.fen_strings) - int(index[1])]
+ cols = ['A', 'B', 'C', 'D', 'E', 'F', 'H', 'G']
+ br = 0
+ for let in cols:
+ if let == index[0].upper():
+ if br < len(row):
+ return row[br]
+ else:
+ break
+ br += 1
+ return 'None'
+
+ def __str__(self):
+ return self.fen
+
+ def __len__(self):
+ return self.size
class ChessScore:
def __init__(self, pieces):
self.pieces = pieces
self.point_vals = {'r': 5, 'n': 3, 'b': 3, 'q': 9, 'k': 4, 'p': 1}
self.total = 0
@property
def score(self):
if self.total != 0:
return self.total
for piece in self.pieces:
self.total += self.point_vals[piece]
return self.total
def __int__(self):
return self.score
def __add__(self, other):
self.total = self.score + other.score
def __sub__(self, other):
self.total = 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 __eq__(self, other):
return self.score == other.score

Божидар обнови решението на 28.11.2022 14:37 (преди почти 2 години)

import re
class ChessException(Exception):
def __init__(self, message):
super().__init__(message)
class KingException(ChessException):
def __init__(self, message="kings"):
self.message = message
super().__init__(self.message)
class PawnException(ChessException):
def __init__(self, message="pawns"):
self.message = message
super().__init__(self.message)
def exception_check(sym, fen):
coords = fen.index(sym) + 1
if coords + 1 < len(fen):
if fen[coords] == 'k' or fen[coords] == 'K':
raise KingException
if coords - 1 >= 0:
if fen[coords] == 'k' or fen[coords] == 'K':
raise KingException
if coords + 8 < len(fen):
- if fen[coords] == 'k' or fen[coords] == 'K':
+ i = coords
+ for i in range(coords, coords+9):
+ if fen[i].isdigit():
+ coords += int(fen[i])
+ if fen[i] == 'k' or fen[i] == 'K':
raise KingException
+ i = 0
if coords - 8 >= 0:
+ i = coords
+ for i in range(coords - 8, coords, -1):
+ if fen[i].isdigit():
+ coords -= int(fen[i])
+ if fen[i] == 'k' or fen[i] == 'K':
+ raise KingException
+ i = 0
+ if fen[coords] == 'k' or fen[coords] == 'K':
+ raise KingException
+ if coords - 9 >= 0:
+ i = coords
+ for i in range(coords - 9, coords, -1):
+ if fen[i].isdigit():
+ coords -= int(fen[i])
+ if fen[i] == 'k' or fen[i] == 'K':
+ raise KingException
+ i = 0
+ if fen[coords] == 'k' or fen[coords] == 'K':
+ raise KingException
+ if coords + 9 < len(fen):
+ i = coords
+ for i in range(coords, coords+10):
+ if fen[i].isdigit():
+ coords -= int(fen[i])
+ if fen[i] == 'k' or fen[i] == 'K':
+ raise KingException
+ i = 0
if fen[coords] == 'k' or fen[coords] == 'K':
raise KingException
class ChessPosition:
def __init__(self, fen):
self.size = 0
self.fen = fen
self.fen_strings = fen.split('/')
bpieces = {'r', 'n', 'b', 'q', 'k', 'p'}
wpieces = {'R', 'N', 'B', 'Q', 'K', 'P'}
white_str = ''
black_str = ''
wking = 0
bking = 0
for sym in fen:
if sym in bpieces:
black_str += sym
self.size += 1
if sym == 'k':
exception_check(sym, fen)
bking += 1
if bking > 1:
raise KingException
elif sym in wpieces:
white_str += sym
self.size += 1
if sym == 'K':
exception_check(sym, fen)
wking += 1
if wking > 1:
raise KingException
if sym == 'p' or sym == 'P':
if sym in self.fen_strings[0] or sym in self.fen_strings[7]:
raise PawnException
if wking == 0 or bking == 0:
raise KingException
self.white = ChessScore(white_str.lower())
self.black = ChessScore(black_str)
def get_white_score(self):
return self.white
def get_black_score(self):
return self.black
def white_is_winning(self):
return self.white > self.black
def black_is_winning(self):
return self.black > self.white
def is_equal(self):
return self.black == self.white
def __getitem__(self, item):
index = re.split('(\d+)', item)
print(index[1])
row = self.fen_strings[len(self.fen_strings) - int(index[1])]
cols = ['A', 'B', 'C', 'D', 'E', 'F', 'H', 'G']
br = 0
for let in cols:
if let == index[0].upper():
if br < len(row):
return row[br]
else:
break
br += 1
return 'None'
def __str__(self):
return self.fen
def __len__(self):
return self.size
class ChessScore:
def __init__(self, pieces):
self.pieces = pieces
self.point_vals = {'r': 5, 'n': 3, 'b': 3, 'q': 9, 'k': 4, 'p': 1}
self.total = 0
@property
def score(self):
if self.total != 0:
return self.total
for piece in self.pieces:
self.total += self.point_vals[piece]
return self.total
def __int__(self):
return self.score
def __add__(self, other):
self.total = self.score + other.score
def __sub__(self, other):
self.total = 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 __eq__(self, other):
return self.score == other.score