Spell casting - Saniyede hasarı nasıl optimize edersiniz


23

Bir kaç büyüyü bilen bir büyücümüz olduğunu hayal edin. Her büyünün 3 özelliği vardır: Hasar, soğuma süresi ve yayın süresi. Oldukça standart RPG olayı.

Dolma süresi: Tekrar o büyüyü yapmadan önce geçen süre (t). Bir büyü, dökülmeye başladığı anda "bekleme süresini" sürdürür.

Cast zamanı: büyüyü kullanması için geçen süre (t). Sihirbaz bir şeyi yayınlarken, başka bir büyü yapılamaz ve iptal edilemez.

Soru şudur: Farklı büyü setleri verilen hasarı nasıl en üst seviyeye çıkarırsınız?

Oyuncular başına en yüksek hasarı hesaplamak kolaydır. Ancak, daha yüksek bir kullanılabilir olduğunda düşük hasarlı bir büyü yapması için "sıkışıp kalması" için beklemenin daha iyi olduğu durumlarda ne olacak?

Örneğin,

  1. Ateş topu: 3000 hasar, 3 saniye oyuncu, 6 saniye soğuma.

  2. Frostbolt: 20 hasar, 4 saniye döküm süresi, 4 saniye soğutma

  3. Ateş püskürmesi: 3 hasar, 3 saniye döküm süresi, 3 saniye soğuma.

Bu durumda, donma çubuğu yerine daha düşük DPCT büyüsüne (ateş patlaması) gitmeyi seçtiyseniz saniyede hasarınız daha yüksek. Bu yüzden bir büyü seçmenin sonuçlarını göz önünde bulundurmalıyız. alt metin

Aşağıdaki örnekte "aşırı döküm" ve "bekliyor" durumları gösterilmektedir. alt metin


Neden bu durumda 1-3-1 yapmalıyım? Neden 1-2-1 değil? Neden 1-3-3-1, 1-3-1-X'ten daha verimli olan, eğer 1-3-1 tek başına hedefi öldürmezse?

@Joe Wreschnig: Bunu işaret ettiğiniz için teşekkür ederiz. Benim örneğimde bir hataydı. Şimdi sadece 2 vaka için basitleştirildi.
aaronfarr

1
Açgözlü, mümkün olduğu kadar mümkün olan en yüksek dps büyüsünü seçerken. Diğer mantığı gözardı etmek, yani. bekleyen.
aaronfarr

1
Sadece suyu çamurlamak için. ∞ hasarı yapan, ancak atması 50 saniye süren bir büyüyü düşünün. Dps / dpct ∞, ancak hedef 50 saniyeden daha kısa sürede başka yollarla öldürülebiliyorsa asla seçilmemelidir.
deft_code

1
En dupe yönlendirmelidir math.stackexchange.com/questions/10414/...
Sparr

Yanıtlar:


23

Tüm AI arama!

AI'nın bağırsaklarına girdiğinizde, bunun ne kadarı gerçekten arama yaptığı şaşırtıcı .

  • durum : mevcut tüm büyülerin kalan süresi.
  • uygunluk : yapılan toplam hasar
  • maliyet : toplam süre
  • dalları : bilinen herhangi bir büyü. Eğer büyü hala cooldowndaysa, bu değeri yayın süresine ekleyin.
  • Amaç : Hedefin toplam sağlığı. Hedef sınırlı miktarda hasar olmalıdır, bu nedenle bilinmeyen bir hedef olması durumunda mümkün olan en büyük sağlığı seçin.
    Alternatif olarak, hedef 50 saniyeden daha az harcayabilir ve arama 50 saniyede yapılabilecek maksimum hasarı bulabilir.

Bu parametreleri Tekdüze Maliyet Araştırmasına (UCS) ve presto garantili optimal savaş planına takın . Eğer bir sezgisel çözüm bulabilirseniz, A * veya IDA * ile arama yaparsanız aynı cevabı çok daha hızlı alırsınız.

UCS'yi kullanmanın bazı avantajları, sadece 3 değişkenle sağladığınızdan çok daha karmaşık durumlar için en uygun döküm sırasını bulabilmesidir. Kolayca ekleyebilecek diğer bazı yönler:

  • zamanla hasar
  • diğer büyülerin soğumasını azaltmak için büyüyü yenile
  • acele büyü, diğer büyülerin daha hızlı döküm yapmasına neden olur.
  • diğer büyülerin daha fazla zarar görmesine neden olan hasar arttırıcı.

UCS her şeye gücü yetmez. Koruma büyülerinin faydalarını modelleyemez. Bunun için alfa-beta aramasına veya minimax'a yükseltmeniz gerekir.
Ayrıca etki alanıyla baş etmiyor ve grup mücadeleleri çok iyi. UCS bu gibi durumlarda makul çözümler sunmak için ince ayar yapılabilir, optimum çözümü bulma garantisi yoktur.


2

Bu özel bir kombinasyonel optimizasyon problemidir. Büyü sayısı arttıkça, optimum kombinasyon kombinasyon / model bulma zorluğu da artar. Sırt çantası probleminde kullanılana benzer buluşsal buluş bu problemin çözümünde değerli olacaktır.


1

'Birim zaman başına hasar' (DPCT) başına düşünmeniz gerekir - örneğin, 3 saniyelik bir atış ve 3000 hasar veren bir ateş topu 1000 DPCT yapar.

Dökümden önce bekleme süresi için 3 saniye beklemeniz gerekirse, bu 500 DPCT'ye düşecektir (3000 hasar, toplam 6 saniyeye bölünmüş, bekleme dahil)

Bu nedenle, bekleme süresinin kalanını da içeren her bir büyünün döküm başına hasar süresini belirlemeniz gerekir. En yüksek DPCT olanı seçin, Gerekirse bekleyin, sonra yayınlayın. Patron ölene kadar tekrarla :)


Sorun şu ki, DPCT çok yanıltıcı olabilir. Örnek olarak, Fireball: 3000 hasarı, 3 saniyelik döküm, 6 saniyelik bekleme süresi, DPCT: 1000 Yazım No: 2: 20 hasar, 4 saniyelik döküm, 4 saniye bekleme süresi, DPCT: 5 Yazım No: 3: 3 karışımına 2 büyü daha ekledik. hasar, 3 saniye döküm, 3 saniye bekleme süresi, DPCT: 1 (unutma, bekleme süresi, büyünün yayınlandığı an başlar) Yazım No. 3'ün DPCT'si daha düşük olmasına rağmen, DPS'nin daha yüksek olmasına neden olur (1-3-1-3 .. .) Yazım # 2'den (1-2-1-2 ...).
aaronfarr

1

Örneğinizi kullanarak, muhtemelen iki büyünün etkinlikte daha yakın olmasını istersiniz, ancak muhtemelen size farklı bir avantaj sağlar. Kısa bir döküm süresine sahip olmak (veya bu konuda döküm süresine sahip olmamak) çok yararlı olacaktır, bu nedenle daha az hasar görüp tekrar kullanması daha uzun sürse bile kullanmaya değer olabilir.

Denklemde her zaman başka bir element dayatabilirsiniz. Mana / Magic Points, oyuncunun bu puanların kullanımının faydaya değer olup olmadığını belirlemesini sağlayarak bu amaca hizmet edebilir.

Genel olarak, bluescrn'un dediği gibi, DPCT (veya en iyi karışımı arayan oyuncular tarafından çok iyi ayarlanmış ve tartışılan birçok oyunda çağrıldığı gibi DPS), özellikle herhangi bir türünüz varsa, dengelemek isteyeceğiniz ana unsurdur. Farklı oyuncuların farklı becerilerle ilerlemelerine izin veren teknoloji / beceri ağaçları, ancak oyunda verilen konumlarında benzer miktarlarda hasar verme yeteneği.


0

Amaçlarıma uygun olan bu algoritmayı buldum

İnsanlar bazı harika noktalar ortaya koydu. Nihai hedef parametrelerinin verilmesi, normal arama algoritmalarının kendi işlerini yapmasını sağlar. yani. t saniyede en uygun hasarı verin, en uygun zamanda x hasar verin.

Algoritmam basitçe en yüksek DPS'ye sahip büyü dizisini döndürür. Travers yaptığınız setin boyutunu azalttığı için hızlı bir algoritmadır, diğer arama ağacı teknikleri hakkında bilgi gerektirmez.

İlk adım, büyü için atım başına en yüksek hasarı veren büyüyü tespit etmektir. Bu büyü "temel" büyü olur çünkü saniye başına en yüksek hasarı garanti eder. Anlamı, eğer aşağıdaki 2 koşul yerine getirilirse, bu büyüyü yapmalısınız: 1) Temel yazım mevcuttur (bekleme süresi değil). 2) Şu anda bir büyü yapmıyorsunuz.

Dolayısıyla, taban çizgisi büyüsü soğuma sırasında diğer büyüler için doldurma meselesi haline gelir. (Döküm zamanı) ve (bekleme süresi - döküm zamanı) arasında. Bununla birlikte, bazı örtüşmeler oluşabilir (yukarıdaki kural 2 yanlıştır).

Daha sonra, 2 kuralı ihlal etmeyen tüm sihir dizilerini bulmak için tüm taban çizgisi dışındaki büyülerden tekrarlanan bir mesele haline gelir.

Üst üste binen büyüler için, temel hecelemenin yapabileceği olası hasarı (en fazla hasara kadar) cezalandırmanız gerekir.

Örneğin, 2 büyü

1: 300 hasar, 3s döküm zamanı, 10s bekleme süresi

2: 290 hasar, 3s döküm zamanı, 3s bekleme süresi

En büyük hasar 1 - 2 - 2 - 2 dizisinden gelir. Bu da 2 saniyelik bir potansiyel # 1 dökümüne üst üste binmesine neden olur. Bununla birlikte, üçüncü büyüyü yapmazsanız (yani 1 - 2 - 2), 1 saniye ile 880 hasar vereceğiniz için bu hala faydalıdır. Ekstra # 2 büyüyü yaparsanız, # 1 olan 1170 - 2 saniyeyi 200 yaparsınız. Yani 970 hasarı göreceli hasarınızdır.


-2

Basit bir "güvenlik seviyesi" tarzı anahtar kılıfı yapabilirsiniz.

Bu başımın tam üstünde, bu yüzden yorgun durumumun düşünce seviyesinin ötesindeki mantık hatalarına dikkat edin, ama umarım bu sizi başlatabilir.

Zamanınızın blok tamsayılarla yapıldığını varsayalım -

// after casting spell
int remainingTime = (coolDown - castTime);
switch(spellJustCast)
{
  // assuming the cast method will have some input validation for whether the spell
  // is off cooldown or not, pass the time as a parameter
  case 3 : castSpell1(remainingTime);
           castSpell2(remainingTime);
           break;
  case 1 : castSpell2(remainingTime);
           castSpell3(remainingTime);
           break;
  case 2 : castSpell1(remainingTime);
           castSpell3(remainingTime);
           break;
  default: System.out.println("Debug!");
           break;
}

Metod çağrılarından bazıları büyü süreniz nedeniyle gereksizdir, ancak bu şekilde güncellemeler için her zaman yer vardır.

Düzenleme: Yeni yazımın yayınlanmasından sonra kalan zamanı sıfırlamanız gerekeceğini, muhtemelen sınıf niteliği / alanı yapıp castSpell yöntemleri içindeki bir çağrıdan ayarlamanız gerekebileceğini fark ettim.


Burada ne elde etmeye çalıştığınız hakkında hiçbir fikrim yok, ancak hiçbir modern oyun motorunun castSpell1 ve castSpell2 gibi işlevleri yoktur.

1
@Joe Wreschnig Onları özel oyun sınıflarında kendi yöntemleri olarak kastettim, bu sadece soyut bir örnek değil, ayrıntılı bir örnek.
kymully

1
Doğru, modern motorlarda büyüler böyle olmaz. Alanları bir dosyadan okunan bir nesneyi alan bir castSpell işlevi vardır. Böyle bir anahtar ifadesinin gerçek bir motorda sürdürülmesi imkansız olur ve bir çeşit planlama algoritması gerekir.

@Joe Wreschnig Anladım. Sadece sorunu çözecek bir yol veriyordum. Bu örnek, bir motor veya belirli bir çerçeve için tasarlanmamış, java dilinde yazılmıştır. Ama dediğin gibi uygulanamazsa, cevabım geçersiz.
kymully
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.