151 lines
3.7 KiB
Python
151 lines
3.7 KiB
Python
import sys
|
|
|
|
tests = [
|
|
# Valid
|
|
{
|
|
"1h": "bking",
|
|
"6c": "wqueen",
|
|
"2g": "bbishop",
|
|
"5h": "bqueen",
|
|
"3e": "wking",
|
|
},
|
|
# Invalid: Illegal total amount of pieces
|
|
{
|
|
"1a": "wrook",
|
|
"1b": "wknight",
|
|
"1c": "wbishop",
|
|
"1d": "wqueen",
|
|
"1e": "wking",
|
|
"1f": "wbishop",
|
|
"1g": "wknight",
|
|
"1h": "wrook",
|
|
"2a": "wpawn",
|
|
"2b": "wpawn",
|
|
"2c": "wpawn",
|
|
"2d": "wpawn",
|
|
"2e": "wpawn",
|
|
"2f": "wpawn",
|
|
"2g": "wpawn",
|
|
"2h": "wpawn",
|
|
"3a": "wrook",
|
|
},
|
|
# Invalid: Illegal amount of pieces
|
|
{
|
|
"8h": "wking",
|
|
"7h": "wking",
|
|
},
|
|
# Invalid: Illegal position length
|
|
{
|
|
"9": "bking",
|
|
},
|
|
# Invalid: Illegal position length
|
|
{
|
|
"9hh": "bking",
|
|
},
|
|
# Invalid: Illegal tile number
|
|
{
|
|
"9h": "bking",
|
|
},
|
|
# Invalid: Illegal tile letter
|
|
{
|
|
"1r": "bking",
|
|
},
|
|
# Invalid: Illegal player color
|
|
{
|
|
"8h": "cking",
|
|
},
|
|
# Invalid: Illegal piece name
|
|
{
|
|
"8h": "wring",
|
|
},
|
|
# Invalid: Illegal piece data type
|
|
{
|
|
"8h": None,
|
|
},
|
|
# Invalid: Illegal board data type
|
|
None,
|
|
]
|
|
|
|
|
|
def invalidAmount(name, present, expected):
|
|
err = f"AmountError: total {name}"
|
|
return f"{err}; total == {present}, expected: <= {expected}"
|
|
|
|
|
|
def invalidPos(name, pos, present, expected):
|
|
err = f"PositionError: {name} '{pos}'"
|
|
return f"{err}; length == {present}, expected: {expected}"
|
|
|
|
|
|
def invalidPiece(name, color_piece, present, expected):
|
|
err = f"PieceError: {name} '{color_piece}'"
|
|
return f"{err}; {name} == {present}, expected: {expected}"
|
|
|
|
|
|
def invalidType(name, present, expected):
|
|
err = f"TypeError: {name} type"
|
|
return False, f"{err}; type == {present}, expected: {expected}"
|
|
|
|
|
|
def isValidPos(pos):
|
|
if len(pos) != 2:
|
|
return invalidPos("length", pos, len(pos), 2)
|
|
number, letter = pos[0], pos[1]
|
|
if number not in "12345678":
|
|
return invalidPos("number", pos, number, "1-8")
|
|
if letter not in "abcdefgh":
|
|
return invalidPos("letter", pos, letter, "a-h")
|
|
|
|
|
|
def isValidPiece(color_piece):
|
|
pieces = "pawn knight bishop rook queen king".split()
|
|
color, piece = color_piece[0], color_piece[1:]
|
|
if color not in "bw":
|
|
return invalidPiece("color", color_piece, color, "w | b")
|
|
if piece not in pieces:
|
|
return invalidPiece("piece", color_piece, piece, " | ".join(pieces))
|
|
|
|
|
|
def isValidAmount(player):
|
|
totals = {
|
|
"all": 16,
|
|
"pawn": 8,
|
|
"king": 1,
|
|
}
|
|
total = 0
|
|
for key, val in totals.items():
|
|
if key in player.keys() and player[key] > val:
|
|
return invalidAmount(f"'{key}'", player[key], val)
|
|
for val in player.values():
|
|
total += val
|
|
if total > totals["all"]:
|
|
return invalidAmount("pieces", total, totals["all"])
|
|
|
|
|
|
def isValidChessBoard(board):
|
|
players, valid, msg = {}, True, "Valid"
|
|
if not isinstance(board, dict):
|
|
return invalidType("board", type(board), type({}))
|
|
for pos, piece in board.items():
|
|
if not isinstance(piece, str):
|
|
return invalidType("piece", type(piece), type(""))
|
|
players.setdefault(piece[0], {})
|
|
player = players[piece[0]]
|
|
player.setdefault(piece[1:], 0)
|
|
player[piece[1:]] += 1
|
|
checks = [isValidPos(pos), isValidPiece(piece), isValidAmount(player)]
|
|
for check in checks:
|
|
if check is not None:
|
|
valid, msg = False, check
|
|
break
|
|
return valid, msg
|
|
|
|
|
|
valid = True
|
|
for test in tests:
|
|
print(f"Testing board '{test}': ")
|
|
valid, msg = isValidChessBoard(test)
|
|
print("=>", msg)
|
|
if not valid:
|
|
sys.exit(1)
|