布尔函数,用于确定白王是否在棋盘上的给定位置检查
Boolean function to determine if white king is in check given positions on a chess board
我正在尝试编写一个程序,如果棋盘上的白王已被选中,该程序将 return 为真。棋盘上的棋子以字符串形式生成并格式化,其中小写值为白色,大写为黑色。:
r*x***k****p***P*****Q*****kp****K*****p***Pb****p***PP***X***KR
| | |X| | | |K|R|
| |p| | | |P|P| |
| | | |P|b| | | |
| |K| | | | | |p|
| | | |k|p| | | |
| | | | | |Q| | |
| | | |p| | | |P|
|r| |x| | | |k| |
我了解如何将棋盘上的单位转换为 x 和 y 坐标,以及棋盘上棋子的数学运算(在 +7 和 +9 上检查兵,在...-2 上检查车, -1、+1、+2...和...-16、-8、+8、+16...,但我无法将其转换为 python,或者停止检查击中另一块或在它“通过”板之前再次循环。到目前为止,这是我的代码,但没有真正正常工作:
def white_check(coded_position):
w_king = coded_position.find("x")
w_king_x = w_king%8
w_king_y = w_king//8
result = False
print(w_king)
# This doesn't work if king is on x = 0 or 8
# Returns true if pawn checks
# if coded_position[w_king+7] == "P" or coded_position[w_king+9] == "P":
#result = True
# try using for loops and going up 1 / 8 at a time and trying each case for rooks / and bishops
# checks right side for rooks
for i in range(w_king,w_king-w_king_x+8):
if coded_position[i] != "*" and coded_position[i] != "K":
result = False
break
if coded_position[i] == "K":
result = True
# checks left side for rooks
for i in range(w_king,w_king-w_king_x,-1):
if coded_position[i] != "*" and coded_position[i] != "K":
result = False
break
if coded_position[i] == "K":
result = True
print(result)
return result
我想我真的太复杂了,有什么明显的我遗漏的吗?
我不会给你代码(至少现在),但我可以给你一些步骤。
目前看起来您正在将所有内容存储为长输入行上的索引。这使得它变得更难,所以第一步是将棋盘表示为字符串列表,其中 1 的长度为 8。
你想要的结果是
board = ["r*x***k*",
"***p***P",
"*****Q**",
"***kp***",
"*K*****p",
"***Pb***",
"*p***PP*",
"**X***KR"]
所以现在白王在 board[0][2]
,黑王在棋盘上移动。我们称之为 (0, 2).
现在你需要算出 (0, 2) 是否在检查中。我这样做的方法是针对每种类型的作品进行锻炼,以检查该位置。您可以将其存储为与当前国王位置的差异列表,并且对于每个位置,您都检查其中的内容是否是可能导致检查的部分。
movements = {
"P": [(1,-1), (1,1)],
"R": [*[(0, i), (0, -i), (i, 0), (-i, 0)] for i in range(7)],
}
这是兵和车的动作。如果 (0, 2)+(1, 1) 或 (0, 2)+(1,-1) 上有棋子,并且这些位置在网格内,则棋子正在检查 (0, 2)。
要在网格内,两个数字都必须介于 0 和 7 之间(含 0 和 7)。
对于 rook 来说有点复杂。当行相同或列相同时,车可以攻击的位置,这就是为什么在上面的一个动作中总是有一个 0。使用 rook 会增加复杂性,您必须排除任何阻碍。搜索国王左侧、右侧、上方和下方的所有内容可能更容易,并在
时停止搜索
- 你到达了棋盘的边缘 - 没有被从这个方向检查
- 您遇到了 不是 车的棋子 - 没有被车从这个方向检查
- 您遇到了一只新车 - 您处于检查状态...
我想这就足够了。请记住,您不必检查每个位置,您只需要找到一个威胁国王的棋子即可。
之后要判断一个王是否被将死就很简单了,因为只要一个王被将死,它周围的所有地方也都被将死,或者无效的地方。
我认为你把事情搞得比实际情况更复杂了。以下是我将使用的步骤:
求王位
在嵌套循环中从该位置遍历所有 8 个方向。
当你到达白色棋子(大写字母)时,打破那个方向。
当你到达板的尽头时,打破那个方向。
如果你到达一个黑色的棋子(小写),你有 4 个选项要检查:
一个。棋子与国王正交并且是车
b。 Piece 是 king 的对角线,是 bishop
c。棋子离王斜1格,是兵
d.任何方向和棋子都是女王
如果 a-d 中的任何一个为真,则 return 为真(国王被选中)。如果整个循环结束,return False.
如果你需要,我可以给你我的检查器的代码。
我正在尝试编写一个程序,如果棋盘上的白王已被选中,该程序将 return 为真。棋盘上的棋子以字符串形式生成并格式化,其中小写值为白色,大写为黑色。:
r*x***k****p***P*****Q*****kp****K*****p***Pb****p***PP***X***KR
| | |X| | | |K|R|
| |p| | | |P|P| |
| | | |P|b| | | |
| |K| | | | | |p|
| | | |k|p| | | |
| | | | | |Q| | |
| | | |p| | | |P|
|r| |x| | | |k| |
我了解如何将棋盘上的单位转换为 x 和 y 坐标,以及棋盘上棋子的数学运算(在 +7 和 +9 上检查兵,在...-2 上检查车, -1、+1、+2...和...-16、-8、+8、+16...,但我无法将其转换为 python,或者停止检查击中另一块或在它“通过”板之前再次循环。到目前为止,这是我的代码,但没有真正正常工作:
def white_check(coded_position):
w_king = coded_position.find("x")
w_king_x = w_king%8
w_king_y = w_king//8
result = False
print(w_king)
# This doesn't work if king is on x = 0 or 8
# Returns true if pawn checks
# if coded_position[w_king+7] == "P" or coded_position[w_king+9] == "P":
#result = True
# try using for loops and going up 1 / 8 at a time and trying each case for rooks / and bishops
# checks right side for rooks
for i in range(w_king,w_king-w_king_x+8):
if coded_position[i] != "*" and coded_position[i] != "K":
result = False
break
if coded_position[i] == "K":
result = True
# checks left side for rooks
for i in range(w_king,w_king-w_king_x,-1):
if coded_position[i] != "*" and coded_position[i] != "K":
result = False
break
if coded_position[i] == "K":
result = True
print(result)
return result
我想我真的太复杂了,有什么明显的我遗漏的吗?
我不会给你代码(至少现在),但我可以给你一些步骤。
目前看起来您正在将所有内容存储为长输入行上的索引。这使得它变得更难,所以第一步是将棋盘表示为字符串列表,其中 1 的长度为 8。
你想要的结果是
board = ["r*x***k*",
"***p***P",
"*****Q**",
"***kp***",
"*K*****p",
"***Pb***",
"*p***PP*",
"**X***KR"]
所以现在白王在 board[0][2]
,黑王在棋盘上移动。我们称之为 (0, 2).
现在你需要算出 (0, 2) 是否在检查中。我这样做的方法是针对每种类型的作品进行锻炼,以检查该位置。您可以将其存储为与当前国王位置的差异列表,并且对于每个位置,您都检查其中的内容是否是可能导致检查的部分。
movements = {
"P": [(1,-1), (1,1)],
"R": [*[(0, i), (0, -i), (i, 0), (-i, 0)] for i in range(7)],
}
这是兵和车的动作。如果 (0, 2)+(1, 1) 或 (0, 2)+(1,-1) 上有棋子,并且这些位置在网格内,则棋子正在检查 (0, 2)。
要在网格内,两个数字都必须介于 0 和 7 之间(含 0 和 7)。
对于 rook 来说有点复杂。当行相同或列相同时,车可以攻击的位置,这就是为什么在上面的一个动作中总是有一个 0。使用 rook 会增加复杂性,您必须排除任何阻碍。搜索国王左侧、右侧、上方和下方的所有内容可能更容易,并在
时停止搜索- 你到达了棋盘的边缘 - 没有被从这个方向检查
- 您遇到了 不是 车的棋子 - 没有被车从这个方向检查
- 您遇到了一只新车 - 您处于检查状态...
我想这就足够了。请记住,您不必检查每个位置,您只需要找到一个威胁国王的棋子即可。
之后要判断一个王是否被将死就很简单了,因为只要一个王被将死,它周围的所有地方也都被将死,或者无效的地方。
我认为你把事情搞得比实际情况更复杂了。以下是我将使用的步骤:
求王位
在嵌套循环中从该位置遍历所有 8 个方向。
当你到达白色棋子(大写字母)时,打破那个方向。
当你到达板的尽头时,打破那个方向。
如果你到达一个黑色的棋子(小写),你有 4 个选项要检查:
一个。棋子与国王正交并且是车
b。 Piece 是 king 的对角线,是 bishop
c。棋子离王斜1格,是兵
d.任何方向和棋子都是女王
如果 a-d 中的任何一个为真,则 return 为真(国王被选中)。如果整个循环结束,return False.
如果你需要,我可以给你我的检查器的代码。