【问题标题】:python game 2048 out of list indexpython game 2048 out of list index
【发布时间】:2016-04-23 02:18:01
【问题描述】:

我正在使用 codesculpter 在 coursera python project 2048 上工作。 当我尝试4 x 45 x 5 时,代码运行良好,但在4 x 5height != width 时显示错误。我想我一定是在__init__ 或其他地方搞砸了,但我想不通。

有人能给我一些建议吗?

这是我迄今为止尝试过的:

import poc_2048_gui
import random

# Directions, DO NOT MODIFY
UP = 1
DOWN = 2
LEFT = 3
RIGHT = 4

# Offsets for computing tile indices in each direction.
# DO NOT MODIFY this dictionary.
OFFSETS = {UP: (1, 0),
           DOWN: (-1, 0),
           LEFT: (0, 1),
           RIGHT: (0, -1)}

def merge(line):
    """
    Helper function that merges a single row or column in 2048
    """

    # creat output list and remove 0
    after_merge=[]
    storage = []


    for num_1 in range(len(line)):
        after_merge.append(0)
        if line[num_1] != 0 :
            storage.append(line[num_1])


    # sum number        
    for num_2 in range(len(storage)):
        if num_2+2> len(storage):
            break
        elif storage[num_2]==storage[num_2+1]:
            storage[num_2]*=2
            storage.pop(num_2+1)

    # replace 0 in after merge          
    for num in range(len(storage)):
        after_merge[num]=storage[num]

    return after_merge


class TwentyFortyEight:
    """
    Class to run the game logic.
    """

    def __init__(self, grid_height, grid_width):
        self.grid_height = grid_height
        self.grid_width = grid_width
        self.cell=[]
        self.indices = {}
        self.indices[UP] = [[0,n] for n in range(grid_width)] 
        self.indices[LEFT] = [[n,0] for n in range(grid_height)] 
        self.indices[RIGHT] = [[n, grid_width - 1] for n in range(grid_height)]
        self.indices[DOWN] = [[grid_height - 1, n]for n in range(grid_width)]

        self.ranges = {}
        self.ranges[UP] = grid_height
        self.ranges[DOWN] = grid_height
        self.ranges[LEFT] = grid_width
        self.ranges[RIGHT] = grid_width

        #self.reset()

    def reset(self):
        """
        Reset the game so the grid is empty except for two
        initial tiles.
        """
        self.cell = [[0*(col+row) for row in range(self.grid_height)] for col in range (self.grid_width)]
        for count in range(2):
            self.new_tile()

    def __str__(self):
        """
        Return a string representation of the grid for debugging.
        """
        a_str = ""
        for row in range(self.grid_height):
            for col in range (self.grid_width):
                a_str += ( str(self.cell[row][col]) + " " )
            a_str += '\n'
        return a_str


    def get_grid_height(self):
        """
        Get the height of the board.
        """
        # replace with your code
        return self.grid_height

    def get_grid_width(self):
        """
        Get the width of the board.
        """
        # replace with your code
        return self.grid_width

    def move(self, direction):
        """
        Move all tiles in the given direction and add
        a new tile if any tiles moved.
        """
        a_list = []
        has_moved = False
        for index in self.indices[direction]:
            for step in range(self.ranges[direction]):
                a_list.append(self.cell[index[0] + OFFSETS[direction][0] * step]
                              [index[1] + OFFSETS[direction][1] * step])
            merged_list = merge(a_list)

            if merged_list != a_list:
                for step in range(self.ranges[direction]):
                    self.cell[index[0] + OFFSETS[direction][0] * step]   \
                    [index[1] + OFFSETS[direction][1] * step] = merged_list[step]
                has_moved = True
            a_list = []

        if has_moved:
            self.new_tile()

    def new_tile(self):
        """
        Create a new tile in a randomly selected empty
        square.  The tile should be 2 90% of the time and
        4 10% of the time.
        """
        # replace with your code
        row=0
        col=0
        available_positions = []
        for row in range(self.grid_height):
            for col in range(self.grid_width):
                if self.cell[row][col] == 0:
                        available_positions.append([row, col])
        if not available_positions:
            print "There are no available positions."

        random_pos=random.choice(available_positions)
        rand_val=random.randint(1,10)
        if rand_val>=9:
            new_tile=4
        else:
            new_tile=2

        self.set_tile(random_pos[0], random_pos[1], new_tile)



    def set_tile(self, row, col, value):
        """
        Set the tile at position row, col to have the given value.
        """
        # replace with your code
        self.cell[row][col] = value

    def get_tile(self, row, col):
        """
        Return the value of the tile at position row, col.
        """
        # replace with your code
        return self.cell[row][col]



poc_2048_gui.run_gui(TwentyFortyEight(4, 4))

【问题讨论】:

  • 你期望什么结果,你会得到什么错误?

标签: python list


【解决方案1】:

好的,我没有一直调试,但这是我发现的。 cell 应该有维度 grid_height * grid_width。对吗?

然而,就在这个循环之前:

for row in range(self.grid_height):
    for col in range(self.grid_width):
        print(row," ",col);
        if self.cell[row][col] == 0:
                available_positions.append([row, col])
if not available_positions:
    print "There are no available positions."

我发现单元格的大小是相反的。那是grid_width * grid_height。将这两行放在嵌套循环之前,自己看看。

print("cell size",len(self.cell)," ",len(self.cell[0]))
print("grid size",self.grid_height," ",self.grid_width)

当尺寸不同时,这将导致IndexError 在行if self.cell[row][col] == 0: 中。话虽如此,您应该逐步了解如何填写网格和单元格。确保它们正确对应。

希望对您有所帮助!

【讨论】:

  • 感谢您的建议!是的,我不太了解如何设置二维数组。另外,感谢您对索引错误的建议。
【解决方案2】:

我进行了快速调试,并且在调用 move() 时得到了 IndexError。仔细看,您似乎期望 self.cell 被填充,但它只通过您的 reset() 函数填充。如果您的 UI 模块在初始化时调用 reset,您可能看不到这一点...

当 row 和 col 不是同一个数字时,会出现第二个 IndexError。这(如另一个答案中所述)是因为您的二维数组表示是 col * row,而不是 row * col

下面是 (4, 6) 的打印输出,它有 4 COLUMN 和 6 ROW。您可能只需要在表示中交换两者:

[0, 0, 0, 0]
[2, 0, 2, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]

对你的语法有潜在的改进,但你可以这样启动你的单元格(用你的用法测试......)

self.cell = [[[0] * self.grid_width] for row in xrange(self.grid_height)]

最后,我相信您可能会在 new_tile 中收到 IndexError,因为 Python 列表从第 0 个元素开始。您需要从 0 迭代到 n-1:

    for row in range(self.grid_height-1):
        for col in range(self.grid_width-1):

【讨论】:

  • 非常感谢!我以前不太明白如何设置二维数组。对于代码“self.cell = [[[0] * self.grid_width] for row in xrange(self.grid_height)]”不知何故,我认为将宽度放在前面或放在前面并不重要。但它实际上有点不同。现在我可以明白为什么我有这个错误了。再次感谢,我真的很感激!
猜你喜欢
  • 2013-04-27
  • 1970-01-01
  • 1970-01-01
  • 2018-02-08
  • 2014-10-20
  • 1970-01-01
  • 2016-05-11
  • 2019-02-23
  • 2021-12-27
相关资源
最近更新 更多