私はパックマンで幽霊のAIについて多くの言及を見つけましたが、パックマンによって幽霊が食べられた後、どのように目が中央の幽霊の穴に戻るのかについては誰も言及しませんでした。
私の実装では、シンプルですがひどいソリューションを実装しました。私は、どの方向をとるべきかを隅々までハードコーディングしました。
より良い/または最良の解決策はありますか?多分異なるレベルのデザインで動作する一般的なものですか?
私はパックマンで幽霊のAIについて多くの言及を見つけましたが、パックマンによって幽霊が食べられた後、どのように目が中央の幽霊の穴に戻るのかについては誰も言及しませんでした。
私の実装では、シンプルですがひどいソリューションを実装しました。私は、どの方向をとるべきかを隅々までハードコーディングしました。
より良い/または最良の解決策はありますか?多分異なるレベルのデザインで動作する一般的なものですか?
回答:
実際、あなたのアプローチは非常に優れたソリューションであり、あらゆる種類のパスファインディングと比較して実行時間がほとんどゼロです。
任意のマップに一般化する必要がある場合は、任意のパスファインディングアルゴリズムを使用できます。たとえば、幅優先検索は実装が簡単です。ゲームを実行する前に、これを使用して、各コーナーでエンコードする方向を計算します。
EDIT(2010年8月11日)::私はちょうどパックマンシステム上で非常に詳細ページを参照してパックマンドシエを、私はここに受け入れ答えを持っているので、私はそれを更新する必要があります感じました。記事はモンスターハウスに戻る行為を明示的にはカバーしていないようですが、パックマンでの直接パスファインディングは以下の場合であると述べています:
私はこのレベルで一般的なレベルの問題を解決しました。レベルが始まる前に、モンスターホールから何らかの「フラッドフィル」を行います。壁ではない迷路のすべてのタイルには、穴からどれだけ離れているかを示す数字が付けられます。したがって、目が68の距離のタイルにあるとき、それらは隣接するタイルのどれが67の距離を持っているかを見ます。それはそれから行く方法です。
従来のパスファインディングアルゴリズムの代わりに、(適切に名前が付けられた!)パックマンの香りのアンチオブジェクトパターンを確認できます。
起動時にモンスターの穴の香りを迷路の周りに拡散させ、目を家に追従させることができます。
匂いが設定されると、実行時のコストは非常に低くなります。
編集:残念ながら、ウィキペディアの記事は削除されたので、WayBack Machineが救いに ...
DijsktraのアルゴリズムやA *アルゴリズムなどのパスファインディングアルゴリズムを確認する必要があります。これはあなたの問題です:グラフ/パスの問題。
機能する単純なソリューションは、保守可能で信頼性が高く、十分に機能するため、優れたソリューションです。あなたはすでに良い解決策を見つけたように思えます...
パス検索ソリューションは、現在のソリューションよりも複雑になる可能性が高く、デバッグが必要になる可能性が高くなります。それもおそらく遅くなります。
IMO、壊れていない場合は修正しないでください。
編集
IMO、迷路が修正された場合、現在のソリューションは優れた/エレガントなコードです。「良い」または「優雅」を「賢い」と同一視する間違えないでください。単純なコードも「良い」「優雅」にすることができます。
迷路レベルを構成できる場合は、最初に迷路を構成するときにパスファインディングを実行する必要があります。最も簡単なのは、迷路デザイナーに手作業で行わせることです。あなたがバジリオン迷路を持っている場合、またはユーザーがそれらを設計できる場合にのみ、私はこれを自動化することを気にします。
(さておき:ルートが手動で設定されている場合、迷路デザイナーは次善のルートを使用してレベルをより興味深いものにすることができます...)
オリジナルのパックマンザゴーストは、「におい」によって黄色の錠剤を食べる人を見つけ、地図に痕跡を残しました。幽霊は、匂いが見つかるまでランダムに歩き回り、その後、匂いの経路をたどって、直接にお連れしました。プレーヤー。パックマンが動くたびに、「匂いの値」は1ずつ減っていきます。
プロセス全体を逆にする簡単な方法は、「ゴーストのにおいのピラミッド」を作成することです。これは、マップの中心に最高点があり、ゴーストがこのにおいの方向に移動するだけです。
pacmanを追跡するために必要なロジックがすでにあるとしたら、それを再利用してみませんか?ターゲットを変更するだけです。まったく同じロジックを使用してまったく新しいルーチンを作成しようとするよりもはるかに少ない作業になるようです。
中心までの距離の値を持つ各正方形はどうですか?このようにして、与えられた正方形ごとに、すべての可能な方向で隣接する正方形の値を取得できます。最も低い値の正方形を選択して、その正方形に移動します。
値は、使用可能なアルゴリズムを使用して事前に計算されます。
これは、それが実際にどのように機能するかについて私が見つけることができた最高の情報源でした。
http://gameai.com/wiki/index.php?title=Pac-Man#Respawn 幽霊が殺されると、体現されていない目が元の場所に戻ります。これは、ゴーストのターゲットタイルをその場所に設定することで簡単に実現できます。ナビゲーションは同じルールを使用します。
それは実際に理にかなっています。たぶん世界で最も効率的ではないかもしれませんが、ターゲットを変更しているだけで、別の状態やそれらに沿った何かについて心配する必要がないとても良い方法です。
補足:パックマンのプログラマーが、非常に限られたメモリの非常に小さなスペースでメッセージシステム全体を作成したのがどれほど素晴らしいかはわかりませんでした。
私はあなたの解決策は問題に適していると思います、それよりも簡単です、ゴーストの目が壁を通り抜けることができる新しいバージョンをより「現実的な」ものにすることです=)
以下は、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
これは幅優先の検索であるため、隣接する新しい正方形sに遭遇するたびに、pを通るのが最適な経路であるという考え方です。O(N)だと思います。
ゲームの実装方法についてはよくわかりませんが、次のことができます。
いくつかの擬似コード:
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
各コーナーでランダムな方向を選択するだけのdtb23の提案ですが、最終的にはモンスターホールの音がひどく非効率的であることがわかります。
ただし、非効率な原点復帰アルゴリズムを利用して、ゲームの難易度のバリエーションを増やすことで、ゲームをより楽しくすることができます。これを行うには、ウェイポイントや塗りつぶしなどの上記のアプローチのいずれかを適用しますが、非決定的に行います。したがって、隅々で、乱数を生成して、最適な方法をとるか、ランダムな方向をとるかを決定できます。
プレイヤーがレベルを上げるにつれて、ランダムな方向がとられる可能性を減らします。これにより、レベルスピード、ゴーストスピード、錠剤を食べるポーズなどに加えて、全体的な難易度レベルに別のレバーが追加されます。幽霊が無害な目である間、リラックスする時間は長くなりますが、時間は進むにつれて短くなります。
ゴーストは、穴からパックマンまでの経路を保存することを提案します。したがって、幽霊が死ぬとすぐに、彼はこの格納されたパスを逆方向にたどることができます。
私のアプローチは(Pacman時代の観点から)少しメモリを集中的に使用しますが、計算は1回だけで済み、どのレベルの設計(ジャンプを含む)でも機能します。
最初にレベルをロードするとき、すべてのモンスターの隠れ家ノードに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());
}
}
すべてのノードにラベルが付けられると、目をルーティングするのは簡単です...最小の距離ラベルを持つ隣接ノードを選択するだけです(注:複数のノードの距離が等しい場合、どちらを選択してもかまいません)。疑似コード:
public Node moveEyes(final Node current) {
return current.neighbours.min((n1, n2) -> n1.distance - n2.distance);
}
私のPacManゲームでは、shortest multiple path home
(ルールセット内で)提供する迷路で機能するアルゴリズムを作成しました。また、トンネル全体で機能します。
レベルが読み込まれると、すべてpath home data in every crossroad
が空になり(デフォルト)、ゴーストは迷路の探索を開始するとcrossroad path home information
、「新しい」交差点に出会うたびに、または既知の交差点に再びつまずくたびに更新され続けます。
オリジナルのパックマンは、経路探索や派手なAIを使用していませんでした。ゲーマーに、実際よりも奥行きがあると信じさせただけですが、実際はランダムでした。ゲームの人工知能/ Ian Millingtonに述べられているように、John Funge。
それが本当かどうかはわかりませんが、私には多くの意味があります。正直なところ、私は人々が話しているこれらの行動を見ていません。彼らが言うように、元の赤/ブリンキーは常にプレーヤーをフォローしていません。誰も意図的にプレーヤーを常にフォローしているようには見えません。彼らがあなたをフォローするチャンスは私にはランダムに見えます。特に、小さなスペースで4人の敵と非常に限られた回転オプションがあり、追跡される可能性が非常に高い場合は、ランダムに動作を見るのは非常に魅力的です。少なくとも最初の実装では、ゲームは非常にシンプルでした。本をチェックしてください、それは最初の章の一つです。