在二维列表中检查对角线(Python)

4

初始问题:对于给定的3x3井字棋棋盘,检查是否有一方玩家获胜。

我想到的最简单的解决方法是旋转矩阵并求每行的和:

board
[[0, 1, 2], [3, 4, 5], [6, 7, 8]]

pr(board)
0 1 2
3 4 5
6 7 8

pr(zip(*board))
0 3 6
1 4 7
2 5 8

上面的0..9数字仅用于显示棋盘上的位置,通常它们会填充为1代表玩家1,-1代表玩家2,0代表未填充的位置。逐行扫描,如果总和为3或-3,则是获胜块。

然而,对角线没有被检查。有没有一种优雅且高效的方法从这样的矩阵中提取对角线呢?我不是指使用“手动”(0、1、2)等平凡的索引,而是获取n x n矩阵的对角线。

P.S.这里的pr只是一个打印二维列表的辅助函数:

def pr(x):
    for row in x:
        print ' '.join(map(str, row))

pr 函数是什么? - David Robinson
辅助函数,请查看我的编辑后的P.S. - LetMeSOThat4U
6个回答

12

您可以使用以下代码获取一个对角线:

[r[i] for i, r in enumerate(board)]
# [0, 4, 8]

和对角线相反的对角线为:

[r[-i-1] for i, r in enumerate(board)]
# [2, 4, 6]

2
你可以将-i-1转换为~i - Maltysen
优雅的解决方案! - senseiwu
对于相反的操作,也可以使用以下方式完成:[r[i] for i, r in enumerate(board[::-1])] - riccardogabellone

4
用幻方给你的游戏场地编号
2|9|4
7|5|3
6|1|8

现在进行三步后,将分数相加并检查总和是否为15 -> 获胜者。您需要为每个玩家检查此内容。当然,在第4步和第5步之后(仅适用于开始游戏的玩家),您必须重新检查。

这是我在我的第一个Java课程中解决此问题的方法。


2
虽然不是直接的答案,但这是最有创意的解决方案。 - LetMeSOThat4U

2

2
在一个正方形棋盘上,对角线要么在索引相等的位置,例如在3x3的棋盘上它们是board[0][0]board[1][1]board[2][2],要么在两个索引之和为棋盘大小减1的位置(在这种情况下有3个位置),例如board[0][2]board[1][1]board[2][0] -- 注意board[1][1]在两组中都包含,这是应该的。这些事实使得编写Python代码来计算它们相当容易:
board = [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
BOARD_SIZE = len(board)

diags1 = [board[i][i] for i in xrange(BOARD_SIZE)]
diags2 = [board[i][BOARD_SIZE-1-i] for i in xrange(BOARD_SIZE)]

print diags1
print diags2

输出:

[0, 4, 8]
[2, 4, 6]

1
这将为您提供一个包含对角线元素的列表,方向为从左上到右下:
[board[i][i] for i in range(len(board))]

这将对相反的方向执行相同的操作:
[board[i][len(board)-i-1] for i in range(len(board))]

-1
tmp_diagonals = [set(), set()]
    num = 0
    for idx in range(len(board) - 1, -1, -1):
        tmp_diagonals[0].add(board[num][num])
        tmp_diagonals[1].add(board[num][idx])
        num += 1

1
你能否编辑你的回答,包括对你的代码的解释? - Michael M.
虽然这段代码片段可能是解决方案,但提供详细的解释真的有助于提高您的帖子质量。请记住,您正在为未来的读者回答问题,而这些人可能不了解您提出代码建议的原因。 - Shawn Hemelstrand
虽然这段代码片段可能是解决方案,但包括详细的解释真的有助于提高您的帖子质量。请记住,您正在回答未来读者的问题,而这些人可能不知道您提出代码建议的原因。 - Shawn Hemelstrand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接