形をしたパズルのピース(たとえば、古典的なテトリスの形)でグリッドを埋めることを目的とするパズルゲームを作成しようと考えています。
隙間を残さずにグリッドを埋めるために使用できることが保証されているピースのセットを生成するにはどうすればよいですか?結果のパズルの難易度をスケーリングするために、このアルゴリズムをどのように適応できますか?
形をしたパズルのピース(たとえば、古典的なテトリスの形)でグリッドを埋めることを目的とするパズルゲームを作成しようと考えています。
隙間を残さずにグリッドを埋めるために使用できることが保証されているピースのセットを生成するにはどうすればよいですか?結果のパズルの難易度をスケーリングするために、このアルゴリズムをどのように適応できますか?
回答:
これは既知の難しい問題であり、特定の部分でタイリングできる長方形を決定します。
ただし、パズルを構築してピースを制御できる場合、それは反対の建設的な問題であり、簡単です...
建設的にソリューションを構築します。あなたが好きないくつかのピースを取り、あなたが望むようにパズルを埋めてください。次に、それを埋めるのに十分な単一の正方形を投入します。これで、少なくとも1つのソリューションがあることが保証されました。または、許可されたピースのセットにいくつかの小さなピースを含めます。
ピースの解決/レイアウトについては、典型的なブルートフォースアプローチは、左から右、次に上から下へと埋めることです。最初のオープンセル(番号LR、TB)を見つけて、許可されたピースを許可された向き(フリッピングを許可する場合は非対称ピースの場合は8つの向き)で配置してみます。おそらく、最初に許可された大きなピースをチェックし、必要に応じて小さなピースに頼ります。気に入らない状態(行き止まり、小片が多すぎるなど)に到達したら、バックトラックします。特定のグリッド/ピースセットが基準を満たさない場合、つまり、終了せずに最後までバックトラックした場合は、別の長方形とピースセットを試してください。
パズルを「より簡単に」作成する1つの方法は、モノミノやドミノのような、より大きなピースをより小さなピースと交換することです。これにより、最後の穴を埋める方法が増えるからです。または、同等に、これらの小さい部分を優先するソリューションを構築します。
一部の著名なポリオミノロジストには以下が含まれます:
==> http://ee.usc.edu/faculty_staff/faculty_directory/golomb.htm Golombはもともと「Polyomino」という用語を作り出した
==> http://www.eklhad.net/polyomino/ Dahlkeは、同一のピースで埋められた非常に多くの長方形を解決しました(特にまれなタイルフォーム)。
この記事(ページ11-13は、免責事項:私は著者の一人)のアルゴリズムを記述する均一完全にタイル張り生成長方形の幅の領域に使用する動的プログラミングW及び高さHに線形である時に、時間の前処理、その後2約かかり(wの。D)(時間/空間をDは、例えばテトリス片の場合には図4に示すように、個々の形状の最長寸法です)。
アイデアは、上記のデイビッドによって説明されたものに似ており、上部のストリップに焦点を当て、穴を作成しないピースを配置します。ここで重要なのは、上部ストリップの各状態に対して許可される代替案を事前に計算することから始めて、リージョンを生成するときに組み合わせ爆発の代金を払わないようにすることです。
アルゴリズムは、(凸)形状の任意のセットに対して機能します。
また、均一ランダム生成の興味深い側面は、連続する生成間の最大の多様性を保証することです(ただし、任意の方法で生成を制限することもできます)。ここにいくつかの典型的な出力があります:
実装に問題があるかどうかをお気軽に質問してください(Pythonの迅速で汚い実装がどこかにあるかもしれません...)
これは、より限定されたハードウェアを少し騙すために過去に使用したテクニックです。これは、より複雑なソリューションほど純粋ではありませんが、毎回実装して機能することがはるかに容易になるという明確な利点があります。
パズル全体に集中するのではなく、より小さな均一な単位に分割します。これらのユニットのそれぞれは、パズルに記入するのがはるかに簡単な正方形または長方形を形成するために一緒にフィットする一連のピースで構成されています。パズルの幅を満たすために、さまざまな構成からランダムに選択します(以下のサンプルですが、非常に多くの構成があります)。以下は4x4、5x4、さらには10x4の例です。
アイデアは、パズルを「ストライプ化」することです。利用可能な残りの部屋に基づいてランダムに幅を選択します。「ストライプ」が終了したら、新しいストライプを開始します。
各「ストライプ」セット内でランダム化することにより、一度に1つのストライプのピースを解放します。難易度を上げたい場合は、一度に2つ以上のストライプからランダムに解放します。
この手法を使用すると、パズルが解決可能であることが保証されるだけでなく、リリースの順序を「だまし」て、生き続けることが容易になります。もちろん、実際には、プレイヤーは各ストライプを完全に解決することができないため、混乱が起こります。
プレイヤーが負けるまでストライプを生成し続けます。もちろん、私の例は4ブロックの高さのストライプですが、より大きく複雑なものを選択することもできます。