Python 我的棋盘验证程序运行正常,但给出的结果不正确

Python 我的棋盘验证程序运行正常,但给出的结果不正确,python,chess,Python,Chess,根据存储在变量中的任意字典是否符合棋盘的标准,程序应该打印True或False。准则如下: 一个有效的棋盘上只有一个黑王和一个白王。每个玩家最多只能有16个棋子,最多8个棋子,并且所有棋子必须在“1a”到“8h”的有效空间内;也就是说,一块不能在空间“9z”上。作品名称以“w”或“b”开头,代表白色或黑色,然后是“兵”、“骑士”、“主教”、“车”、“女王”或“国王”。当错误导致棋盘不正确时,此功能应检测。 我的程序如下所示: board = {'1h': 'bking', '6c': 'wque

根据存储在变量中的任意字典是否符合棋盘的标准,程序应该打印True或False。准则如下: 一个有效的棋盘上只有一个黑王和一个白王。每个玩家最多只能有16个棋子,最多8个棋子,并且所有棋子必须在“1a”到“8h”的有效空间内;也就是说,一块不能在空间“9z”上。作品名称以“w”或“b”开头,代表白色或黑色,然后是“兵”、“骑士”、“主教”、“车”、“女王”或“国王”。当错误导致棋盘不正确时,此功能应检测。

我的程序如下所示:

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”

这里有我遗漏的东西吗


提前非常感谢,如果问题太基本或太宽泛,我深表歉意。

如果您临时将所有
返回False
替换为
引发异常
,那么很容易看到哪个部分返回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
如果我们找到一个匹配项,我们会中断,但是如果没有中断,我们会返回false。继续,我们发现你在另外两个地方犯了这个错误

我们还可以看到,这里的逻辑不是很好:

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))

我建议将
raiseexception
s保留到它完成时,此时您只需将它们替换为
return False

如果您临时将所有
return False
替换为
raiseexception
,则很容易看到哪个部分返回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
如果我们找到一个匹配项,我们会中断,但是如果没有中断,我们会返回false。继续,我们发现你在另外两个地方犯了这个错误

我们还可以看到,这里的逻辑不是很好:

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))

我建议将
raiseexception
s保留到它完成时,此时您只需将它们替换为
return False

问题在于循环,例如:

        for i in range(1,9):
            if not k.startswith(str(i)):
                return False
它坚持要从所有这些数字开始,而不是从任何数字开始。该回路可替换为:

        for i in range(1,9):
            if k.startswith(str(i)):
                break
        else:
            return False
请注意,条件是相反的。如果存在匹配,则它将从循环中中断。如果未找到匹配项,则将执行
else
块。注意此处的缩进:
else
for
循环相关,而不是
if
块,如果for循环完成而没有中断,则将执行该块

有几个地方也有类似的问题

还有一个地方需要括号:

        if not (v.startswith('b') or v.startswith('w')):
因为不带括号的原文相当于:

        if (not v.startswith('b')) or v.startswith('w'):
因为
not
的运算符优先级高于二进制布尔运算符,如

将这些修复组合在一起可以提供:

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))

问题在于循环,例如:

        for i in range(1,9):
            if not k.startswith(str(i)):
                return False
它坚持要从所有这些数字开始,而不是从任何数字开始。该回路可替换为:

        for i in range(1,9):
            if k.startswith(str(i)):
                break
        else:
            return False
请注意,条件是相反的。如果存在匹配,则它将从循环中中断。如果未找到匹配项,则将执行
else
块。注意此处的缩进:
else
for
循环相关,而不是
if
块,如果for循环完成而没有中断,则将执行该块

有几个地方也有类似的问题

还有一个地方需要括号:

        if not (v.startswith('b') or v.startswith('w')):
因为不带括号的原文相当于:

        if (not v.startswith('b')) or v.startswith('w'):
因为
not
的运算符优先级高于二进制布尔运算符,如

将这些修复组合在一起可以提供:

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))

这正是我想要实现的,是的。我还是不明白怎么回事?在我第一次运行程序时,同一个块给出了一条错误消息,但那是因为我没有将“I”传递给string函数。在我做了之后,程序运行了,但是打印错误…我扩展了我的答案。如果不断出现错误,则需要练习调试。将
print()
语句放在任何地方,或引发
异常
,以便您可以遵循代码trail@Mandera例外情况是一个很好的建议。我在每个返回语句之前都尝试了不同的“打印”语句(在得出与您关于代码本身相同的结论之前),但是快速搜索和替换
引发异常
肯定更快更容易。@alaniwi哈哈,我也在做同样的事,但谢谢!这正是我想要实现的,是的。我还是不明白怎么回事?在我第一次运行程序时,同一个块给出了一条错误消息,但那是因为我没有将“I”传递给string函数。在我做了之后,程序运行了,但是打印错误…我扩展了我的答案。如果不断出现错误,则需要练习调试。将
print()
语句放在任何地方,或引发
异常
,以便您可以遵循代码trail@Mandera例外情况是一个很好的建议。我费尽心思把不同的东西放进去