nプレイヤー間で16進グリッドを均等に分割する方法は?


15

単純な16進グリッドベースのゲームを作成していますが、マップをプレーヤー間で均等に分割する必要があります。マップはランダムに作成され、プレイヤーに比較的小さなエリアでほぼ同じ量のセルを持たせたいです。たとえば、マップに4人のプレーヤーと80個のセルがある場合、各プレーヤーには約20個のセルがあります(スポットオンである必要はありません)。また、各プレイヤーは、隣接するセルを4つ以下にする必要があります。つまり、マップが生成されるとき、最大の「チャンク」はそれぞれ4セルを超えることはできません。

これは2人または3人のプレイヤーにとって常に可能ではないことを知っています(これは「マップの色付け」問題に似ているため)。しかし、4〜8人のプレイヤーの場合、この問題にどのように対処できますか?


セルオートマトンは、これに似た簡単な方法です。シンプルなマップ、4つのバイオーム、およびそれらの配布方法
MichaelHouse

回答:


3

これは私がすることです:

  1. すべてのセルをランダムなプレーヤーに割り当てます。大きなマップでは、これはすべてのプレイヤーにかなり偶数のタイルを生成する可能性が非常に高いはずです。小さなマップでは、おそらくいくつかの修正を行う必要があります。
  2. 大きすぎるチャンクを分割します。最も簡単な方法は、すべてのタイルをチャンクにして、各タイルをランダムに割り当てることです。
  3. セルの数が不均衡な場合(たとえば、プレーヤーAのセル数が24で、プレーヤーBのセル数が16)、過大なプレーヤーから過小なプレーヤーにいくつかのセルを再割り当てします。
  4. チャンクをもう一度確認してください。ステップ3で新しいチャンクが導入された場合は、ステップ2に戻ります。そうでない場合は、素敵なマップです!

PSこの問題は決して不可能ではないと思います。地図の色付けの問題はまったく異なります(1つは、色の代わりに図形->色->タイルの割り当て)。
Junuxx

私はこのアプローチがかなり好きですが、エリアサイズのバランスをとろうとして長時間実行する可能性はありませんか?
マナブレイク

1
@manabreak:私が作った何か、それを試してみると。ステップ2への小さな変更(ランダムに再割り当てするのではなく、すべてのプレーヤーを循環して再割り当てする)で、非常にうまく機能します。時間があるときに書きます。
Junuxx

1
それはまさに私が探していたものです。:)
マナブレイク

1

n合計で16進数のセルとpプレイヤーがいると仮定すると、p <= nこれに取り組む最善の方法は、セルラーオートマトン(CA)を介したラウンドロビン配信です。

初期化

ランダムに(および/またはマップの中心からの距離などの何らかのヒューリスティックを使用して)各プレイヤーの開始セルを選択します。以来p <= n、これは問題になりません。

セルオートマトン

16進セル間の完全な接続が必要です。セルごとに6隣接配列を提案します。

class Cell
{
   //... other members...
   Cell[6] neighbours = new Cell[6];
}

固定サイズの配列を使用すると、セル間の地形方向の概念が存在することができますが、リストやベクトルは存在しません。特定のナビゲーション操作が簡単になる可能性があるため、これをお勧めします。

16進マップを行ごとにオフセットして2D配列に保存することもできます。ただし、これは、セルごとに隣接配列を保存するよりも、1行おきに幾何学的オフセットがあるために、やや直感的ではない場合があります。

すべてのセルが隣接するすべてのものに接続されていることを確認してください。完全な16進マップを生成する際に、セルごとに行ごとにこの操作を実行できます。PS最終的に非長方形の16進数マップが必要な場合は、個々のセルとそれらのセルへの参照を削除して、負のスペースを形成し、有機マップアウトラインを作成できます。

ラウンドロビン配布

擬似コード:

count number of neutral cells in entire map, minus those starting cells taken by players
while neutral cells remain (or while true)
   for each player
      if player has not yet reached expected territory size in cells
         for each cell already constituting this player's territory
           if territory can grow by one cell into a neutral neighbour
              grow into neighbour
              reduce neutral cell count for entire map by one
              if no more neutral cells remain in map
                 break out of outermost while loop immediately
              else
                 continue to next player immediately
begin game

このアルゴリズムは、プレイヤーのテリトリー有効な成長スペースがある場合、ラウンドロビン方式で各プレイヤーにテリトリーを1つずつ成長させる機会を与えます。特定のプレーヤーがさらに成長するのをブロックされた場合、アルゴリズムはこれにもかかわらず、それを行うプレーヤーの領域を成長させ続けますまだ有効で成長しているスペースを持っています。プレーヤーが制限に達するとすぐに、すべてのプレーヤーを同じ数のセルに簡単に制限できますが、必要に応じて、簡単に把握できるはずです。

これにより、各プレーヤーに最大サイズの「ホームテリトリー」が提供されます。「島」の領域を追加して、そのプレーヤーのセル数割り当てを満たすために、プレーヤーがローカルスペースを使い果たして成長したら、ニュートラルセルリストから新しい開始セルを選択し、そこから同じ「成長」プロセスに進みます。この方法では、ランダムなノイズではなく、各プレイヤーに対して適切なサイズの一貫した島のセットになります。


優れたドキュメントとアルゴリズムの擬似コードを提供しますが、これが質問者の質問と一致するかどうかはわかりません。質問では、「最大の「チャンク」はそれぞれ4セルを超えることはできません」と述べていますが、アルゴリズムでは、できるだけ大きな接続グループを作成します。
fnord

@fnordいいえ、ありません。あなたは私の答えを正しく読みませんでした。擬似コードに明示的に制限を設けました:「プレーヤーがまだセル内で予想される領域サイズに達していない場合」。ダウン票を削除してください。質問の改訂履歴をチェックして、コメントや投票の前からこれが当てはまることを確認してください。
エンジニア

質問では、「4つ以下の隣接セル」が必要ですが、各ユーザーがマップの予想される部分を持っている必要があります。これは、私にとって、eがリスクゲームがすべてのプレーヤーのマップをランダムに配分する方法に似ていることを意味します。答えは、マップを「最大サイズの「ホームテリトリー」」に分割します。確かに、予想されるテリトリーサイズの制限に達するとアルゴリズムは停止しますが、後のテキストで言及しますが、そのプレイヤーが新しい「島」を取得する方法はわかりません。
-fnord

@fnordロジックに問題があります。最後の文で、あなたは私のアルゴリズムが島の大きさnで停止することを認め、その後「道が見えない」と言って自分と矛盾することを認めます。質問に答えたことがありますか?この一般化されたアルゴリズムは、セルを散布する(n1に制限する)か、島を作成する(n> 1に設定する)ために使用できます。したがって、1つのアルゴリズムで、分散するだけでなくグループ化することもできます。これはOPの質問に答えないのですか?どのように下票に値するのでしょうか?
エンジニア

上記のコメントを編集しますが、手遅れです。「あなたのアルゴリズムには方法ありません」。ただし、この概念については後のテキストで言及します。
-fnord

0

別のアプローチは、「公平」ではあるが規則的な分布から始め、シミュレーテッドアニーリングに似た手法を使用して、公平性を失うことなく規則性を分割することです。

  • グリッドのすべてのセルに規則的なパターンで色を割り当てることから始めます(たとえば、最初の行に '123412341234'パターンを繰り返し、次の行に '341234123412'が続くなど)。これは、マップの形状が特に悪い場合、色の不均一な分布につながる可能性がありますが、固定マップから始めていると思われるため均等に分散された規則的な色を見つけることができるはずです。
  • 次に、必要な数のステップについて次の手順を繰り返します(実際の「完了」基準はないため、実験により、合理的な最小ステップ数がわかります)。
    • グリッドの2つの要素をランダムに選択します
    • 彼らが同じ色を持っている場合、もう一度試してみてください(それ以外の場合は意味がありません。交換は何もしないからです。同じ色に当たる確率は1/4、同じ色に当たる確率は1/16しかありません)連続して2回ですので、何度も再試行する必要はありません)
    • これらの2つの要素の色を仮に入れ替えます
    • スワップ後、要素の位置で新しく形成された領域のサイズをテストします。
      • 各要素の新しいスポットから外側に向かって単純な塗りつぶしを行い、スワップの色の領域がどれだけ大きくなるかを判断します。
    • これらの2つの領域のいずれかがしきい値よりも大きい場合、暫定スワップを元に戻します。それ以外の場合、2つの要素の色のスワップを「最終化」します。

ここで重要なのは、2つのスポットをスワップしているという事実は、色のバランスを崩さないことを意味し、同様に、スワップを完了する前に行うテストは、大きすぎる領域を作成しないことを保証するということです。グリッドを表示する手段がある場合は、このプロセスを視覚化して、繰り返しスワップを通じてどのようにリージョンを「構築」するかを見ることができます。

偶然、均等に分散された通常のカラーリングから始めることができない場合でも、カラーリングを均等に分散するのと同じようなことができるはずです。次に、それが過剰に表現された色の1つである場合、その色を不十分に表現された色の1つに暫定的に設定し、新しい色の領域が大きくなりすぎないことを確認します。


確率的アプローチは非効率的です。考慮されたステップを取る私のようなアプローチの場合、ランタイムはn個のマップセルに対してO(n)にアプローチします。アルゴリズムの場合、O(n * m)です。ここで、mは島ごとに(実際には、潜在的な島ごとに)必要なセルの数です。実行時間を容易に推定できるアルゴリズムを目指してください。偶然に生成されたマップを修正する代わりに、最初の段階で破損または偶然のないマップをnステップで生成し、制御された効率的なプロセスを維持することをお勧めします。
エンジニア
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.