This is an exercise in the Automate The Boring Stuff book. I am supposed to create a function that takes a dictionary argument that represents a chess board (ex: {'1h': 'bking', '6c': 'wqueen', '2g': 'bbishop', etc.}) and returns True or False depending on if the board is valid.
A valid board will have (A) exactly one black king and exactly one white king. (B) Each player can only have at most 16 pieces, (C) at most 8 pawns, and (D) all pieces must be on a valid space from '1a' to '8h'; that is, a piece can’t be on space '9z'. (E) The piece names begin with either a 'w' or 'b' to represent white or black, followed by 'pawn', 'knight', 'bishop', 'rook', 'queen', or 'king'. This function should detect when a bug has resulted in an improper chess board.
#Example dictionary of coordinates (keys) and pieces (values)
#my_board = {"1a":"wking", "2a":"bking", "8b":"wpawn", "3a":"wpawn"}
def isValidChessBoard(board):
#Creating a dictionary of pieces (keys) and the number of pieces (values)
num_pieces = {}
list_pieces = ["bpawn", "bking", "bqueen", "brook", "bbishop", "bknight", "wpawn", "wking", "wqueen", "wrook", "wbishop", "wknight"]
for v in board.values():
num_pieces.setdefault(v, 0)
num_pieces[v] = num_pieces[v] + 1
for i in list_pieces:
if i not in num_pieces:
num_pieces.setdefault(i, 0)
#Making sure there is exactly one king on each side
if (num_pieces["wking"] != 1) or (num_pieces["bking"] != 1):
return False
#Making sure there are no more than 8 pawns on each side
if ("bpawn" or "wpawn" in num_pieces) and (num_pieces["bpawn"] or num_pieces["wpawn"]) > 8:
return False
#Making sure every piece is apprpriately named (b/w + king/queen/rook/pawn/knight/bishop)
for j in num_pieces:
if j not in list_pieces:
return False
#Making sure there are no more than 16 pieces on each side
if num_pieces["bpawn"] + num_pieces["bking"] + num_pieces["bqueen"] + num_pieces["brook"] + num_pieces["bbishop"] + num_pieces["bknight"] > 16:
return False
if num_pieces["wpawn"] + num_pieces["wking"] + num_pieces["wqueen"] + num_pieces["wrook"] + num_pieces["wbishop"] + num_pieces["wknight"] > 16:
return False
#Making sure that the board coordinates are all between (a-h, and 1-8)
in_range = 0
possible_coordinates = []
for i in range(1, 9):
for j in ["a", "b", "c", "d", "e", "f", "g", "h"]:
possible_coordinates.append(str(i)+str(j))
for k in board.keys():
if k in possible_coordinates:
in_range = in_range + 1
if len(board) != in_range:
return False
return True
if isValidChessBoard(my_board) == True:
print("Valid Board")
else:
print("Invalid Board")
I know that the code works, but I was wondering if there were any faux-pas that I am implementing, or if there is anything I could obviously do to make it cleaner. Thanks!
for i in list_pieces: if i not in num_pieces: num_pieces.setdefault(i, 0)
mean? I understand what everything else means thanks \$\endgroup\$