简体   繁体   English

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

[英]How would you represent a MineSweeper grid in Python?

What datastructure would you use in Python to represent the internal state of a MineSweeper grid? 您将在Python中使用什么数据结构来表示MineSweeper网格的内部状态?

Each x,y position will hold a numerical value which represents its current cell state (unexplored, mine, flag, ?). 每个x,y位置将保持一个数值,表示其当前的单元状态(未探测,我的,标志,?)。

Should I use nested lists? 我应该使用嵌套列表吗? This seems like the closest thing to a 2D array and it is what I would probably use in any other language (2d array that is). 这似乎是最接近2D数组的东西,它是我可能在任何其他语言中使用的(2d数组)。

I'm not that experienced with Python so could someone give me a suggestion? 我不熟悉Python,所以有人可以给我一个建议吗?

Use a nested list. 使用嵌套列表。 It's easy to set up: 它很容易设置:

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

field[x][y] = "*"

The clearest thing would probably be a new class: 最清楚的事情可能是一个新类:

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]

To be used like this: 要像这样使用:

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

you could use a 2 dimensional array, holding objects for the state of each field: 你可以使用一个二维数组,为每个字段的状态保存对象:

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()

Just to throw another option in the mix, you could use dicts indexed by tuples 只是为了在混合中抛出另一个选项,你可以使用由元组索引的dicts

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

If you use an instance of Board class you can always change the internal representation later. 如果您使用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]

    ...

Where FieldState is similar to the one from @zlack's answer . 其中FieldState类似于@ zlack的回答

I think there are basically two layers of data: 1) map data: does square have a bomb (eg represented by -1) or how many bombs are around it, 2) display data, what is shown on the square: bomb count, bomb, flag, question mark, empty, unopened. 我认为基本上有两层数据:1)地图数据:方形有炸弹(例如用-1表示)或围绕它有多少炸弹,2)显示数据,方块上显示的内容:炸弹数,炸弹,国旗,问号,空,未打开。

So two nested lists (or one nested list of tuples) might be enough. 因此,两个嵌套列表(或一个嵌套的元组列表)可能就足够了。

You could mark locations with a single int showing exactly what sits there, easing your coding considerably. 您可以使用单个int标记位置,准确显示其中的内容,从而大大简化编码。 You wouldnt need two data layers. 您不需要两个数据层。

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

Now since the first bit of that int shows whether there is a bomb or not, we can actually give it a few more bits and indicate neighbour count as well. 现在,因为该int的第一位显示是否有炸弹,我们实际上可以给它几个位并指示邻居计数。

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

and so on. 等等。 Storing this only takes a single byte and even leaves room for expansion. 存储它只需要一个字节,甚至可以留出扩展空间。

A map of 'tile' or 'cell' objects, keyed to the coordinates as a pair. “tile”或“cell”对象的地图,作为一对键入坐标。

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

Of course, map takes a little more space than array, and the tile class will have a tiny bit more footprint than a primitive bitmap or number, but I assume your board isn't 1024x1024 and you're not in a highly constrainted RAM situation. 当然,map占用的空间比数组要多一些,而tile类的占用空间比原始的位图或数字要小一些,但我认为你的主板不是1024x1024而且你没有处于高度受限的RAM状态。

If you do more than look up the tiles in the grid, then do consider JF's Board object to wrap the array. 如果您不仅仅在网格中查找切片,那么请考虑使用JF的Board对象来包装数组。

Python is an OO language, and often the simplest and clearest thing that works is to use classes and objects wisely. Python是一种面向对象语言,通常最简单,最清晰的工作就是明智地使用类和对象。

Note: you might also look at the named_tuple class for situations that seem too simple for a proper class. 注意:您还可以查看named_tuple类,了解对于正确的类而言似乎过于简单的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM