Hakunok
Hakunok

Reputation: 9

Chess Dictionary Validator code keeps returning FALSE

I'm relatively new to coding, so any criticism is appreciated. I just finished chapter 5 of Automate the Boring Stuff and started the practice projects of the chapter. I've looked at other codes on the same project to see their takes on it, and to see how I can do it. But the code keeps returning False as the value, and I'm not sure where the issue is.

import string

chessboard = {'1h': 'bking', '6c': 'wqueen', '2g': 'bbishop', '5h': 'bqueen', '3e': 'wking'}

def isValidChessBoard(chessboard):

    # Define the components 
    bpieces, wpieces = 0, 0
    bking, wking, bpawn, wpawn = 0, 0, 0, 0
    valid = True
    coord = True
    
    # Check if board has exactly 1 black and white king.
    if bking and wking != 1:
        valid = False
    
    # Check if there are at most 16 pieces, at most 8 pawns, and must be within '1a' and '8h'. 
    if bpieces or wpieces > 16:
        valid = False
    if bpawn or wpawn > 8: 
        valid = False
    
    for x in range(1,9):
        for y in list(map(chr,range(ord('a'), ord('h')+1))):
            coord = True
    
    # Check if the pieces begins with 'b' or 'w'; followed by 'pawn', 'knight', 'bishop', 'rook', 'queen' or 'king'.
    for piece in chessboard.values():
    
        if piece != 'b' or 'w' + 'pawn' or 'knight' or 'bishop' or 'rook' or 'queen' or 'king':
            valid = False
    
    if valid and coord:
        return True
    else:
        return False
    
print(isValidChessBoard(chessboard))

I think the issue is around here:

if piece != 'b' or 'w' + 'pawn' or 'knight' or 'bishop' or 'rook' or 'queen' or 'king': 
    valid = False

But I'm not sure, with how little experience I have with codes.

Upvotes: 0

Views: 255

Answers (1)

Nipuna Upeksha
Nipuna Upeksha

Reputation: 428

The value False comes because your chessboard is not getting checked for its pieces and your default values for bpieces and wpieces are 0 and the default values for bking, wking, bpawn and wpawn are 0. And some of your checks are getting overridden in later checks. This is a plausible code snippet I came up with. I hope you can improve it.

import string
from collections import Counter

chessboard = {'1h': 'bking', '6c': 'wqueen', '2g': 'bbishop', '5h': 'bqueen', '3e': 'wking'}

def isValidChessBoard(chessboard):

    # count the number of pieces in board
    res = dict(Counter(chessboard.values()))
    
    # Define the components 
    bpieces, wpieces = sum([v for k,v in res.items() if k[0]=='b']), sum([v for k,v in res.items() if k[0]=='w'])
    bking, wking, bpawn, wpawn = res['bking'] if 'bking' in res.keys() else 0, res['wking'] if 'wking' in res.keys() else 0, res['bpawn'] if 'bpawn' in res.keys() else 0, res['wpawn'] if 'wpawn' in res.keys() else 0
    
    # Check if board has exactly 1 black and white king.
    if bking !=1 or wking != 1:
        return False
    
    # Check if there are at most 16 pieces, at most 8 pawns, and must be within '1a' and '8h'. 
    if bpieces > 16 or wpieces > 16:
        return False
    if bpawn > 8 or wpawn > 8: 
        return False
    
    for pos in chessboard.keys():
        if pos[0] not in range(0,9) and pos[1] not in ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']:
            return False
    
    # Check if the pieces begins with 'b' or 'w'; followed by 'pawn', 'knight', 'bishop', 'rook', 'queen' or 'king'.
    pieces_list = ['king', 'queen', 'pawn', 'knight', 'bishop', 'rook']
    for piece in chessboard.values():
        if (piece[0] != 'b' or piece[0]!='w') and piece[1:] not in pieces_list:
            return False
    
    return True
    
print(isValidChessBoard(chessboard))

Upvotes: 1

Related Questions