在 2D 列表中从 x 到 y 进行索引的紧凑方法

Compact way to index from x to y in 2D list

我正在做 Cisco NetAkad 课程中的 tictactoe 项目:https://www.youtube.com/watch?v=7GDtI9SpGgU 我在游戏中无视规定的项目要求。 我为董事会使用了一个普通列表:board = [1, 2, 3, 4, 5, 6, 7, 8, 9] 该程序运行正常,输出与项目要求的相同。

但项目要求特别说明要使用二维列表:board = [[1, 2, 3], [4, 5, 6], [7, 8, 9]。因为我想练习使用 2D 列表,所以我重写了程序,发现它需要更多行和更复杂的索引。

我的第一个问题是:在检查是否有获胜者的函数中,是否可以使用二维列表仅使用索引检查所有方向是否有 3 个连续的“X”或“O” ?如果是,如何? (我不认为编写大量 'if' 与许多 'and' 相结合是有效的,并且使用索引在普通列表中效果很好)

作为初学者,我的措辞可能不清楚,所以这里是检查“X”是否获胜以及低于我预期的部分:

if board[0][0:3].count("X") == 3 or board[1][0:3].count("X") == 3 \
or board[2][0:3].count("X") == 3 or board[0:3][0].count("X") == 3 \
or board[0:3][1].count("X") == 3 or board[0:3][2].count("X") == 3 \
or board[0:3][0:3].count("X") == 3 or board[0:3][3::-1].count("X") == 3:
    print("I won: you lost.")

索引 [0][0:3]、[1][0:3] 和 [2][0:3] 按预期工作(行),它识别获胜。 但是,当程序为 运行 时,[0:3][0] 被读取为 [0][0:3]。 (检查列不起作用) [0:3][0:3] 和 [0:3][3::-1] 显然不起作用(对角线)。

第二个问题:有什么更好的方法来检查获胜者?

最后一个问题:在这种情况下,使用二维列表比使用普通列表有优势吗?

非常感谢您的任何反馈。

您可以执行如下操作:

for key in ['X', 'O']:
    temp = []
    count = 0
    for row in board:
        if row.count(key) == 3:
            count = 3
            break

        if key in row:
            temp.append(row.index(key))

    if count == 3 or (len(list(set(temp))) == 1 and len(temp) == 3) or temp in ([0,1,2], [2,1,0]):
        print("I won: you lost. " + key + " wins")

解决方案的想法是获取内部列表中 'X' 位置的索引(索引的使用证明了每个“2D 列表”[列表列表] 的理由你的最后一个问题)。这是通过在 tic-tac-toe 的每个 'row' 列表上循环来完成的。我们将索引存储在变量 'temp'.

第一个条件检查一行是否有 3 'X's,如果是,它会中断 for 循环的执行,保存 count=3。第二个条件最有趣,因为它在行中存储了 'X' 的索引。例如,当中间列有 X 时,在循环结束时,temp 将等于:

[2,2,2] if the tic-tac-toe was 
O-X-
O-X-O
 -X-O

因此,如果在 'temp' 列表中有一个唯一的数字([1,1,1] 唯一的是 1,[2,2,2] 唯一的是 2 等),那么有赢家。这是由以下人员完成的:

len(list(set(temp))) # (inside) Get unique values / Make it a list / Measure its length

如果长度为1,则有唯一位置。除此之外,为了在井字游戏未完全填满时考虑代码 运行,我们检查 len(temp) == 3。最后,我们使用条件

的 'temp in ([0,1,2], [2,1,0])' 部分检查对角线匹配

'index [0:3][0]' 无法按预期工作的原因是,第一个切片指向整个列表,您在位置 0 处取值 [1,2,3] .换句话说 board[0:3] 等于 board

由于潜在状态太少,只有8个获胜状态,我可能会直接评估它们:

gameboard = [
    ["x","-","-"],
    ["x","-","-"],
    ["x","-","-"]
]

possilbe_winning_states = [
    [(0,0), (0,1), (0,2)],
    [(1,0), (1,1), (1,2)],
    [(2,0), (2,1), (2,2)],

    [(0,0), (1,0), (2,0)],
    [(0,1), (1,1), (2,1)],
    [(0,2), (1,2), (2,2)],

    [(0,0), (1,1), (2,2)],
    [(0,2), (1,1), (2,0)]
]

for possilbe_winning_state in possilbe_winning_states:
    squares = [gameboard[square[0]][square[1]] for square in possilbe_winning_state]
    if squares.count("x") == 3:
        print("X Win")
        break
    elif squares.count("o") == 3:
        print("O Win")
        break
else:
    print("no winner yet")