我怎样才能在这个游戏中使用更少的 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']
。
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']
。