你会如何用Python代表MineSweeper网格?

时间:2009-11-26 20:17:32

标签: python data-structures

您将在Python中使用什么数据结构来表示MineSweeper网格的内部状态?

每个x,y位置将保存一个数值,表示其当前的单元格状态(未探测,我的,标记,?)。

我应该使用嵌套列表吗?这似乎是最接近2D数组的东西,它是我可能在任何其他语言中使用的(2d数组)。

我不熟悉Python,所以有人可以给我一个建议吗?

7 个答案:

答案 0 :(得分:8)

使用嵌套列表。它很容易设置:

field = [([None] * height) for x in range(width)]

field[x][y] = "*"

最清楚的事情可能是一个新课程:

class MineField(object):
    class _SingleField(object):
        mine = False
        flagged = False
        covered = True

    width = None
    height = None

    def __init__(self, width, height):
        super(MineField, self).__init__()
        self.width = width
        self.height = height
        self._field = [[self._SingleField() for y in range(height)]
                                            for x in range(width)]

        self.init_field(10)

    def init_field(self, minecount):
        pass

    def __getitem__(self, index):
        x, y = index
        return self._field[x][y]

要像这样使用:

> m = MineField(10,10)
> m[4,9].mine
False

答案 1 :(得分:6)

你可以使用一个二维数组,为每个字段的状态保存对象:

class FieldState(object):
  def __init__(self):
    self.unexplored = True
    self.mine = Random()
    self.flag = Random()
    ...

for x in range(12):
  for y in range(24):
    list[x][y] = FieldState()

答案 2 :(得分:3)

只是在混合中抛出另一个选项,你可以使用由元组索引的dicts

board = {}
board[1, 2] = 9

答案 3 :(得分:1)

如果您使用Board类的实例,则可以随时更改内部表示。

class Board(object):
    def __init__(self, width, height):
        self.__width, self.__height = width, height
        self._board = [[FieldState() for y in xrange(height)]
                       for x in xrange(width)]
    @property
    def width(self):
        return self.__width

    def mark(self, x, y):
        self._board[x][y].mark()

    def __getitem__(self, coord):
        """
        >>> board = Board(3, 4)
        >>> field = board[1,2] # 2nd column, 3rd row
        """
        x, y = coord
        return self._board[x][y]

    ...

其中FieldState@zlack's answer中的{{1}}类似。

答案 4 :(得分:1)

我认为基本上有两层数据:1)地图数据:方形有炸弹(例如用-1表示)或围绕它有多少炸弹,2)显示数据,方块上显示的内容:炸弹数,炸弹,国旗,问号,空,未开封。

因此,两个嵌套列表(或一个嵌套的元组列表)可能就足够了。

答案 5 :(得分:0)

您可以使用单个int标记位置,准确显示其中的位置,从而大大简化编码。您不需要两个数据层。

00 nothing, noflag
10 bomb, noflag
01 nothing,flagged
11 bomb, flagged

现在因为该int的第一位显示是否有炸弹,我们实际上可以给它多几个位并指示邻居计数。

000 no-neighbor
001 one neighbor
010 two...

等等。存储它只需要一个字节,甚至可以留出扩展空间。

答案 6 :(得分:0)

“tile”或“cell”对象的地图,以坐标为一对键。

current = (1,1)
if grid[current].isFlagged():
   do_whatever;

当然,map占用的空间比数组要多一些,而tile类的占用空间比原始的位图或数字要多一些,但我认为你的主板不是1024x1024而且你不是很高有限的RAM情况。

如果您不仅仅在网格中查找切片,那么请考虑使用JF的Board对象来包装数组。

Python是一种面向对象语言,通常最简单,最清晰的方法就是明智地使用类和对象。

注意:您也可以查看named_tuple类,了解对于正确的类而言似乎过于简单的情况。