我目前正在尝试在 python 3 中创建奥赛罗游戏(又名黑白棋)。
我对程序的部分有很大的问题,它应该评估移动是否有效。
我要创建的内容:
- 检查板上的位置是否为空
- 检查是否有相反颜色的邻居
- 如果有这样的邻居,请继续朝那个方向前进,看看我们是否可以在不越过空位的情况下到达我们自己的一块。
我尝试了许多不同的功能,但我无法正确...
在下面的链接中是我最近的尝试,
我目前正在尝试在 python 3 中创建奥赛罗游戏(又名黑白棋)。
我对程序的部分有很大的问题,它应该评估移动是否有效。
我要创建的内容:
我尝试了许多不同的功能,但我无法正确...
在下面的链接中是我最近的尝试,
检查板上的位置是否为空
首先想到的是将棋盘表示为一个字符串,其中字符串中的每个字符都代表该方格的状态,从 0(左上角)到 63(右下角)。
例如,假设你用"o"表示一个被白色占据的正方形,黑色用"x"表示,而一个空的正方形将是"."。. 因此,对于起始状态,它将是:
board = "...........................ox......xo..........................."
然后,如果您想检查一个正方形是否为空,您将检查该字符是否为空,例如:
if board[0] == ".":
#Square 0 (top left corner) is empty!
检查是否有相反颜色的邻居
为此,您可以预先存储与正方形的所有邻居相对应的方向元组(这也有助于计算可能的移动):
DIRECTIONS = [
(0, -1), #Up
(1, -1), #Up-Right
(1, 0), #Right
(1, 1), #Down-Right
(0, 1), #Down
(-1, 1), #Down-Left
(-1, 0), #Left
(-1, -1), #Up-Left
]
其中元组的第一项是水平移动的量,第二项是垂直移动的量。所以如果你想找到相反颜色的邻居,你会得到当前方块的索引:
row, col = index // 8, index % 8 #To convert from an index from string to (x, y) values
然后循环遍历方向,并使用上面的逻辑检查邻居的颜色。
current = board[index]
for x, y in DIRECTIONS:
r, c = index // (8), index % (8)
r += y
c += x
tile = board[r * 8 + c]
if tile != current and tile != ".": #Not same color, and not empty, so must be opposite color
#Do stuff
现在,因为这是非常基本的代码,它不包括当前图块位于角落边缘的可能性,索引会转到不正确的位置,循环。一种可能性是将这些情况硬编码并忽略这些方向,但是也可以使用另一种(更清洁的方式 imo)。除了将板表示为 64 个字符的字符串,您还可以将其表示为 100 个字符的字符串以包含如下边框:
? ? ? ? ? ? ? ? ? ?
? . . . . . . . . ?
? . . . . . . . . ?
? . . . . . . . . ?
? . . . . . . . . ?
? . . . . . . . . ?
? . . . . . . . . ?
? . . . . . . . . ?
? . . . . . . . . ?
? ? ? ? ? ? ? ? ? ?
然后您可以简单地检查“邻居”是否是边界的一部分(在这种情况下由问号表示,但可以是除了用于表示空白空间和圆盘的那些之外的任何其他东西)。
但是,您需要考虑的是,您必须将 8x8 板适当地转换为 10x10(并转换回来)。
如果有这样的邻居,请继续朝那个方向前进,看看我们是否可以在不越过空位的情况下到达我们自己的一块。
一旦你实现了上述逻辑,这非常简单,你只需要一个while循环来检查某个方向的瓷砖,如果我们达到原始颜色是否可以拍摄它们。
SIZE = 8
DIDRECTIONS = [....]
def possible_moves(board, token):
board = add_border(board) #Converting to 10x10
moves = []
if token == "x":
other = "o"
else:
other = "x"
for space in [i for i, j in enumerate(board) if j == "."]:
for x, y in DIRECTIONS:
r, c = space // (SIZE + 2), space % (SIZE + 2)
r += y
c += x
tile = board[r * (SIZE + 2) + c]
#Checking to see if we reach one of the original discs
entered = False
while tile == other:
entered = True
r += y
c += x
tile = board[r * (SIZE + 2) + c]
if entered is True and tile == token:
moves.append((space // (SIZE + 2), space % (SIZE + 2)))
break
moves = [(r - 1) * (SIZE) + (c - 1) for r, c in moves] #Converting back to 8x8
return moves