我可以在 python 中对具有多个条件的 if-else 语句使用嵌套 for 循环吗?

2024-03-17

我编写了一个程序来检查棋盘是否有效。在我的代码的一部分中,我测试了各个部分的数量是否正确。

count 是字典,它是我要检查的板的库存。例如(b代表黑色,w代表白色):

count = {'bking': 1, 'wking': 1, 'bpawn': 3, 'bbishop': 1, 'wrook': 1, 'wqueen': 1}

可能的颜色和款式可在列表中找到:

colors = ['b', 'w']
pieces = ['queen', 'rook', 'knight', 'bishop', 'pawn']

我有以下带有多个条件的丑陋的 if-else 语句:

if count['bking'] == 1 and \
    count['wking'] == 1 and \
    count.get('bqueen', 0) <= 2 and \
    count.get('wqueen', 0) <= 2 and \
    count.get('bpawn', 0) <= 8 and \
    count.get('wpawn', 0) <= 8 and \
    count.get('brook', 0) <= 2 and \
    count.get('wrook', 0) <= 2 and \
    count.get('bknight', 0) <= 2 and \
    count.get('wknight', 0) <= 2 and \
    count.get('bbishop', 0) <= 2 and \
    count.get('wbishop', 0) <= 2 and \
    len(board) <= 32:
        return True
    else:
        return False

有没有办法用嵌套的 for 循环来简化这个 if-else 结构?我意识到 get() 方法的代码行非常重复。我的想法是创建一个迭代颜色的外部 for 循环和迭代各个片段的内部循环。 get() 调用中的第一个参数是颜色列表中的项目与片段列表中的项目的串联。有没有办法做到这一点?

有没有另一种方法可以使这个 if-else 语句更加Pythonic?

这是我的第一次尝试:

for c in colors:
   for p in pieces[:4]:
      if count.get(c + p, 0) <= 2:
   if count.get(c + pieces[-1], 0) <= 8:
      return = True
   else:
      return = False

但这不起作用,我收到语法错误或缩进错误。

我的原始代码似乎有效如下:

# chessDictValidator.py

def boardInventory(board):
    # Makes an inventory of the board to be evaluated.
    count = {}
    for value in board.values():
        count.setdefault(value, 0)
        count[value] += 1
    return count

def boardCounter(board):
    # Checks if amounts of pieces are valid.
    count = boardInventory(board)
    if count['bking'] == 1 and \
    count['wking'] == 1 and \
    count.get('bqueen', 0) <= 2 and \
    count.get('wqueen', 0) <= 2 and \
    count.get('bpawn', 0) <= 8 and \
    count.get('wpawn', 0) <= 8 and \
    count.get('brook', 0) <= 2 and \
    count.get('wrook', 0) <= 2 and \
    count.get('bknight', 0) <= 2 and \
    count.get('wknight', 0) <= 2 and \
    count.get('bbishop', 0) <= 2 and \
    count.get('wbishop', 0) <= 2 and \
    len(board) <= 32:
        return True
    else:
        return False

def fieldValidator(board):
    # Checks if the board contains valid fields.
    fieldOK = 0
    for key in board.keys():
        if key[0] in fieldInt and key[1] in fieldChar:
            fieldOK += 1
        else:
            return False
    if fieldOK == len(board):
        return True

def pieceValidator(board):
    # Checks if the pieces are spelled correctly.
    pieceOK = 0
    for value in board.values():
        if value[0] in pieceColor and value[1:] in pieces:
            pieceOK += 1
        else:
            return False
    if pieceOK == len(board):
        return True

def boardValidator(board):
    # Checks if the board is valid, depending on the tests above. Prints an error message when board is invalid.
    valid = 'This is a valid chess board!'
    invalid = 'Invalid chess board!'
    wrong = 'There is a wrong {0} in your board!'
    numPieces = 'There is something wrong with the allowed amount of pieces!'
    if fieldValidator(board) and pieceValidator(board) and boardCounter(board):
        print(valid)
    elif fieldValidator(board) == False:
        print(invalid, wrong.format('field'))
    elif pieceValidator(board) == False:
        print(invalid, wrong.format('piece'))
    elif boardCounter(board) == False:
        print(invalid, numPieces)

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

fieldInt = ['1', '2', '3', '4', '5', '6', '7', '8']
fieldChar = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
pieceColor = ['b', 'w']
pieces = ['king', 'queen', 'knight', 'rook', 'bishop', 'pawn']

boardValidator(board)

首先,我建议将这项检查外包给专门的职能部门。

其次,您可以使用具有预期最大值的字典,并使用理解all()以便更简洁地执行检查。

max_counts = {
    'bking': 1,
    'bqueen': 1,
    'brook': 2,
    'bknight': 2,
    'bbishop': 2,
    'bpawn': 8,
    'wking': 1,
    'wqueen': 1,
    'wrook': 2,
    'wknight': 2,
    'wbishop': 2,
    'wpawn': 8
}

def board_is_valid(count, board):
    return len(board) <= 32 and all(
               count[piece] <= ct 
               for (piece, ct) in max_counts.items()
           )

如果你想稍微不那么冗长max_counts,您可以尝试创建一个具有基本计数的虚拟字典king, queen, rook等,并使max_counts添加该列表的两个副本的结果,其中一个带有'b'每个键和另一个键的前缀为'w'。但如果这是整套作品,我认为这是没有必要的。


还要考虑到这可能不是验证棋盘的万无一失的方法。兵可以升级为除国王之外的任何其他类型的棋子,因此技术上可以拥有多于一个后或两个以上的车。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我可以在 python 中对具有多个条件的 if-else 语句使用嵌套 for 循环吗? 的相关文章

随机推荐