Как бы вы представили сетку MineSweeper в Python? - PullRequest
3 голосов
/ 26 ноября 2009

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

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

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

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

Ответы [ 7 ]

8 голосов
/ 26 ноября 2009

Использовать вложенный список. Это легко настроить:

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
6 голосов
/ 26 ноября 2009

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

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()
3 голосов
/ 27 ноября 2009

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

board = {}
board[1, 2] = 9
1 голос
/ 27 ноября 2009

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

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

1 голос
/ 26 ноября 2009

Если вы используете экземпляр класса 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 .

0 голосов
/ 31 января 2012

Карта объектов «плитка» или «ячейка», привязанная к координатам в виде пары.

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

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

Если вы не только просматриваете тайлы в сетке, то можете рассмотреть объект Board JF, чтобы обернуть массив.

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

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

0 голосов
/ 05 июня 2011

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...