使用列表在 Python 矩阵中查找对角线

我正在尝试编写游戏 connect-4,并且我尝试在 7x6 矩阵中查找代码的一部分,连续 4 个对角线或连续 4 个 2 的对角线。我的这部分代码不起作用,我尝试了我能做的一切。有时它会检测到有 4 个 1s 或 4 个 2s 的对角线而不是。我创建了矩阵,在 6 个零列表的每个位置放置了一个 7 个零列表。我正在尝试仅使用列表函数来执行此操作,我无法使用 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")

或从右到左对角线。#我不想使用尚未使用的函数,也不想以其他方式使用,因为我必须以这种方式理解。谢谢


POPMUISE
浏览 251回答 3
3回答

天涯尽头无女友

如果您考虑“从右到左”循环的逻辑,您实际上只是以相反的顺序执行与“从左到右”循环相同的操作。要真正获得“从右到左”的正确传递,您必须让索引i和j索引向不同的方向移动。因此,您在本节中的条件语句应如下所示:if i-3>=0 and j+3<7:&nbsp; &nbsp; 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)&nbsp; 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 ):&nbsp; &nbsp; &nbsp; &nbsp; print("There is at least one right to left diagonal")您可以通过导入像AResem 所示numpy或itertools像 AResem 所示的库来进行大量优化。由于以下原因,该答案并不完全正确。当你说return True, k你没有对 的值进行任何控制时,k因为它在上面的列表理解中使用过,并且只会拥有它迭代的最后一个项目的值。因此,当您的函数找到对角线时,大约三分之二的时间会报告错误的数字。这是一个经过编辑的函数,可以给出正确的结果:def check_diagonals(matrix):&nbsp; &nbsp; for offset in range(-2, 4):&nbsp; &nbsp; &nbsp; &nbsp; diag = matrix.diagonal(offset=offset)&nbsp; &nbsp; &nbsp; &nbsp; # Here you can create a tuple of numbers with the number of times they are repeated.&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; # This allows you to keep your k and g values associated.&nbsp; &nbsp; &nbsp; &nbsp; repeat_groups = [(k, sum(1 for _ in g)) for k, g in&nbsp; groupby(diag)]&nbsp; &nbsp; &nbsp; &nbsp; # By using the built-in max function with the 'key' keyword, you can find&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; # the maximum number of repeats and return the number associated with that.&nbsp; &nbsp; &nbsp; &nbsp; num, max_repeats = max(repeat_groups, key=lambda item: item[1])&nbsp; &nbsp; &nbsp; &nbsp; if max_repeats >= 4:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return True, num&nbsp; &nbsp; return False, None如果您在print添加语句的情况下运行此函数,您可以获得如下输出:Matrix:&nbsp;[[1 0 2 2 1 0 1]&nbsp;[0 2 0 2 1 1 1]&nbsp;[2 2 0 0 0 0 1]&nbsp;[0 0 2 2 0 2 2]&nbsp;[2 1 1 1 1 1 0]&nbsp;[2 2 0 2 1 0 2]]offset -2diag [2 0 1 2]repeat_groups [(2, 1), (0, 1), (1, 1), (2, 1)]num, max_repeats 2 1offset -1diag [0 2 2 1 1]repeat_groups [(0, 1), (2, 2), (1, 2)]num, max_repeats 2 2offset 0diag [1 2 0 2 1 0]repeat_groups [(1, 1), (2, 1), (0, 1), (2, 1), (1, 1), (0, 1)]num, max_repeats 1 1offset 1diag [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:&nbsp; &nbsp; return True, num如果您愿意,您可以尝试重新创建它而不使用numpy它。

森栏

你可以考虑使用 numpy 来解决这个问题。这里有一些代码可以帮助您入门。import numpy as npfrom itertools import groupbydef check_diagonals(matrix):&nbsp; &nbsp; for offset in range(-2, 4):&nbsp; &nbsp; &nbsp; &nbsp; diag = matrix.diagonal(offset=offset)&nbsp; &nbsp; &nbsp; &nbsp; if max([sum(1 for _ in g) for k, g in&nbsp; groupby(diag)]) >= 4:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return True, k&nbsp; &nbsp; return False, None# random test matrixmatrix = np.random.randint(0, 3, 6 * 7)matrix = matrix.reshape(6,7)# left to right checkresp_tuple = check_diagonals(matrix)if resp_tuple[0]:&nbsp; &nbsp; print("There is at least one left to right diagonal: {}'s'".format(resp_tuple[1]))else:&nbsp; &nbsp; # right to left&nbsp; &nbsp; resp_tuple = check_diagonals(np.fliplr(matrix))&nbsp; &nbsp; if resp_tuple[0]:&nbsp; &nbsp; &nbsp; &nbsp; print("There is at least one right to left diagonal:&nbsp; &nbsp; &nbsp;{}'s'".format(resp_tuple[1]))&nbsp; &nbsp; else:&nbsp; &nbsp; &nbsp; &nbsp; # No diagonals&nbsp; &nbsp; &nbsp; &nbsp; print('No diagonals')

冉冉说

也许由于您解析条件语句的方式,您没有得到正确的答案。你应该有if&nbsp;cond1&nbsp;or&nbsp;cond2: &nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;do&nbsp;something括号中包含的条件()。目前只有您的第二个条件包含在括号中。请尝试以下操作:if&nbsp;(matrix[i][j]==1&nbsp;and&nbsp;matrix[i+1][j+1]==1&nbsp;and&nbsp;matrix[i+2][j+2]==1&nbsp;and&nbsp;matrix[i+3][j+3]==1)&nbsp;&nbsp;or&nbsp;(matrix[i][j]==2&nbsp;and&nbsp;matrix[i+1][j+1]==2&nbsp;and&nbsp;matrix[i+2][j+2]==2&nbsp;and&nbsp;matrix[i+3][j+3]==2&nbsp;): &nbsp;&nbsp;&nbsp;&nbsp;print("There&nbsp;is&nbsp;at&nbsp;least&nbsp;one&nbsp;left&nbsp;to&nbsp;right&nbsp;diagonal")
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python