Bomberman için Minimax


11

Bomberman oyununun klonunu geliştiriyorum ve farklı AI türlerini deniyorum. İlk önce A * ile durum uzayında arama yaptım ve şimdi Minimax algoritması ile farklı bir yaklaşım denemek istiyorum. Benim sorunum, bulduğum her minimax makalesinin oyuncuların alternatif olduğunu varsayması. Ancak Bomberman'da her oyuncu aynı anda bazı eylemlerde bulunur. Bir oyun kenesi için tüm olası durumları üretebileceğimi düşünüyorum, ancak dört oyuncu ve 5 temel eylem (4 hamle ve bomba yeri) ile oyun ağacının ilk seviyesinde 5 ^ 4 eyalet veriyor. Bu değer bir sonraki her seviyede katlanarak artacaktır. Bir şey mi kaçırıyorum? Uygulamanın herhangi bir yolu var mı yoksa tamamen farklı bir algoritma mı kullanmalıyım? Herhangi bir öneriniz için teşekkürler


1
Bu biraz konu dışı olsa da, AI ile yapmaktan hoşlandığım bir şey, AI için hedefleri veya kişilikleri kullanmaktır. İstifleme güç artışları, agresif olmayan, intikam, acele vb. avladığınız bir oyuncuya veya yok etmek istediğiniz bir bloğa oldukça yakındır).
Benjamin Danger Johnson

2
Evet, birkaç şeyi kaçırıyorsunuz, ama onları işaret ettiğiniz için bana teşekkür etmeyeceksiniz çünkü daha da kötüleşiyorlar. 5 temel eylem yoktur. Bazı karelerde 5 "hareket" bulunur (4 yön ve sabit dur); diğerlerinde 3 (iki yönde engellendikleri için) vardır; Ortalama olarak 4'tür. Ama koşarken bir bomba bırakabilirsiniz , bu yüzden ortalama dallanma faktörü 8'dir.
Peter Taylor

Monte carlo ağaç aramasını kullanarak sorunuzun cevabını verdim.
SDwarfs

Minimax, Bomberman kadar çok seçeneğe sahip bir durumda yararlı değildir. Bir hamlenin mantıklı olup olmadığını görmek için yeterince ileri gitmeden önce arama yeteneğinizi tüketeceksiniz.
Loren Pechtel

Yanıtlar:


8

Bombacı adam gibi Gerçek Zamanlı Strateji oyunları yapay zeka ile zor zamanlar geçiriyor. Akıllı olmasını istiyorsunuz ama aynı zamanda mükemmel olamaz.

AI mükemmelse, oyuncularınız hayal kırıklığına uğrayacaktır. Ya hep kaybederler ya da saniyede 0,3 kare alırsınız.

Yeterince akıllı değilse, oyuncularınız sıkılır.

Benim önerim, biri AI'nın nereye gittiğini belirleyen diğeri ne zaman bomba atmak için en iyi olduğunu belirleyen iki AI işlevine sahip olmaktır. Hareketin tahmini gibi şeyleri, bir düşmanın mevcut konuma bomba düşmesi durumunda tehlikeli olacak bir noktaya doğru ilerleyip ilerlemediğini belirlemek için kullanabilirsiniz.

Zorluğa bağlı olarak, zorluğu iyileştirmek veya azaltmak için bu işlevleri değiştirebilirsiniz.


2
Zaman, hayal kırıklığı ve sıkıntı sıkıntı değil. Bomberman'da farklı AI yaklaşımları hakkında lisans tezi yazıyorum ve bunları karşılaştırıyorum. Yani mükemmel ise daha iyi. Şu anda bu minimax ile sıkışıp
kaldım

1
Minimax algoritmasında karşılaşacağınız sorun işlem süresidir. Tüm düşman hareketlerini takip etmeniz ve oyun tarzını ve karşı oyun tarzınızı belirlemeniz gerekir. Görünüşe göre zaten bunun farkındasınız, ancak bu oyunu yavaşlatmadan gerçek zamanlı bir oyun için oldukça zor bir görev olabilir. Bir oyun ağacı oluşturmak yerine, eylemlerinizi gerçek zamanlı olarak belirlemeniz gerekecek, belki daha fazla oynadıkça daha iyi hale gelen bir makine öğrenme algoritması oluşturmalısınız?
UnderscoreZero

4

Fark ettiğiniz gibi, Bomberman sıra tabanlı bir oyun olarak simüle edilemeyecek kadar karmaşık. Olası kendi kararlarını ve diğer tüm oyuncuların olası tüm kararlarını tahmin etmek işe yaramaz.

Bunun yerine daha stratejik bir yaklaşım kullanmayı tercih etmelisiniz.

Kendinize şunu sormalısınız: Bomberman oynarken bir insan oyuncu nasıl karar verir? Genellikle, bir oyuncu dört temel önceliği takip etmelidir:

  1. bombaların patlama alanlarından kaçının
  2. bombalar yerleştir, böylece diğerleri patlama alanlarından kaçınamaz
  3. powerups toplamak
  4. kayaları patlatmak için bomba yerleştir

Birinci öncelik, bir "tehlike haritası" oluşturularak yerine getirilebilir. Bir bomba yerleştirildiğinde, kapladığı tüm karolar "tehlikeli" olarak işaretlenmelidir. Bomba ne kadar erken patlarsa (zincir reaksiyonlarını aklınızda bulundurun!), Tehlike seviyesi o kadar yüksek olur. AI, yüksek bir tehlikeye sahip bir alanda olduğunu fark ettiğinde, uzaklaşmalıdır. Bir yol çizdiğinde (herhangi bir nedenden ötürü) yüksek tehlike seviyesine sahip alanlardan kaçınılmalıdır (yapay olarak onlara daha yüksek bir yol maliyeti ekleyerek uygulanabilir).

Tehlike haritası hesaplaması, AI'yı aptalca kararlardan korumak için daha da geliştirilebilir (başka bir oyuncu yakınındayken kaçması zor alanlara girmek gibi).

Bu zaten makul bir savunma yapay zekası yaratmalıdır. Peki ya saldırı?

Yapay Zeka şu anda makul derecede güvenli olduğunu fark ettiğinde, saldırgan manevralar planlamalıdır: Bombaları yerleştirerek diğer oyuncuların etrafındaki tehlike haritasını nasıl artırabileceğini düşünmelidir. Bomba yerleştirmek için bir yer seçerken, yakın yerlere gitmesi gerekir, böylece oraya kadar hareket etmek zorunda kalmaz. Ayrıca, ortaya çıkan tehlike haritası makul bir kaçış rotasına izin vermediğinde bomba yerlerini de göz ardı etmelidir.


Bunu oynamakla ilgili sınırlı deneyimim, genellikle yetkin bir rakibi öldürmek için birden fazla bomba yerleştirmeniz gerektiğidir - bir stratejinin bunu dikkate alması gerekir. Yaklaşık stratejinizle AI'lara karşı oynadım, köşeye sıkışmadıkça sizi öldürmede oldukça etkisizler.
Loren Pechtel

4

Bir oyun kenesi için tüm olası durumları üretebileceğimi düşünüyorum, ancak dört oyuncu ve 5 temel eylem (4 hamle ve bomba yeri) ile oyun ağacının ilk seviyesinde 5 ^ 4 eyalet veriyor.

Doğru! Her oyun kene için 5 ^ 4 (hatta 6 ^ 4, tüm yönlerde yürümek, durdurmak ve "bomba koymak?") Eylemleri aramak gerekir. AMA, bir oyuncu zaten hareket etmeye karar verdiğinde, hareketin gerçekleşmesi biraz zaman alır (örn. 10 oyun kenesi). Bu dönemde olasılıkların sayısı azalır.

Bu değer bir sonraki her seviyede katlanarak artacaktır. Bir şey mi kaçırıyorum? Uygulamanın herhangi bir yolu var mı yoksa tamamen farklı bir algoritma mı kullanmalıyım?

Bir karma tabloyu yalnızca aynı oyun durumu "alt ağacı" nı bir kez hesaplamak için kullanabilirsiniz. Oyuncu A'nın yukarı ve aşağı yürüdüğünü düşünün, diğer tüm oyuncular "beklerken", aynı oyun durumundasınız. "Sol-sağ" veya "sağ-sol" ile aynıdır. "Yukarı-sonra-sola" ve "sola-yukarı-yukarı" hareket ettirmek de aynı duruma neden olur. Karma Tablosu kullanarak, daha önce değerlendirilmiş bir oyun durumu için hesaplanan puanı "yeniden kullanabilirsiniz". Bu büyüme hızını oldukça azaltır. Matematiksel olarak, üstel büyüme fonksiyonunuzun tabanını azaltır. Karmaşıklığı ne kadar azalttığı hakkında bir fikir edinmek için, eğer oyuncu sadece yukarı / aşağı / sola / sağa / durdurma hareket edebiliyorsa, haritadaki erişilebilir konumlara (= farklı oyun durumları) kıyasla sadece bir oyuncu için mümkün olan hamlelere bakalım. .

derinlik 1: 5 hareket, 5 farklı durum, bu özyineleme için 5 ek durum

derinlik 2: 25 hareket, 13 farklı durum, bu özyineleme için 8 ek durum

derinlik 3: 6125 hareket, 25 farklı durum, bu özyineleme için 12 ek durum

Bunu görselleştirmek için kendinize cevap verin: haritadaki hangi alanlara bir hamle, iki hamle, üç hamle ile ulaşılabilir. Cevap: Başlangıç ​​konumundan maksimum mesafe = 1, 2 veya 3 olan tüm alanlar.

Bir HashTable kullanırken, her erişilebilir oyun durumunu (örnek 3'te derinlik 3'te) yalnızca bir kez değerlendirmeniz gerekir. Bir HashTable olmadan bunları birden çok kez değerlendirmeniz gerekir, bu da derinlik seviyesi 3'te 25 yerine 6125 değerlendirme anlamına gelir. En iyisi: Bir HashTable girişini hesapladıktan sonra, sonraki zaman adımlarında tekrar kullanabilirsiniz ...

Ayrıca, daha derinlemesine araştırmaya değmeyen artımlı derinleştirme ve alfa-beta budama "kes" alt ağaçlarını da kullanabilirsiniz. Satranç için bu, aranan düğümlerin sayısını yaklaşık% 1'e düşürür. Alfa-beta budamaya kısa bir giriş burada bir video olarak bulunabilir: http://www.teachingtree.co/cs/watch?concept_name=Alpha-beta+Pruning

İleri çalışmalar için iyi bir başlangıç http://chessprogramming.wikispaces.com/Search . Sayfa satrançla ilgilidir, ancak arama ve optimizasyon algoritmaları tamamen aynıdır.

Oyuna daha uygun olacak bir başka (ama karmaşık) AI algoritması "Geçici Fark Öğrenme" dir.

Saygılarımızla

Stefan

Not: Olası oyun durumlarının sayısını azaltırsanız (örneğin haritanın çok küçük boyutu, oyuncu başına sadece bir bomba, başka bir şey yok), tüm oyun durumları için bir değerlendirmeyi önceden hesaplama şansı vardır.

--Düzenle--

Bir nöron ağını eğitmek için minimum hesaplamaları çevrimdışı hesaplanmış sonuçlarını da kullanabilirsiniz. Veya bunları elle uygulanan stratejileri değerlendirmek / karşılaştırmak için kullanabilirsiniz. Örneğin, önerilen “kişilikler” in bazılarını ve hangi durumlarda hangi stratejinin iyi olduğunu tespit eden bazı buluşsal yöntemler uygulayabilirsiniz. Bu nedenle durumları "sınıflandırmalısınız" (örneğin oyun durumları). Bu aynı zamanda bir nöronal ağ tarafından da ele alınabilir: El kodlu stratejilerden hangisinin mevcut durumda en iyi sonucu verdiğini tahmin etmek ve onu yürütmek için bir nöronal ağ eğitin. Bu, gerçek bir oyun için son derece iyi gerçek zamanlı kararlar üretmelidir. Çevrimdışı hesaplamaların ne kadar sürdüğü önemli değil (oyundan önce), aksi takdirde elde edilebilen düşük derinlik sınırındaki bir aramadan çok daha iyi.

- düzenle # 2 -

En iyi hamlelerinizi yalnızca her 1 saniyede bir yeniden hesaplarsanız, daha yüksek seviye planlaması yapmaya da çalışabilirsiniz. Bununla ne demek istiyorum? 1 saniyede kaç hamle yapabileceğinizi biliyorsunuz. Böylece ulaşılabilir konumların bir listesini yapabilirsiniz (örneğin, bu 1 saniyede 3 hamle olursa, 25 ulaşılabilir pozisyonunuz olacaktır). Sonra şöyle planlayabilirsiniz: "X konumuna gidin ve bir bomba yerleştirin". Bazılarının önerdiği gibi, yönlendirme algoritması için kullanılan bir "tehlike" haritası oluşturabilirsiniz (x konumuna nasıl gidilir? Hangi yol tercih edilmelidir [çoğu durumda bazı değişiklikler olabilir]). Bu, büyük bir HashTable'a kıyasla daha az bellek tüketir, ancak daha az optimum sonuç verir. Ancak daha az bellek kullandığı için önbellekleme efektleri nedeniyle daha hızlı olabilir (L1 / L2 bellek önbelleklerinizin daha iyi kullanılması).

EK OLARAK: Kaybedilen varyasyonları sıralamak için her biri bir oyuncu için hamle içeren ön aramalar yapabilirsiniz. Bu nedenle diğer tüm oyuncuları oyundan çıkarın ... Her oyuncunun kaybetmeden hangi kombinasyonları seçebileceğini kaydedin. Yalnızca kaybedilen hamleler varsa, oyuncunun en uzun süre hayatta kaldığı hareket kombinasyonlarını arayın. Bu tür ağaç yapılarını saklamak / işlemek için, aşağıdaki gibi dizin işaretleyicileri olan bir dizi kullanmalısınız:

class Gamestate {
  int value;
  int bestmove;
  int moves[5];
};

#define MAX 1000000
Gamestate[MAX] tree;

int rootindex = 0;
int nextfree = 1;

Her durumun bir değerlendirme "değeri" vardır ve dizi ağacını "ağaç" içinde hareketlerle depolayarak (0 = dur, 1 = yukarı, 2 = sağ, 3 = aşağı, 4 = sol) hareket ederken bir sonraki Gamestates'e bağlanır [0 ] hareket etmek [4]. Ağacınızı özyinelemeli olarak oluşturmak için bu şöyle görünebilir:

const int dx[5] = { 0,  0, 1, 0, -1 };
const int dy[5] = { 0, -1, 0, 1,  0 };

int search(int x, int y, int current_state, int depth_left) {
  // TODO: simulate bombs here...
  if (died) return RESULT_DEAD;

  if (depth_left == 0) {
    return estimate_result();
  }

  int bestresult = RESULT_DEAD;

  for(int m=0; m<5; ++m) {
    int nx = x + dx[m];
    int ny = y + dy[m];
    if (m == 0 || is_map_free(nx,ny)) {
      int newstateindex = nextfree;
      tree[current_state].move[m] = newstateindex ;
      ++nextfree;

      if (newstateindex >= MAX) { 
        // ERROR-MESSAGE!!!
      }

      do_move(m, &undodata);
      int result = search(nx, ny, newstateindex, depth_left-1);
      undo_move(undodata);

      if (result == RESULT_DEAD) {
        tree[current_state].move[m] = -1; // cut subtree...
      }

      if (result > bestresult) {
        bestresult = result;
        tree[current_state].bestmove = m;
      }
    }
  }

  return bestresult;
}

Bu tür ağaç yapısı çok daha hızlıdır, çünkü dinamik olarak bellek ayırmak gerçekten çok yavaştır! Ancak, arama ağacını saklamak da oldukça yavaş ... Bu daha çok ilham kaynağı.


0

Herkesin sırayla döndüğünü hayal etmek yardımcı olur mu?

Teknik olarak, altta yatan sistemde aslında yaparlar, ancak işler serpiştirilmiş ve örtüştüğü için, aynı anda çalışıyor gibi görünüyorlar .

Ayrıca animasyonun her karesinden sonra AI'yi çalıştırmanız gerekmediğini unutmayın . Birçok başarılı gündelik oyun AI algoritmasını sadece saniyede bir kez çalıştırır, AI kontrollü karakterlere nereye gitmeleri gerektiği veya ne yapmaları gerektiği hakkında bilgi verir, bu bilgi AI karakterlerini kontrol etmek için kullanılır diğer çerçevelerde.


AI'yi animasyonun her karesini değil, her saniyesini hesaplıyorum. Her saniye ortamım tüm oyuncuların eylemlerini toplar ve onlara yeni güncellenmiş durum gönderir.
Billda
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.