Codémon, seni seçtim!


55

Nazik komşunuz Doktor Tree, size Codémon adında üç büyülü yaratık verdi. Yakındaki Colorville kasabasında bir savaş turnuvası var. Sen hiç kimsenin olmadığı gibi, en iyisi misin?

genel bakış

Bu bir savaş turnuvası. Her oyuncu üç canavardan oluşan bir takımı kontrol eder ve amaç diğer takımı nakavt etmek (öldürmektir). Kazanılan ve bağlanan puanlar ile 100 tur vardır. En yüksek puana sahip takım kazanır!

Canavarlar

Bir Codémon karmaşık bir küçük yaratıktır. Seçilebilecek beş tip (öğe), üç istatistik ve her birinde üç hareketli yuva vardır.

Türleri

Her Codémon'a bir tip atanır . Beş tür Normal, Psişik, Ateş, Su ve Çim. Her birinin güçlü ve zayıf yönleri vardır. Hasar, aşağıdaki şemaya dayanmaktadır:

tip grafik

Sayılar hasar çarpanlarıdır. Örneğin, Ateşe Saldıran Su 0.5 değiştiriciye sahiptir (yarı hasar), Ateşe Saldıran Çim iki katına çıkarılır (2).

İstatistikleri

Her canavarın, savaş yeteneklerini belirleyen üç istatistiği vardır. Saldırı verdiği hasarı arttırır. Savunma aldığı hasarı azaltır. Hız, daha düşük Hız olanlara göre hareket etmesine izin verir.

Her canavar, her stat için 50 başlangıç ​​değerine ve maksimum 100 değerine sahiptir. Canavarlarınızı yarattığınızda, 80 ek stat puanı (her biri) atayabileceksiniz . Hiçbir kişisel statün 100'den fazla geçemeyeceğini unutmayın. Yani, 100/80/50, 90/80/60 veya 65/65/100 dağılımınız olabilir, ancak 120/50/60 yasa dışıdır. Yasadışı istatistiklere sahip herhangi bir takım diskalifiye edilir. Sen değil gerekli tüm 80 puan kullanmak, ama muhtemelen en az 50/50/50 ile gitmemeli.

Ayrıca HP'yi bir stat olarak düşünebilirsiniz, ancak her Codémon'un değiştirilemez bir 100 HP'si vardır. HP sıfıra düştüğünde, savaşa devam edemezler. Her savaştan önce HP 100'e kadar doldurulur.

hamle

Her canavar üç savaş hamlesi biliyor. Seçilen üç ayrı olmalıdır, bu nedenle Punch / Punch / Punch yoktur.

Her türden üçü olmak üzere 15 hamle var. Her tür doğrudan bir saldırı, etkisi olan daha zayıf bir saldırı ve tek bir etki hareketi vardır.

id  name        type    power   uses    usable  effect

0   Punch       N       20      -       NFWG
1   Heal        N        0      3       NFWG    Heals 50 HP
2   Slow        N       10      5       NFWG    Enemy speed x0.8
3   Pain        P       20      -       PFWG
4   Sleep       P        0      3       PFWG    No enemy action until wake
5   Weaken      P       10      5       PFWG    Enemy Atk x0.8
6   Fireball    F       20      -       NPFW
7   Burn        F        0      3       NPFW    Enemy -10 HP each turn
8   Sharpen     F       10      5       NPFW    Own Atk x1.25
9   Watergun    W       20      -       NPWG    
10  Confuse     W        0      3       NPWG    Enemy may strike itself (10 power)
11  Shield      W       10      5       NPWG    Own Def x1.25
12  Vine        G       20      -       NPFG
13  Poison      G        0      3       NPFG    Enemy -5xTurns HP each turn
14  Sap         G       10      5       NPFG    Enemy Def x0.8

typehareketin türünü ifade eder. poweronun çarpıcı gücüdür. usesSavaş başına kaç kez kullanılabileceğini gösterir ( -sınırsızdır). usablehangi türler tarafından kullanılabileceğini gösterir (örneğin, Punch, yok olduğu gibi Psişik bir türe verilemez P). effectHareketlerin ne gibi etkileri olduğunu gösterir. Her zaman işe yarayan İyileşme dışında, her bir efektin çalışma şansı% 75'tir.

Bir canavarın istatistiklerini değiştiren efektler için efektler yığınlanabilir . Örneğin, Weaken'i iki kez kullanmak, rakibinizin saldırısını 0.64 etkinliğe düşürebilir. Canavarın istatistiklerini değiştirmeyen efektler (Uyku, Yanma vb.) Yığılmaz .

Uyku , rakibi uyku durumuna geçirir ve her dönüşte% 60 uyanma şansı verir. Uyuyan canavarlar tarafından herhangi bir işlem yapılmayacaktır.

Yanarken aktif olduğunda her turun sonunda rakibe 10 HP hasar verir . Zehir benzer çalışır, ancak her turda artan miktarda alır. İlk dönüşte 5 olur ve daha sonra her dönüşte 5 kazanır. Dördüncü sırayla 20'ye zarar verecek. Bunlar canavarın cinsinden etkilenmeyen veya bonuslara tabi olmayan düz hasarlardır.

Karışıklık , yapılması söylenenleri yapmak yerine bir canavarı kendi başına saldırabilir. Bu saldırı 10'lu güce sahip ve belirli bir zamanda% 30'luk bir şansı var.

Açık olmak gerekirse, etkiler savaşın sonuna kadar sürecek (yukarıda belirtildiği gibi Uyku hariç).

Ayrıca, ilgili tipte bir canavar tarafından kullanılması durumunda, hamleler de% 20 güç kazanıyor. Örneğin, Vine kullanan bir Grass monster, Punch kullanırken değildir.

Gizli İstatistikler

Her canavarın istatistikleri ve türü (ancak hamle değil ) kamu bilgisidir. Rakipleriniz, en iyi aksiyonu seçmek için ne savaştıklarını görebilecekler. Ancak, gizli olan bonuslar da var.

Özellikle, her iki savaştan sonra , ekibinizdeki her canavar için bir "bonus" stat puanı kazanacaksınız. Tüm canavarlara puanlar verilir , ölü veya diri, kazanan veya kaybeden. Bunu, seçtiğiniz üç istatistikten hangisine atayabilirsiniz. Onları tek bir canavara yığamazsınız; Her canavar her seferinde bir tane alır . Bu noktalar 100 limitine karşı bağışıklık kazanır. 100 savaş turu olacağından, bu bonusları kendisine tahsis ederseniz 149'a kadar tek bir stat alabileceğiniz anlamına gelir. Yine, rakip sadece "temel" istatistiklerinizi görecek, bu nedenle turnuvada ne kadar uzağa giderseniz, onların bilgisi o kadar fazla olur.

Savaş

Her seferinde bir takım aktif olan üç takım arasında savaş yapılır. Başlangıçta, rakibin takımı gösterilecek ve ilk "aktif" oyuncunuz olarak hangi canavarın seçileceği sorulacak.

Bundan sonra, dönüşler aşağıdaki adımlarla gerçekleşir:

  • Anahtar: Zorunlu canavar anahtarları (varsa) gerçekleşir
  • Savaş eylemini seç
  • Anahtar: İsteğe bağlı herhangi bir canavar anahtarı (savaş eylemi olarak seçilir) gerçekleşir
  • Uyku Kontrolü: Uykudan uyanma şansı
  • Saldırı 1: Mümkünse, hızlı canavar kendi hareketini kullanır
  • Saldırı 2: Mümkünse, diğer canavar seçtiği hamleyi kullanır
  • Etki hasarı: Canlı canavarlara yanık / zehir hasarı uygulayın

"Speedier" daha hızlı olan canavar anlamına gelir. Her iki hız istatistiği aynıysa, her turda PRNG jetonlu çevirme ile seçilir.

Aktif canavarınızın öldüğü herhangi bir dönüşün sonunda, yeni bir aktif seçmeniz istenecektir. Sen olabilir ayrıca aktif canavarlar geçmeyi tercih sizin hareket olarak (hayatta birden fazla olması koşuluyla) herhangi bir dönüş için. Yine, hamleniz olarak geçerseniz, o dönüşü bir savaş hamlesi yapmazsınız.

Etkin değilken canavarlar "işlenmez". Bu, yanma / zehirlenme hasarı almadıkları, zehir sayaçlarının birikmediği, uykudan uyanmadıkları vb . Anlamına gelir . Bu diğer canavar savaş oyunu değil. Saldırı yükseltilmiş ve yakılmış durumdayken kapatırsanız, geri döndüğünüzde hala orada olacaklar.

Etkili hasar, aktif rakibinizi öldürseniz de etmeseniz de gerçekleşir. Bu şekilde, her iki takımın üyeleri tek seferde ölebilir.

Bir takım kullanılabilir canavarlardan kaçtığında, kaybederler. Her iki takımda aynı sırada koşarsa, bu bir kravat. Savaş 1000 dönüş sürerse, bu bir kravat.

Hasar belirleme formülü:

floor((effAttack / effDefense) * movePower * typeMultiplier * moveBoost)

effAttackve effDefenseolan etkili canavarlar için istatistikleri. Etkili saldırı, Saldırı ve Bonus Saldırı eklenerek elde edilir, daha sonra herhangi bir etkisi değişirse çarpılarak (0.8 veya 1.25). Bu efektlerin birikebileceğini unutmayın.

Hasar sadece tip değiştirici 0 (Normal <--> Psişik) veya hareketin Gücü 0 (İyileş, Yan, vb.) Olduğunda 0 olabilir. Aksi takdirde, minimum 1 olarak uygulanır.

Turnuva

Turnuvalar 100 tur sürer. Her turda takımlar rastgele karıştırılır ve birbirlerine karşı eşleştirilir. Tek sayıda takım varsa, kalanlar bir bye alır (beraberlik puanları). Bir savaşı kazanmak, takımı 2 puan kazanır , bağlar 1 değerindedir ve hiçbir şey kaybetmez. Sonunda en yüksek puana sahip takım kazanır!

Eğer takımlar bağlanırsa, ilk sıradaki sırayı belirlemek için sadece ilk etapta bağlı takımların yer aldığı bir turnuva gerçekleşir.

Protokol

Denetleyici programınıza dört komuttan birini gönderir. İlk karakter, gerekirse aşağıdaki verileri izleyerek komut türünü belirler.

Programınız komutu argüman olarak kabul edecek ve bir saniye içinde STDOUT'ye cevap verecektir . STDIN dinlerken hayatta kalmayın, orada olmayacak. Her komut yeni bir süreç ortaya çıkarır.

Diske veri / durum yazabilirsiniz. Herhangi bir dosyayı ekibinizle aynı ada sahip bir alt klasöre yerleştirin. 32 kilobayttan fazla veri yazmayın, aksi takdirde diskalifiye edilirsiniz. Veriler turlar arasında devam edecek, ancak turnuvalar arasında silinecek.

Komutları

Takım Verileri

Bu, takımınızı kaydettirmek için turnuva başında bir kez gönderilir. Cevabınız sabit olmalı , her turnuva için farklı olmamalıdır .

Sorgu:

T

Tepki:

name|member0|member1|member2

nametakım adınıza sahip bir dizedir. Lütfen ayrıştırma kolaylığı için yalnızca alfasayısal kullanın. memberNher canavarın ayrıntılarını veren bir üye dizisidir:

Üye dizesi:

name:typeid:attack:defense:speed:moveid0:moveid1:moveid2

Yine, 'isim' bir dizedir, bu sefer bu canavarın ismiyle. typeidonun tipi. Tip kimlikleri yukarıdaki tabloda gösterilen sıradadır, Normal = 0 ve Çim = 4.

Sonraki üç alan sizin temel istatistiklerinizdir. Yukarıdaki istatistikler bölümünde açıklanan sınırları unutmayın.

Son üç canavarın hamleleri. ID'ler yukarıdaki hareket tablosunda gösterilmiştir.

Örnek bir ekip verisi cevabı şöyle görünebilir:

DummyTeam|DummyA:0:50:60:70:0:1:2|DummyB:0:50:60:70:0:1:2|DummyC:0:50:60:70:0:1:2

Çöpleri, kötü biçimlendirilmiş veya yasadışı verileri geri gönderen hiçbir takım düzeltilinceye kadar katılmayacaktır.

Aktif seç

Bu, her savaşın başlangıcında ve bir canavar öldüğünde ve değiştirilmesi gerektiğinde gönderilir.

Sorgu:

C#battleState

battleStatemevcut savaşın durumunu gösterir. Burada benimle ayı, bu çirkin:

yourTeamState#theirTeamState

Neye XteamStatebenziyor:

name:activeSlot|member0state|member1state|member2state

activeSlothangi canavarın aktif olduğunu gösterir (0-2). Üye devletler iki farklı tada sahiptir. Bu senin takımınsa, ekstra bilgi verir. Yani,

Sizin memberXstate:

name:id:attack:defense:speed:hp:typeid:poisonedturns:moveCount0:moveCount1:moveCount2:bonusAttack:bonusDefense:bonusSpeed:effectid:effectid:effectid

Onların memberXstate:

name:id:attack:defense:speed:hp:typeid:poisonedturns:effectid:effectid:effectid

idkullanmaktan hoşlanmıyorsanız canavarları takip etmek için kullanabileceğiniz bir tamsayı tanımlayıcısıdır name.

attack:defense:speedsenin olan taban istatistikleri.

poisonedturns Size kaç kez zehirlendiğinizi söyler.

moveCountXHer hareket için kaç kullanımınız kaldığını söyler. 0 ise, kullanılamaz. Sınırsız hamle için, bu negatif olacaktır.

bonus(stat) Her stat için atadığınız bonus puan miktarıdır.

effectidcanavarınıza uygulanan, değişken boyutlu bir efekt listesidir. Orada olacak olmayan bir arka olmak :veya mevcut aktif etkilerinin olup olmadığı, ipe. Yığılmış efektler varsa, listede birden fazla efekt olarak görünecektir.

Etki kimlikleri:

0  NONE           (should not appear, internal use)
1  POISON
2  CONFUSION 
3  BURN 
4  SLEEP 
5  HEAL           (should not appear, internal use)
6  ATTACK_UP
7  ATTACK_DOWN
8  DEFENSE_UP
9  DEFENSE_DOWN
10 SPEED_DOWN

Tepki:

memberSlot

Gerekli olan tek cevap, hangi üyeye aktif olmak istediğinizi söyleyen tek bir sayı 0,1,2'dir. Bu, savaşabilecek bir üye olmalı. 1Üye 1 ölmüşse geri göndermeyin .

Savaş eylem

Her seferinde ne yapacağınıza karar vermeniz gerekir.

Sorgu:

A#battleState

battleStateYukarıda tarif edildiği gibi burada tam olarak budur.

Tepki:

Bir hamle kullanmak için, hareketin bulunduğu yuvayı geri gönderin. Örneğin, Punch'ı slot 0'a atadıysam, gönderme 0Punch gerçekleştirir.

Başka bir üyeye geçmek için üyenin yuvasına artı on gönderin . Böylece üye 2'ye geçmek için gönderin 12.

[0,1,2,10,11,12] 'de bulunmayan herhangi bir şey geçersiz sayılır ve bu işlem yapılmaz.

Bonus İstatistikleri

Her iki savaştan sonra, her takım üyesi için gizli bir bonus puanı kazanırsınız.

Sorgu:

B#yourTeamState

Takımın durumu yukarıda gösterilenle aynı, tekrar etmemi sağlama.

Tepki:

stat0:stat1:stat2

Yanıtınız, her takım üyesi için hangi statün yükseltileceğini temsil edecektir. Saldırı 0, Savunma 1, Hız 2.

Böylece, bir üyenin hızını, ikinci üyenin saldırısını ve üçüncü üyenin savunmasını yükseltmek için, aşağıdakileri yanıtlarsınız:

2:0:1

kontrolör

Kontrolör BitBucket'te bulunabilir: https: //Geobits@bitbucket.org/Geobits/codemon.git

Derlenmiş tüm sınıf dosyalarını, başvuruları ve players.conf dosyasını bir klasöre atıp çalıştırın.

Kontrolörün ana sınıfı denir Tournament. Kullanım:

java Tournament [LOG_LEVEL]

0-4 arasındaki günlük seviyeleri artan bilgi verir. Seviye 0 turnuvayı sessizce yürütür ve sadece 3. seviyenin adım adım yorum yaptığı yerde sonuçları verir. Seviye 4, hata ayıklama çıktısıdır.

Turnuvaya gönderimler players.confekleyebilirsiniz. Programı çalıştırmak için gereken komut satırı dizesini sadece satır başına bir tane ekleyin. İle başlayan satırlar yorumdur #.

Gönderinize, benim eklemem gereken komutu players.confve derleme adımlarını (gerekirse) ekleyin .

Dahil üç Normal hareketi ile tüm Normal üyelerden oluşan kukla bir ekip. Rastgele hareketleri seçiyorlar ve korkunç istatistiklere sahipler. Onları dayak eğlenin.

Çeşitli Kurallar

  • Herhangi bir harici kaynağı okuyamaz veya yazamazsınız (kendi alt klasörünüz dışında, yukarıda belirtilen 32 kB'ye kadar).

  • Takımınızın "kör" turnuvasına girmesi gerekiyor. Bu, belirli bir takım / canavarın belirli bir durumda ne yapacağını bulmak için diğer insanların kaynağını analiz edemeyeceğiniz anlamına gelir. Sen edebilirsiniz hiçbir hardcoding bu bilgileri rakibinin hamlelerini / istatistikleri analiz etmek ve turnuva ilerledikçe takip fakat.

  • Diğer işlemlere / gönderimlere müdahale etmeyin. Onları çağırmak yok, verilerini elde etmek için yansıma kullanmak, vb. Bilgisayarımı karıştırmayın. Sadece deneme. Bu benim takdirime bağlı. İhlalcilerin gelecekteki girişleri engellenebilir.

  • Yarışmacılar en fazla iki girişle sınırlıdır . Daha fazla gönderirseniz, sadece gönderilen ilk ikisini puanlayacağım. Birini iptal etmek istiyorsanız, silin.

  • Girişler yalnızca diğer girişleri desteklemek için bulunmayabilir. Ayrıca, diğer yarışmacıları dolaylı olarak diskalifiye etmeye çalışamazsınız (örneğin, bunu diske yazmaya çalışan DQ oyuncularına 27M karakter takımı adı kullanarak). Her gönderim kendi esası ile kazanmak için oynamalıdır.

  • Programınız bir seferde en fazla bir çocuk süreci doğurabilir (doğrudan değil, torunlar). Hem ana hem de alt süreçler çıktı verdikten sonra doğrudan sonlandırılmalıdır. Her iki durumda da, zaman aşımını aşmadığınızdan emin olun.

  • Turnuva, Ubuntu çalıştıran bilgisayarımda Intel i7 3770K işlemci ile gerçekleştirilecek.

Sonuçlar

Bunlar mevcut oyuncuların sonuçları. En iyi yarışmacılar arasında çok yakın ve tur sayısını 500'e kadar çarpmayı düşünüyorum (ve bonus puanlarının aralığını eşleşecek şekilde ayarlamayı). Herhangi bir itiraz, yorum?

------- Final Results -------

158     Happy3Campers
157     LittleKid
71      InsideYourHead
68      HardenedTrio
46      BitterRivals

Google Drive'da tam oynatma sonuçları


62
Çok iyi olmak istiyorum / Hiç bir kodun olmadığı gibi / Kaza yapmamak benim testim / Hata ayıklamak benim sebebim! / LAN üzerinde seyahat edeceğim / Komut dosyası çok geniş / Anlaşılmaya çalışıyorum / BIOS'umu neden kızarttım! / Codémon, sen ve ben / Golf tüm gözlerin görebildiği / Codémon, sen benim en iyi arkadaşımsın / Program bittikten sonra! / Codémon, o kadar gerçek bir lanet / Hiçbir segfault bizi geçemez / Bana öğret ve ben sana öğreteceğim / Codémon
Kaz Wolfe,

1
Turları 500'e çıkarmak yerine, bir turda herkesle savaşan herkesin oluşması iyi olurdu. Böylece bye, eşit olmayan sayıda yarışmacı için artık hiçbir şey yok ve maç çiftlerinin adil ve eşit bir şekilde dağıldığından emin olunur.
foobar

@foobar Bundan kaçınmak istedim çünkü savaşları n^2bunun yerine ölçeklendirir n. Sadece mevcut 7 yarışmacı ve 100 rauntla, bu 2100 savaş (bu oyuna göre 300 ve 500 raunt ile 1500). Sadece daha fazla giriş geldiğinde daha da kötüleşiyor. Mermi sayısını geri ölçekleyebildim, ancak doğal değişkenlik nedeniyle (esp'lerle ilgili esp) ve bunu yapmak için tereddüt ettim (50 puan için).
Geobits

Bu zorluk bir güncelleme gerektirmiyor mu? :)
GholGoth21 17.03.2015

@ GholGoth21 Evet, inanıyorum. Muhtemelen bugün anlayamıyorum, ama belki yarın ya da ertesi gün. İsterseniz perşembe gününe kadar güncellenmediyse sohbete binin.
Geobits

Yanıtlar:


16

Mutlu 3 kampçı - PHP

Muhalefeti zayıflatıcı büyülerle yok etmeyi ve çürümelerini izlemeyi seven bir avuç korkak.

EDIT : Bay Lumpy ağır şekilde cezalandırıldı ve artık kötü sözler demeyecek


KullanışlıKullanışlıGrass - atk:50 def:99 spd:81 Confuse Poison Heal

İnsanları sorunlu el sıkışmalarıyla karıştırmayı seven zehirli bir silahsız kunduz


FlippyFlippyWater - atk:50 def:99 spd:81 Confuse Burn Heal

Aptalca konuşmalar ve alev savaşları için yumuşak noktaya sahip bir ilan tahtası usta.


çatlakçatlakFire - atk:50 def:99 spd:81 Burn Poison Heal

Kitle imha silahları en sevdiği şekerlerdir.


TopaklıTopaklıPhp - lines:500 clarity:05 spd:01 Gather Guess Store

Neredeyse 2 basamak IQ ve olağanüstü hafızası sayesinde Lumpy, düşman hareketlerini tahmin edebilir. Şey, çoğunlukla.


strateji

Strateji, rakiplerin en kısa zamanda zehirlenmesi, yakılması ve karışmasıdır.
Yukarıdaki 3 büyüden daha az güçlü göründüğü için uyku kullanılmadı.
Karışıklık, uzun vadede ölümcül bir olaydır, çünkü saldırıları% 30 oranında azaltır (hem hasar veren hem de heceleme yapmak), şifacıların kendilerini iyileştirmesini engeller ve ağır vuruşlara ağır zarar verir (50 def / 100 atk canavar kendi başına 20 puan hasar verir) ).

Bir düşman iyice yapıştırıldığında, kampçılarım onu ​​cızırtıyor, çürüyor ve ölümüne yumrukluyor.

Yüksek savunma ve iyileştirme, acı sırasında gelen hasarı azaltmak için kullanılır.

3 kampçım dövüşürken, Sihirli geyik Lumpy her harekette düşmanları izler ve bazen onları tanımlamayı başarır. Bilgi, bundan faydalanmak için elinden gelenin en iyisini yapan savaşçılarımıza geri gönderilir.

Savunmadan sonra hız artırmak için en önemli stat.
Girişim, bir sonraki darbe gelmeden önce şifa uygulamak için çok önemlidir.

Saldırı hiç kullanılmaz.

Nihai silahın büyüsü mü?

Zehir, yanma ve kafa karışıklığı gibi büyüler, diğer saldırıların genel taş / kağıt / makas mantığından kaçar.

Bir canavar etkilendiğinde, büyücü öldükten sonra bile HP'leri kaybetmeye devam edecek. Sanki tekerin hayaleti ona saldırmaya devam ediyormuş gibi.
Ayrıca, zehir tamamen parlatılmış kitlesel saldırıdan hızlı bir şekilde daha güçlü hale gelir (5 turdan sonra 50 puanın üstünde).

Zehirli ve yanmış bir canavarın yaşam beklentisi, 3 iyileşmeyle bile 8 turdan öteye gitmez.

As Martin'in botlar gösterir gibi görünmektedir, oyun dengesi oldukça iyidir.
Saf yazımcılar ve saf saldırganlar arasındaki dengeyi belirleyecek olan temel bir girişimdir.

Kod

İle çağır php campers.php

Çirkin bir karmaşa, ama açıkçası arayüz ya da yardımcı olmuyor.

Şimdi uygun şekilde saldırgan bir rekabet ortaya çıktı, uzun planlı düşman hareketlerimi tahmin ettim.
Saldırıların analiz edilmesi, çeşitli akrobasi kesintileri ve son sıraların sürekli depolanmasını gerektirir; bu, paranoyak denetleyici arayüzüyle tam ölçekli bir savaş anlamına gelir.
Güzel bir şey değil, altı ayaklı bir jackrabbit de değil, ama yeterli bir iş yapıyor.

<?php

// ============================================================================
// Game
// ============================================================================
class G {
    static $code_type = array ("Normal", "Psychic", "Fire", "Water", "Grass", "?", "self"); 
    static $code_move = array    ("Punch", "Heal", "Slow", "Pain", "Sleep", "Weaken", "Fireball", "Burn", "Sharpen", "Watergun", "Confuse", "Shield", "Vine", "Poison", "Sap", "?", "self", "pass");
    static $move_uses = array (1000,3,5,1000,3,5,1000,3,5,1000,3,5,1000,3,5,   2000,2000);
    static $move_type      = array (0,0,0,1,1,1,2,2,2,3,3,3,4,4,4, 5,5,5);
    static $move_dmg       = array (20,0,10,20,0,10,20,0,10,20,0,10,20,0,10,  20,10,0);
    static $move_forbidden = array (1,1,1,0,0,0,4,4,4,2,2,2,3,3,3);
    static $code_effect = array ("N", "Poison", "Confuse", "Burn", "Sleep", "H", "Sharpen", "Weaken", "Shield", "Sap", "Slow"); 
    static $decode_type, $decode_move, $decode_effect;
    static $damage_multiplier = array (
        array (2, 0, 1, 1, 1, 0),
        array (0, 2, 1, 1, 1, 0),
        array (1, 1,.5, 2,.5, 0),
        array (1, 1,.5,.5, 2, 0),
        array (1, 1, 2,.5,.5, 0),
        array (2, 2, 2, 2, 2,-1),
        array (9, 9, 9, 9, 9, 9, 1));
    static $atk_score = array ("Poison"=> 1002, "Confuse"=>1001, "Burn"=>1000);
    static $status_field = "atk:def:spd:hp:type:Pturns";
    static $all_moves, $strong_moves, $medium_moves, $effect_moves, $possible_moves;

    function init()
    {
        self::$status_field = explode (":", self::$status_field);
        foreach (array ("type", "move", "effect") as $table) self::${"decode_$table"} = array_flip (self::${"code_$table"});
        foreach (self::$code_move as $c=>$m)
        {
            if ($m == "?") break;
            self::$all_moves[] = new Move($m);
            if (self::$move_uses[$c] >  5) self::$strong_moves[] = $m;
            if (self::$move_uses[$c] == 5) self::$medium_moves[] = $m;
            if (self::$move_uses[$c] == 3) self::$effect_moves[] = $m;
            for ($type = 0 ; $type != 5 ; $type++) if ((self::$move_uses[$c] >  5) && (self::$move_forbidden[$c] != $type)) self::$possible_moves[$type][] = $m;
        }
    }

    function __construct ($name, $team)
    {
        $this->turn = 0;
        $this->name = $name;
        $this->team = $team;
        $this->results_pending = false;
    }

    function parse_team ($tpack, $own_team)
    {
        $pack = explode ("|", $tpack);
        list ($name,$active) = explode (":", array_shift($pack));
        if ($own_team)
        {
            $team = $this->team;
        }
        else
        {
            if (!isset($this->enemies[$name])) $this->enemies[$name] = new Team(array (new Monster (), new Monster (), new Monster ()));
            $team = $this->foes = $this->enemies[$name];
        }
        $team->active = $active;
        foreach ($pack as $i=>$mpack) $team->monster[$i]->parse_monster ($own_team, $mpack);
    }

    function choose_active ()
    {
        // detect start of round
        $team = $this->team;
        $foes = $this->foes;
        foreach ($team->monster as $i=>$m) if ($m->hp > 0) $candidate[$i] = $m;
        if (count ($candidate) == 3)
        {
            $this->results_pending = false;
            $this->round++;

            // reinitialize all monsters
            foreach (array($team, $foes) as $t)
            foreach ($t->monster as $m)
                $m->start_round();

            // guess initial opponent
            $opponent = $foes->initial_opponent();
        }
        else
        {
            $this->analyze_last_round();
            $opponent = $foes->active();
        }
        return $this->do_switch ($opponent);
    }

    function choose_attacker ($foe)
    {
        foreach ($this->team->monster as $i=>$m) if ($m->can_attack($foe)) $candidate[$i] = $m;
        if (isset($candidate))
        {
            uasort ($candidate, function ($a,$b) use ($foe) { return ($a->atk_score != $b->atk_score) ? $b->atk_score - $a->atk_score : $b->life_expectancy($foe) - $a->life_expectancy($foe); });
            return key($candidate);
        }
        return -1;
    }

    function do_switch ($foe)
    {
        $replacement = $this->choose_attacker ($foe);
        if ($replacement < 0)
        {
            $candidate =  $this->team->monster;
            uasort ($candidate, function ($a,$b) use ($foe) { return $b->life_expectancy($foe) - $a->life_expectancy($foe); });
            $replacement = key($candidate);
        }

        $this->old_own = $this->team->monster[$replacement];
        $this->old_own->attack = "pass";
        return $replacement;
    }

    function choose_action ()
    {
        $this->analyze_last_round();
        $own = $this->team->active();
        $foe = $this->foes->active();
        $this->old_own = $own;

        if ($own->hp <= $own->max_damage($foe) && $own->can_do ("Heal")) return $own->execute("Heal");
        if ($attack = $own->can_attack($foe)) return $own->execute($attack);
        if ($own->hp <= 50 && $own->can_do ("Heal")) return $own->execute("Heal");

        return 10 + $this->do_switch ($foe);    
    }

    function choose_bonus()
    {
        foreach ($this->team->monster as $m)
        {
            if ($m->spd_b == 0) { $m->spd_b++; $res[] = 2; }
            else                { $m->def_b++; $res[] = 1; }
        }
        return implode (":", $res);
    }

    function parse ($parts)
    {
        self::parse_team ($parts[1], true);
        self::parse_team ($parts[2], false);    
    }

    function analyze_last_round()
    {
        if ($this->results_pending)
        {
            $this->results_pending = false;

            $foes = $this->foes;
            $foe = null;
            foreach ($foes->monster as $m) if ($m->hp != $m->old->hp) $foe = $m;
            if ($foe === null) $foe = $foes->monster[$foes->active];

            $this->old_own->guess_attack($foe);
        }
    }

    function process ($line)
    {
        $parts = explode ("#", $line);
        switch ($parts[0])
        {
        case "T": // register for tournament
            echo "$this->name|$this->team";
            break;
        case "C": // designate active monster
            $this->parse ($parts);
            echo $this->choose_active();
            break;
        case "A": // choose round action
            $this->parse ($parts);
            echo $this->choose_action();

            // save current state
            foreach (array($this->team, $this->foes) as $t)
            foreach ($t->monster as $m)
            {
                unset ($m->old);
                $m->old = clone ($m);
            }
            $this->results_pending = true;
            break;
        case "B": // distribute stat bonus
            echo $this->choose_bonus();
            break;
        }

    }
}
G::init();

// ============================================================================
// Move
// ============================================================================
class Move {
    function __construct ($move)
    {
        $this->register($move);
    }

    function register ($move)
    {
        $this->type = G::$decode_move[$move];
        $this->reinit();
    }

    function reinit()
    {
        $this->uses = G::$move_uses[$this->type];
    }

    function __tostring() { return G::$code_move[$this->type]."($this->uses)"; }
}

// ============================================================================
// Monster
// ============================================================================
class Monster { 
    function __construct ($name="?", $type="?", $atk=100, $def=100, $spd=100, $m0="?", $m1="?", $m2="?")
    {
        $this->name = $name;
        $this->type = G::$decode_type[$type];
        $this->atk  = $atk;
        $this->def  = $def;
        $this->spd  = $spd;
        $this->hp   = 100;
        $this->move = array (new Move($m0), new Move($m1), new Move($m2));
        $this->atk_b = 0;
        $this->def_b = 0;
        $this->spd_b = 0;
        foreach (G::$code_effect as $e) $this->$e = 0;
    }

    function __tostring ()
    {
        return implode (":", array (
            $this->name,
            $this->type,
            $this->atk,
            $this->def,
            $this->spd,
            $this->move[0]->type,
            $this->move[1]->type,
            $this->move[2]->type));
    }

    function start_round()
    {
        foreach ($this->move as $m) $m->reinit();
    }

    function parse_monster ($own_team, $spack)
    {
        $pack = explode (":", $spack);
        $name = array_shift ($pack); // get name
        array_shift ($pack); // skip id
        if ($this->name == "?") $this->name = $name; // get paranoid
        else if ($this->name != $name) die ("expected $this->name, got $name");

        // store updated values
        foreach (G::$status_field as $var) $this->$var = array_shift ($pack);
        if ($own_team)
        {
            foreach ($this->move as $m) $m->new_count = array_shift($pack);
            $pack = array_slice ($pack, 3); // these are maintained internally
        }
        $var = array();
        foreach ($pack as $e) @$var[G::$code_effect[$e]]++; 
        foreach (G::$code_effect as $e) $this->$e = @$var[$e]+0;
    }

    function damage_recieved ($attack, $foe=null)
    {
        if ($attack == "self") $foe = $this;
        $a = G::$decode_move[$attack];
        $type = G::$move_type[$a];
        $dmg = g::$move_dmg[$a];

        if ($dmg == 0) return 0;

        $atk = ($foe ->atk+$foe ->atk_b) * pow (.8, ($foe ->Weaken - $foe ->Sharpen));
        $def = ($this->def+$this->def_b) * pow (.8, ($this->Sap    - $this->Shield ));

        $boost = ($foe->type == $type) ? 1.2 : 1;
        return max (floor ($dmg * $atk / $def * $boost * G::$damage_multiplier[$this->type][$type]), 1);
    }

    function guess_attack_from_effect ($attacks)
    {
        foreach ($attacks as $status) if ($this->$status != $this->old->$status) return $status;
        return "?";
    }

    function guess_attack_from_damage ($foe, $damages)
    {
        $select = array();
        foreach (G::$possible_moves[$foe->type] as $attack)
        {
            $dmg = $this->damage_recieved ($attack, $foe);
            foreach ($damages as $damage) if ($damage != 0 && abs ($dmg/$damage-1) < 0.1) $select[$attack] = 1;
        }
        $res = array();
        foreach ($select as $a=>$x) $res[] = $a;
        return $res;
    }

    function guess_attack ($foe)
    {
        $attempt = G::$decode_move[$this->old->attack];
        $success = ($this->old->attack == "pass");
        foreach ($this->move as $m)
        {
            if ($m->type == $attempt)
            {
                if ($m->new_count == $m->uses-1)
                {
                    $m->uses--;
                    $success = true;
                }
                break;
            }
        }

        $possible = array();
        $attack = $this->guess_attack_from_effect (array("Burn", "Confuse", "Poison", "Sleep", "Slow", "Weaken", "Sap"));
        if ($attack == "?") $attack = $foe->guess_attack_from_effect (array("Sharpen", "Shield"));
        if ($attack == "?")
        {
            $foe_damage = $this->old->hp - $this->hp - (10 * $this->Burn + 5 * $this->Pturns*$this->Poison);
            if ($this->old->attack == "Heal" && $success) $foe_damage += 50;
            $possible_dmg[] = $foe_damage;
            //;!;if ($this->Confuse) $possible_dmg[] = $foe_damage + $this->damage_recieved ("self");
            $possible = $this->guess_attack_from_damage ($foe, $possible_dmg);
            if (count ($possible) == 1) $attack = $possible[0];
        }
        if ($attack == "?")
        {
            $own_damage = $foe->old->hp - $foe->hp 
                        - (10 * $foe->Burn + 5 * $foe->Pturns*$foe->Poison)
                        + $foe->damage_recieved ($this->attack);
            if (abs ($own_damage/50+1) < 0.1) $attack = "Heal";
        }
        if ($attack != "?")
        {
            $type = G::$decode_move[$attack];
            if ($attack != "?")
            {
                foreach ($foe->move as $m) if ($m->type == $type) goto found_old;
                foreach ($foe->move as $m) if ($m->type == 15) { $m->register($attack); goto found_new; }
            }
            found_new:
            found_old:
        }
    }

    function max_damage($foe)
    {
        $dmg = 0;
        foreach ($foe->move as $m) $dmg = max ($dmg, $this->damage_recieved (G::$code_move[$m->type], $foe));
        return $dmg;
    }

    function expected_damage ($foe)
    {
        return $this->max_damage($foe) + 10 * $this->Burn + 5 * ($this->Pturns+1);
    }

    function life_expectancy ($foe)
    {
        $hp = $this->hp;
        $poison = $this->Pturns;
        $heal = $this->can_do ("Heal");
        $dmg = $this->max_damage($foe);
        for ($turn = 0 ; $hp > 0 && $turn < 10; $turn++)
        {
            $hp -= 10 * $this->Burn + 5 * $poison;
            if ($poison > 0) $poison++;
            $hp -= $dmg;
            if ($hp <= 0 && $heal > 0) { $hp+=50; $heal--; }
        }
        return 100 * $turn + $this->hp;
    }

    function can_attack ($foe)
    {
        $attack = false;
        if ($this->hp > 0)
        {
            if      (!$foe->Poison  && $this->can_do ("Poison" )) $attack = "Poison";
            else if (!$foe->Confuse && $this->can_do ("Confuse")) $attack = "Confuse";
            else if (!$foe->Burn    && $this->can_do ("Burn"   )) $attack = "Burn";
        }
        $this->atk_score = ($attack === false) ? 0 : G::$atk_score[$attack];
        return $attack;
    }

    function can_do($move)
    {
        $type = G::$decode_move[$move];
        foreach ($this->move as $m) if ($m->type == $type && $m->uses > 0) return $m->uses;
        return false;
    }

    function execute($move)
    {
        $type = G::$decode_move[$move];
        foreach ($this->move as $i=>$m) if ($m->type == $type) 
        { 
            if ($m->uses > 0)
            {
//;!;               $m->uses--;
                $this->attack = $move;
            }
            else $this->attack = "pass";
            return $i; 
        }
        die ("$this asked to perform $move, available ".implode(",", $this->move));
    }
}

// ============================================================================
// Team
// ============================================================================
class Team {
    function __construct ($members)
    {
        $this->monster = $members;
    }

    function __tostring()
    {
        return implode ("|", $this->monster);
    }

    function active ()
    {
        return $this->monster[$this->active];
    }

    function initial_opponent()
    {
        return $this->monster[0];
    }
}

// ============================================================================
// main
// ============================================================================
$input = $argv[1];

$team_name = "H3C";
$mem_file = "$team_name/memory.txt";
$trc_file = "$team_name/trace.txt";
if (!file_exists($team_name)) mkdir($team_name, 0777, true) or die ("could not create storage directory '$team_name'");
if ($input == "T") array_map('unlink', glob("$team_name/*.txt"));

if (file_exists($mem_file)) $game = unserialize (file_get_contents ($mem_file));
else
{
    $team = new Team (
        array (
            new Monster ("Handy" , "Grass" , 50, 99, 81, "Confuse", "Poison", "Heal"),
            new Monster ("Nutty" , "Fire"  , 50, 99, 81, "Burn"   , "Poison", "Heal"),
            new Monster ("Flippy", "Water" , 50, 99, 81, "Confuse" , "Burn" , "Heal")));
    $game = new G($team_name,$team);
}

$game->process ($input);
file_put_contents ($mem_file, serialize($game));

Sonuçlar

LittleKid hala tehdit ediyor, ama üçlüm zehirli ucubelerini adil bir farkla yendi.

Martin botları, inisiyatif eksikliğinden mahkumdur ve hızlarının arttırılması, saldırı yapma kapasitesinde kenarlarını köreltecek olan saldırıyı düşürmeyi gerektirir.

Gezegen JavaScript'ten gelen yeni yarışmacılar birebir ekiple aynı, ancak diğer rakiplere karşı daha kötü durumdalar. Aslında LittleKid'in puanını düşürmeye yardım ediyorlar :).

Öyle görünüyor ki sevimli arkadaşlarım tepenin kralları.

170             H3C
158             Nodemon
145             LittleKid
55              InsideYourHead
42              HardenedTrio
30              BitterRivals

Ve benim de üzerinde PHP yok. Yerini Metatap'larla paspaslamanı bekliyorum, çünkü yavaşça saldıracaklar ve ölümüne zehirleneceklerdi.
Sp3000

... * ve * net olarak yandı: D. Bu karmaşık kurallarla ilgili sorun: baskın bir stratejinin ortaya çıkması çok muhtemel. Bu büyülere karşı koruma olmadığından, kodonun şişman adamı ve küçük oğlu olabilirler.

Makas, kâğıt, taş gibi geçişsiz bir oyunla daha fazla karşılaştırırdım - efektler uzun
sürdüğü

2
Evet, Poison and Burn için bir çare bulamadığımda hayal ettiğim şey budur. Hayalimdeki gerçeği getirdiğiniz için teşekkür ederim.
justhalf

1
Bay Lumpy, aynı rakipten 3 farklı saldırı tespit ettiğinde şaşkınlığını ifade ediyor :). Neredeyse tamamlanmış sabit bir sürümüm var, ancak şu anda başka bir şeyin tam ortasındayım, bu yüzden düzeltme bir gün içinde gönderilecek.

7

SertleştirilmişTrio, Python 3

Geobits bize iki başvuruda bulunacak kadar iyi olduğundan , birincisi için aptalca bir şey göndereceğimi düşündüm: P

Parti, aynı istatistiklere ve hamlelere sahip üç Codemon'dur (Metapod1, Metapod2, Metapod3):

  • 80 saldırı, 100 savunma, 50 hız
  • Yumruk, İyileşme, Kalkan Sertleştirme

Tüm bonus puanları savunmaya da verilir.


from collections import namedtuple
import sys

BattleState = namedtuple("BattleState", ["us", "them"])
TeamState = namedtuple("TeamState", ["name", "active", "members"])
MemberState = namedtuple("MemberState", ["name", "id", "attack", "defense", "speed", "hp",
                                         "typeid", "poisonedturns", "otherstats"])

def parse_battle_state(state):
    return BattleState(*map(parse_team_state, state.split("#")))

def parse_team_state(state):
    na, *members = state.split("|")
    name, active = na.split(":")
    return TeamState(name, int(active), list(map(parse_member_state, members)))

def parse_member_state(state):
    name, id_, attack, defense, speed, hp, typeid, poisonedturns, *rest = state.split(":")
    return MemberState(name, int(id_), float(attack), float(defense), float(speed),
                       float(hp), int(typeid), int(poisonedturns), rest)

command = sys.argv[1].strip()

if command.startswith("T"):
    print("HardenedTrio|Metapod1:0:80:100:50:0:1:11|"
          "Metapod2:0:80:100:50:0:1:11|Metapod3:0:80:100:50:0:1:11")

elif command.startswith("C"):
    battle_state = parse_battle_state(command[2:])

    for i, codemon in enumerate(battle_state.us.members):
        if codemon.hp > 0:
            print(i)
            break

elif command.startswith("A"):
    battle_state = parse_battle_state(command[2:])
    current_codemon = battle_state.us.members[battle_state.us.active]

    if current_codemon.hp < 50 and int(current_codemon.otherstats[1]) > 0:
        print(1) # Heal up if low

    elif int(current_codemon.otherstats[2]) > 0:
        print(2) # Harden!

    else:
        print(0) # Punch!

elif command.startswith("B"):
    print("1:1:1")

İle koş

py -3 <filename>

(veya kurulumunuza bağlı olarak python/ python3yerine py)



1
@ FryAmTheEggman Metapod, HARDEN!
Sp3000

Kodunu okumaya çalışıyorum ama kafam karıştı int(current_codemon.otherstats[1])>0. Durum etkisi varsa bu doğru mu? Ve sadece iki durum etkisi varsa sertleşmeyi mi kullanıyor?
Mooing Duck

@MooingDuck Codemon'unuz için moveCounts'den önce sahip effectidolduğunuzdan Harden'i kullanıp kullanamayacağını kontrol ediyor. Ayrıştırma konusunda tembelleşmiştim, bu yüzden oraya yığıldı.
Sp3000

@ Sp3000: Ah! Sağ! HAHAHA!
Mooing Duck

6

Kafanın içinde Ruby

  • Brian : Medyum, Saldırı: 100, Savunma: 50, Hız: 80, Ağrı, Ateş Topu, Su Tabancası
  • Elemon1 : Psişik, Saldırı: 100, Savunma: 50, Hız: 80, Ateş Topu , Su Tabancası , Asma
  • Elemon2 : Psişik, Saldırı: 100, Savunma: 50, Hız: 80, Ateş Topu , Su Tabancası , Asma
TEAM_SPEC = "InsideYourHead"+
            "|Brian:1:100:50:80:3:6:9"+
            "|Elemon1:1:100:50:80:6:9:12"+
            "|Elemon2:1:100:50:80:6:9:12"

def parse_battle_state request
    request.map do |team_state|
        state = {}
        parts = team_state.split '|'
        state[:active] = parts.shift.split(':')[1].to_i
        state[:monsters] = parts.map do |monster_state|
            monster = {}
            parts = monster_state.split(':')
            monster[:name] = parts[0]
            monster[:hp] = parts[5].to_i
            monster[:type] = parts[6].to_i
            monster
        end
        state
    end
end

request = ARGV[0].split '#'
case request.shift
when 'T'
    puts TEAM_SPEC
when 'C'
    battle_state = parse_battle_state request
    my_state = battle_state[0]
    puts my_state[:monsters].find_index {|monster| monster[:hp] > 0}
when 'A'
    battle_state = parse_battle_state request
    my_state, their_state = *battle_state
    my_monster = my_state[:monsters][my_state[:active]]
    their_monster = their_state[:monsters][their_state[:active]]
    puts [1,0,1,2,0][their_monster[:type]]
when 'B'
    puts '0:0:0'
end

İle koş

ruby InsideYourHead.rb

Bu Manu'nun botuna karşı çok iyi çalışmıyor, ama diğer üçünü yeniyor. Takım ve canavar isimleri oldukça rastgele ... Daha iyi bir şey bulursam değiştirebilirim.

Strateji oldukça basit: saldırı! Her üç canavar da yalnızca saf saldırı hamlelerine sahip ve rakibin canavarının türüne göre hamlelerini seçiyorlar.

Daha sonra bir İyileşme atmayı deneyebilirim.


1
Hehe bu daha ilginç hale gelir. Bunun için sana güvenebileceğimi biliyordum Martin :)

6

LittleKid, Java

Küçük bir çocuk 3 özdeş kodlayıcı buldu ve onları eğitti. Onlar iyileşme + zehirlenme saldırıları ile çok can sıkıcı. Sadece normal tip kodonları kullanmak, onları her tür düşmanla eşleştiği için onları belirli düşmanlarla eşleştirme ihtiyacını ortadan kaldırır.

public class LittleKid {

    public static void main(String[] args) {
        if(args.length < 1){
            System.out.println("Geobits says you can't do this.");
            System.exit(0);
        }

        String[] sections = args[0].split("#");
        String me, them, out = "";
        switch(sections[0]){
            case "T":
                out = "LittleKid";
                out += "|Poisoner:0:80:100:50:0:1:13";
                out += "|Poisoner:0:80:100:50:0:1:13";
                out += "|Poisoner:0:80:100:50:0:1:13";
                break;
            case "B":
                out = "1:1:1";
                break;
            case "C":
                me = sections[1];
                them = sections[2];
                int pick = 0;

                if(!isAlive(me, pick)){
                    for(int i=0;i<3;i++){
                        if(isAlive(me,i))
                            pick = i;
                    }
                }

                out = String.valueOf(pick);
                break;
            case "A":
                me = sections[1];
                them = sections[2];
                int active = getActive(me);
                int enemyActive = getActive(them);
                if (getField(me, HP, active) < 50 && getField(me, MOVE1, active) != 0) {
                    out = "1";
                } else if (getEffectCount(them, POISON, enemyActive, false) < 1 && getField(me, MOVE2, active) != 0) {
                    out = "2";
                } else {
                    out = "0";
                }
                break;
            default:
                out = "Invalid query from controller.";             
        }
        System.out.println(out);
    }

    static boolean isAlive(String teamState, int who){
        return getField(teamState, HP, who) > 0;
    }

    static int getActive(String teamState){
        return Integer.parseInt(teamState.split("\\|")[0].split(":")[1]);
    }

    static int getField(String teamState, int field, int who){
        String[] fields = teamState.split("\\|")[who+1].split(":");
        return Integer.parseInt(fields[field]);
    }

    static int getEffectCount(String teamState, int effect, int who, boolean mine){
            String[] fields = teamState.split("\\|")[who+1].split(":");
            int count = 0;
            for(int i=mine?14:8;i<fields.length;i++){
                if(Integer.parseInt(fields[i]) == effect)
                    count++;
            }
            return count;
    }

    final static int ID =       1; 
    final static int ATTACK =   2; 
    final static int DEFENSE =  3; 
    final static int SPEED =    4; 
    final static int HP =       5; 
    final static int TYPE =     6;
    final static int MOVE0 =    8; 
    final static int MOVE1 =    9; 
    final static int MOVE2 =    10;

    final static int POISON =           1;
}

5
" Geobits bunu yapamayacağınızı söylüyor ": D
Geobits

Zehir görünüyor bu oyunda gerçek A-bombası :)

5

Nodémon - Javascript

Durum baskın bir strateji olarak göründüğü için, bu takım önce rakiplere zehir ve kafa karışıklığı gibi durumları alma hızına odaklanır ve daha sonra rakip uzaklaştığında iyileşme ve / veya uyku ile durur.

PHP kurulu değil, bu yüzden Kampçılar aleyhine test edilmedi, ancak denemelerimde LittleKid için iyi bir rakip gibi görünüyor (ve Bitter Rakiplerini yok ediyor).

/*jshint node:true*/
'use strict';

var fs = require('fs');

var dataFile = 'Nodemon/data.json';
function getData(callback) {
  fs.readFile(dataFile, 'utf8', function(err, contents) {
    var data = {round: 0};

    if(!err) {
      data = JSON.parse(contents);
    }

    callback(data);
  });
}

function saveData(data, callback) {
  fs.mkdir('Nodemon', function() {    
    fs.writeFile(dataFile, JSON.stringify(data), callback);
  });
}

var effect = {
  poison: '1',
  confusion: '2',
  burn: '3',
  sleep: '4',
  heal: '5',
  attackUp: '6',
  attackDown: '7',
  defenseUp: '8',
  defenseDown: '9',
  speedDown: '10'
};

function parseMemberCommon(args) {
  return {
    name: args[0],
    id: args[1],
    baseAttack: +args[2],
    baseDefense: +args[3],
    baseSpeed: +args[4],
    hp: +args[5],
    typeId: args[6],
    poisonedTurns: +args[7],
    effects: args.slice(8)
  };
}

function parseOwnMember(arg) {
  var args = arg.split(':');

  var ownArgs = args.splice(8, 6);

  var member = parseMemberCommon(args);

  member.moveCount = [
    +ownArgs[0],
    +ownArgs[1],
    +ownArgs[2]
  ];

  member.bonusAttack = +ownArgs[3];
  member.bonusDefense = +ownArgs[3];
  member.bonusSpeed = +ownArgs[3];

  return member;
}

function parseOpponentMember(arg) {
  return parseMemberCommon(arg.split(':'));
}

function parseTeamStateCommon(arg, memberParse) {
  var args = arg.split(':');
  var state = {
    name: args[0],
    members: []
  };
  args = arg.substring(state.name.length + 1).split('|');
  var activeSlot = args[0];
  for(var index = 1; index < args.length; index++) {
    state.members.push(memberParse(args[index]));
  }
  state.activeMember = state.members[activeSlot];
  return state;
}

function parseOwnState(arg) {
  return parseTeamStateCommon(arg, parseOwnMember);
}

function parseOpponentState(arg) {
  return parseTeamStateCommon(arg, parseOpponentMember);
}

function parseBattleState(arg) {
  var args = arg.split('#');
  return {
    own: parseOwnState(args[0]),
    opponent: parseOpponentState(args[1])
  };
}

function teamData() {

  saveData({round:0}, function() {
    console.log('Nodemon|' + 
      'Charasaur:0:50:80:100:10:13:1|' +
      'Bulbtortle:4:50:80:100:10:13:1|' +
      'Squirtmander:1:50:80:100:10:13:4');
  });
}

function getActiveIndex(battleState) {
  for(var index = 0; index < battleState.own.members.length; index++) {
    var member = battleState.own.members[index];
    if(member.hp > 0) {
      return index;
    }
  }
}

function chooseActive(arg) {
  var battleState = parseBattleState(arg);

  getData(function(data) {
    var allFull = true;
    for(var index = 0; index < battleState.opponent.members.length; index++) {
      var member = battleState.opponent.members[index];
      if(!data.maxSpeed || member.baseSpeed > data.maxSpeed) {
        data.maxSpeed = member.baseSpeed;
      }
      if(member.hp < 100) {
        allFull = false;
      }
    }

    if(allFull) {
      data.round++;
    }

    saveData(data, function() {
      console.log(getActiveIndex(battleState));
    });    
  });
}

function useMove(moves, battleState) {
  var fighter = battleState.own.activeMember;

  for(var moveIndex = 0; moveIndex < moves.length; moveIndex++) {
    var move = moves[moveIndex];
    if(fighter.moveCount[move]) {
      return move;
    }

    for(var memberIndex = 0; memberIndex < battleState.own.members.length; memberIndex++) {
      var member = battleState.own.members[memberIndex];

      if(member.hp > 0 && member.moveCount[move] > 0) {
        return 10 + memberIndex;
      }
    }
  }

  return -1;  //do nothing
}

function battleAction(arg) {
  var battleState = parseBattleState(arg);

  var fighter = battleState.own.activeMember;
  var opponent = battleState.opponent.activeMember;

  var attemptedMoves = [];

  if(opponent.effects.indexOf(effect.poison) === -1) {
    attemptedMoves.push(1);
  }

  if(opponent.effects.indexOf(effect.confusion) === -1) {
    attemptedMoves.push(0);
  }

  if(fighter.name === 'Squirtmander') {
    //sleep
    if(opponent.effects.indexOf(effect.sleep) === -1) {
      attemptedMoves.push(2);
    }
  }
  else {
    //heal
    if(fighter.hp <= 60) {
      attemptedMoves.push(2);
    }
  }

  console.log(useMove(attemptedMoves, battleState));
}

function bonusStats(arg) {
  var teamState = parseOwnState(arg);

  getData(function(data) {
    var result = '1:';

    if(data.round % 4 === 0) {
      result += '1:';
    }
    else {
      result += '2:';
    }
    if(teamState.members[2].baseSpeed + teamState.members[2].bonusSpeed > data.maxSpeed + (data.round / 2)) {
      result += '1';
    }
    else {
      result += '2';
    }
    console.log(result);
  });
}

var actions = {
  'T': teamData,
  'C': chooseActive,
  'A': battleAction,
  'B': bonusStats
};

var arg = process.argv[2];
actions[arg[0]](arg.substring(2));

İle koş

node nodemon

PS, nodemon için özür diler .


Bu, sunucu tarafı senaryo küresel savaşına

4

Acı Rakipler - Java

Değiştirmeyi seven bir Çimen / Ateş / Su ekibi.

Greenosaur

Herhangi biri üzerinde en azından tarafsız bir kapsama sahip. Savunmasızlığı telafi etmek için yüksek hız.

Type: Grass
Attack:   80     Vine
Defense:  50     Punch
Speed:   100     Pain

Searizard

Düşük saldırı ile Sap düşmanlarına çalışır. Bundan sonra Burns ve Ateş topları.

Type: Fire
Attack:  100     Fireball
Defense:  50     Burn
Speed:    80     Sap

Blastshield

Zaten yüksek savunmasını geliştirmek için Kalkan kullanır. Gerektiğinde iyileşir.

Type: Water
Attack:   80     Watergun
Defense: 100     Shield
Speed:    50     Heal

kod

Bu, kontrol ünitesine de dahildir. Bu ise DummyTeam aksine, rakip takım. Gereken komut players.confşudur:

java BitterRivals

public class BitterRivals {

    public static void main(String[] args) {
        if(args.length < 1){
            System.out.println("You're not doing this right. Read the spec and try again.");
            System.exit(0);
        }

        String[] sections = args[0].split("#");
        String me, them, out = "";
        switch(sections[0]){
            case "T":
                out = "BitterRivals";
                out += "|Greenosaur:4:80:50:100:12:0:3";
                out += "|Searizard:2:100:50:80:6:7:14";
                out += "|Blastshield:3:80:100:50:9:11:1";
                break;
            case "B":
                out = "2:0:1";
                break;
            case "C":
                me = sections[1];
                them = sections[2];

                int pick = 0;
                switch(getField(them, TYPE, getActive(them))){
                    case 0:
                    case 1:
                    case 3:
                        pick = 0;
                        break;
                    case 2:
                        pick = 2;
                        break;
                    case 4:
                        pick = 1;
                        break;
                }

                if(!isAlive(me, pick)){
                    for(int i=0;i<3;i++){
                        if(isAlive(me,i))
                            pick = i;
                    }
                }

                out = pick + "";
                break;
            case "A":
                me = sections[1];
                them = sections[2];
                int active = getActive(me);
                int oType = getField(them, TYPE, getActive(them));
                switch(active){
                    case 0:         // Greenosaur
                        switch(oType){
                            case 0:
                            case 4:
                                out = "1";
                                break;
                            case 1:
                                out = "2";
                                break;
                            case 3:
                                out = "0";
                                break;
                            case 2:
                                if(isAlive(me, 2)){
                                    out = "12";
                                } else if(isAlive(me, 1)){
                                    out = "11";
                                } else {
                                    out = "1";
                                }
                                break;
                        }
                        break;
                    case 1:         // Searizard
                        if(oType == 3){
                            if(isAlive(me, 0)){
                                out = "10";
                                break;
                            } else if(isAlive(me, 2)){
                                out = "12";
                                break;
                            }
                            if(getEffectCount(them, BURN, getActive(them), false) < 1 && getField(me, MOVE1, active) > 0){
                                out = "1";
                            } else if(getField(me, MOVE2, active) > 0){
                                out = "2";
                            } else {
                                out = "3";
                            }                           
                        } else {
                            if(getField(them, ATTACK, getActive(them)) < 80){
                                if(getEffectCount(them, DEFENSE_DOWN, getActive(them), false) < 1 && getField(me, MOVE2, active) > 0){
                                    out = "2";
                                    break;
                                } else if(getEffectCount(them, BURN, getActive(them), false) < 1 && getField(me, MOVE1, active) > 0){
                                    out = "1";
                                    break;
                                }
                            }
                            out = "0";
                        }
                        break;
                    case 2:         // Blastshield
                        if(oType == 4){
                            if(isAlive(me, 1)){
                                out = "11";
                                break;
                            } else if(isAlive(me, 0)){
                                out = "10";
                                break;
                            }
                        }
                        if(getField(me, HP, active) < 50 && getField(me, MOVE2, active) > 0){
                            out = "2";
                        } else if(getEffectCount(me, DEFENSE_UP, active, true) < 3 && getField(me, MOVE1, active) > 0){
                            out = "1";
                        } else {
                            out = "0";
                        }
                        break;
                }
                break;
            default:
                out = "Invalid query from controller.";             
        }
        System.out.println(out);
    }

    static boolean isAlive(String teamState, int who){
        return getField(teamState, HP, who) > 0;
    }

    static int getActive(String teamState){
        return Integer.parseInt(teamState.split("\\|")[0].split(":")[1]);
    }

    static int getField(String teamState, int field, int who){
        String[] fields = teamState.split("\\|")[who+1].split(":");
        return Integer.parseInt(fields[field]);
    }

    static int getEffectCount(String teamState, int effect, int who, boolean mine){
            String[] fields = teamState.split("\\|")[who+1].split(":");
            int count = 0;
            for(int i=mine?14:8;i<fields.length;i++){
                if(Integer.parseInt(fields[i]) == effect)
                    count++;
            }
            return count;
    }

    final static int ID =       1; 
    final static int ATTACK =   2; 
    final static int DEFENSE =  3; 
    final static int SPEED =    4; 
    final static int HP =       5; 
    final static int TYPE =     6; 
    final static int PTURNS =   7; 
    final static int MOVE0 =    8; 
    final static int MOVE1 =    9; 
    final static int MOVE2 =    10; 
    final static int HA =       11; 
    final static int HD =       12; 
    final static int HS =       13; 

    final static int POISON =           1;
    final static int CONFUSION =        2;
    final static int BURN =             3;
    final static int SLEEP =            4;
    final static int ATTACK_UP =        6;
    final static int ATTACK_DOWN =      7;
    final static int DEFENSE_UP =       8;
    final static int DEFENSE_DOWN =     9;
    final static int SPEED_DOWN =       10;
}

4

Hata 310: Çok Fazla Yönlendirme - C ++

Zehirin tahribatına karşı koymak için oldukça eğitimli ve düzenli bir ekip

Üç hafta boyunca kodeklerimi zorla eğittim. Birkaç takım kurdum. Sonunda, bu zorlukla yüzleşmeye hazırım. Tüm zehirleyici rakiplerime cevap vermek için, her biri belirli bir rolü olan çok farklı kodlara sahip bir ekip kurdum.


panzehir(Görüntü)

Type : Normal - atk:50 def:100 spd:80 - Poison/Burn/Heal

Panzehir zehiri sever. O kadar ki onu acele etmekten zehir ataklarına engel olamıyorum.


Zen(Görüntü)

Type : Fire - atk:100 def:80 spd:50 - Poison/Vine/Heal

Zen, tüm etkileriyle uyum sağlayan çok şaşırtıcı bir koddur. Düşmanlarının sessizliğine karşı çaba gösterip yormalarını izlemeyi tercih ediyor.


Triforce(Görüntü)

Type : Psychic - atk:88 def:60 spd:82 - Fireball/Watergun/Vine

Triforce her zaman savaşmaya hazır olan klasik bir kodondur. Bu, üç elementi kontrol etmek için psişik gücünü kullanıyor ve mümkün olduğu kadar fazla zarar veriyor.


Takımı buradan indirebilirsiniz:

Linux:

http://dl.free.fr/iHYlmTOQ2

ile başlatmak ./Error310TMR

Pencereler :

http://dl.free.fr/vCyjtqo2s

ile başlatmak ./Error310TMR.exe

Kod tam bir c ++ projesidir. Nasıl yayınlayacağımı bilmiyorum.

$ wc -l src/*
    165 src/BruteForce.cpp
     26 src/BruteForce.h
    349 src/Codemon.cpp
     77 src/Codemon.h
     21 src/Logger.cpp
     35 src/Logger.h
    105 src/NoTimeToExplain.cpp
     27 src/NoTimeToExplain.h
    240 src/Recoverator.cpp
     31 src/Recoverator.h
     26 src/StrManip.cpp
     16 src/StrManip.h
    303 src/Team.cpp
     68 src/Team.h
     88 src/TooManyRedirects.cpp
     24 src/TooManyRedirects.h
     87 src/Unrecoverable.cpp
     27 src/Unrecoverable.h
     59 src/enums.cpp
    119 src/enums.h
     68 src/main.cpp
   1961 total

Ancak bu çok etkilidir:

------- Final Results -------

176     Error310TMR
131     H3C
130     LittleKid
121     Nodemon
58      InsideYourHead
47      HardenedTrio
37      BitterRivals

2

Peri masalı

Oldukça genel bir yol ortasında takımı. Kendi işini yapmaya çalışan üç arketipten yola çıkıp, kendi işlerini yapamıyorlarsa, bunu değiştir.

Bu takım, yeni meta zehir gibi görünmeden önce yaratılmıştı, ilk başta yaptığımdan beri takımımı değiştirmekle yetinmiyordum, çoğu zaman sadece ayrıştırmayı denemek için harcadım. Turnuvayı test etmek için henüz çalıştıramadım, ancak oldukça yoğun bir hafta oldu. Bu aslında benim test verilerimle göründüğü gibi çalışmıyorsa, işten sonra biraz daha parlaklık uygulayacağım.

#!/bin/perl
use 5.20.0;
use strict;

use constant MINE => 0;
use constant THEIRS => 1;

$_ = $ARGV[0];

if(/^T/){
    say 'FairyTale|Fairy:1:89:90:51:3:4:13|Dragon:2:100:50:80:6:1:8|Assassin:0:70:60:100:0:1:10';

} elsif(/^C#(.*)/){
    my $state = readBattleState($1);
    if($state->[MINE]->{$state->[MINE]->{slot}}{hp}){
        say $state->[MINE]->{slot};
    } elsif($state->[MINE]->{($state->[MINE]->{slot}+1)%3}{hp}){
        say (($state->[MINE]->{slot}+1)%3);
    } else {
        say (($state->[MINE]->{slot}+2)%3);
    }

} elsif(/^A#(.*)/){
    my $state = readBattleState($1);
    my @actives = (
        $state->[MINE]->{$state->[MINE]->{slot}},
        $state->[THEIRS]->{$state->[THEIRS]->{slot}}
    );
    if($state->[MINE]->{slot} == 0){
        if(!exists($actives[THEIRS]{effects}{4}) && $actives[MINE]{pp}->[1]){
            say 1;
        } elsif(!exists($actives[THEIRS]{effects}{1}) && $actives[MINE]{pp}->[2]) {
            say 2;
        } elsif(!$actives[THEIRS]{type}) {
            if($state->[MINE]->{($state->[MINE]->{slot}+1)%3}{hp} > 0){
                say (($state->[MINE]->{slot}+1)%3);
            } elsif($state->[MINE]->{($state->[MINE]->{slot}+2)%3}{hp} > 0) {
                say (($state->[MINE]->{slot}+2)%3);
            } else {
                say 0;
            }
        } else {
            say 0;
        }
    } elsif($state->[MINE]->{slot} == 1){
        if(!exists($actives[MINE]{effects}{6}) && $actives[MINE]{pp}->[2]){
            say 2;
        } elsif ($actives[MINE]{hp} > 10 && $actives[MINE]{hp} < 50 && $actives[MINE]{pp}->[1]){
            say 1;
        } else {
            say 0;
        }
    } elsif($state->[MINE]->{slot} == 2){
        if(!exists($actives[MINE]{effects}{6}) && $actives[MINE]{pp}->[2]){
            say 2;
        } elsif ($actives[MINE]{hp} > 10 && $actives[MINE]{hp} < 50 && $actives[MINE]{pp}->[1]){
            say 1;
        } elsif($actives[THEIRS]{type} == 1) {
            if($state->[MINE]->{($state->[MINE]->{slot}+1)%3}{hp} > 0){
                say (($state->[MINE]->{slot}+1)%3);
            } elsif($state->[MINE]->{($state->[MINE]->{slot}+2)%3}{hp} > 0) {
                say (($state->[MINE]->{slot}+2)%3);
            } else {
                say 0;
            }
        } else {
            say 0;
        }
    }

} elsif(/^B#(.*)/){
    my $state = readTeam($1, 1);
    say '1:0:2';
}

sub readBattleState {
    local $_ = $_[0];
    if(/^(.*?)#(.*?)$/){
        my @teams;
        $teams[0] = readTeam($1, 1);
        $teams[1] = readTeam($2, 0);
        return \@teams;
    }
}

sub readTeam {
    my $isMine = $_[1];
    local $_ = $_[0];
    if(/.*?:(?<slot>.*?)\|(.*?)\|(.*?)\|(.*?)$/){
        my %team;
        $team{slot} = $1;
        $team{0} = $isMine ? readYourMember($2) : readTheirMember($2);
        $team{1} = $isMine ? readYourMember($3) : readTheirMember($3);
        $team{2} = $isMine ? readYourMember($4) : readTheirMember($4);
        return \%team;
    }
    return 0;
}

sub readYourMember {
    local $_ = $_[0];
    if(/(?<name>.*?):(?<id>.*?):(?<atk>.*?):(?<def>.*?):(?<spd>.*?):(?<hp>.*?):(?<type>.*?):(?<poison>.*?):(?<move0>.*?):(?<move1>.*?):(?<move2>.*?):(?<batk>.*?):(?<bdef>.*?):(?<bspd>.*?)(?<effects>(?::.*)|$)/){
        my %effects = map { $_ => 1 } readEffects($+{effects});
        my %member = (
            name   => $+{name},
            id     => $+{id},
            hp     => $+{hp},
            atk    => $+{atk}+$+{batk},
            def    => $+{def}+$+{bdef},
            spd    => $+{spd}+$+{bspd},
            type   => $+{type},
            pp     => [$+{move0}, $+{move1}, $+{move2}],
            poistrn=> $+{poison},
            effects=> \%effects
        );
        return \%member;
    }
}

sub readTheirMember {
    local $_ = $_[0];
    if(/(?<name>.*?):(?<id>.*?):(?<atk>.*?):(?<def>.*?):(?<spd>.*?):(?<hp>.*?):(?<type>.*?):(?<poison>.*?)(?<effects>(?::.*)|$)/){
        my %effects = map { $_ => 1 } readEffects($+{effects});
        my %member = (
            name   => $+{name},
            id     => $+{id},
            hp     => $+{hp},
            atk    => $+{atk},
            def    => $+{def},
            spd    => $+{spd},
            type   => $+{type},
            poistrn=> $+{poison},
            effects=> \%effects
        );
        return \%member;
    }
    return 0;
}

sub readEffects {
    local $_ = $_[0];
    my @retval = /:([^:]*)/g;
    if(!@retval){
        @retval = (0);
    }
    return @retval;
}

İle koş

perl fairytale.pl

İlk bottan sonra ölen üyelerin 'aktif' seçilmesinden dolayı bu bot atıldı. Görebildiğim ilk savaşı asla geçemez.
Geobits

Gerçekten mi? Bu hatanın daha önce işe
yattığını sanıyordum

Unutmayın, bir mahkum yıkıldığında, sağlık noktalarının 0 veya daha az azaldığını unutmayın . Yani if($state->[MINE]->{$state->[MINE]->{slot}}{hp})ifade olmadan doğru çalışmaz >0.
GholGoth21

Ah, evet, bu işe yarar.
mezzoEmrys

0

Kukla Takımı - Java

(rakip olmayan CW)

Bu üzerinde çalışılacak aptal bir ekip. Hepsi her turda hamleleri arasında rasgele seçim yapan (Yumruk, İyileşme, Yavaş) olan normal tiplerdir. Bununla iyi eğlenceler.

public class DummyTeam {

    public static void main(String[] args) {
        if(args.length < 1){
            System.out.println("You need to run this from the tournament. Try to keep up.");
            System.exit(0);
        }

        String[] sections = args[0].split("#");
        String out = "";
        switch(sections[0]){
            // team data
            //      sends back all Normal types with minimum stats and Normal moves (randomized name suffixes to distinguish in tests)
            case "T":
                out = "DummyTeam";
                for(int i=0;i<3;i++)
                    out += "|Dummy"+((char)(Math.random()*26)+65) + i + ":0:50:50:50:0:1:2";
                break;
            // bonus points
            //      shoves them all in defense every time
            case "B":
                out = "1:1:1";
                break;
            // choose active
            //      picks last active if alive, otherwise loops to find first living member
            case "C":
                String[] team = sections[1].split("\\|");
                int current = Integer.parseInt(team[0].split(":")[1]);
                if(Integer.parseInt(team[current+1].split(":")[5]) > 0){
                    out = current + "";
                } else {
                    for(int i=1;i<team.length;i++){
                        if(Integer.parseInt(team[i].split(":")[5]) > 0){
                            out = (i - 1) + "";
                        }
                    }
                }               
                break;
            // choose action
            //      chooses a random move. does not check if it ran out of uses, so wastes turns quite often
            case "A":
                out = ((int)(Math.random()*3)) + "";
                break;
            default:
                out = "Invalid query from controller.";             
        }
        System.out.println(out);
    }


}
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.