我正在尝试对游戏connect-4进行编码,而我的代码中有一部分试图在7x6矩阵中找到对角线,该对角线是连续4个或连续4个2s。 我的这部分代码无法正常工作,我尝试了所有可能的方法。有时它会检测到对角线为4 1s或4 2s的对角线。我创建了将7个零列表放置在6个零列表的每个位置的矩阵。我正在尝试仅使用列表函数来执行此操作,但是我无法使用numpy库或类似库。 好的,在代码的这一部分中,我试图查找在矩阵的每个对角线中是否连续有4个零。 PD:我只是想找到从左到右的ATM对角线。感谢您的帮助,因为英语不是我的主要语言,所以我尽力解释了我的问题。 这是我的代码:
import random
llista = [0]*6 #when i say llista y mean matrix
for i in range(6):
llista[i]=[0]*7
#Here i fill the 7*6 matrix of 0s 1s and 2s randomly so i can see if it works.
for i in range(30):
x=random.randrange(-1,-7,-1)
y=random.randrange(0,7,1)
llista[x][y]=1
for i in range(30):
x=random.randrange(-1,-7,-1)
y=random.randrange(0,7,1)
llista[x][y]=2
#This 2 loops here are too see if it is possible to have a diagonal in the matrece because if you want a diagonal u need at least a one or 2 in the center, the problem is not here.
for i in range(-1,-7,-1):
possible = False
if llista[i][3]==1:
possible = True
break
for i in range(7):
possible2 = False
if llista[-4][i]==1 or llista[-4][i]==1:
possible2=True
break
if possible==True and possible2==True:
#The problem starts here. This first loop i use it too find the diagonals that go from left to right. I want to find diagonals of 4 1s or 4 2s.
for i in range(len(llista)-3):
for j in range(len(llista[i])-3):
#This if is too see if we have four 1 or 2 togheter in the list, if we have them it prints the sentence below.
if (llista[i][j]==1 and llista[i+1][j+1]==1 and llista[i+2][j+2]==1 and llista[i+3][j+3]==1) or (llista[i][j]==2 and llista[i+1][j+1]==2 and llista[i+2][j+2]==2 and llista[i+3][j+3]==2 ):
print("There is at least one left to right diagonal")
#This loop is the same than the last one but to find diagonals from right to left (a 4 diagonal made of 1s or 2s)
for i in range(len(llista)):
for j in range(len(llista[i])):
if i-3<0 and j-3<0:
if (llista[i][j]==1 and llista[i-1][j-1]==1 and llista[i-2][j-2]==1 and llista[i-3][j-3]==1) or (llista[i][j]==2 and llista[i-1][j-1]==2 and llista[i-2][j-2]==2 and llista[i-3][j-3]==2 ):
print("There is at least one right to left diagonal")
#Here i print the matrix
for i in range(6):
print(llista[i])
#So this program should say if there is at least one left to right diagonal
或从右到左对角线。 #我不想使用尚未被使用的功能,并且我不想做另一种方式,因为我必须理解这种方式。谢谢
答案 0 :(得分:0)
由于解析条件语句的方式,也许您没有得到正确的答案。 你应该有
if cond1 or cond2:
# do something
,条件放在括号()
中。目前,括号中仅包含您的第二个条件。
请尝试以下操作:
if (matrix[i][j]==1 and matrix[i+1][j+1]==1 and matrix[i+2][j+2]==1 and matrix[i+3][j+3]==1) or (matrix[i][j]==2 and matrix[i+1][j+1]==2 and matrix[i+2][j+2]==2 and matrix[i+3][j+3]==2 ):
print("There is at least one left to right diagonal")
答案 1 :(得分:0)
您可以考虑使用numpy解决此问题。这里有一些代码可以帮助您入门。
import numpy as np
from itertools import groupby
def check_diagonals(matrix):
for offset in range(-2, 4):
diag = matrix.diagonal(offset=offset)
if max([sum(1 for _ in g) for k, g in groupby(diag)]) >= 4:
return True, k
return False, None
# random test matrix
matrix = np.random.randint(0, 3, 6 * 7)
matrix = matrix.reshape(6,7)
# left to right check
resp_tuple = check_diagonals(matrix)
if resp_tuple[0]:
print("There is at least one left to right diagonal: {}'s'".format(resp_tuple[1]))
else:
# right to left
resp_tuple = check_diagonals(np.fliplr(matrix))
if resp_tuple[0]:
print("There is at least one right to left diagonal: {}'s'".format(resp_tuple[1]))
else:
# No diagonals
print('No diagonals')
答案 2 :(得分:0)
如果您考虑“从右到左”循环的逻辑,实际上您实际上是在执行与“从左到右”循环相反的顺序。要真正获得“从右到左”的传递权,您必须使i
和j
索引朝不同的方向移动。
因此,本节中的条件语句应如下所示:
if i-3>=0 and j+3<7:
if (llista[i][j]==1 and llista[i-1][j+1]==1 and llista[i-2][j+2]==1 and llista[i-3][j+3]==1) or (llista[i][j]==2 and llista[i-1][j+1]==2 and llista[i-2][j+2]==2 and llista[i-3][j+3]==2 ):
print("There is at least one right to left diagonal")
如AResem所示,通过导入numpy
或itertools
之类的库,您可以使用大量的优化方法。出于以下原因,该答案并不完全正确。
当您说return True, k
时,您并没有对k
的值进行任何控制,因为它在上面的列表推导中使用过,并且仅具有迭代的最后一项的值。因此,当您的函数找到对角线时,它将在大约三分之二的时间报告错误的数字。
以下是经过编辑的函数,可以提供正确的结果:
def check_diagonals(matrix):
for offset in range(-2, 4):
diag = matrix.diagonal(offset=offset)
# Here you can create a tuple of numbers with the number of times they are repeated.
# This allows you to keep your k and g values associated.
repeat_groups = [(k, sum(1 for _ in g)) for k, g in groupby(diag)]
# By using the built-in max function with the 'key' keyword, you can find
# the maximum number of repeats and return the number associated with that.
num, max_repeats = max(repeat_groups, key=lambda item: item[1])
if max_repeats >= 4:
return True, num
return False, None
如果在添加了print
语句的情况下运行此功能,则可以得到如下输出:
Matrix:
[[1 0 2 2 1 0 1]
[0 2 0 2 1 1 1]
[2 2 0 0 0 0 1]
[0 0 2 2 0 2 2]
[2 1 1 1 1 1 0]
[2 2 0 2 1 0 2]]
offset -2
diag [2 0 1 2]
repeat_groups [(2, 1), (0, 1), (1, 1), (2, 1)]
num, max_repeats 2 1
offset -1
diag [0 2 2 1 1]
repeat_groups [(0, 1), (2, 2), (1, 2)]
num, max_repeats 2 2
offset 0
diag [1 2 0 2 1 0]
repeat_groups [(1, 1), (2, 1), (0, 1), (2, 1), (1, 1), (0, 1)]
num, max_repeats 1 1
offset 1
diag [0 0 0 0 1 2]
repeat_groups [(0, 4), (1, 1), (2, 1)]
num, max_repeats 0 4
(True, 0)
There is at least one left to right diagonal: 0's' # Correct!
如果您想忽略零的对角线,则可以轻松添加一个额外条件,例如
if max_repeats >= 4 and num != 0:
return True, num
如果需要,您可以尝试不使用numpy
而重新创建它。