dimanche 2 février 2020

Automate the Boring Stuff - Chapter 5 - Chess Dictionary Validator

First post, new to programming and having fun! All feedback on this post and my questions are welcome.

I'm working through Automate the Boring Stuff and attacking the first Chapter 5 problem Chess Dictionary Validator.

In this chapter, we used the dictionary value {'1h': 'bking', '6c': 'wqueen', '2g': 'bbishop', '5h': 'bqueen', '3e': 'wking'} to represent a chess board. Write a function named isValidChessBoard() that takes a dictionary argument and returns True or False depending on if the board is valid.

A valid board will have exactly one black king and exactly one white king. Each player can only have at most 16 pieces, at most 8 pawns, and all pieces must be on a valid space from '1a' to '8h'; that is, a piece can’t be on space '9z'. 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.

my questions and code:

  1. Is evaluating dictionary keys/values through these for loops + multiple if statements the "best practice"? It seems like a lot of code. Changing to include some elif caused issues if it followed with another if statement in the for loop.
  2. Line 23 if i[0] == 'b': errors out because the chess spaces which are empty string values have no character at i[0]. What's the best way to express/evaluate empty values? If it is with '', should I add leading condition in the loop which evaluates value == '', and then 'continue'?
  3. Why can I not collapse line 15 into 11 such that I have one statement: if 'bking' or 'wking' not in board.values():? If I try that, the statement result is True; however the dictionary contains both values so shouldn't it evaluate to False and keep the code running?
def isValidChessBoard(board):
    while True:
        blackPieces = 0
        whitePieces = 0
        wpawn = 0
        bpawn = 0
        letterAxis = ('a','b','c','d','e','f','g','h')
        pieceColour = ('b','w')
        pieceType = ('pawn','knight','bishop','rook','queen','king')

        #one black king and one white king
        if 'bking' not in board.values():
            print('KingError')
            return False
            break
        if 'wking' not in board.values():
            print('KingError')
            return False
            break

        #each player has <= 16 pieces
        for i in board.values():
            if i[0] == 'b':
                blackPieces+=1
            if i[0] == 'w':
                whitePieces+=1
            if whitePieces >= 17:
                print('TotalPieceError')
                return False
                break
            if blackPieces >= 17:
                print('TotalPieceError')
                return False
                break

        #each player has <= 8 pawns
        for i in board.values():
            if i == 'wpawn':
                wpawn+=1
            elif i == 'bpawn':
                bpawn+=1
            if wpawn or bpawn >= 9:
                print('PawnError')
                return False
                break

        #all pieces must be on valid space from '1a' to '8h'
        for i in board.keys():
            if int(i[0]) >= 9:
                print('SpacesError')
                return False
                break
            if i[1] not in letterAxis:
                print('yAxisError')
                return False
                break

        #piece names begin with 'w' or 'b'
        for i in board.values():
            if i[0] not in pieceColour:
                print('WhiteOrBlackError')
                return False
                break

        #piece names must follow with 'pawn', 'knight', 'bishop', 'rook', 'queen', 'king'
        for i in board.values():
            if i[1:] not in pieceType:
                print('PieceTypeError')
                return False
        return 'This board checks out'

board = {'1a': 'bking','2a': 'bqueen','3a': 'brook','4a': 'brook',
'5a': 'bknight','6a': 'bknight','7a':'bbishop','8a': 'bbishop',
'1b': 'bpawn','2b': 'bpawn','3b': 'bpawn','4b':'bpawn',
'5b': 'bpawn','6b': 'bpawn','7b': 'bpawn','8b': 'bpawn',
'1c': 'wking','2c': 'wqueen','3c': 'wrook','4c': 'wrook',
'5c': 'wbishop','6c': 'wbishop','7c': 'wknight','8c':'wknight',
'1e': 'wpawn','2e': 'wpawn','3e': 'wpawn','4e': 'wpawn',
'5e': 'wpawn','6e': 'wpawn','7e': 'wpawn','8e': 'wpawn',
'1f': '','2f': '','3f': '','4f': '','5f': '','6f': '','7f': '','8f': '',
'1g': '','2g': '','3g': '','4g': '','5g': '','6g': '','7g': '','8g': '',
'1h': '','2h': '','3h': '','4h': '','5h': '','6h': '','7h': '','8h': '',}

print(isValidChessBoard(board))

Error:
Traceback (most recent call last):
line 23, in isValidChessBoard
    if i[0] == 'b':
IndexError: string index out of range

Aucun commentaire:

Enregistrer un commentaire