如何在2048游戏中上移?

时间:2018-07-07 19:46:03

标签: python python-3.x list

我已经列出了一个看起来像2048板的列表:

nlist = [2, 2, 4, 8, 0, 2, 8, 0, 0, 0, 0, 2, 4, 2, 2, 0]

在2048游戏板上看起来像这样:

2 2 4 8
0 2 8 0
0 0 0 2
4 2 2 0

我想进行移位,将每个(不是行)中的所有0都删除,然后放回去,以便0处于底部,非零数字转到顶部,这样当我按 w 键时,该面板现在看起来像这样:

2 2 4 8
4 2 8 2
0 2 2 0
0 0 0 0

我只需要找到一种方法来遍历每行和每行有2个for循环。

5 个答案:

答案 0 :(得分:4)

如果您使用2D NumPy数组,或者至少使用行列表列表或列列表列表,而不是像这样的平面列表,这会容易得多。

但是,如果您想使用平面列表,可以通过添加按行和列访问该列表的函数来简化操作,因此您不必到处都写算法:

def getrc(nlist, width, r, c):
    return nlist[r*width+c]

def setrc(nlist, width, r, c, value):
    nlist[r*width+c] = value

现在,获取或设置整个列很简单:

def getc(nlist, size, c):
    return [getrc(nlist, size, r, c) for r in range(size)]

def setc(nlist, size, c, col):
    for r in range(size):
        setrc(nlist, size, r, c, col[r])

现在您只需要编写一个带有列列表的shift函数:

def shift(lst):
    # Get all the nonzero values in the column
    result = [value for value in lst if value]
    # And pad it with zeros
    result.extend(0 for value in lst if not value)
    return result

现在您可以将它们放在一起:

def shiftcolumns(nlist, size):
    for c in range(size):
        col = getc(nlist, size, c)
        col = shift(col)
        setc(nlist, size, c, col)

您能使它更简洁或更有效吗?当然。但是您能够理解,调试和扩展代码吗?如果没有,则保持简单。

如果您真的希望它更高效-尽管几乎没有关系-您可能应该在这里使用NumPy。

如果您真的希望它简洁明了,您应该再次 在此处使用NumPy。然后,代码不仅会更短,而且更容易理解,更难出错。 (或者,如果您这样做是为了练习如何教自己如何进行2D索引,请编写您的 own 2D数组类,该类只包含NumPy所做的一小部分,将这些{{1 }},getrcsetrc等在getc__getitem__方法中起作用。)

答案 1 :(得分:2)

一种简单的方法是使用读写循环

for col in range(4):
    wp = 0  # write pointer
    for row in range(4): # read loop
        if data[row*4+col] != 0:
            # non-zero: copy this element in place
            data[wp*4+col] = data[row*4+col]
            wp += 1
    # Fill the rest with zeros
    for row in range(wp, 4):
        data[row*4+col] = 0

答案 2 :(得分:1)

import operator
nlist = [2, 2, 4, 8, 0, 2, 8, 0, 0, 0, 0, 2, 4, 2, 2, 0]
size = int(len(nlist) ** .5)
print(list(zip(*map(lambda c: list(filter(bool, c)) + list(filter(operator.__not__, c)), zip(*[nlist[i * size: (i + 1) * size] for i in range(size)])))))

这将输出:

[(2, 2, 4, 8), (4, 2, 8, 2), (0, 2, 2, 0), (0, 0, 0, 0)]

或者如果您希望将其展平:

print([a for r in zip(*map(lambda c: list(filter(bool, c)) + list(filter(operator.__not__, c)), zip(*[nlist[i * size: (i + 1) * size] for i in range(size)]))) for a in r])

这将输出:

[2, 2, 4, 8, 4, 2, 8, 2, 0, 2, 2, 0, 0, 0, 0, 0]

答案 3 :(得分:1)

我对这个问题的看法:

from itertools import chain

nlist = [2, 2, 4, 8, 0, 2, 8, 0, 0, 0, 0, 2, 4, 2, 2, 0]

def slice(l):
    for i in range(4):
        new_row = []
        for j in nlist[i::4]:
            try:
                new_row.insert(new_row.index(0), j) if j > 0 else new_row.append(j)
            except ValueError:
                new_row.insert(1, j)
        yield new_row

new_list = list(chain.from_iterable(zip(*slice(nlist))))

for i in range(4):
    print(nlist[i*4:i*4+4])

print()

for i in range(4):
        print(new_list[i*4:i*4+4])

print(f'\nnew_list={new_list}')

输出为:

[2, 2, 4, 8]
[0, 2, 8, 0]
[0, 0, 0, 2]
[4, 2, 2, 0]

[2, 2, 4, 8]
[4, 2, 8, 2]
[0, 2, 2, 0]
[0, 0, 0, 0]

new_list=[2, 2, 4, 8, 4, 2, 8, 2, 0, 2, 2, 0, 0, 0, 0, 0]

答案 4 :(得分:1)

这是您想要做的另一种方式。注意,为了测试目的,我稍微修改了板子数据。

def vert_shift_zeros(board, width, height):
    """ Shift all the zeros to the end of each column in the board. """
    for col in range(width):
        # Get a column of data.
        column = [board[row*width + col] for row in range(height)]

        # Shift all the zeros in it to the end.
        shifted_column = [value for value in column if value]
        shifted_column.extend([0 for _ in range(height-len(shifted_column))])

        # Replace column with shifted data.
        for row in range(HEIGHT):
            board[row*width + col] = shifted_column[row]

if __name__ == '__main__':
    # A non-square board for testing purposes.
    WIDTH, HEIGHT = 5, 4
    nlist = [2, 2, 4, 8, -1,
             0, 2, 8, 0, -2,
             0, 0, 0, 2, -3,
             4, 2, 2, 0, -4]

    vert_shift_zeros(nlist, WIDTH, HEIGHT)
    for row in range(HEIGHT):
         print(', '.join(str(value)
                for value in nlist[row*WIDTH: (row+1)*WIDTH]))

输出:

2, 2, 4, 8, -1
4, 2, 8, 2, -2
0, 2, 2, 0, -3
0, 0, 0, 0, -4