《Python编程快速上手——让繁琐工作自动化 第2版》
5.6 实践项目
5.6.1 国际象棋字典验证器
在本章中,我们用字典值{'1h': 'bKing', '6c': 'wQueen', '2g': 'bBishop', '5h': 'bQueen', '3e': 'wKing'}代表棋盘。编写一个名为isValidChessBoard()的函数,该函数接收一个字典作为参数,根据棋盘是否有效,返回True或False。
一个有效的棋盘只有一个黑王和一个白王。每个玩家最多只能有16个棋子,最多8个兵,并且所有棋子必须位于从'1a'到'8h'的有效位置内:也就是说,棋子不能在位置'9z'上。棋子名称以'w'或'b'开头,代表白色或黑色;然后是'Pawn'、'Knight'、'Bishop'、'Rook'、'Queen'、或'King'。如果出现了“棋盘不正确”的错误,这个函数应该能检测出来。
——————————————————————————————————————
def isValidChessBoard(board):
# 检查棋盘位置有效性
valid_positions = {f"{row}{col}" for row in '12345678' for col in 'abcdefgh'}
"""这是一个集合推导式,等效于:
valid_positions = set()
for row in '12345678': # 遍历1-8行
for col in 'abcdefgh': # 遍历a-h列
valid_positions.add(f"{row}{col}") # 组合成"1a"格式的位置
生成示例:
执行后会生成包含64个棋盘位置的集合:
{'1a', '1b', '1c', ..., '8f', '8g', '8h'}
具体前几项为:
第1行:'1a', '1b', '1c', '1d', '1e', '1f', '1g', '1h'
第2行:'2a', '2b', ..., '2h'
...
第8行:'8a', '8b', ..., '8h'"""
for position in board.keys():
if position not in valid_positions:
return False
# 初始化计数器
piece_counts = {
'w': {'Pawn': 0, 'King': 0, 'Queen': 0, 'Rook': 0, 'Bishop': 0, 'Knight': 0},
'b': {'Pawn': 0, 'King': 0, 'Queen': 0, 'Rook': 0, 'Bishop': 0, 'Knight': 0}
}
# 检查棋子命名有效性并计数
valid_pieces = {'Pawn', 'Knight', 'Bishop', 'Rook', 'Queen', 'King'}
for piece in board.values():
if len(piece) < 2 or piece[0] not in ('w', 'b'):
return False
piece_type = piece[1:]
if piece_type not in valid_pieces:
return False
color = piece[0]
piece_counts[color][piece_type] += 1
# 检查棋子数量限制
for color in ('w', 'b'):
total_pieces = sum(piece_counts[color].values())
if total_pieces > 16:
return False
if piece_counts[color]['Pawn'] > 8:
return False
if piece_counts[color]['King'] != 1:
return False
if piece_counts[color]['Queen'] > 1:
return False
if piece_counts[color]['Bishop'] > 2:
return False
if piece_counts[color]['Rook'] > 2:
return False
if piece_counts[color]['Knight'] > 2:
return False
return True
# 测试用例
test_board = {'1h':'wRook','1e': 'bKing', '6c': 'wQueen', '2g': 'bBishop', '5h': 'bQueen', '3e': 'wKing','7c':'bBishop'}
print(isValidChessBoard(test_board)) # 应返回True
399

被折叠的 条评论
为什么被折叠?



