2

我目前正在尝试在 python 3 中创建奥赛罗游戏(又名黑白棋)。

我对程序的部分有很大的问题,它应该评估移动是否有效。

我要创建的内容:

  1. 检查板上的位置是否为空
  2. 检查是否有相反颜色的邻居
  3. 如果有这样的邻居,请继续朝那个方向前进,看看我们是否可以在不越过空位的情况下到达我们自己的一块。

我尝试了许多不同的功能,但我无法正确...

在下面的链接中是我最近的尝试,

github上的git链接

4

1 回答 1

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
于 2021-10-16T15:59:19.413 回答