我的棋盘验证程序有效,但给出的结果不正确
My chess-board validation program works, but gives an incorrect result
程序应该根据存储在变量中的任意字典是否满足棋盘的标准来打印 True 或 False。标准如下:
一个有效的棋盘只有一个黑王和一个白王。每个玩家最多只能有 16 个棋子,最多 8 个棋子,并且所有棋子必须在'1a'到'8h'的有效 space 上;也就是说,一块不能在 space '9z' 上。棋子名称以 'w' 或 'b' 开头,代表白色或黑色,然后是 'pawn'、'knight'、'bishop'、'rook'、 'queen',或 'king'。此函数应检测错误何时导致棋盘不正确。
我的程序是这样的:
board = {'1h': 'bking', '6c': 'wqueen', '2g': 'bbishop',\
'5h': 'bqueen', '3e': 'wking'}
def isValidChessBoard(_board_):
gen_num=0
pawn_num=0
wking_num=0
bking_num=0
letters=['a','b','c','d','e','f','g','h']
pieces=['pawn','knight','bishop','rook','king','queen']
for v in _board_.values():
gen_num+=1
if gen_num > 16:
return False
for v in _board_.values():
if v.endswith('pawn'):
pawn_num+=1
if pawn_num > 8:
return False
for v in _board_.values():
if v =='wking':
wking_num+=1
if v =='bking':
bking_num+=1
if wking_num!=1 or bking_num!=1:
return False
for k in _board_.keys():
for i in range(1,9):
if not k.startswith(str(i)):
return False
for k in _board_.keys():
for i in letters:
if not k.endswith(i):
return False
for v in _board_.values():
if not v.startswith('b') or v.startswith('w'):
return False
for v in _board_.values():
for i in pieces:
if not v.endswith(i):
return False
return True
print(isValidChessBoard(board))
该词典似乎符合给定的标准。但是,每次我尝试 运行 时,程序都会打印“'False'”。
我在这里遗漏了什么吗?
在此先感谢您,如果问题太基础或太宽泛,我深表歉意。
如果您暂时将所有 return False
替换为 raise Exception
那么很容易看出哪一部分是 returning False。
这样做之后我们可以看到这部分是问题所在:
for k in _board_.keys():
for i in range(1,9):
if not k.startswith(str(i)):
return False
不确定您要在那里做什么,我猜您是在尝试检查棋子的编号是否在 1 到 8 之间?使这项工作的一个小改动是:
for k in _board_.keys():
for i in range(1,9):
if k.startswith(str(i)):
break
else:
return False
如果找到匹配项,我们会中断,但如果没有中断,那么我们 return 错误。继续,我们发现您在另外两个地方犯了这个错误。
我们也可以看出这里的逻辑不太好:
if not v.startswith('b') or v.startswith('w'):
大概应该是这样的:
if not v.startswith('b') and not v.startswith('w'):
把所有这些放在一起你得到这个:
board = {'1h': 'bking', '6c': 'wqueen', '2g': 'bbishop',\
'5h': 'bqueen', '3e': 'wking'}
def isValidChessBoard(_board_):
gen_num=0
pawn_num=0
wking_num=0
bking_num=0
letters=['a','b','c','d','e','f','g','h']
pieces=['pawn','knight','bishop','rook','king','queen']
for v in _board_.values():
gen_num+=1
if gen_num > 16:
raise Exception
for v in _board_.values():
if v.endswith('pawn'):
pawn_num+=1
if pawn_num > 8:
raise Exception
for v in _board_.values():
if v =='wking':
wking_num+=1
if v =='bking':
bking_num+=1
if wking_num!=1 or bking_num!=1:
raise Exception
for k in _board_.keys():
for i in range(1,9):
if k.startswith(str(i)):
break
else:
raise Exception
for k in _board_.keys():
for i in letters:
if k.endswith(i):
break
else:
raise Exception
for v in _board_.values():
if not v.startswith('b') and not v.startswith('w'):
raise Exception
for v in _board_.values():
for i in pieces:
if v.endswith(i):
break
else:
raise Exception
return True
print(isValidChessBoard(board))
我建议保留 raise Exception
s 直到完成,此时您只需将它们替换为 return False
。
问题在于循环,例如:
for i in range(1,9):
if not k.startswith(str(i)):
return False
它坚持要以这些数字中的 all 开头,而不是以其中的 any 开头。循环可以替换为:
for i in range(1,9):
if k.startswith(str(i)):
break
else:
return False
注意条件是倒置的。如果 是 匹配项,则它会从循环中中断。如果找到 no 个匹配项,则将执行 else
块。注意这里的缩进:else
与 for
循环有关, 不是 if
块,如果 for 循环完成但未被执行,则会执行破.
有几个地方有类似的问题。
您还有一个地方需要括号:
if not (v.startswith('b') or v.startswith('w')):
因为不带括号的原文相当于:
if (not v.startswith('b')) or v.startswith('w'):
因为 not
的运算符优先级高于 or
.
等二元布尔运算符
将这些修复放在一起得到:
board = {'1h': 'bking', '6c': 'wqueen', '2g': 'bbishop',\
'5h': 'bqueen', '3e': 'wking'}
def isValidChessBoard(_board_):
gen_num=0
pawn_num=0
wking_num=0
bking_num=0
letters=['a','b','c','d','e','f','g','h']
pieces=['pawn','knight','bishop','rook','king','queen']
for v in _board_.values():
gen_num+=1
if gen_num > 16:
return False
for v in _board_.values():
if v.endswith('pawn'):
pawn_num+=1
if pawn_num > 8:
return False
for v in _board_.values():
if v =='wking':
wking_num+=1
if v =='bking':
bking_num+=1
if wking_num!=1 or bking_num!=1:
return False
for k in _board_.keys():
for i in range(1,9):
if k.startswith(str(i)):
break
else:
return False
for k in _board_.keys():
for i in letters:
if k.endswith(i):
break
else:
return False
for v in _board_.values():
if not (v.startswith('b') or v.startswith('w')):
return False
for v in _board_.values():
for i in pieces:
if v.endswith(i):
break
else:
return False
return True
print(isValidChessBoard(board))
程序应该根据存储在变量中的任意字典是否满足棋盘的标准来打印 True 或 False。标准如下: 一个有效的棋盘只有一个黑王和一个白王。每个玩家最多只能有 16 个棋子,最多 8 个棋子,并且所有棋子必须在'1a'到'8h'的有效 space 上;也就是说,一块不能在 space '9z' 上。棋子名称以 'w' 或 'b' 开头,代表白色或黑色,然后是 'pawn'、'knight'、'bishop'、'rook'、 'queen',或 'king'。此函数应检测错误何时导致棋盘不正确。
我的程序是这样的:
board = {'1h': 'bking', '6c': 'wqueen', '2g': 'bbishop',\
'5h': 'bqueen', '3e': 'wking'}
def isValidChessBoard(_board_):
gen_num=0
pawn_num=0
wking_num=0
bking_num=0
letters=['a','b','c','d','e','f','g','h']
pieces=['pawn','knight','bishop','rook','king','queen']
for v in _board_.values():
gen_num+=1
if gen_num > 16:
return False
for v in _board_.values():
if v.endswith('pawn'):
pawn_num+=1
if pawn_num > 8:
return False
for v in _board_.values():
if v =='wking':
wking_num+=1
if v =='bking':
bking_num+=1
if wking_num!=1 or bking_num!=1:
return False
for k in _board_.keys():
for i in range(1,9):
if not k.startswith(str(i)):
return False
for k in _board_.keys():
for i in letters:
if not k.endswith(i):
return False
for v in _board_.values():
if not v.startswith('b') or v.startswith('w'):
return False
for v in _board_.values():
for i in pieces:
if not v.endswith(i):
return False
return True
print(isValidChessBoard(board))
该词典似乎符合给定的标准。但是,每次我尝试 运行 时,程序都会打印“'False'”。
我在这里遗漏了什么吗?
在此先感谢您,如果问题太基础或太宽泛,我深表歉意。
如果您暂时将所有 return False
替换为 raise Exception
那么很容易看出哪一部分是 returning False。
这样做之后我们可以看到这部分是问题所在:
for k in _board_.keys():
for i in range(1,9):
if not k.startswith(str(i)):
return False
不确定您要在那里做什么,我猜您是在尝试检查棋子的编号是否在 1 到 8 之间?使这项工作的一个小改动是:
for k in _board_.keys():
for i in range(1,9):
if k.startswith(str(i)):
break
else:
return False
如果找到匹配项,我们会中断,但如果没有中断,那么我们 return 错误。继续,我们发现您在另外两个地方犯了这个错误。
我们也可以看出这里的逻辑不太好:
if not v.startswith('b') or v.startswith('w'):
大概应该是这样的:
if not v.startswith('b') and not v.startswith('w'):
把所有这些放在一起你得到这个:
board = {'1h': 'bking', '6c': 'wqueen', '2g': 'bbishop',\
'5h': 'bqueen', '3e': 'wking'}
def isValidChessBoard(_board_):
gen_num=0
pawn_num=0
wking_num=0
bking_num=0
letters=['a','b','c','d','e','f','g','h']
pieces=['pawn','knight','bishop','rook','king','queen']
for v in _board_.values():
gen_num+=1
if gen_num > 16:
raise Exception
for v in _board_.values():
if v.endswith('pawn'):
pawn_num+=1
if pawn_num > 8:
raise Exception
for v in _board_.values():
if v =='wking':
wking_num+=1
if v =='bking':
bking_num+=1
if wking_num!=1 or bking_num!=1:
raise Exception
for k in _board_.keys():
for i in range(1,9):
if k.startswith(str(i)):
break
else:
raise Exception
for k in _board_.keys():
for i in letters:
if k.endswith(i):
break
else:
raise Exception
for v in _board_.values():
if not v.startswith('b') and not v.startswith('w'):
raise Exception
for v in _board_.values():
for i in pieces:
if v.endswith(i):
break
else:
raise Exception
return True
print(isValidChessBoard(board))
我建议保留 raise Exception
s 直到完成,此时您只需将它们替换为 return False
。
问题在于循环,例如:
for i in range(1,9):
if not k.startswith(str(i)):
return False
它坚持要以这些数字中的 all 开头,而不是以其中的 any 开头。循环可以替换为:
for i in range(1,9):
if k.startswith(str(i)):
break
else:
return False
注意条件是倒置的。如果 是 匹配项,则它会从循环中中断。如果找到 no 个匹配项,则将执行 else
块。注意这里的缩进:else
与 for
循环有关, 不是 if
块,如果 for 循环完成但未被执行,则会执行破.
有几个地方有类似的问题。
您还有一个地方需要括号:
if not (v.startswith('b') or v.startswith('w')):
因为不带括号的原文相当于:
if (not v.startswith('b')) or v.startswith('w'):
因为 not
的运算符优先级高于 or
.
将这些修复放在一起得到:
board = {'1h': 'bking', '6c': 'wqueen', '2g': 'bbishop',\
'5h': 'bqueen', '3e': 'wking'}
def isValidChessBoard(_board_):
gen_num=0
pawn_num=0
wking_num=0
bking_num=0
letters=['a','b','c','d','e','f','g','h']
pieces=['pawn','knight','bishop','rook','king','queen']
for v in _board_.values():
gen_num+=1
if gen_num > 16:
return False
for v in _board_.values():
if v.endswith('pawn'):
pawn_num+=1
if pawn_num > 8:
return False
for v in _board_.values():
if v =='wking':
wking_num+=1
if v =='bking':
bking_num+=1
if wking_num!=1 or bking_num!=1:
return False
for k in _board_.keys():
for i in range(1,9):
if k.startswith(str(i)):
break
else:
return False
for k in _board_.keys():
for i in letters:
if k.endswith(i):
break
else:
return False
for v in _board_.values():
if not (v.startswith('b') or v.startswith('w')):
return False
for v in _board_.values():
for i in pieces:
if v.endswith(i):
break
else:
return False
return True
print(isValidChessBoard(board))