《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'。如果出现了“棋盘不正确”的错误,这个函数应该能检测出来。
运行代码:
包含各种异常情况的字典,可打开注释运行查看结果
from typing import Dict
# 正常
chessboard_dict: Dict[str, str] = {'1h': 'bKing', '6c': 'wQueen', '2g': 'bBishop', '5h': 'bQueen', '3e': 'wKing'}
# 棋盘范围错误
# chessboard_dict: Dict[str, str] = {'1h': 'bKing', '6c': 'wQueen', '2g': 'bBishop', '5h': 'bQueen', '3e': 'wKing', '9z': 'bBishop'}
# 单方多King
# chessboard_dict: Dict[str, str] = {'1h': 'bKing', '6c': 'wQueen', '2g': 'bBishop', '5h': 'bQueen', '3e': 'wKing', '4e': 'wKing'}
# 单方少King
# chessboard_dict: Dict[str, str] = {'1h': 'bKing', '6c': 'wQueen', '2g': 'bBishop', '5h': 'bQueen'}
# 单方多棋子
# chessboard_dict: Dict[str, str] = {'1h': 'bKing', '6c': 'wQueen', '2g': 'bBishop', '5h': 'bQueen', '3e': 'wKing', '4e': 'bQueen', '5e': 'bQueen'}
# 棋子名称错误/不存在
# chessboard_dict: Dict[str, str] = {'1h': 'bKing', '6c': 'wQueen', '2g': 'bBishop', '5h': 'bQueen', '3e': 'wKing', '4e': 'sjv'}
def isValidChessBoard(originaldict: Dict[str, str]):
chessboard_list = []
for x in range(1, 9):
for y in [chr(i) for i in range(ord('a'), ord('h') + 1)]:
chessboard_list.append(str(x) + str(y))
# print(chessBoard_list)
chessman_list = []
for i in ['b', 'w']:
for j in ['King', 'Queen', 'Rook', 'Bishop', 'Knight', 'Pawn']:
chessman_list.append(str(i) + str(j))
# print(chessman_list)
chessman_counts = {}
for key, value in originaldict.items():
if key not in chessboard_list:
print(f'Chessboard range error:{key}')
return False
if value not in chessman_list:
print(f'Wrong chess piece name:{value}')
return False
if value in chessman_counts:
chessman_counts[value] += 1
else:
chessman_counts[value] = 1
# print(chessman_counts)
if not ((chessman_counts.get('bKing', 0) == 1) and (chessman_counts.get('wKing', 0) == 1)):
print('The number of king is incorrect')
return False
elif not ((chessman_counts.get('bQueen', 0) in list(range(2))) and (
chessman_counts.get('wQueen', 0) in list(range(2)))):
print('The number of Queen is incorrect')
return False
elif not ((chessman_counts.get('bRook', 0) in list(range(3))) and (
chessman_counts.get('wRook', 0) in list(range(3)))):
print('The number of Rook is incorrect')
return False
elif not ((chessman_counts.get('bBishop', 0) in list(range(3))) and (
chessman_counts.get('wBishop', 0) in list(range(3)))):
print('The number of Bishop is incorrect')
return False
elif not ((chessman_counts.get('bKnight', 0) in list(range(3))) and (
chessman_counts.get('wKnight', 0) in list(range(3)))):
print('The number of Knight is incorrect')
return False
elif not ((chessman_counts.get('bPawn', 0) in list(range(9))) and (
chessman_counts.get('wPawn', 0) in list(range(9)))):
print('The number of Pawn is incorrect')
return False
else:
return True
print(isValidChessBoard(chessboard_dict))
运行结果:
正常:
True
进程已结束,退出代码0
异常:
Chessboard range error:9z
False
进程已结束,退出代码0
题干个人理解:
题目要求:
1.1a-8h代表棋盘
2.w和b代表阵容
3.以位置为键,以棋子为值
isValidChessBoard函数需要校验:
1.棋盘范围
2.必须有且仅有一个白王King和一个黑王
3.除王外,每位玩家最多有1后Queen、2战车Rook、2主教Bishop、2骑士Knight、8兵Pawn(国际象棋规则)
4.玩家不能有除以上六种棋子外的其他棋子
5.返回True或False