【问题标题】:How to check for win in custom sized tic-tac-toe diagonals如何检查自定义大小的井字游戏对角线是否获胜
【发布时间】:2019-07-30 23:29:37
【问题描述】:

我正在制作一个简单的井字游戏,用户可以在其中指定网格的大小(列数和行数)。
我需要创建一个函数,它可以检查网格中所有对角线的胜利。

对于网格,我使用的是一个二维列表,看起来像这样(3x3 示例):

grid = [['x', '-', 'o'], 
        ['o', 'x', '-'], 
        ['-', '-', 'x']]
grid[row][col]

这应该是一个胜利的局面

我已经创建了垂直和水平赢的检查,但我不太清楚如何检查对角线。

这是我在代码中检查行胜的方法:

min_win_streak 是最小连胜纪录(例如在经典的 3x3 井字游戏中,它是 3)

def check_rows(grid, min_win_streak):
    winner = '-'
    for row in grid:
        win_streak = 0
        for element in row:
            if element != '-':
                if element == winner:
                    win_streak += 1
                    winner = element
                    if win_streak >= min_win_streak:
                        return True, winner
                else:
                    win_streak = 1
                    winner = element
            else:
                win_streak = 0
                winner = '-'
    return False, None



我需要check_diags() 函数,返回值应该是:

  • win for x,该函数应返回 True, 'x'
  • win for o,该函数应返回 True, 'x'
  • no win,该函数应返回 False、None

【问题讨论】:

  • 请提供您现有的其中一个方向的代码,以便我们根据您的需要进行调整。要求我们从头开始提供代码有点超出 Stack Overflow 的范围。更重要的是,它不会与您已经完成的工作很好地融合。
  • @Prune 我已经添加了 check_rows() 函数
  • 您是否尝试过使用嵌套 for 循环和数学公式,例如 'if grid[i][j] == grid[i+1][j+1] == grid[i+ 2][j+2]'?您需要确保 i 和 j 在 range(len(grid)-2) 内。
  • @ToddBurus 我试过了,但我想不出任何公式。
  • 嗯,任何对角线的形式都是 (i, j), (i+1, j+1), (i+2, j+2)(即向下倾斜的对角线)或 (i, j+2), (i+1, j+1), (i+2, j)(向上倾斜的对角线)。然后你可以把它放在一个嵌套的 for 循环子句中。

标签: python list logic tic-tac-toe


【解决方案1】:

您可以使用以下嵌套的 for 循环检查 2x2 中的对角线:

for i in range(len(grid)-2):
    for j in range(len(grid)-2):
        if grid[i][j] == grid[i+1][j+1] == grid[i+2][j+2] and grid[i][j] != '-':
            print('Winner')
        elif grid[i][j+2] == grid[i+1][j+1] == grid[i+2][j] and grid[i][j+2] != '-':
            print('Winner')

如果需要,可以将其插入到具有所需返回值的函数中来代替 print 语句。这应该可以扩展到 3x3、4x4 等,而且更改相当容易。

【讨论】:

  • 通常,这段代码可以工作,但问题是,用户可以指定网格的大小,可以是 5x8 之类的东西,不仅是 NxN,而且这段代码在这些情况下会失败,并且用户还可以指定连胜有多大(在本例中为 3),但这可以改变。
  • 对不起,我误读了他的意图。我没有通读添加的代码就将“连胜”表示其他意思。我假设网格是正方形的。使用一些添加的变量来修改这些因素会很容易。对角线是对角线。感谢您的提醒。
【解决方案2】:

感谢您发布代码。我用 all 函数替换了你的 win_streak 检查循环。下面的代码比你想用在一个巨大的网格上做更多的工作,但它很容易(更容易)理解和适应,而且它足够快用于围棋游戏(在 19x19 上连续 5 个)板)。

我留下了一个跟踪print 语句来说明它正在检查的对角线。您应该能够将其调整为 NE-SW 对角线 (check_slash_diag)。

grid = [['x', '-', 'o', 'o'],
        ['o', 'x', 'o', '-'],
        ['-', 'o', 'x', 'x'],
        ['-', 'x', 'o', '-']]

def check_backslash_diag(grid, min_win_streak):

    grid_size = len(grid)
    grid_extra = grid_size - min_win_streak   # This is the "extra" space in a long line

    # This pair of loops will iterate through the upper-left square of side 
    #   grid_extra+1, starting points of any diagonals long enough to contain a win.
    for start_row in range(grid_extra+1):
        for start_col in range(grid_extra+1):
            # Extract a diagonal "row" of length min_win_streak
            diag = [grid[start_row+i][start_col+i] for i in range(min_win_streak)]
            print(start_row, start_col, diag)  # DEBUG: Display checked diagonals
            if all(diag[i] == diag[0] for i in range(min_win_streak)):
                print(diag[0], "wins on NW-SE diagonal at", start_row, start_col)

check_backslash_diag(grid, 3)

输出:

0 0 ['x', 'x', 'x']
x wins on NW-SE diagonal at 0 0
0 1 ['-', 'o', 'x']
1 0 ['o', 'o', 'o']
o wins on NW-SE diagonal at 1 0
1 1 ['x', 'x', '-']

【讨论】:

    猜你喜欢
    • 2016-01-25
    • 1970-01-01
    • 2023-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多