#🔒 Need help with this practice program from Automate the boring stuff

58 messages · Page 1 of 1 (latest)

clear mesa
#

Chess Dictionary Validator

In this chapter, we used the dictionary value {'h1': 'bK', 'c6': 'wQ', 'g2': 'bB', 'h5': 'bQ', 'e3': 'wK'} to represent a chessboard. Write a function named isValidChessBoard() that takes a dictionary argument and returns True or False depending on whether the board is valid.

A valid board will have exactly one black king and exactly one white king. Each player can have at most 16 pieces, of which only eight can be pawns, and all pieces must be on a valid square from '1a' to '8h'. That is, a piece can’t be on square '9z'. The piece names should begin with either a 'w' or a '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 chessboard. (This isn’t an exhaustive list of requirements, but it is close enough for this exercise.)

drifting krakenBOT
#

@clear mesa

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

clear mesa
#
import sys, copy

entry = input('enter your move: ')

STARTING_PIECES = {'a8': 'bR', 'b8': 'bNa', 'c8': 'bB', 'd8': 'bQ',
'e8': 'bK', 'f8': 'bB', 'g8': 'bN', 'h8': 'bR', 'a7': 'bP', 'b7': 'bP',
'c7': 'bP', 'd7': 'bP', 'e7': 'bP', 'f7': 'bP', 'g7': 'bP', 'h7': 'bP',
'a1': 'wR', 'b1': 'wN', 'c1': 'wB', 'd1': 'wQ', 'e1': 'wK', 'f1': 'wB',
'g1': 'wN', 'h1': 'wR', 'a2': 'wP', 'b2': 'wP', 'c2': 'wP', 'd2': 'wP',
'e2': 'wP', 'f2': 'wP', 'g2': 'wP', 'h2': 'wP'}

def startchecker(board):
    for piece in board:
        if piece in square.keys():
            if piece.startswith('w' or 'W'):
                for piece 

            print(f'piece exists: {piece}')


if str(entry).startswith('w'):
    ##count number of white pieces:





startchecker(entry)

# 0. check if piece names begin with 'w' or 'b' 
##1. check if both whites and blacks are only 16
##2. check if given input is in the dictionary's keys
##3. check if the input has one of each powers like queen, king
# 4. check if pieces are in the valid squares(check if the 3rd argument is a value from the dictionary keys)
#

This is all I can think of for now.

#

I don't know how to think about this problem

eager vale
# clear mesa I don't know how to think about this problem

Can you write the function header?

Then write out all the checks from the specification above; separate them into distinct sentences and make them comments in the function.
Sketch code, or at least logic, underneath each comment.
If you need to test how many of something there is, what other work might you need to do before that to make it easy?

clear mesa
#

Uhh

#

I'm unable to

#

I don't know how to say this but I'm not able to know where to start

#

with respect to the code

eager vale
#

Ok. Let's translate it.

"Write a function named isValidChessBoard() that takes a dictionary argument and returns True or False depending on whether the board is valid.

A valid board will have exactly one black king and exactly one white king. Each player can have at most 16 pieces, of which only eight can be pawns, and all pieces must be on a valid square from '1a' to '8h'. That is, a piece can’t be on square '9z'. The piece names should begin with either a 'w' or a '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 chessboard."

clear mesa
#

I know I'm supposed to count the pawns

eager vale
#

"Write a function named isValidChessBoard() that takes a dictionary argument and returns True or False depending on whether the board is valid" means:

def isValidChessBoard(board) -> bool:
clear mesa
#

Okay

eager vale
#

Fill in some comments:

  # A valid board will have exactly one black king and exactly one white king.
  # Each player can have at most 16 pieces, of which only eight can be pawns,
  # and all pieces must be on a valid square from '1a' to '8h'. That is, a piece can’t be on square '9z'.
  # The piece names should begin with either a 'w' or a '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 chessboard.
#

Then put code underneath each comment.

#

It can start as pseudocode: plain but simple English about how to test each comment

clear mesa
#

okay

eager vale
#

So can you fill in any of the bits?

clear mesa
#

I'll start counting with the pawns first?

#

Or should I see if the input is valid?

eager vale
#

It doesn't really matter. Whatever comes first to hand.

#

Also, think about the overall logic: you need to return False if the board is invalid.

#

There's a bit of a disconnect between them expecting pawn etc when the piece codes just have p etc. Just write it for p, since that's what's in the data.

clear mesa
#

wP = 0
def isvalidchessboard(board) -> bool:
    for square in board.keys():
        if board[square] == 'wP':
            wP = wP + 1
        if wP > 8:
            sys.exit("Invalid board: too many white pawns")    
#

So do I make counters similar to this?

eager vale
#

Ok, there are several things to modify here.
wP shouldn't be a global variable; everything you need to do should be local variables inside the function.
Also, inside the function wP is already a local variable. And thus unrelated to the wP in the global variables. It's local because you assign to it.
Anyway, move the wP = 0 to inside the function.

eager vale
# clear mesa So do I make counters similar to this?

I'd be inclined to make a dictionary containing the counts. That way:

  • the piece on the board is directly the key in the dictionary
  • you can then look up the dictionary afterwards to count pawns or kings or whatever.
#

So I'm suggesting: count everything. Then just look a the pieces you care about.

cosmic epoch
#

i.e. don't use sys.exit

clear mesa
#

Oh okay

#

sorry

#


def isvalidchessboard(board) -> bool:
    piececount = {wP : 0 , wK : 0, wQ : 0, wN : 0, wB : 0, wR : 0, bP : 0, bK: 0, bQ : 0, bN : 0, bB : 0, bR : 0 }


    for square in board.keys():
        if board[square] in STARTING_PIECES.keys():

            piececount[square] = piececount[square] + 1
        if piececount['wP'] > 8:
            return False
        elif piececount['wK'] > 1:
            return False
        elif 
        ```
#

I came up with something like this

#

still writing

eager vale
#

You'll need quotes around the keys of placecount.

#

Your validation count checks should happen outside the loop. So unindent them one level.

clear mesa
#

yeah forgot

#

Damn I had so much brain fog till you pointed out the obvious

#

Thanks a lot

#

def isvalidchessboard(board) -> bool:
    piececount = { 'wP' : 0 , 'wK' : 0, 'wQ' : 0, 'wN' : 0, 'wB' : 0, 'wR' : 0, 'bP' : 0, 'bK': 0, 'bQ': 0, 'bN' : 0, 'bB' : 0, 'bR': 0 }


    for square in board.keys():
        if board[square] in STARTING_PIECES.keys():

            piececount[square] = piececount[square] + 1
    if piececount['wP'] or piececount['bP']> 8:
        return False
    elif piececount['wK'] or piececount['bK'] > 1:
        return False
    elif piececount['wQ'] or piececount['bQ'] > 1:
        return False
    elif piececount['wN'] or piececount['bN'] > 2:
        return False
    elif piececount['wB'] or piececount['bB'] > 2:
        return False
    elif piececount['wR'] or piececount['bR'] > 2:
        return False
    elif square not in STARTING_PIECES.keys():
        return False
    
    else:
        return True

        ```
#

Ok this is what I could come up with

clear mesa
#

Ok I'm getting false negatives

#
 if board[square] in STARTING_PIECES.keys():

Function is returning this as false even when using a board with starting pieces

#
def isvalidchessboard(board) -> bool:
    piececount = { 'wP' : 0 , 'wK' : 0, 'wQ' : 0, 'wN' : 0, 'wB' : 0, 'wR' : 0, 'bP' : 0, 'bK': 0, 'bQ': 0, 'bN' : 0, 'bB' : 0, 'bR': 0 }


    for square in board.keys():
        if board[square] in STARTING_PIECES.keys():

            piececount[square] = piececount[square] + 1
        else:
            return False
                
    if piececount['wP'] or piececount['bP']> 8:
        return False
    elif piececount['wK'] or piececount['bK'] > 1:
        return False
    elif piececount['wQ'] or piececount['bQ'] > 1:
        return False
    elif piececount['wN'] or piececount['bN'] > 2:
        return False
    elif piececount['wB'] or piececount['bB'] > 2:
        return False
    elif piececount['wR'] or piececount['bR'] > 2:
        return False
        
    else:
        return True
cosmic epoch
#

it doesn't mean "if either piececount['wP'] or piececount['bP'] are greater than 8"

#

the or in programming is a logical or, it is used with two independent conditions

#

either side of the or is an expression in itself

#

!or-gotcha can explain it better, read vvv

drifting krakenBOT
#
The or-gotcha

When checking if something is equal to one thing or another, you might think that this is possible:

# Incorrect...
if favorite_fruit == 'grapefruit' or 'lemon':
    print("That's a weird favorite fruit to have.")

While this makes sense in English, it may not behave the way you would expect. In Python, you should have complete instructions on both sides of the logical operator.

So, if you want to check if something is equal to one thing or another, there are two common ways:

# Like this...
if favorite_fruit == 'grapefruit' or favorite_fruit == 'lemon':
    print("That's a weird favorite fruit to have.")

# ...or like this.
if favorite_fruit in ['grapefruit', 'lemon']:
    print("That's a weird favorite fruit to have.")
drifting krakenBOT
#
Python help channel closed for inactivity

This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.