web-dev-qa-db-ja.com

パックマン:目はどのようにしてモンスターの穴に戻るのですか?

パックマンで幽霊のAIについて多くの言及を見つけましたが、誰も幽霊がパックマンに食べられた後、目が中心の幽霊の穴に戻る方法について言及していませんでした。

私の実装では、シンプルだがひどいソリューションを実装しました。私は、どの方向をとるべきかを隅々までハードコーディングしました。

より良い/または最良のソリューションはありますか?異なるレベルのデザインで動作する一般的なものでしょうか?

321

実際、あなたのアプローチは、あらゆる種類の経路探索と比較して実行時間がほとんどゼロの、非常に素晴らしいソリューションです。

任意のマップに一般化する必要がある場合、任意のパス検索アルゴリズムを使用できます-たとえば、幅優先検索は実装が簡単です-それを使用して、ゲームを実行する前に、各コーナーでエンコードする方向を計算します。

編集(2010年8月11日):Pacmanシステムの非常に詳細なページを参照しました: The Pac-Man Dossier 、ここで受け入れられた答えがあるので、更新する必要があると感じました。この記事は、怪物の家に明示的に戻る行為を扱っているようには見えませんが、パックマンでの直接の経路探索は次の場合であると述べています。

  • 次の交差点に向かって移動し続けます(これは基本的に「選択肢が与えられたとき、次のステップで見られるように、方向を反転させない方向を選択する」という特別なケースです)。
  • 交差点で、あなたがちょうど来たものを除いて、隣接する出口広場を見てください。
  • ゴールに最も近いものを選ぶ。複数が目標の近くに均等にある場合は、上、左、下、右の順序で最初の有効な方向を選択します。
151
Kylotan

この方法で汎用レベルのこの問題を解決しました。レベルを開始する前に、モンスターホールから何らかの「洪水」を起こします。壁ではない迷路のすべてのタイルには、穴からどれだけ離れているかを示す数字が付けられます。したがって、目が68の距離にあるタイルにある場合、隣接するタイルのどれが67の距離にあるかを確認します。それがその後の道です。

85

より伝統的な経路探索アルゴリズムの代替として、(適切な名前が付けられています!) Pac-Man Scent Antiobject pattern を見ることができます。

起動時に迷路の周りにモンスターの穴の匂いを拡散させ、目を家に追いかけることができます。

臭いが設定されると、ランタイムコストは非常に低くなります。


編集:残念ながらウィキペディアの記事は削除されたので、 WayBack Machine to the rescue ...

42
Dan Vinton

Dijkstraのアルゴリズム または A *アルゴリズム のようなパス検索アルゴリズムを見てください。これがあなたの問題です:グラフ/パスの問題。

18

動作するシンプルなソリューションはすべて、保守可能で信頼性が高く、十分なパフォーマンスを発揮するのが良いソリューションです。あなたはすでに良い解決策を見つけているようです...

経路探索ソリューションは、現在のソリューションよりも複雑になる可能性が高いため、デバッグが必要になる可能性が高くなります。また、おそらく遅くなります。

IMO、破損していない場合は修正しないでください。

[〜#〜] edit [〜#〜]

IMO、迷路が固定されている場合、現在のソリューションis良い/エレガントなコード。 「良い」または「エレガントな」を「賢い」と間違えないでください。単純なコードは、「良い」と「エレガントな」場合もあります。

構成可能な迷路レベルがある場合は、迷路を最初に構成するときにパスファインディングを実行する必要があるかもしれません。最も簡単なのは、迷路のデザイナーに手作業でやらせることです。あなたが途方もない迷路を持っている場合、またはユーザーがそれらを設計できる場合、私はこれを自動化するだけです。

(脇:経路が手作業で構成されている場合、迷路の設計者は準最適経路を使用してレベルをさらに面白くすることができます...)

18
Stephen C

オリジナルのパックマンでは、ゴーストは「臭い」で黄色いピルイーターを見つけ、マップ上に痕跡を残します。ゴーストは匂いを見つけるまでランダムに歩き回ります。プレーヤー。パックマンが移動するたびに、「香りの値」は1ずつ減少します。

さて、プロセス全体を逆にする簡単な方法は、「ゴーストの匂いのピラミッド」を持つことです。これは、マップの中心に最高点があり、ゴーストはこの匂いの方向に移動します。

14
Ivo Wetzel

Pacmanを追いかけるために必要なロジックをすでに持っていると仮定して、なぜそれを再利用しませんか?ターゲットを変更するだけです。まったく同じロジックを使用してまったく新しいルーチンを作成しようとするよりも、はるかに少ない作業になるようです。

5
John Gardeniers

これは、実際にどのように機能するかについて見つけることができる最高のソースでした。

http://gameai.com/wiki/index.php?title=Pac-Man#Respawn 幽霊が殺されると、実体化されていない目が元の場所に戻ります。これは、ゴーストのターゲットタイルをその場所に設定することで簡単に実現できます。ナビゲーションは同じルールを使用します。

実際には理にかなっています。世界で最も効率的ではないかもしれませんが、ターゲットを変更するだけで、他の状態やそれらの線に沿って何かを心配する必要のない素敵な方法です。

サイドノート:pac-manプログラマーが基本的に、非常に限られたメモリの非常に小さなスペースでメッセージシステム全体を作成していたことに気づきませんでした...それは驚くべきことです。

3
Midpipps

中心までの距離の値を持つ各正方形はどうですか?このようにして、指定された各正方形について、考えられるすべての方向で直接隣接する正方形の値を取得できます。最も低い値の正方形を選択し、その正方形に移動します。

値は、利用可能なアルゴリズムを使用して事前に計算されます。

3
mvbl fst

これは経路探索の問題です。一般的なアルゴリズムについては、 http://wiki.gamedev.net/index.php/A* をご覧ください。

3
Marijn

各コーナーでランダムな方向を選択するというdtb23の提案では、最終的にモンスターホールの音がひどく不十分であることがわかります。

ただし、ゲームの難易度により多くのバリエーションを導入することにより、非効率的な帰宅アルゴリズムを利用してゲームをより楽しくすることができます。これを行うには、ウェイポイントや塗りつぶしなどの上記のアプローチのいずれかを適用しますが、非決定的に実行します。そのため、すべてのコーナーで、乱数を生成して、最適な方法をとるか、ランダムな方向をとるかを決定できます。

プレイヤーがレベルを進めるにつれて、ランダムな方向が取られる可能性を減らします。これにより、レベル速度、ゴースト速度、ピルイーティングポーズ(など)に加えて、全体的な難易度レベルに別のレバーが追加されます。幽霊がただ無害な目である間にリラックスする時間がありますが、その時間は進むにつれて短くなります。

2
imoatama

短い答え、あまりよくない。 :)パックマンの迷路を変更すると、目が必ずしも戻ってくるとは限りません。周りに浮かぶハックのいくつかはその問題を抱えています。だから、それは協力的な迷路を持つことに依存しています。

2
dwidel

あなたの解決策は問題に対して正しいと思います、それよりも簡単です、幽霊の目が壁を通過できる新しいバージョンをより「現実的」にすることです=)

2
Hernán Eche

AmmoQのフラッドフィルのアイデアのアナログと擬似コードを次に示します。

queue q
enqueue q, ghost_Origin
set visited

while q has squares
   p <= dequeue q
   for each square s adjacent to p
      if ( s not in visited ) then
         add s to visited
         s.returndirection <= direction from s to p
         enqueue q, s
      end if
   next
 next

アイデアは、幅優先探索であるため、新しい隣接する正方形に遭遇するたびに、最適なパスはpを経由します。 O(N)だと思う。

2
Mark Peters

ゲームの実装方法についてはあまり知りませんが、次のことができます。

  1. ゲートに対する目の位置の相対位置を決定します。つまり、上に残っていますか?すぐ下?
  2. 次に、2つの方向のいずれかと反対側に目を移動し(ゲートの右側にある場合は左に移動し、ゲートの下に移動するなど)、壁が存在するかどうかを確認します。
  3. それを妨げる壁がある場合は、他の方向と反対に動かします(たとえば、ピンに対する目の座標が右北で、現在左に動いていて、途中に壁がある場合)南に移動します。
  4. 移動するたびにチェックし続けることを忘れないでください。ゲートに対する目がどこにあるかを確認し、緯度座標がないときを確認します。すなわち、それはゲートの上だけです。
  5. 壁がある場合、ゲートの上のみに移動する場合は、左または右に移動し、目が巣穴に入るまでこの番号1〜4を繰り返します。
  6. パックマンで行き止まりを見たことはありませんが、このコードは行き止まりを説明しません。
  7. また、私は私の擬似コードで、Originにまたがる壁の間で目が「ぐらつく」ときの解決策を含めました。

いくつかの擬似コード:

   x = getRelativeOppositeLatitudinalCoord()
   y
   origX = x
    while(eyesNotInPen())
       x = getRelativeOppositeLatitudinalCoordofGate()
       y = getRelativeOppositeLongitudinalCoordofGate()
       if (getRelativeOppositeLatitudinalCoordofGate() == 0 && move(y) == false/*assume zero is neither left or right of the the gate and false means wall is in the way */)
            while (move(y) == false)
                 move(origX)
                 x = getRelativeOppositeLatitudinalCoordofGate()
        else if (move(x) == false) {
            move(y)
    endWhile
2
thyrgle

私は、幽霊が彼が穴からパックマンにたどった道を保存することを提案します。そのため、幽霊が死ぬとすぐに、彼はこの保存された経路を逆方向にたどることができます。

2
Fischer Ludrian
  1. ゲームを開始する前に、マップにノード(交差点)を保存します
  2. モンスターが死ぬと、ポイント(座標)を取得し、ノードリストで最も近いノードを見つけます。
  3. そのノードから穴までのすべてのパスを計算します
  4. 長さで最短経路を取る
  5. ポイントと最も近いノードの間のスペースの長さを追加します
  6. パス上に描画して移動する

楽しい!

1
GingerHead

私のアプローチは(Pacman時代の観点から)少しメモリを集中的に使用しますが、一度計算するだけでよく、あらゆるレベルのデザイン(ジャンプを含む)で機能します。

ノードに一度ラベルを付ける

最初にレベルをロードするときに、すべてのモンスターレイアノードに0(レイアからの距離を表す)のラベルを付けます。すべてのノードにラベルが付けられるまで、接続されたノード1、ノード2に接続されたノードなどに外向きのラベルを付けます。 (注:隠れ家に複数の入り口がある場合でも機能します)

各ノードを表すオブジェクトとそれらの隣人への接続が既にあると仮定しています。擬似コードは次のようになります。

public void fillMap(List<Node> nodes) { // call passing lairNodes
    int i = 0;

    while(nodes.count > 0) {
        // Label with distance from lair
        nodes.labelAll(i++);

        // Find connected unlabelled nodes
        nodes = nodes
            .flatMap(n -> n.neighbours)
            .filter(!n.isDistanceAssigned());
    }
}

Flood-fill out from lair

目が最小距離ラベルで隣に移動する

すべてのノードにラベルが付けられると、目のルーティングは簡単になります...最小距離ラベルを持つ隣接ノードを選択するだけです(注:複数のノードの距離が等しい場合、どちらを選択してもかまいません)。擬似コード:

public Node moveEyes(final Node current) {
    return current.neighbours.min((n1, n2) -> n1.distance - n2.distance);
}

完全にラベル付けされた例

Complete map

1
AjahnCharles

Pacmanパスが非ランダムであることを知っている(つまり、特定のレベル0-255、真っ黒、点滅、小指、およびクライドは、そのレベルに対してまったく同じパスで機能します)。

これを取って、pac manが幽霊を食べたとき、眼球オブジェクトがペンディングする「リターンパス」として迷路全体を囲むいくつかのマスターパスがあると思います。

1
Incognito

Pacmanのゴーストは、目標が達成されるまで最初にXまたはYで一致しようとするという点で、予測可能なパターンに従います。私はいつも、これは目が戻ってきたときもまったく同じだと思っていました。

1
plinth

私のPacManゲームでは、やや「 shortest multiple path home "アルゴリズム(これは一連のルール内で)で提供する迷路で機能し、トンネル全体でも機能します。

レベルがロードされると、すべてのpath home data in every crossroadは空(デフォルト)で、ゴーストが迷宮を探索し始めると、crossroad path home informationは、「新しい」交差点に到達するたびに、または既知の交差点で別のパスから再びつまずくたびに更新され続けます。

0
iNyuu