2009-11-26 4 views
3

Какая структура данных вы используете в Python для представления внутреннего состояния сетки MineSweeper?Как вы представляете сетку MineSweeper в Python?

Каждая позиция x, y будет содержать числовое значение, которое представляет собой текущее состояние ячейки (неизведанное, мое, флаг,?).

Должен ли я использовать вложенные списки? Это похоже на самое близкое к 2D-массиву, и это то, что я, вероятно, использовал бы на любом другом языке (2d-массив, который есть).

Я не настолько опытен с Python, чтобы кто-нибудь дал мне предложение?

ответ

6

вы могли бы использовать 2 одномерный массив, держа объекты для состояния каждого поля:

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

Поскольку вы используете класс, почему бы не «__getitem__» взять кортеж в качестве аргумента. 'def __getitem __ (self, (x, y)): return self._field [x] [y]'. Затем вы можете использовать 'm [4,9]' –

+0

@gnibbler: Не знаю, как-то я думал, что это сделает его более сложным ... (хотя я уже реализовал такой метод '__getitem__' некоторое время назад) Спасибо , –

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.

3

Просто бросить еще один вариант в смеси, можно использовать dicts индексированных кортежей

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

Я думаю, что есть в основном два слоя данных: 1) данные карт: это квадрат имеет бомбу (например, представленную на -1) или сколько бомб вокруг него, 2) отображать данные, что показано на квадрате: количество бомб, бомба, флаг, знак вопроса, пустой, нераскрытый.

Таким образом, может быть достаточно двух вложенных списков (или одного вложенного списка кортежей).

0

Вы можете отметить местоположения с одним int, показывающим, что именно там сидит, значительно ослабляя ваше кодирование. Вам не нужны два слоя данных.

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

Теперь, так как первый бит этого междунар показывает, есть ли бомба или нет, мы можем на самом деле дать ему еще несколько битов и указать кол-соседей, а также.

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

и так далее. Хранение этого занимает всего один байт и даже оставляет место для расширения.

0

Карта объектов 'tile' или 'cell', привязанных к координатам как пара.

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

Конечно, карта занимает немного больше места, чем массив, а класс плитка будет иметь чуть-чуть больше, чем след примитивного растрового изображения или номер, но я предполагаю, что ваша плата не 1024х1024 и вы а не в ситуации с высокой степенью ограниченности ОЗУ.

Если вы делаете больше, чем смотрите на плитки в сетке, тогда рассмотрите объект Board JF для обертывания массива.

Python - это язык OO, и часто самая простая и ясная вещь, которая работает - разумно использовать классы и объекты.

Примечание: вы также можете посмотреть класс named_tuple для ситуаций, которые кажутся слишком простыми для соответствующего класса.

Смежные вопросы