在Python 2d数组中连续确定三个

Jon*_*han 5 python arrays

我正在使用带有M x N板的Python井字游戏。我正在尝试找到一种有效的方法来确定玩家是否获胜(垂直,水平或对角线方向连续3个。)游戏的大多数3x3实现方式只是在每个回合之后检查所有可能的获胜组合。对于庞大的董事会,这似乎有些极端。

4x4示例:(使用1和2代替X和O)

board = ([1,0,2,1], [0,0,0,1], [2,2,0,0], [1,0,0,1])
for row in board:
    print row
Run Code Online (Sandbox Code Playgroud)

谢谢-乔纳森

FMc*_*FMc 3

尽管这种方法有一定的吸引力,但它可能不是特别快。

# A bogus game with wins in several directions.
board = (
    [1,1,2,1],
    [0,2,1,1],
    [2,2,2,1],
    [1,0,0,1],
)

# A few convenience variables.    
n_rows = len(board)    
lft = [ [0] * i for i in range(n_rows) ]  # [[], [0], [0, 0], [0, 0, 0]]
rgt = list(reversed(lft))

# Create transpositions of the board to check for wins in various directions.
transpositions = {
    'horizontal' : board,
    'vertical'   : zip(*board),
    'diag_forw'  : zip(* [lft[i] + board[i] + rgt[i] for i in range(n_rows)] ),
    'diag_back'  : zip(* [rgt[i] + board[i] + lft[i] for i in range(n_rows)] ),
}

# Apply Jonathan's horizontal-win check to all of the transpositions.
for direction, transp in transpositions.iteritems():
    for row in transp:
        s = ''.join( map(str, row) )
        for player in range(1,3):
            if s.find(str(player) * 3) >= 0:
                print 'player={0} direction={1}'.format(player, direction)
Run Code Online (Sandbox Code Playgroud)

输出:

player=1 direction=diag_back
player=2 direction=diag_forw
player=2 direction=horizontal
player=1 direction=vertical
Run Code Online (Sandbox Code Playgroud)

对角转置背后的想法是使用lftrgt作为左右填充来移动行。例如,diag_forw添加填充后的列表如下所示(填充字符显示为句点,即使实际代码中使用了零)。

1 1 2 1 . . .
. 0 2 1 1 . .
. . 2 2 2 1 .
. . . 1 0 0 1 
Run Code Online (Sandbox Code Playgroud)

然后我们简单地使用 转置该数组zip(*foo),这使我们能够利用 Jonathan 的好主意来寻找横向胜利。