如何在列表列表中移动项目?

How to move an Item inside a list of lists?

我有以下列表列表,表示存储在 space 中的矩阵:

[' ', '1', '1', ' ']
[' ', '1', ' ', ' ']
[' ', '1', ' ', ' ']
[' ', ' ', ' ', ' ']

数字 1s 代表倒置的 L(如伽玛,“Γ”)。我怎样才能让这个“物体”像块一样左右移动?我用“asdw”键移动它

我尝试这样做是为了做出正确的方向运动(顺便说一句,它没有做出正确的运动),但我认为这不是最好的方法,也不认为我真的可以将其升级为其他运动:

x = input("Movement: ")

if x == 'd':
    for i in range(4):
        for j in range(4):
            if space[i][j] == '1':
                try:
                    if space[i][j+1] == ' ':
                        space[i][j] = ' '
                        space[i][j+1] = '1'
                    if space[i][j+1] == '1' and space[i][j+2] == ' ':
                        space[i][j] = ' '
                        space[i][j+2] = '1'
                except IndexError:
                    pass

还有其他方法可以尝试吗?或者更正我正在使用的那个?提前致谢

实现此目的的一种方法是将其视为矩阵并应用矩阵变换。这不会阻止人物离开屏幕,但会移动它并且比你现在做的更有效。

为简单起见,我会将您的矩阵转换为 1 和 0,因为使用起来更简单:

import numpy as np

data = np.array([
          [0, 1, 1, 0],
          [0, 1, 0, 0],
          [0, 1, 0, 0],
          [0, 0, 0, 0],
       ])

要对整个矩阵应用右平移和左平移,您需要分别对 rightleft 数组执行矩阵乘法:

right = np.array([
    [0, 1, 0, 0],
    [0, 0, 1, 0],
    [0, 0, 0, 1],
    [0, 0, 0, 0],
])

left = np.array([
    [0, 0, 0, 0],
    [1, 0, 0, 0],
    [0, 1, 0, 0],
    [0, 0, 1, 0],
])

例如,

print(data, '\n')
d = np.matmul(data, right)
print(d, '\n')
d = np.matmul(d, right)
print(d)

Out:
[[0 1 1 0]
 [0 1 0 0]
 [0 1 0 0]
 [0 0 0 0]] 

[[0 0 1 1]
 [0 0 1 0]
 [0 0 1 0]
 [0 0 0 0]] 

[[0 0 0 1]
 [0 0 0 1]
 [0 0 0 1]
 [0 0 0 0]]

很明显,这里的问题是,一旦碰到边缘,它就不会停止,数值就会丢失。

列表的列表对于表示矩阵来说很笨重。相反,您可以使用实际的 matrix-like 类型,即可用于平移形状的 NumPy ndarray. NumPy includes a roll() 函数,因此您只需要提供方向即可。

首先,为了更好的可读性,我将使用 0 和 1。

import numpy as np

space = np.array([
    [0, 1, 1, 0],
    [0, 1, 0, 0],
    [0, 1, 0, 0],
    [0, 0, 0, 0],
])

然后我们就可以正确滚动了:

>>> np.roll(space, 1, 1)
[[0 0 1 1]
 [0 0 1 0]
 [0 0 1 0]
 [0 0 0 0]]

要执行其他方向,您只需要提供正确的值,您可以将其包装在这样的函数中:

def move_shape_in_array(array, direction):
    directions = {
        "up": (-1, 0),
        "left": (-1, 1),
        "down": (1, 0),
        "right": (1, 1),
    }
    shift, axis = directions[direction]
    return np.roll(array, shift=shift, axis=axis)
>>> move_shape_in_array(space, "right")
[[0 0 1 1]
 [0 0 1 0]
 [0 0 1 0]
 [0 0 0 0]]

但这并不能防止形状超出边缘。相反,它环绕着:

>>> move_shape_in_array(space, "up")
[[0 1 0 0]
 [0 1 0 0]
 [0 0 0 0]
 [0 1 1 0]]

要真正防范,在移动之前检查边上是否有1:

edge_idx = 0 if shift == -1 else -1
edge = array[edge_idx] if axis == 0 else array[:, edge_idx]

if edge.any():
    return array

(将其插入上述函数的 shift, axis =return 行之间。)