我怎样才能在这个游戏中使用更少的 for 循环,并使用更少的行代码变得更加有效和动态?

How can i use less for loops in this game and be much effective and dynamic with less lin eof codes?

def tic_tac_toe(board):

    mess = []   
    organize = []     
    winner = []   
    n = len(board)

我可以不用这么多 for 循环来做这个吗?

    for i in range(len(board)):
        for j in range(len(board[i])):
            mess.append(board[j][i]) 
     #appending all vertical items


    for i in range(len(board)):
        for j in range(len(board[i])):
            mess.append(board[i][j]) 
    #appending all horizontal items


    for i in range(len(board)):
        for j in range(len(board[i])):
            i = j
            mess.append(board[i][j])
        break

    #appending items that have the same i and j index (i==0 j==0,i==1 j==1,i==2 j ==2) or better say all items in these position (\)


    for i in range(len(board)):
        for j in range(len(board[i])):
            if j - i == 2 or i - j == 2 or (i == 1 and j == 1):
                mess.append(board[i][j])  
    #appending items in these indexes : (i ==0 j ==2 , i == 1 j == 1, i ==2 j == 0) items in these position (/) 



    organize = [mess[k: k + n] for k in range(0, len(mess), n)] # creating nested list of all possible moves


    winner = ["X" if organize[i].count("X") == 3 else "O" if organize[i].count("O") == 3 else "Draw" for i in range(len(organize))] # "X" if 3 "X"s in organize[i]. "O" if 3 "O"s in organize[i] and "Draw" otherwise .

由此决定胜负。如果获胜者列表中有一个“X”,则获胜者是“X”。 "O" 也一样。但如果获胜者列表中的所有元素都是“平局”,则游戏为平局。

强文本

    if "X" in winner:
        return "X"
    elif "O" in winner:
        return "O"
    elif winner.count("Draw") == 8 :
        return "Draw"  

   

print(tic_tac_toe([
    ["X", "X", "O"],
    ["O", "O", "X"],
    ["X", "X", "O"]
])) # ➞ "Draw"

对于 for 循环,您可以轻松地编写 1 个循环而不是 2 个:

而不是:

for i in range(len(board)):
    for j in range(len(board[i])):
        mess.append(board[j][i])

你可以写:

for i, j in enumerate(board):
    mess.append(board[j][i])

并且肯定这适用于其他 for 循环。

不过你也可以写一个函数来减少for循环的次数。

如果你喜欢用 numpy 来做,你可以简化它很多。 Numpy 允许你旋转棋盘,这意味着你可以找到与垂直线具有相同代码的水平线(两条对角线也是如此)。

import numpy as np

organize = []

board_rotated = np.rot90(board).tolist() # rotate the board

organize.extend(board) # add horiztonal
organize.extend(board_rotated) # add vertical
organize.append(np.diag(board).tolist()) # add top-left to bottom-right diagonal
organize.append(np.diag(board_rotated).tolist()) # add top-right to bottom-left diagonal

无需任何 for 循环即可完成,而且您不需要 mess 列表。一切都直接添加到 organize.


它会旋转棋盘,这使您可以在旋转棋盘上执行与在未旋转棋盘上完全相同的操作,以获得所有解决方案。在问题提供的示例中,board_rotated 将是:

[['O', 'X', 'O'],
 ['X', 'O', 'X'],
 ['X', 'O', 'X']]

不出所料,这已经旋转了 90 度。
.extend() 函数调用只是将每一行添加到 organise。在 board 的情况下,行是水平值。这些行是使用 board_rotated.
时的垂直值 使用 np.diag() 给出矩阵的对角线。对于 board,这是 ['X', 'O', 'O'],对于 board_rotated,这是 ['O', 'O', 'X']