我编写了一个程序来检查棋盘是否有效。在我的代码的一部分中,我测试了各个部分的数量是否正确。
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)