Маджонг - расставляйте плитки, чтобы обеспечить хотя бы один путь к победе, независимо от расположения - PullRequest
8 голосов
/ 02 октября 2008

Независимо от того, какой макет используется для плиток, есть ли хороший способ разделить плитки, чтобы вы могли гарантировать пользователю, что в начале игры существует хотя бы один путь для завершения головоломки выиграть игру?

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

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

Ответы [ 8 ]

17 голосов
/ 02 октября 2008

Поместите все плитки в обратном порядке (т.е. разложите доску, начиная с середины, выполняя)

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

8 голосов
/ 02 октября 2008

Играйте в игру наоборот.

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

7 голосов
/ 16 декабря 2009

Я знаю, что это старый вопрос, но я сталкивался с этим, когда решал проблему сам. Ни один из ответов здесь не является идеальным, и некоторые из них имеют сложные предостережения или нарушат патологические схемы. Вот мое решение:

Решите доску (вперед, а не назад) с неотмеченными плитками. Удалите две бесплатные плитки одновременно. Вставьте каждую пару, которую вы удаляете, в стек «подходящей пары». Часто это все, что вам нужно сделать.

Если вы зашли в тупик (numFreeTiles == 1), просто перезагрузите ваш генератор :) Я обнаружил, что обычно я не захожу в тупик, и до сих пор у меня было максимальное число повторов 3 для 10- или так раскладки я пробовал. Как только я нажму 8 попыток, я сдаюсь и просто случайным образом назначаю остальные плитки. Это позволяет мне использовать один и тот же генератор как для настройки доски, так и для функции перемешивания, даже если игрок облажался и перешел в 100% неразрешимое состояние.

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

К сожалению, в зависимости от платы это может зацикливаться вечно. Если в итоге вы удалите пару, которая напоминает дорогу «без розетки», где все последующие «дороги» являются тупиковыми, и есть несколько тупиков, ваш алгоритм никогда не завершится. Я не знаю, возможно ли спроектировать плату там, где это будет иметь место, но если это так, решение все еще есть.

Чтобы решить эту большую проблему, обрабатывайте каждое возможное состояние платы как узел в группе обеспечения доступности баз данных, причем каждая выбранная пара является ребром на этом графике. Произведите случайный обход, пока не найдете листовой узел на глубине 72. Следите за своей историей обхода, чтобы вы никогда не повторяли спуск.

Поскольку тупики встречаются реже, чем решения первой попытки в макетах, которые я использовал, сразу приходит на ум гибридное решение. Сначала попытайтесь решить это с минимальным объемом памяти (сохраните выбранные пары в вашем стеке). После того, как вы попали в первый тупик, переходите к полной маркировке / генерации ребер при посещении каждого узла (ленивая оценка, где это возможно).

Я очень мало изучал теорию графов, поэтому, возможно, есть лучшее решение для задачи случайного обхода / поиска DAG:)

Редактировать: На самом деле вы могли использовать любое из моих решений с созданием платы в обратном порядке, а именно сообщение от 13 октября 2008 года. У вас остались те же предостережения, потому что вы все равно можете оказаться в тупике. Генерация доски в обратном порядке имеет более сложные правила. Например, вы гарантированно потерпите неудачу в настройке, если не начнете, по крайней мере, НЕКОТОРЫЕ из своих строк с первой части посередине, например, в макете с 1 длинной строкой. Выбор совершенно случайного (легального) первого хода в генераторе решения с большей вероятностью приведет к решаемой доске.

5 голосов
/ 02 октября 2008

Единственное, что мне удалось придумать, - это положить плитки в соответствующие пары, как своего рода обратная игра Пасьянс Маджонг. Таким образом, в любой момент во время размещения фишек доска должна выглядеть так, как будто она находится в середине реальной игры (то есть никакие фишки не плавают на 3 слоя выше других фишек).

Если плитки в совпадающих парах размещаются в обратной игре, это всегда должно приводить как минимум к одному прямому пути для решения игры.

Я бы хотел услышать другие идеи.

0 голосов
/ 28 января 2010

У вас в игре 144 фишки, каждая из 144 фишек имеет список блоков. (верхний тайл в стеке имеет пустой список блоков)

Все действительные ходы требуют, чтобы их "current__vertical_Block_list" был пустым ... это может быть матрица 144x144, то есть 20 КБ памяти плюс список блоков ВЛЕВО и ВПРАВО, также по 20 КБ каждый.

Создание действительной таблицы перемещения из (remaning_tiles) AND ((пустой CURRENT VERTICAL BLOCK LIST) и ((пустой CURRENT LEFT BLOCK LIST) ИЛИ (пустой CURRENT RIGHT BLOCK LIST)))

Выберите 2 случайных тайла из действительной таблицы ходов и запишите их Обновите (текущие таблицы Vert, левый и правый), запишите снятые плитки в стек

Теперь у нас есть список ходов, которые составляют действительную игру. Назначьте соответствующие типы плиток каждому из 72 ходов.

для сложных игр, отслеживать, когда каждая плитка становится доступной. найти наборы, которые имеют (рано, рано, поздно, поздно) и (поздно, поздно, поздно, рано), так как он пуст, вы найдете 1 EE 1 LL и 2 LE блока .. из блока 2 LE, найдите EARLY, который блокирует ЛЮБОЙ другой EARLY, который ( кроме правого блокирования левой боковой части)
Как только вы получите действительную игру, поиграйте с заказом.

0 голосов
/ 13 октября 2008

Вот правила, которые я использовал в своей реализации.

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

  • имеет все ячейки на более низких уровнях уже заполнены
  • место для второго лада не блокируется первым, учитывая, что первый лад уже установлен на борту
  • оба места находятся "по краям" уже построенной кучи:
    • ЛИБО как минимум один сосед слева или справа
    • ИЛИ это первый лад подряд (все ячейки справа и слева рекурсивно свободны)

Эти правила не гарантируют, что сборка всегда будет успешной - иногда она оставляет две свободные ячейки самоблокирующимися, и сборку следует повторить (или, по крайней мере, последние несколько ладов) На практике «черепаха» встраивается не более чем в 6 попыток.

Большинство существующих игр, по-видимому, ограничивают размещение первых ("первых в ряду") ладов где-то посередине. Это дает более удобные конфигурации, когда на краях очень длинных рядов нет лада, оставаясь до последнего движения игрока. Однако «середина» отличается для разных конфигураций.

Удачи:)

P.S. Если вы нашли алгоритм, который создает разрешимую кучу за один ход - пожалуйста, дайте мне знать.

0 голосов
/ 02 октября 2008

Я полагаю, что лучший ответ уже выдвинут: создание набора путем его решения «в обратном порядке» - то есть начиная с пустой доски, затем добавляя пару куда-то, добавляя еще одну пару в разрешимую позицию и так далее. ..

Если вы предпочитаете подход «Большого взрыва» (генерируя весь набор случайным образом в начале), вы очень мачо разработчик или просто чувствуете себя мазохистом сегодня, вы можете представить все пары, которые вы можете убрать. из заданного набора и как они зависят друг от друга через ориентированный граф.

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

Реализация этого решения оставлена ​​читателю в качестве упражнения: D

0 голосов
/ 02 октября 2008

Solitaire? Просто предположение, но я предполагаю, что ваш компьютер должен пройти игру (или близко к ней), чтобы определить это.

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

В некоторой степени вы можете убедиться, что одна из 4 плиток находится не более чем на X слоев ниже другой X.

В большинстве игр, которые я вижу, есть команда перемешивания, когда кто-то застревает.

Я бы попробовал разные вещи и посмотрел, что работает лучше.

...