KOTH: Savaşan Kasabalar


22

Nihai sonuçlar burada!

Giriş

Bu oyun Manu'nın Town of Town oyunundan ilham alıyor . Kılıç ve sihir dünyasında gerçekleşir. Bütün kıtayı yöneten kral az önce öldü ve birçok şehir devletinin efendileri şimdi bölge üzerinde savaşıyor. Sizler bu lordlardan birisiniz ve amacınız her şehri ele geçirmek ve yönetmek.

Prensip

İnsanlar 8 sınıfa ayrılır :

Warlocks : Fighter (magic)
Crusaders : Fighter (melee)
Amazons : Fighter (range)
Corsairs : Utility (steal, guard, transport)
Bishops : Utility (convert, exorcize)
Necromancers : Utility (resurrect)
Architects : Utility (build)
Peons : Resource (income, recruits)

Oyun başladığında, bir kasabayı yönetiyorsun. Her kasabada 100 kişi var . Onları bu 8 kategori arasında bölmelisin.

Sonra asıl oyun sırayla başlar. Bir dönüş , 7'si etkileşimli olan 12 aşamadan oluşur ( komut istemek için botlar isteyin). Bir sonraki aşama, önceki aşama her kasaba tarafından gerçekleştirildiğinde başlar (Faz 1: Kasaba 1, Kasaba 2, Kasaba 3 ...; Faz 2: Kasaba 1, Kasaba 2, Kasaba 3 ...):

1. Raise Taxes                              - AUTOMATED 
2. Steal Money                              - INTERACTIVE
3. Recruit Troops                           - INTERACTIVE
4. Pay Wages                                - AUTOMATED
5. Try Revolt                               - AUTOMATED
6. Convert Soldiers                         - INTERACTIVE
7. Attack Town                              - INTERACTIVE
8. Raise Corpses                            - INTERACTIVE
9. Move Army or Tribute                     - INTERACTIVE
10. Defend against Threats                  - AUTOMATED
11. Construct Buildings                     - INTERACTIVE
12. Make Children                           - AUTOMATED

Denetleyici size komut argümanları üzerinden girdi sağlar, programınızın stdout üzerinden çıktı vermesi gerekir.

Sözdizimi

Çıktı (hazırlık)
Oyun başlamadan önce, kontrol birimi tartışmasız gönderiminizi başlatır. Bu, 100 kişiyi 8 kategoriye ayırman gerektiği anlamına geliyor.

Çıktı yapmanız gerekir: Warlocks Crusaders Amazons Corsairs Bishops Necromancers Architects Peons

Örneğin: 15 10 12 10 7 5 1 40.

Her kasaba da 500 altın ve 5 cesetle başlıyor.

Girdi
Programınız her çağrıldığında, bu biçimde argümanlar alacak:Round;Phase;YourPlayerId;YourTownId;PlayerId_TownId_Gold_Corpses_Warlocks_Crusaders_Amazons_Corsairs_Bishops_Necromances_Architects_Peons_Temples_Barracks_Estates_Palaces;PlayerId_TownId_Gold_Corpses_Warlocks_Crusaders_Amazons_Corsairs_Bishops_Necromances_Architects_Peons_Temples_Barracks_Estates_Palaces;...

Örnek giriş 1;2;1;1;0_0_600_5_15_10_12_10_7_5_1_40_0_0_0_0;1_1_700_5_15_10_12_10_7_5_1_40_0_1_0_2;...

Burada 1. raunt olduğunu görüyorsunuz, 2. etapta 1. kasabada 1. sıradasınız. 700 altın, 5 ceset, 15 büyücü, 10 haçlı, 12 Amazon, 10 corsair, 7 piskopos, 5 büyücü, 1 mimar, 40 piyon, 0 tapınak, 1 kışla, 0 mülk ve 2 saray.

Çıktı

Oynamaya bak.

Oynanış

Tüm aşamalar

Komut W = BEKLE

Geçersiz komut = BEKLE

Aşama 1: Vergileri Yükseltme

Gelir, nüfusunuza ve tamamladığınız binalara göre üretilir:

+5 gold * Peons
+2 gold * (Warlocks + Bishops + Necromancers) * TEMPLES
+2 gold * (Crusaders + Amazons) * BARRACKS
+2 gold * (Corsairs + Peons) * ESTATES
+10 gold * PALACES

2. Aşama: Para Çalmak

Bu aşamada, bir kasabadan Corsairs göndererek para çalabilirsiniz. Her Corsair, 10 kadar altın çalabilir (yani 12 Corsair, 120 kadar altın çalabilir). Hedef kasabada yeterince altın yoksa, korsanların azami borç tutarına kadar her şeyi çalacak: 200 altın . Sahip olduğunuzdan daha fazla Corsairs göndermeye çalışırsanız, program mevcut tüm Corsairs'lerinizi kullanır.

Komut sözdizimi :S DestinationId Corsairs

Faz 3: Asker Birlikleri

Burada, biraz altın harcayarak piyonlarınızı eğitebilirsiniz. Yeterli sayıda piyon ve altının olduğu sürece istediğin kadar birim alabilirsin. Gerektiğinden daha fazlasını işe almaya çalışırsan, her şey harcanana kadar oyun rastgele işe başlar. Program, maksimum kotalarınıza saygı duyuyor (yalnızca 8 piyon ile 10 haçlı ve 5 haraç toplamaya çalışırsanız, örneğin 6 haçlı ve 2 haydut toplayacak), örneğin 8 haydut veya 8 büyücü değil.

Warlock :       10 gold
Crusader :      10 gold
Amazon :        10 gold
Corsair :       12 gold 
Bishop :        20 gold
Necromancer :   20 gold
Architect :     15 gold

Komut sözdizimi :R Warlocks Crusaders Amazons Corsairs Bishops Necromancers Architects

Aşama 4: Ücretlerin Ödenmesi

Maaşlar popülasyonunuza göre borçlandırılır:

-1 gold * (Warlock + Crusaders + Amazons)
-2 gold * (Corsairs + Bishops + Necromancers + Architects)

Aşama 5: İsyanı Dene

Bakiyeniz negatiftirse, şehrinizin kontrolünü Kanun Hukuku'na bırakmış olursunuz . Bir isyandan sonra, kasabanın altınları başlangıç ​​değerine sıfırlanır: 500 altın . Nüfus şu anki seviyelerinde tutulur.

Aşama 6: Askerleri Dönüştür

Piskoposlarınızın her biri 1 düşman askerini (Warlock, Haçlı veya Amazon) seçilen bir kasabadan birim başına 50 altın ücret karşılığında dönüştürebilir. Dönüştürülen birimler kasabanızda bulunan kuvvetlere katılır. İşe alımlarda olduğu gibi, yeterli altın veya piskoposunuz yoksa, program kotaları gözetirken rastgele dönüşecektir.

Komut sözdizimi :C DestinationId Warlocks Crusaders Amazons

Aşama 7: Saldırı Şehri

Bir Kasabayı ele geçirmek için Warlock, Haçlı ve Amazon ordusunu gönderebilirsin. Sizden daha fazlasını göndermeye çalışırsanız, program herkesi gönderir.

Askerler bu düzeni izleyen 1.5 savaş bonusuna sahipler : Mage > Range > Melee > Mage(örneğin, Amazon savaşan bir Warlock 1,5 güç kazanıyor). Yalnızca fazla olan birimler bu bonusu alır (yani, bir Warlock ve bir Amazon ile savaşan bir Warlock bu bonusu alamaz). Bonus, hem saldırı hem de savunma ile ilişkilendirilir.

Kayıplar, kazananın toplam gücüne göre kazananın birimleri arasında rastgele dağıtılır (yani, Saldırı gücü: 12'ye göre, Savunma gücü: 14, Savunma, 12 birimi kaybeder ve kaybeder). Gevşek, tüm birimlerini gevşetir. Her ölü birim, saldırıya uğrayan kasabanın ceset sayımına eklendi. Suç kazanırsa, şehir yakalanır ve şimdi saldırganın mülkiyetidir. Ayrıca bu kasabada bulunan altınları, cesetleri ve piyonları tutar. Korsanlar, Piskoposlar, Nekromancılar ve Mimarlar potansiyel baskının önüne kaçıyorlar.

Savunma hiçbir şey almaz.

Komut sözdizimi :A DestinationId Warlocks Crusaders Amazons

Aşama 8: Cesetleri Yükseltmek

Büyücülerinizin her biri, ceset tüketip altın harcayarak 5 piyona kadar diriltebilir. Dirilen her Piyonun bedeli 1 ceset ve 20 altındır. Yapabildiğinizden daha fazla diriltmeye çalışırsanız, program sahip olduğunuz her şeyi harcayacaktır.

Komut sözdizimi :R Corpses

Aşama 9: Orduyu veya Vergi Hareketi

Birimleri başka bir şehre gönderebilirsiniz. Sizden daha fazlasını göndermeye çalışırsanız, program herkesi gönderir.

Komut sözdizimi :M DestinationId Warlocks Crusaders Amazons Corsairs Bishops Necromancers Architects

Veya, Corsairs'in gemilerini kiralayarak altın gönderebilirsiniz. Her bir korsan 200 adede kadar altın taşıyabilir . Elinizden daha fazlasını göndermeye çalışırsanız, program elinizde olanları gönderecektir.

Komut sözdizimi :T DestinationId Gold

Aşama 10: Tehditlere Karşı Savunma

Birkaç tehdit tehdidi kasabanıza zarar verir:

  • Zombiler: Ölüler her zaman göründükleri kadar ölü değildir. Kasabanızdaki cesetlerin% 10'u (zeminli) uyanacak ve beyinleri yiyecektir. Her zombi 1 Peon yiyecek ve daha sonra hiçlik içinde dolaşacak (Zombilerin ve Yenilen Peon'ların cesetleri tüketilir).
  • İblisler: Piyonların vaaz duymaları gerekir, yoksa Karanlık Ruhları çağırmaya başlarlar. Piskoposunun her biri 50 Piyona kadar olan ihtiyaçları karşılar. Heretiklerinin% 10'u (zemini) (Aşırı Piyonlar) Şeytanlar'ı doğuracak. Şeytanlar her biri 1 Peon öldürür ve cehenneme geri döner (Peon'ların cesetleri kasaba sayısına eklenir).
  • Haydutlar: Kanunlar mahallede ikamet ediyor. Toplam haydutların nüfusu eşit olarak şehirler arasında bölünmüş ve serveti çalmaya gönderilmiştir. Tek savunmanız Corsairs devriyeleriniz. Her bir korsan 5 yasadışıya kadar durabilir. Durdurulamayan her kanun kaçağı şehrinizden 10 altın çalıyor (azami şehir borcu 200 altın)

Oyunun başında en az 1 şehir dışında (100 kişilik nüfus), sonra her 5 oyuncu için 1 tane daha üretilir (örn. 1-4 Oyuncular: 1 Salgın, 5-9 Oyuncular: 2 Salgın ...). Haydutlar ile tanınabilirid = -1

Aşama 11: Yapı Kurma

Bu aşamaya geldiğinizde, şehrinizdeki binaların inşaatı Mimar sayısına göre ilerledi. Her Mimar, tek bir binanın tamamlanmasını% 8 arttırır. Bir Bina% 100'e ulaştığında, tamamlanır ve bir sonraki "Vergiler" Aşamasında gelir elde etmeye başlar. İnşaat kuyruğu otomatik olarak yönetilir (ilk gelenin önce gelmesi gerekir).

Daha sonra diğer Binaların inşaatına da başlayabilirsiniz (BuildingId = Parantez içindeki harf):

TEMPLE (T) :        200 Gold
BARRACKS (B) :      200 Gold
ESTATE (E) :        200 Gold
PALACE (P) :        500 Gold

İstediğiniz sayıda Binanın inşaatına başlayabilirsiniz ve eğer yeterli altınınız yoksa, Bina yoksayılır. Yeni Binalarınızın inşaatı sadece bir sonraki tura başlayacaktır.

Komut sözdizimi :B BuildingId BuildingId BuildingId ...

Aşama 12: Çocuk Yap

Her beş turda (5., 10., 15. ...), yeni Piyonlar doğacak ve savaşmaya hazır olacak. Her Şakayık çifti 1 Peon yapar (yani, 23 Piyon 11 yeni Piyon üretir).

kurallar

  • Botlar, belirli diğer botları yenmek veya desteklemek için yazılmamalıdır.
  • Dosyalara yazma izin verilir. Lütfen "yoursubmissionname.txt" yazınız, oyun başlamadan önce klasör boşaltılacaktır. Diğer dış kaynaklara izin verilmez.
  • Gönderinizin yanıt vermesi için 1 saniye kaldı (şehir başına).
  • Gönderilerinizi derlemek ve çalıştırmak için komutlar verin.

Kazanan

Kazanan, 100 turdan sonra en fazla kasabaya sahip olanıdır. Bir oyuncu bütün kasabaları yakalarsa oyun durur ve kazanır. Eğer birden fazla oyuncu aynı miktarda kasabaya sahipse, toplam popülasyon sayılır, ardından altın miktarı.

kontrolör

Kontrol cihazını github'da bulabilirsiniz. Ayrıca, Java ile yazılmış 2 örnekleme çubuğu içerir. Eclipse'de açın, derlenmiş botları kök klasöre yerleştirin ve kontrol programına bir sınıf ekleyin (tıpkı örnek çizimleri gibi).

kavgalar

Mücadele formülü şöyle bir şeydir:

Her asker sınıfı için (Warlock, Haçlı, Amazon):

  • Suç ve savunma arasındaki dengeyi hesaplayın (örneğin, her sınıftan kim daha fazla ve kaç tane daha?)
  • Aşırı askerler için (yani, pozitif dengenin değeri), kaç tane “zayıf hedef” olduğuna bakın (bkz. Faz 7 diyagramı).
  • Uygun askerleri (yani "aşırı askerler" ile karşılaştırıldığında "zayıf hedefler") ile ikramiye ile çarpma kuvvetini artırın ve gerisini 1 savaş gücü ile ekleyin.

Buradan bir simülatör deneyebilirsiniz: http://ideone.com/ArJosE (sadece askerlerin değerlerini değiştir, ikramiye ve toplam güç elde edersin)

İşte birkaç test durumu:

Attack      Defense     A. Bonus    D. Bonus   A. Str      D. Str    Winner
20/10/0     12/12/12    8/0/0       0/2/10     34.0        42.0      Defense
40/0/5      12/12/12    12/0/0      0/12/0     51.0        42.0      Attack
0/60/8      10/30/2     0/10/6      8/0/0      76.0        46.0      Attack
20/20/40    90/5/5      0/15/5      40/0/0     90.0        120.0     Defense

Nihai sonuçlar

10 oyunun ortalaması. Sözdizimi:Player(Towns, Population, Gold)

1. Opportunist(6.4, 4165, 2895626)
2. Politician(6.4, 1048, 42542)
3. Outlaw(2.8, 1575, 349073)
4. YoungEarl(0.4, 3424, 941624)
5. Aegis(0, 0, 0)
 . Butter(0, 0, 0)
 . Commander(0, 0, 0)
 . Lannister(0, 0, 0)
 . Machiaveli(0, 0, 0)
 . Monarch(0, 0, 0)
 . Serenity(0, 0, 0)
 . Sehtimianer(0, 0, 0)
 . Sleeper(0, 0, 0)
 . Zealots(0, 0, 0)

10 oyunun sonuçları: http://pastebin.com/GdufEYjm

2 oyunun günlükleri tamamlandı: http://pastebin.com/GQDZ0JdY & http://pastebin.com/m3UBTDuC

Herkese iyi oynadım, Politikacı ve Muhalifler arasındaki kavga çok yakındı.


Oyuncu etkileşimi sayısını artırarak, stratejilerde çeşitlilik görmeyi umuyorum. Bununla birlikte, basit bir bot çok az sayıda hatta elde edilebilir.
Thrax

The total Outlaws population is divided equitably between towns and sent to steal wealth.Toplam kaç tane haydut var?
MegaTom

@ MegaTorn Başlangıçta, her birinde 5 oyuncu (en az 1) ve birer kişi olmak üzere 100 kişi için bir Outlaws şehri var. Daha sonra oyun ilerledikçe, Outlaws isyanlardan görünebilir veya diğer oyuncular tarafından öldürülebilir.
Thrax

Rakip bir kasabada kaç bina olduğunu nasıl bilebiliriz? denetleyici bu bilgiyi göndermiyor gibi görünüyor. Bu, başarılı bir saldırının gerçekten ücret ödeyememe ve derhal şehri bir devrime
gevşetme ihtimaline yol açıp açamayacağına

Bir kasaba 5. aşamaya düştüğünde, diğer oyuncu kasabaları bu şehri ele geçirebilir mi? Öyleyse, nüfus sınıfı tipleri korunuyor mu? örneğin: Warlocks, Haçlılar, Amazonlar'da 20/20/40 savaşçıları varsa, o şehri almak için savaşmanız gereken şey bu mu?
Mantık Şövalyesi

Yanıtlar:


8

Fırsatçı, Java v2

Kendilerini sunarken fırsat bulmaya çalışır ... ama oyunun sonunda hiçbiri kendini göstermiyorsa (ve hala çekişiyorsa), o zaman tümüyle dışarı çıkar.

güncelleyin:

Durron597'nin fikirlerinden bazılarını birleştirdi. Şimdi, en güçlü rakibin gücünü tamamen dönüştürebildiğinde piskoposları işe almayı bırakıp, asker satın almaya odaklanıyor.

Ayrıca v1, başlangıç ​​popülasyonunun yayılmasının 100'e kadar eklemediği bir başlangıç ​​engeline sahipti ... sadece 98!

package moogiesoft;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

public class Opportunist  {

private static final float FIGHTING_BONUS = 1.5f;
public static final int GOLD_PER_PEON = 5;
public static final int GOLD_PER_TEMPLE = 2;
public static final int GOLD_PER_BARRACKS = 2;
public static final int GOLD_PER_ESTATE = 2;
public static final int GOLD_PER_PALACE = 10;
private static final int CONVERSION_COST = 50;
private static final int GOLD_PER_STEAL = 10;
private static final int GOLD_MAX_DEBT = 200;
private static final int CORSAIR_COST = 12;
private static final int BISHOP_COST = 20;
private static final int ARCHITECT_COST = 15;
private static final int BARRACKS_COST = 200;
private static final int MILITARY_COST = 10;

int round;
int phase;
int playerID;
int thisTownID;


List<Town> towns;
List<Town> myTowns;
List<Town> otherTowns;
List<Town> otherNonOutlawTowns;
List<Town> otherOutlawTowns;

Town thisTown;

public static void main(String[] args){
    if (args.length == 0) {
        System.out.println("8 8 9 22 8 0 13 32");
    } else {
        new Opportunist().respond(args[0].split(";"));
    }
}

private void respond(String[] args) {

    round = Integer.parseInt(args[0]);
    phase = Integer.parseInt(args[1]);
    playerID = Integer.parseInt(args[2]);
    thisTownID = Integer.parseInt(args[3]);

    towns = new ArrayList<>();
    myTowns = new ArrayList<>();
    otherTowns = new ArrayList<>();
    otherNonOutlawTowns= new ArrayList<>();
    otherOutlawTowns= new ArrayList<>();

    for (int i = 4; i < args.length; i++){
        towns.add(new Town(args[i]));
    }

    for (Town town : towns){
        if (town.isMine()){
            myTowns.add(town);
            if (town.isThisTown()){
                thisTown = town;
            }
        } else {
            otherTowns.add(town);
            if (town.getOwnerId()!=-1)
            {
                otherNonOutlawTowns.add(town);
            }
            else
            {
                otherOutlawTowns.add(town);
            }
        }
    }


    switch (phase)
    {
        case 2: steal(); break;
        case 3: recruit(); break;
        case 6: convert(); break;
        case 7: attack(); break;
        case 8: resurrect(); break;
        case 9: move(); break;
        case 11: build(); break;
        default: System.out.println("W"); break;
    }
}

private void steal() {
    ArrayList<Town> architectSoldierSortedNonOutlawTowns = new ArrayList<>(otherNonOutlawTowns);
    architectSoldierSortedNonOutlawTowns.sort((a,b)->b.getArchitects()-a.getArchitects()==0?a.getSoldiers()-b.getSoldiers():b.getArchitects()-a.getArchitects());
    Town targetTown =null;
    int targetTownStolenGold = 0;

    // Try to steal from the towns that have the most architects as they are the long term threat.
    for (Town town : architectSoldierSortedNonOutlawTowns)
    {
        if (estimateProceedsOfTheft(town,thisTown)>thisTown.calculateTaxes())
        {
              targetTown=town;
              break;
        }
    }

    // see if we can cause revolution in any non outlaw towns or if the target proceeds of theft is not sufficent to support this town...
    if (targetTown==null || estimateProceedsOfTheft(targetTown,thisTown)+thisTown.calculateTaxes()<thisTown.calculateSalary()*2)
    {
        for (Town town : otherNonOutlawTowns)
        {

            if (town.getGold()-town.calculateSalary()-thisTown.getCorsairs()*GOLD_PER_STEAL<0)
            {
               int stolenGold = estimateProceedsOfTheft(town,thisTown);
               if (stolenGold>targetTownStolenGold)
               {
                   targetTownStolenGold=stolenGold;
                   targetTown=town;
               }
            }

        }
    }

    // just pick the strongest opponent
    if (targetTown==null && round<5)
    {
        targetTown = otherNonOutlawTowns.stream().max((a,b) -> a.getSoldiers() - b.getSoldiers()).orElse(null);
    }

    // or if the target proceeds of theft is not sufficent to support this town... select the non outlaw town with the most gold!
    if (targetTown==null || estimateProceedsOfTheft(targetTown,thisTown)+thisTown.calculateTaxes()<thisTown.calculateSalary()*2)
    {
        targetTown = otherNonOutlawTowns.stream().max((a,b) -> a.gold - b.gold).orElse(null);
    }

    // otherwise just pick the outlaw town with the most gold.
    if (targetTown==null)
    {
        targetTown = otherTowns.stream().max((a,b) -> a.gold - b.gold).orElse(null);
    }

    System.out.println("S " + targetTown.getId() + " " + thisTown.getCorsairs());

}

private void recruit() {
    Town strongestTown=otherTowns.stream().max((a,b)->a.getSoldiers()-b.getSoldiers()).orElse(null);
    Town mostRepoductiveTown=otherTowns.stream().max((a,b)->a.getPeons()-b.getPeons()).orElse(null);

    int originalNoOfPeonsAvailableToConvert = 0;
    boolean recruitSoldiers=true;
    // last round... no point in keeping any peons... make them soldiers. 
    if (round==100)
    {
        originalNoOfPeonsAvailableToConvert = thisTown.getPeons();
    }
    // looks like our bishops can recruit the full force of the strongest enemy... so lets just recruit soldiers.
    else if (strongestTown!=null && strongestTown.getSoldiers()<thisTown.getBishops())
    {
        originalNoOfPeonsAvailableToConvert = thisTown.getPeons()-mostRepoductiveTown.getPeons();
    }
    // ok so we need more bishops...
    else if (round>5)
    {
        recruitSoldiers=false;
        originalNoOfPeonsAvailableToConvert = thisTown.getPeons()/10;
    }

    int amazonRecruit = 0;
    int crusaderRecruit = 0;
    int warlockRecruit = 0;
    int bishopRecruit = 0;
    int corsairRecruit = 0;
    int architectRecruit = 0;

    while (originalNoOfPeonsAvailableToConvert>0)
    {
        int noOfPeonsAvailableToConvert=originalNoOfPeonsAvailableToConvert;
        int recruitsLeft;
        do
        {
            recruitsLeft=noOfPeonsAvailableToConvert;

            if (recruitSoldiers)
            {
                if (noOfPeonsAvailableToConvert-->0) amazonRecruit++;
                if (noOfPeonsAvailableToConvert-->0) crusaderRecruit++;
                if (noOfPeonsAvailableToConvert-->0) warlockRecruit++;
            }
            // see if we want to recruit more bishops...
            else if (thisTown.getBishops()<(round<30?Math.pow(2,round/4):thisTown.getPeons()-50))
            {
               if (noOfPeonsAvailableToConvert-->0) bishopRecruit++;
            }
        } while (noOfPeonsAvailableToConvert>0 && noOfPeonsAvailableToConvert!=recruitsLeft);

        noOfPeonsAvailableToConvert = noOfPeonsAvailableToConvert<0?0:noOfPeonsAvailableToConvert;
        Town simulatedTown = new Town(thisTown);
        simulatedTown.setPeons(thisTown.getPeons()-(originalNoOfPeonsAvailableToConvert-noOfPeonsAvailableToConvert));
        simulatedTown.setAmazons(simulatedTown.getAmazons()+amazonRecruit);
        simulatedTown.setCrusaders(simulatedTown.getCrusaders()+crusaderRecruit);
        simulatedTown.setWarlocks(simulatedTown.getWarlocks()+warlockRecruit);
        simulatedTown.setBishops(simulatedTown.getWarlocks()+bishopRecruit);
        simulatedTown.setCorsairs(simulatedTown.getWarlocks()+corsairRecruit);
        simulatedTown.setArchitects(simulatedTown.getWarlocks()+architectRecruit);
        simulatedTown.setGold(simulatedTown.getGold()-amazonRecruit*MILITARY_COST
                                                     -crusaderRecruit*MILITARY_COST
                                                     -warlockRecruit*MILITARY_COST
                                                     -bishopRecruit*BISHOP_COST
                                                     -corsairRecruit*CORSAIR_COST
                                                     -architectRecruit*ARCHITECT_COST
                                                     -BARRACKS_COST // aways have enough to build a building!
                                                     );

        // ensure that we can afford (both now and in the future) to recruit this number of bishops...
        if (estimateProceedsOfTheft(thisTown) + simulatedTown.calculateTaxes()-simulatedTown.calculateSalary()>0 && simulatedTown.getGold()>simulatedTown.calculateSalary())
            break;
        originalNoOfPeonsAvailableToConvert--;
    }

    System.out.println("R " + warlockRecruit + " " + crusaderRecruit + " " + amazonRecruit + " " + corsairRecruit + " " + bishopRecruit + " 0 " + architectRecruit);
}

private void convert() {
    int currentGold = thisTown.getGold();
    int futureTaxGeneration = thisTown.calculateTaxes();
    int futureSalaryCost = thisTown.calculateSalary();
    int futureProceedsOfCrime = estimateProceedsOfTheft(thisTown);
    int futureCashFlow = futureTaxGeneration+futureProceedsOfCrime-futureSalaryCost;
    int goldAvailableToSpend = currentGold-=BARRACKS_COST;

    if (goldAvailableToSpend>CONVERSION_COST && futureCashFlow>0)
    {
        Town strongestTown = null;

        // sort towns by architects and then soldiers...
        ArrayList<Town> architectSoldierSortedNonOutlawTowns = new ArrayList<>(otherNonOutlawTowns);
        architectSoldierSortedNonOutlawTowns.sort((a,b)->b.getArchitects()-a.getArchitects()==0?a.getSoldiers()-b.getSoldiers():b.getArchitects()-a.getArchitects());
        for (Town town :architectSoldierSortedNonOutlawTowns)
        {
            // if we could use all our bishops...then we shall target this town...
            if (town.getSoldiers()-thisTown.getBishops()>0)
            {
                strongestTown =town;
                break;
            }
        }

        // no town targeted... select the town with the most soldiers then.
        if (strongestTown == null)
        {
            strongestTown = findStrongestTownThatCanDefeatGivenTown(thisTown);
        }

        if (strongestTown == null)
        {
            // this town is already surpreme! lets see if we can be fivolous and attempt to convert anyway...
            if (thisTown.getGold()>thisTown.calculateSalary()*2)
            {
                strongestTown=otherNonOutlawTowns.stream().max((a,b)->a.getSoldiers()-b.getSoldiers()).orElse(null);
            }
        }

        // no town targeted... select the town with the most soldiers then.
        if (strongestTown == null)
        {
            strongestTown=otherTowns.stream().max((a,b)->a.getSoldiers()-b.getSoldiers()).orElse(null);
        }

        // we have selected a town... try to convert from it...
        if (strongestTown != null)
        {
            Town simulatedThisTown = new Town(thisTown);
            int amazonConversionCount=0;
            int warlockConversionCount=0;
            int crusaderConversionCount=0;

            // iterate until we are unable to pay for conversion or unable to support converted forces
            while(true)
            {
                futureTaxGeneration = simulatedThisTown.calculateTaxes();
                futureSalaryCost = simulatedThisTown.calculateSalary();
                futureCashFlow = futureTaxGeneration+futureProceedsOfCrime-futureSalaryCost;

                goldAvailableToSpend-=CONVERSION_COST;

                // see if we can afford to convert another military unit or have run out of bishops to use...
                if (amazonConversionCount+warlockConversionCount+crusaderConversionCount==thisTown.getBishops() || goldAvailableToSpend < 0 || futureCashFlow<0) break;

                // convert a amazon... if any...
                if (strongestTown.getAmazons()>0)
                {
                    amazonConversionCount++;
                    simulatedThisTown.setAmazons(simulatedThisTown.getAmazons()+1);
                    strongestTown.setAmazons(strongestTown.getAmazons()-1);
                }
                // convert a crusader... if any...
                else if (strongestTown.getCrusaders()>0)
                {
                    crusaderConversionCount++;
                    simulatedThisTown.setCrusaders(simulatedThisTown.getCrusaders()+1);
                    strongestTown.setCrusaders(strongestTown.getCrusaders()-1);
                }
                // convert a warlock... if any...
                else if (strongestTown.getWarlocks()>0)
                {
                    warlockConversionCount++;
                    simulatedThisTown.setWarlocks(simulatedThisTown.getWarlocks()+1);
                    strongestTown.setWarlocks(strongestTown.getWarlocks()-1);
                }
                // no more units to convert from the targeted town...
                else
                {
                    break;
                }

            }

            System.out.println("C " + strongestTown.getId() + " " + warlockConversionCount + " " + crusaderConversionCount + " " + amazonConversionCount);
            return;
        }
    }
    System.out.println("W");
}

private void attack() {

    // nearing end game.. lets just attack every thing blindly :P
    if (round>=99)
    {
        for (Town town : towns)
        {
            if (!town.isMine())
            {
                Town simulatedThisTown = new Town(thisTown);
                Town simulatedOtherTown = new Town(town);

                // attempt to attack the opponent with all our soldiers.
                if (battle(simulatedThisTown,simulatedOtherTown,thisTown.getWarlocks(),thisTown.getCrusaders(),thisTown.getAmazons()))
                {
                    System.out.println("A "+ town.getId()+ " " + thisTown.getWarlocks()+ " " + thisTown.getCrusaders()+ " " + thisTown.getAmazons() );
                    return;
                }
            }
        }
    }

    // we should be in a good position... lets try to take over strongest opponent...
    if (round>32)
    {
        Town strongestTown = otherTowns.stream().max((a,b)->a.getSoldiers()-b.getSoldiers()).orElse(null);
        Town simulatedThisTown = new Town(thisTown);
        Town simulatedStrongestTown = new Town(strongestTown);

        int warlockRegiment = thisTown.getWarlocks();
        int crusaderRegiment = thisTown.getCrusaders();
        int amazonRegiment = thisTown.getAmazons();

        List<Town> remainderNonOutLawTowns = new ArrayList<Town>(otherNonOutlawTowns);
        remainderNonOutLawTowns.remove(strongestTown);

        Town nextStrongestTown = remainderNonOutLawTowns.stream().max((a,b)->a.getSoldiers()-b.getSoldiers()).orElse(null);
        boolean firstLoop=true;

        // attempt to attack the strongest opponent with the least number of soldiers possible and still be in a position to likely not succumb to the next strongest opponent.
        while (nextStrongestTown!=null && warlockRegiment+crusaderRegiment+amazonRegiment>0 && battle(simulatedThisTown,simulatedStrongestTown,warlockRegiment,crusaderRegiment,amazonRegiment))
        {

            Town simulatedThisTownAfterWinning = new Town(simulatedThisTown);
            Town simulatedNextStrongestTown = new Town(nextStrongestTown);

            if (nextStrongestTown==null ||
                battle(simulatedNextStrongestTown,simulatedThisTownAfterWinning,
                       simulatedNextStrongestTown.getWarlocks()*2/3,
                       simulatedNextStrongestTown.getCrusaders()*2/3,
                       simulatedNextStrongestTown.getAmazons()*2/3))
            {
                if (firstLoop) break;
                System.out.println("A "+ strongestTown.getId()+ " " + warlockRegiment+ " " + crusaderRegiment+ " " + amazonRegiment );
                return;
            }
            firstLoop=false;
            warlockRegiment-=warlockRegiment>0?1:0;
            crusaderRegiment-=crusaderRegiment>0?1:0;
            amazonRegiment-=amazonRegiment>0?1:0;

            simulatedThisTown = new Town(thisTown);
            simulatedStrongestTown = new Town(strongestTown);
        }

        // it looks like we are in a power deadlock with one other town... lets see if going all out will make us the victor....
        if (otherNonOutlawTowns.size()==1)
        {
            simulatedThisTown = new Town(thisTown);
            Town simulatedRemainingTown = new Town(otherNonOutlawTowns.get(0));

            if (battle(simulatedThisTown,simulatedRemainingTown,thisTown.getWarlocks(),thisTown.getCrusaders(),thisTown.getAmazons()))
            {
                System.out.println("A "+ simulatedRemainingTown.getId()+ " " + thisTown.getWarlocks()+ " " + thisTown.getCrusaders()+ " " + thisTown.getAmazons() );
                return;
            }
        }
    }

    System.out.println("W");
}

private void move() {

    // give half our funds to the most needy town...
    List<Town> poorMyTowns = myTowns.stream().filter(a->a.calculateTaxes()-a.calculateSalary()<0).collect(Collectors.toList());
    if (poorMyTowns.size()>0)
    {
        Town poorTown = poorMyTowns.get(new Random().nextInt(poorMyTowns.size()));

        if (poorTown.getId() != thisTownID)
        {
            System.out.println("T "+poorTown.getId()+ " "+ thisTown.getGold()/2);
            return;
        }
    }

    System.out.println("W");

}

private void resurrect() {
    // zombie shmozies!
    System.out.println("W");
}

private void build() {
    // endevour to always build a barracks or estate (which ever is more lucrative)
    int currentGold = thisTown.getGold();
    int futureTaxGeneration = thisTown.calculateTaxes();
    int futureSalaryCost = thisTown.calculateSalary();
    int futureProceedsOfCrime = estimateProceedsOfTheft(thisTown);
    int futureCashFlow = futureTaxGeneration+futureProceedsOfCrime-futureSalaryCost;
    int goldAvailableToSpend = currentGold;

    if (goldAvailableToSpend>BARRACKS_COST && futureCashFlow>0)
    {
        if (thisTown.getAmazons()+thisTown.getCrusaders()>thisTown.getCorsairs()+thisTown.getPeons())
        {
            System.out.println("B B");
            return;
        }
        else
        {
            System.out.println("B E");
            return;
        }
    }
    System.out.println("W");
}

private class Town  {

    private int ownerId =-1;
    private int id = -1;
    private int gold;
    private int corpses;
    private int warlocks;
    private int crusaders;
    private int amazons;
    private int corsairs;
    private int bishops;
    private int necromancers;
    private int architects;
    private int peons;
    private int temples;
    private int barracks;
    private int estates;
    private int palaces;

    public Town(String string){
        String[] args = string.split("_");
        ownerId = Integer.parseInt(args[0]);
        id = Integer.parseInt(args[1]);
        gold = Integer.parseInt(args[2]);
        corpses = Integer.parseInt(args[3]);
        warlocks = Integer.parseInt(args[4]);
        crusaders = Integer.parseInt(args[5]);
        amazons = Integer.parseInt(args[6]);
        corsairs = Integer.parseInt(args[7]);
        bishops = Integer.parseInt(args[8]);
        necromancers = Integer.parseInt(args[9]);
        architects = Integer.parseInt(args[10]);
        peons = Integer.parseInt(args[11]);
        temples = Integer.parseInt(args[12]);
        barracks = Integer.parseInt(args[13]);
        estates = Integer.parseInt(args[14]);
        palaces = Integer.parseInt(args[15]);
    }

    //Copy constructor
    public Town(Town source)
    {
        this.ownerId=source.ownerId;
        this.id=source.id;
        this.gold=source.gold;
        this.corpses=source.corpses;
        this.warlocks=source.warlocks;
        this.crusaders=source.crusaders;
        this.amazons=source.amazons;
        this.corsairs=source.corsairs;
        this.bishops=source.bishops;
        this.necromancers=source.necromancers;
        this.architects=source.architects;
        this.peons=source.peons;
        this.temples = source.temples;
        this.barracks = source.barracks;
        this.estates = source.estates;
        this.palaces = source.palaces;

    }

    public void setOwnerId(int ownerId)
    {
        this.ownerId = ownerId;
    }

    public void setGold(int gold)
    {
        this.gold = gold;
    }

    public void setCorpses(int corpses)
    {
        this.corpses = corpses;
    }

    public void setWarlocks(int warlocks)
    {
        this.warlocks = warlocks;
    }

    public void setCrusaders(int crusaders)
    {
        this.crusaders = crusaders;
    }

    public void setAmazons(int amazons)
    {
        this.amazons = amazons;
    }

    public void setCorsairs(int corsairs)
    {
        this.corsairs = corsairs;
    }

    public void setBishops(int bishops)
    {
        this.bishops = bishops;
    }

    public void setNecromancers(int necromancers)
    {
        this.necromancers = necromancers;
    }

    public void setArchitects(int architects)
    {
        this.architects = architects;
    }

    public void setPeons(int peons)
    {
        this.peons = peons;
    }

    public int getTemples()
    {
        return temples;
    }

    public int getBarracks()
    {
        return barracks;
    }

    public int getEstates()
    {
        return estates;
    }

    public int getPalaces()
    {
        return palaces;
    }

    public int getOwnerId() {
        return ownerId;
    }

    public int getId() {
        return id;
    }

    public int getGold() {
        return gold;
    }

    public int getCorpses() {
        return corpses;
    }

    public int getWarlocks() {
        return warlocks;
    }

    public int getCrusaders() {
        return crusaders;
    }

    public int getAmazons() {
        return amazons;
    }

    public int getCorsairs() {
        return corsairs;
    }

    public int getBishops() {
        return bishops;
    }

    public int getNecromancers() {
        return necromancers;
    }

    public int getArchitects() {
        return architects;
    }

    public int getPeons() {
        return peons;
    }

    public int getSoldiers() {
        return getWarlocks() + getCrusaders() + getAmazons();
    }

    public boolean isMine(){
        return getOwnerId() == playerID;
    }

    public boolean isThisTown(){
        return id == thisTownID;
    }

    public int calculateSalary()
    {
        return (getWarlocks() + getCrusaders() + getAmazons()) + 2*(getCorsairs()+getBishops()+ getArchitects()+ getNecromancers());
    }

 // algorithm taken from Game.java
    public int calculateTaxes()
    {
        int taxes = 0;
        taxes += (getPeons() * GOLD_PER_PEON);
        taxes += ((getWarlocks() + getBishops() + getNecromancers()) * (getTemples() * GOLD_PER_TEMPLE));
        taxes += ((getCrusaders() + getAmazons()) * (getBarracks() * GOLD_PER_BARRACKS));
        taxes += ((getPeons() + getCorsairs()) * (getEstates() * GOLD_PER_ESTATE));
        taxes += (getPalaces() * GOLD_PER_PALACE);
        return  taxes; 
    }

}

// algorithm taken from Game.java
private boolean battle(Town attackingTown, Town defendingTown, int attackingWarlocks, int attackingCrusaders, int attackingAmazons)
{
    int sourceWarlocks = Math.min(attackingTown.getWarlocks(), Math.max(0, attackingWarlocks));
    int sourceCrusaders = Math.min(attackingTown.getCrusaders(), Math.max(0, attackingCrusaders));
    int sourceAmazons = Math.min(attackingTown.getAmazons(), Math.max(0, attackingAmazons));

    int destinationWarlocks = defendingTown.getWarlocks();
    int destinationCrusaders = defendingTown.getCrusaders();
    int destinationAmazons = defendingTown.getAmazons();

    int sourceWarlocksBalance = Math.max(0, sourceWarlocks - destinationWarlocks);
    int sourceWarlocksBonus = Math.min(sourceWarlocksBalance, destinationAmazons);
    float sourceWarlocksStrength = (sourceWarlocks - sourceWarlocksBonus + (sourceWarlocksBonus * FIGHTING_BONUS));
    int sourceCrusadersBalance = Math.max(0, sourceCrusaders - destinationCrusaders);
    int sourceCrusadersBonus = Math.min(sourceCrusadersBalance, destinationWarlocks);
    float sourceCrusadersStrength = (sourceCrusaders - sourceCrusadersBonus + (sourceCrusadersBonus * FIGHTING_BONUS));
    int sourceAmazonsBalance = Math.max(0, sourceAmazons - destinationAmazons);
    int sourceAmazonsBonus = Math.min(sourceAmazonsBalance, destinationCrusaders);
    float sourceAmazonsStrength = (sourceAmazons - sourceAmazonsBonus + (sourceAmazonsBonus * FIGHTING_BONUS));
    float sourceTotalStrength = sourceWarlocksStrength + sourceCrusadersStrength + sourceAmazonsStrength;

    int destinationWarlocksBalance = Math.max(0, destinationWarlocks - sourceWarlocks);
    int destinationWarlocksBonus = Math.min(destinationWarlocksBalance, sourceAmazons);
    float destinationWarlocksStrength = (destinationWarlocks - destinationWarlocksBonus + (destinationWarlocksBonus * FIGHTING_BONUS));
    int destinationCrusadersBalance = Math.max(0, destinationCrusaders - sourceCrusaders);
    int destinationCrusadersBonus = Math.min(destinationCrusadersBalance, sourceWarlocks);
    float destinationCrusadersStrength = (destinationCrusaders - destinationCrusadersBonus + (destinationCrusadersBonus * FIGHTING_BONUS));
    int destinationAmazonsBalance = Math.max(0, destinationAmazons - sourceAmazons);
    int destinationAmazonsBonus = Math.min(destinationAmazonsBalance, sourceCrusaders);
    float destinationAmazonsStrength = (destinationAmazons - destinationAmazonsBonus + (destinationAmazonsBonus * FIGHTING_BONUS));
    float destinationTotalStrength = destinationWarlocksStrength + destinationCrusadersStrength + destinationAmazonsStrength;


    if (sourceTotalStrength > destinationTotalStrength) {

        RandomNumberGenerator rand = new RandomNumberGenerator();
        int[] limits = new int[3];
        limits[0] = sourceWarlocks;
        limits[1] = sourceCrusaders;
        limits[2] = sourceAmazons;
        int[] losses = rand.genNumberWithLimits((int) Math.ceil(destinationTotalStrength), limits);

        attackingTown.setWarlocks(attackingTown.getWarlocks() - sourceWarlocks);
        attackingTown.setCrusaders(attackingTown.getCrusaders() - sourceCrusaders);
        attackingTown.setAmazons(attackingTown.getAmazons() - sourceAmazons);

        defendingTown.setWarlocks(sourceWarlocks - losses[0]);
        defendingTown.setCrusaders(sourceCrusaders - losses[1]);
        defendingTown.setAmazons(sourceAmazons - losses[2]);
        defendingTown.setCorsairs(0);
        defendingTown.setBishops(0);
        defendingTown.setNecromancers(0);
        defendingTown.setArchitects(0);

        defendingTown.setCorpses(defendingTown.getCorpses() + destinationWarlocks + destinationCrusaders + destinationAmazons + losses[0] + losses[1] + losses[2]);
        defendingTown.setOwnerId(attackingTown.getOwnerId());
        return true;
    } else if (sourceTotalStrength <= destinationTotalStrength) {

        RandomNumberGenerator rand = new RandomNumberGenerator();
        int[] limits = new int[3];
        limits[0] = destinationWarlocks;
        limits[1] = destinationCrusaders;
        limits[2] = destinationAmazons;
        int[] losses = rand.genNumberWithLimits((int) Math.ceil(sourceTotalStrength), limits);

        attackingTown.setWarlocks(attackingTown.getWarlocks() - sourceWarlocks);
        attackingTown.setCrusaders(attackingTown.getCrusaders() - sourceCrusaders);
        attackingTown.setAmazons(attackingTown.getAmazons() - sourceAmazons);

        defendingTown.setWarlocks(destinationWarlocks - losses[0]);
        defendingTown.setCrusaders(destinationCrusaders - losses[1]);
        defendingTown.setAmazons(destinationAmazons - losses[2]);

        defendingTown.setCorpses(defendingTown.getCorpses() + sourceWarlocks + sourceCrusaders + sourceAmazons + losses[0] + losses[1] + losses[2]);
    }
    return false;

}

/**
 * Taken from Game.java
 *
 * Generate N random numbers when their SUM is known
 *
 * @author Deepak Azad
 */

public class RandomNumberGenerator  {

    public int[] genNumbers(int n, int sum){
        int[] nums = new int[n];
        int upperbound = Long.valueOf(Math.round(sum*1.0/n)).intValue();
        int offset = Long.valueOf(Math.round(0.5*upperbound)).intValue();

        int cursum = 0;
        Random random = new Random(new Random().nextInt());
        for(int i=0 ; i < n ; i++){
            int rand = random.nextInt(upperbound) + offset;
            if( cursum + rand > sum || i == n - 1) {
                rand = sum - cursum;
            }
            cursum += rand;
            nums[i]=rand;
            if(cursum == sum){
                break;
            }
        }
        return nums;
    }

    public int[] genNumberWithLimits(int sum, int[] limits) {

        int n = limits.length;
        int[] nums = new int[n];
        int total = 0;

        for (int l : limits) {
            total += l;
        }

        if (total <= sum)
            return limits;

        Random random = new Random(new Random().nextInt());
        while (sum > 0) { 
            int x = random.nextInt(n);
            if (nums[x] < limits[x]) {
                nums[x] += 1;
                sum--;
            }
        }
        return nums;
    }
}

// algorithm taken from Game.java
private int estimateProceedsOfTheft(Town theivingTown)
{
    int bestTownToTheiveProceedsAmount = -1;
    for (Town town : towns)
    {
        int goldStolen = estimateProceedsOfTheft(town,theivingTown);

        if (goldStolen > bestTownToTheiveProceedsAmount)
        {
            bestTownToTheiveProceedsAmount=goldStolen;
        }             
    }
    return bestTownToTheiveProceedsAmount;
}

// algorithm taken from Game.java
private int estimateProceedsOfTheft(Town victimTown,Town theivingTown)
{
    int goldStolen = 0;

    if (victimTown.getOwnerId()!= theivingTown.getOwnerId())
    {
        int goldReserve = victimTown.getGold() + GOLD_MAX_DEBT > 0 ? victimTown.getGold() + GOLD_MAX_DEBT : GOLD_MAX_DEBT - Math.abs(victimTown.getGold());
        int goldToSteal = theivingTown.getCorsairs() * GOLD_PER_STEAL;
        goldStolen = Math.min(goldReserve, goldToSteal);
    }

    return goldStolen;
}

// exactly as the method name states :)
private Town findStrongestTownThatCanDefeatGivenTown(Town defendingTown)
{
    int strongestSurvivingForce=-1;
    Town strongestTown=null;
    for (Town town : towns)
    {
        if (town.getOwnerId()!=defendingTown.getOwnerId() && town.getOwnerId()!=-1)
        {
            Town simulatedThisTown = new Town(defendingTown);
            Town simulatedOtherTown = new Town(town);

            // check to see if the other town could defeat this town
            if (battle(simulatedOtherTown,simulatedThisTown,simulatedOtherTown.getWarlocks(), simulatedOtherTown.getCrusaders(), simulatedOtherTown.getAmazons()))
            {
                //and if so, if it is the most overwhelming win, then that town is the target of conversion.
                int survivingForce=simulatedOtherTown.getAmazons()+simulatedOtherTown.getCrusaders()+simulatedOtherTown.getWarlocks()+
                                simulatedThisTown.getAmazons()+simulatedThisTown.getCrusaders()+simulatedThisTown.getWarlocks();
                if (survivingForce>strongestSurvivingForce)
                {
                    strongestSurvivingForce=survivingForce;
                    strongestTown = town;
                }
            }
        }
    }
    return strongestTown;
}
}

Çalıştırmak için: 1. Moogiesoft dizinine yerleştirin 2. Ana dizinde: java moogiesoft.Opportunist


Vaov! Bu oldukça iyi!
TheNumberOne

Açıkçası bu harika, ama bence, eğer başkalarının bir araya getirdiğinden daha fazla piskoposunuz varsa, Piskoposları satın almaya son vererek 1’i marjinal olarak iyileştirebileceğinizi düşünüyorum. Son puanınızı çok daha yüksek yapmalı.
durron597,

Teşekkürler, iyi öneriler. Onları birleştirmeye devam
edeceğim

Aferin, Opportunist'in stratejisi gerçekten ilginçti!
Thrax

@Thrax meydan okuma için teşekkürler! Deneylerime göre, Fırsatın ne kadar iyi oynadığı konusunda şansın büyük bir faktörü var. Başlangıç ​​yakın dövüş turlarında kolayca gömülebilir. Normalde Zealot tarafından.
Moogie

8

Aegis, Java

Aegis güvenli bir şekilde oynamaya ve lüks mülklerle dolu güzel bir konut bloğu inşa ederken diğer oyuncuların kendi aralarında savaşmasını beklemeye çalışıyor. Altın değerli bir kaynak olduğundan, Aegis komşularından çalmak ve zor kazanılan paralarını korumak için yeterli Corsairs toplar.

import java.util.ArrayList;
import java.util.List;

public class Aegis {

    int round;
    int phase;
    int playerID;
    int thisTownID;

    final int PEONS_PER_BISHOPS = 50;
    final int GOLD_STOLEN_PER_CORSAIR = 10;
    final int AVERAGE_COST_PER_UNIT = 2;
    final int GOLD_SAFETY = 100;
    final int PEONS_SAFETY = 20;
    final int COST_CORSAIR = 12;
    final int COST_SOLDIER = 10;
    final int COST_ESTATE = 200;
    final int MAX_CORSAIRS = 30;

    List<Town> towns;
    List<Town> myTowns;
    List<Town> otherTowns;

    Town thisTown;

    public static void main(String[] args){
        if (args.length == 0) {
            System.out.println("10 10 10 10 1 1 3 55");
        } else {
            new Aegis().protect(args[0].split(";"));
        }
    }

    private void protect(String[] args) {

        round = Integer.parseInt(args[0]);
        phase = Integer.parseInt(args[1]);
        playerID = Integer.parseInt(args[2]);
        thisTownID = Integer.parseInt(args[3]);

        towns = new ArrayList<>();
        myTowns = new ArrayList<>();
        otherTowns = new ArrayList<>();

        for (int i = 4; i < args.length; i++){
            towns.add(new Town(args[i]));
        }

        for (Town town : towns){
            if (town.isMine()){
                myTowns.add(town);
                if (town.isThisTown()){
                    thisTown = town;
                }
            } else {
                otherTowns.add(town);
            }
        }

        switch (phase) {
        case 2: steal(); break;
        case 3: recruit(); break;
        case 6: convert(); break;
        case 7: attack(); break;
        case 8: move(); break;
        case 9: resurrect(); break;
        case 11: build(); break;
        }
    }

    private void steal() {
        Town richestTown = otherTowns.stream().max((a,b) -> a.gold - b.gold).get();
        System.out.println("S " + richestTown.getId() + " " + thisTown.getCorsairs());
    }

    private void recruit() {
        Town richestTown = otherTowns.stream().max((a,b) -> a.gold - b.gold).get();
        Town soldierTown = otherTowns.stream().max((a,b) -> (a.amazons + a.warlocks + a.crusaders) - (b.amazons + b.warlocks + b.crusaders)).get();
        int requiredBishops = Math.max(0, Math.floorDiv(thisTown.getPeons(), PEONS_PER_BISHOPS) - thisTown.getBishops());
        int requiredNecromancers = Math.max(0, 1 - thisTown.getNecromancers());
        int requiredArchitects = Math.max(0, 5 - thisTown.getArchitects());
        int requiredCorsairs = Math.max(0, Math.min(MAX_CORSAIRS - thisTown.getCorsairs(), Math.floorDiv(richestTown.getGold(), GOLD_STOLEN_PER_CORSAIR)));
        int goldAvailable = thisTown.getGold() - (AVERAGE_COST_PER_UNIT * thisTown.getUnits()) - GOLD_SAFETY;
        int peonsAvailable = Math.max(0, thisTown.getPeons() - PEONS_SAFETY);
        int recruitedCorsairs = 0;
        int[] recruits = new int[3];
        int i = 0;
        while (peonsAvailable >= 5 && goldAvailable >= 50 && recruitedCorsairs < requiredCorsairs) {
            recruitedCorsairs++;
            peonsAvailable--;
            goldAvailable-=COST_CORSAIR;
        }
        while (peonsAvailable >= 5 && goldAvailable >= 50) {
            if (soldierTown.getSoldiers() > thisTown.getSoldiers()) {
                i = (i >= recruits.length - 1 ? 0 : i+1);
                recruits[i]++;
                peonsAvailable--;
                goldAvailable-=COST_SOLDIER;
            } else {
                break;
            }
        }
        if (recruits[0] + recruits[1] + recruits[2] + recruitedCorsairs + requiredBishops + requiredNecromancers + requiredArchitects > 0) {
            System.out.println("R " + recruits[0] + " " + recruits[1] + " " + recruits[2] + " " + recruitedCorsairs + " " + requiredBishops + " " +  requiredNecromancers + " " + requiredArchitects);
        } else {
            System.out.println("W");
        }
    }

    private void convert() { 
        System.out.print("W");
    }

    private void attack() {
        if (this.countOtherPlayers() <= 1) {
            Town richestTown = otherTowns.stream().max((a,b) -> a.getGold() - b.getGold()).get();
            int neededWarlocks =  thisTown.getWarlocks() - richestTown.getWarlocks();
            int neededCrusaders = thisTown.getCrusaders() - richestTown.getCrusaders();
            int neededAmazons = thisTown.getAmazons() - richestTown.getAmazons() ;

            if (neededWarlocks > 0 && neededCrusaders > 0 && neededAmazons > 0) {
                System.out.println("A " + richestTown.getId() + " " + (richestTown.getWarlocks() + 1) + " " + (richestTown.getCrusaders() + 1) + " " + (richestTown.getAmazons() + 1));  
            } else {
                System.out.println("W");
            }
        } else {
            System.out.println("W");
        }
    }

    private void move() {
        for (Town town : myTowns) {
            int goldBalance = town.getGold() - (AVERAGE_COST_PER_UNIT * thisTown.getUnits()) + GOLD_SAFETY;
            if (goldBalance <= 0) {
                System.out.println("T " + town.getId() + " " + (-goldBalance + GOLD_SAFETY));
                break;
            }
        }
        System.out.println("W");
    }

    private void resurrect() {
        if (thisTown.getCorpses() > 0) {
            int corpses = Math.min(5, thisTown.getCorpses());
            System.out.print("R " + corpses);
        } else {
            System.out.print("W");
        }
    }

    private void build() {
        int goldAvailable = thisTown.getGold() - (AVERAGE_COST_PER_UNIT * thisTown.getUnits()) - GOLD_SAFETY;
        if (goldAvailable >= (COST_ESTATE + 50)) {
            System.out.println("B E");
        } else {
            System.out.println("W");
        }
    }

    public int countOtherPlayers() {
        List<Integer>players = new ArrayList<>();
        for (Town town : otherTowns) {
            if (!players.contains(town.getOwnerId()) && town.getOwnerId() >= 0) players.add(town.getOwnerId());
        }
        return players.size();
    }

    private class Town {

        private final int ownerId;
        private final int id;
        private final int gold;
        private final int corpses;
        private final int warlocks;
        private final int crusaders;
        private final int amazons;
        private final int corsairs;
        private final int bishops;
        private final int necromancers;
        private final int architects;
        private final int peons;
        private final int temples;
        private final int barracks;
        private final int estates;
        private final int palaces;

        public Town(String string){
            String[] args = string.split("_");
            ownerId = Integer.parseInt(args[0]);
            id = Integer.parseInt(args[1]);
            gold = Integer.parseInt(args[2]);
            corpses = Integer.parseInt(args[3]);
            warlocks = Integer.parseInt(args[4]);
            crusaders = Integer.parseInt(args[5]);
            amazons = Integer.parseInt(args[6]);
            corsairs = Integer.parseInt(args[7]);
            bishops = Integer.parseInt(args[8]);
            necromancers = Integer.parseInt(args[9]);
            architects = Integer.parseInt(args[10]);
            peons = Integer.parseInt(args[11]);
            String[] args2 = args[12].split("-");
            temples = Integer.parseInt(args2[0]);
            barracks = Integer.parseInt(args2[1]);
            estates = Integer.parseInt(args2[2]);
            palaces = Integer.parseInt(args2[3]);
        }
        public int getOwnerId() {
            return ownerId;
        }
        public int getId() {
            return id;
        }
        public int getGold() {
            return gold;
        }
        public int getCorpses() {
            return corpses;
        }
        public int getWarlocks() {
            return warlocks;
        }
        public int getCrusaders() {
            return crusaders;
        }
        public int getAmazons() {
            return amazons;
        }
        public int getCorsairs() {
            return corsairs;
        }
        public int getBishops() {
            return bishops;
        }
        public int getNecromancers() {
            return necromancers;
        }
        public int getArchitects() {
            return architects;
        }
        public int getPeons() {
            return peons;
        }
        public int getTemples() {
            return temples;
        }
        public int getBarracks() {
            return barracks;
        }
        public int getEstates() {
            return estates;
        }
        public int getPalaces() {
            return palaces;
        }
        public int getBuildings() {
            return getTemples() + getBarracks() + getEstates() + getPalaces();
        }
        public int getSoldiers() {
            return getWarlocks() + getCrusaders() + getAmazons();
        }
        public int getUnits() {
             return getSoldiers() + getCorsairs() + getBishops() + getNecromancers() + getArchitects();
        }
        public int getCitizens() {
            return getUnits() + getPeons();
        }
        public boolean isMine(){
            return getOwnerId() == playerID;
        }
        public boolean isThisTown(){
            return id == thisTownID;
        }
    }

}

İle derleyin javac Aegis.java

İle koş java Aegis


8

Genç Earl, Python 2

sürüm 3.1

Güncelleştirme:

Genç Earl’ün annesi, artık savaşın durmasıyla savaşına katlanacak. Onun yerine şehir binalarına girecek. Earl'ün artık ekonomik danışmanları ve çok fazla e-tablosu var. Daha basit bir yaşam diliyor, oda hizmetçilerini sadece kovalayabiliyordu.

import sys, re
from random import *
from operator import itemgetter

(PLAYER, TOWN, GOLD, CORPSES, WARLOCKS, CRUSADERS, AMAZONS, 
CORSAIRS, BISHOPS, NECROMANCERS, ARCHITECTS, PEONS, 
TEMPLES, BARRACKS, ESTATES, PALACES) = range(16)
OUTLAW = -1

def seqalloc(seq, num):
    outseq = []
    totalw = float(sum(seq))
    for weight in seq:
        share = int(round(num * weight / totalw)) if weight else 0
        outseq.append(share)
        totalw -= weight
        num -= share
    return outseq

def getstrength(t): return sum(t[WARLOCKS:AMAZONS+1])
def calcprofit(t): return t[GOLD] + 20*t[PEONS] + 200*t[ESTATES]
def getincome(t): return 5*t[PEONS] + 2*(t[PEONS]+t[CORSAIRS])*t[ESTATES]

if len(sys.argv) < 2:
    print 5,20,5,   12,4,1,13,   40
else:
    try:
        output = 'W'

        parts = sys.argv[1].split(';')
        turn, phase, me, thistown = [int(parts.pop(0)) for i in range(4)]
        # Catagorize towns:
        towns = [map(int, re.split(r'_', town)) for town in parts]
        outlaws = [t for t in towns if t[PLAYER] == OUTLAW]
        mytowns = [t for t in towns if t[PLAYER] == me]
        enemy = [t for t in towns if t[PLAYER] not in (me, OUTLAW)]
        # Situation:
        here = [t for t in mytowns if t[TOWN] == thistown][0]
        strength = sorted(enemy, key=getstrength)
        strengthoutlaw = sorted(outlaws, key=getstrength)
        profenemy = sorted(enemy, key=calcprofit)
        profoutlaw = sorted(outlaws, key=calcprofit)
        rich = outlaws + sorted(enemy, key=itemgetter(GOLD))
        bandits = sum(sum(t[4:12]) for t in outlaws)
        # Planning:
        siblings = [t for t in mytowns if t != here]
        bodytowns = [t for t in mytowns if t[CORPSES] > 0]
        myincome = getincome(here)
        isrich = all(t[GOLD] < here[GOLD]*1.5 for t in enemy)
        wages = getstrength(here) + sum(here[CORSAIRS:ARCHITECTS+1]) * 2
        newpeons = (turn % 5 == 1) if turn > 1 else 0
        theft = 10 * max(0, bandits/len(enemy+mytowns) - here[CORSAIRS]*5)

        if phase == 2:
            output = 'S %u %u' % (rich[-1][TOWN], here[CORSAIRS])

        elif phase == 3:
            cash = max(0, here[GOLD] - wages)
            if theft < myincome:
                if here[ARCHITECTS] and cash > 200:
                    cash -= 200
                cash = max(0, cash - 150)
            # must haves:
            cors = (bandits/len(mytowns+enemy)) / 5 + 1
            cors = cors if cors < 25 else 0
            bish = here[PEONS]/50 + 1
            necro = here[CORPSES]/20 + 1
            require = [cors, bish, necro, 0]
            need = [0]*3 + [max(0, p-q) for p,q in zip(require, here[7:11])]
            if sum(need)*22 < cash:
                train = need
            else:
                train = seqalloc(need, cash/22)
            now = [p+q for p,q in zip(here[4:11], train)]
            cash -= sum(p*q for p,q in zip(train[3:], [12,20,20,15]))
            cash -= sum(train)*2   # new wages
            # nice to have:
            raises = min(here[CORPSES]/4+1, now[5]*5, cash/20)
            cash -= raises * 20
            archreq = max(0, 13 - here[ARCHITECTS])
            if theft < myincome and archreq * 17 < cash:
                train[6] += archreq
                cash -= archreq * 17
                if cash > 200:
                    cash -= 200
            newbish = max(0, cash/50 - now[4])
            if newpeons:
                bishreq = (myincome - 200 - wages)/50 * 12/10
                newbish += max(0, bishreq - (now[4]+newbish))
            newbish = min(newbish, cash/22)
            train[4] += newbish
            cash -= newbish * 22

            if sum(train) > 0:
                output = 'R %u %u %u %u %u %u %u' % tuple(train)

        elif phase == 6:
            cash = here[GOLD]
            if theft < myincome:
                if here[ARCHITECTS] and cash > 200:
                    cash -= 200
                cash = max(0, cash - 150)
            raises = min(here[CORPSES]/4+1, here[NECROMANCERS]*5, cash/20)
            cash -= raises * 20
            count = min(cash/50, here[BISHOPS])
            if count > 0:
                target = (strengthoutlaw + strength)[-1]
                count = min(count, sum(target[4:7]))
                ftrs = seqalloc(target[4:7], count)
                output = 'C %u %u %u %u' % tuple([target[TOWN]] + ftrs)

        elif phase == 7:
            force = getstrength(here)
            target = None
            if not enemy or force > getstrength(strength[-1])*2:
                for town in profenemy[::-1]+profoutlaw[::-1]:
                    if force > getstrength(town)*4:
                        target = town
                        break
            if target:
                raiders = seqalloc(here[4:7], force/2)
                output = 'A %u %u %u %u' % tuple([target[TOWN]] + raiders)

        elif phase == 8:
            cash = here[GOLD]
            if theft < myincome:
                if here[ARCHITECTS] and cash > 200:
                    cash -= 200
                cash = max(0, cash - 150)
            raises = min(here[CORPSES]/4+1, here[NECROMANCERS]*5, cash/20)
            if raises > 0:
                output = 'R %s' % raises

        elif phase == 9:
            if here[CORPSES] == 0 and bodytowns:
                dest = max(bodytowns, key=itemgetter(CORPSES))
                necro = min(here[NECROMANCERS], dest[CORPSES]/20+1)
                output = 'M %u 0 0 0 0 0 %u 0' % (dest[TOWN], necro)
            elif siblings and theft < 100 and isrich:
                given = min(here[GOLD]/33, here[CORSAIRS]*200)
                dest = max(siblings, key=getincome)
                output = 'T %u %u' % (dest[TOWN], given)

        elif phase == 11:
            if here[ARCHITECTS] and here[GOLD] >= 200:
                output = 'B E'
    except:
        pass
    print output

Performans analizi

Oyun yarışmasında, en son Earl başarılı oldu. 10 oyunun 2'sinde oyuncu kasabalara karşı kazanmayı başardı, ancak haydut kasabalarını ele geçirme zamanı geldiğinde dondu. Bu hatayı düzelttim - o kadar uzağa gideceğini asla düşünmedim ;-). Ön görüşte, kontrol cihazını indirmeliydim ve Earl'ü test etmeliydim.

En iyi girişler için @ Moogie ve @ TheBestOne'ı tebrik ederiz. Sadece birinin kazanabileceği bir utanç. İkisi de çok iyi.

Daha fazla oyun varsa, onarılan Earl'ün iki şampiyona karşı nasıl hayatta kaldığını görmek isterim. @Thrax'ın bunun için boş vakti olacağını umuyorum.



Sonuçları görmek için yeni Earl ile 3 oyun daha oynayacağım. Ben de kendiniz test etmek istiyorsanız git güncel tutmak. (ve neredeyse bir sonraki KOTH üzerinde çalışmayı bitirdim, çok yakında yeni bir tane bekleyin!)
Thrax

İşte sonuçlar: 1. Outlaw(12, 6671, 2233682) 2. YoungEarl(3, 6346, 208215) 3. Politician(1, 96, 0)o zaman 1. YoungEarl(16, 2514, 72315)ve sonunda 1. Politician(16, 1562, 53467). YoungEarl gerçekten güzel bir tanrı işi yapıyor.
Thrax,

Teşekkürler Thrax. Earl bunu mahvediyor gibi görünüyor. Asla hadi geç kalmaktan iyidir?
Mantık Şövalye

Moogie ve TheBestOne hala koşuda olduğundan, başka bir ödül için 100 oyun çalıştırmaya çalışacağım. (Ancak itibar konusunda biraz kısayım, en az iki kez harcadığımdan yani 300 rep'e ihtiyacım var)
Thrax

6

TheLannisters (Java)

Bu ismi seçtim çünkü bu gönderim cehennem kadar zenginleşiyor. Ayrıca, cümle TheLannisters gave birth to 30 childrenkomik geliyor: D

Düzenleme: Şimdi uzun süre saldırı bekler ve oyuncularını askerlerini çalarak rahatsız eder. Ayrıca her tür birimi işe alabilir.

import java.util.ArrayList;
import java.util.List;

public class TheLannisters {
    private static final int COST_PER_SOLDIER = 11;
    private static final int COST_PER_CORSAIR = 14;
    private static final int COST_PER_BISHOP = 22;
    private static final int COST_PER_CONVERTION = 50;
    private final int MIN_PEONS;
    private final int phase;
    private final int myId;
    private final int round;
    private final List<Town> myTowns = new ArrayList<>();
    private final List<Town> enemyTowns = new ArrayList<>();
    private final List<Town> enemyPlayerTowns = new ArrayList<>();
    private final List<Town> outlawTowns = new ArrayList<>();
    private Town thisTown = null;

    public static void main(String[] args){
        if (args.length == 0) {
            System.out.println("12 14 10 11 3 5 5 40");
        } else {
            new TheLannisters(args[0].split(";")).command();
        }
    }

    public TheLannisters(String[] args) {
        round = Integer.parseInt(args[0]);
        phase = Integer.parseInt(args[1]);
        myId = Integer.parseInt(args[2]);
        MIN_PEONS = 40 + round/2;
        int thisTownId = Integer.parseInt(args[3]);

        boolean hasAlreadyCommanded = false;
        for (int i = 4; i < args.length; i++){
            Town town = new Town(args[i], hasAlreadyCommanded);
            if (town.isMine()){
                myTowns.add(town);
                if (town.id == thisTownId){
                    thisTown = town;
                    hasAlreadyCommanded = true;
                }
            } else {
                enemyTowns.add(town);
                if (town.isOutlawTown()) {
                    outlawTowns.add(town);
                } else {
                    enemyPlayerTowns.add(town);
                }
            }
        }
    }

    private void command() {
        switch (phase) {
            case 2: steal(); break;
            case 3: recruit(); break;
            case 6: convert(); break;
            case 7: attack(); break;
            case 8: resurrect(); break;
            case 9: move(); break;
            case 11: build(); break;
        }
    }

    private void steal() {
        int goldToSteal = thisTown.corsairs * 10;

        int mostSoldiers = -1;
        Town richestTown = null;
        for (Town town : enemyPlayerTowns) {
            if (town.getSoldiers() > mostSoldiers && town.gold >= goldToSteal) {
                richestTown = town;
                mostSoldiers = town.getSoldiers();
            }
        }
        if (richestTown != null) {
            printCommand("S " + richestTown.id + " " + thisTown.corsairs);
        }

        // player with most gold (could be an outlaw)
        int mostGold = -1;
        for (Town town : enemyTowns) {
            if (town.gold > mostGold) {
                richestTown = town;
                mostGold = town.gold;
            }
        }
        printCommand("S " + richestTown.id + " " + thisTown.corsairs);
    }

    private void recruit() {
        int freePeons = (thisTown.peons - MIN_PEONS);
        if (!thisTown.isWeak()) {
            freePeons /= 2;
        }
        int freeGold = thisTown.gold - thisTown.getSoldiers() - thisTown.getCitizens() * 2;

        if (freePeons <= 0 || freeGold < COST_PER_SOLDIER) {
            printCommand("W");
        }

        int bishops = 0;
        if ((thisTown.bishops * 50 < thisTown.peons || thisTown.gold > 500) && freeGold >= COST_PER_BISHOP) {
            bishops = 1;
            freeGold -= COST_PER_BISHOP;
            freePeons--;
        }

        int necromancers = 0;
        if (thisTown.necromancers == 0 && freeGold >= COST_PER_BISHOP) {
            necromancers = 1;
            freeGold -= COST_PER_BISHOP;
            freePeons--;
        }

        int corsairs = 0;
        if (thisTown.getsRobbed() && freeGold >= COST_PER_CORSAIR) {
            corsairs = 1;
            freeGold -= COST_PER_CORSAIR;
            freePeons--;
        }

        int architects = 0;
        if (thisTown.architects == 0 && freeGold > 500) {
            architects = 1;
            freeGold -= COST_PER_BISHOP;
            freePeons--;
        }

        int producableSoldiers = Math.min(freePeons, freeGold / COST_PER_SOLDIER);
        int soldierPerType = producableSoldiers / 3;
        int crusaders = soldierPerType + (producableSoldiers % 3);
        printCommand("R " + soldierPerType + " " + crusaders + " " + soldierPerType + " " + corsairs + " " + bishops + " " + necromancers + " " + architects);
    }

    private void convert() {
        int freeGold = 0;
        if (thisTown.isWeak() || thisTown.corpses <= 0) {
            freeGold = thisTown.gold - 300;
        }
        if (freeGold < COST_PER_CONVERTION || thisTown.bishops == 0 || (round < 2 && thisTown.getSoldiers() > 35)) {
            printCommand("W");
        }
        int soldiersToConvert = freeGold / COST_PER_CONVERTION;
        int soldiersPerType = soldiersToConvert / 3;
        int amazons = soldiersPerType + (soldiersToConvert % 3);

        Town destination = null;        
        int mostSoldiers = -1;
        if (destination == null) {
            for (Town town : enemyPlayerTowns) {
                if (town.getSoldiers() > mostSoldiers) {
                    destination = town;
                    mostSoldiers = town.getSoldiers();
                }
            }
        }
        if (destination == null) {
            destination = outlawTowns.get(0);
        }
        printCommand("C " + destination.id + " " + soldiersPerType + " " + soldiersPerType + " " + amazons);
    }

    private void attack() {
        int leastSoldiers = Integer.MAX_VALUE;
        Town destination = null;

        if (thisTown.isWeak() || round < 21) {
            printCommand("W");
        }

        for (Town town : enemyTowns) {
            if (town.getSoldiers() < leastSoldiers) {
                destination = town;
                leastSoldiers = town.getSoldiers();
            }
        }

        boolean attackTogether = false;
        for (Town town : myTowns) {
            if (!town.hasAlreadyCommanded && !town.isWeak() && !town.equals(thisTown)) {
                attackTogether = true;
            }
        }

        if (thisTown.getSoldiers() / 3.5 > destination.getSoldiers() || (attackTogether && thisTown.getSoldiers() / 2 >= destination.getSoldiers())) {
            int warlocks = thisTown.warlocks/2;
            int crusaders = thisTown.crusaders/2;
            int amazons = thisTown.amazons/2;
            while (warlocks + crusaders + amazons > (destination.getSoldiers() + 3) * 3) {
                warlocks = Math.max(0, --warlocks);
                crusaders = Math.max(0, --crusaders);
                amazons = Math.max(0, --amazons);
            }
            if (enemyPlayerTowns.size() == 0) {
                // dont send too many soldiers => otherwise they revolt
                printCommand("A " + destination.id + " " + (destination.warlocks + 2) + " " + (destination.crusaders + 2) + " " + (destination.amazons + 2));
            }
            printCommand("A " + destination.id + " " + warlocks + " " + crusaders + " " + amazons);
        } else {
            printCommand("W");
        }
    }

    private void resurrect() {
        printCommand("R 999");      
    }

    private void move() {
        if (myTowns.size() == 1 || thisTown.corpses > 10) {
            printCommand("W");
        }
        int leastGold = thisTown.gold;
        Town destination = null;
        for (Town town : myTowns) {
            if (town.gold < leastGold) {
                leastGold = town.gold;
                destination = town;
            }
        }
        if (destination != null && (thisTown.hasMostGold() || (thisTown.gold > 100 && destination.gold - destination.getSoldiers() - destination.getCitizens() * 2 < 300) || (thisTown.gold > 300 && destination.getsRobbed()))) {
            printCommand("T " + destination.id + " " + Math.max(thisTown.gold / 10, 30));
        }
        for (Town town : myTowns) {
            if (town.isWeak()) {
                printCommand("M " + town.id + " " + (thisTown.warlocks / 4) + " "  + (thisTown.crusaders / 4) + " "  + (thisTown.amazons / 4) + " 0 0 0 0");
            }
        }
        printCommand("W");
    }

    private void build() {
        if (thisTown.gold >= 500) {
            printCommand("B P");
        } else if (thisTown.gold > 300) {
            if (round % 2 == 0) {
                printCommand("B E");
            }
            printCommand("B B");    
        }
    }

    private class Town {

        private final int ownerId;
        private final int id;
        private final int gold;
        private final int corpses;
        private final int warlocks;
        private final int crusaders;
        private final int amazons;
        private final int corsairs;
        private final int bishops;
        private final int necromancers;
        private final int architects;
        private final int peons;
        private final boolean hasAlreadyCommanded;

        public Town(String string, boolean hasAlreadyCommanded){
            String[] args = string.split("_");
            ownerId = Integer.parseInt(args[0]);
            id = Integer.parseInt(args[1]);
            gold = Integer.parseInt(args[2]);
            corpses = Integer.parseInt(args[3]);
            warlocks = Integer.parseInt(args[4]);
            crusaders = Integer.parseInt(args[5]);
            amazons = Integer.parseInt(args[6]);
            corsairs = Integer.parseInt(args[7]);
            bishops = Integer.parseInt(args[8]);
            necromancers = Integer.parseInt(args[9]);
            architects = Integer.parseInt(args[10]);
            peons = Integer.parseInt(args[11]);
            this.hasAlreadyCommanded = hasAlreadyCommanded;
        }

        public int getSoldiers() {
            return warlocks + crusaders + amazons;
        }

        public int getCitizens() {
            return corsairs + bishops + necromancers + architects;
        }

        public boolean isMine(){
            return ownerId == myId;
        }

        public boolean isOutlawTown() {
            return ownerId == -1;
        }

        public boolean isWeak() {
            return willBeWeak(1);
        }

        public boolean willBeWeak(double divisor) {
            if (enemyPlayerTowns.size() == 0) {
                return false;
            }
            int mySoldiers = (int) (getSoldiers() * divisor);
            int weakerTowns = 0;
            for (Town town : enemyTowns) {
                if (town.getSoldiers() < mySoldiers) {
                    weakerTowns++;
                }
            }
            for (Town town : myTowns) {
                if (town.getSoldiers() < mySoldiers) {
                    weakerTowns++;
                }
            }
            return weakerTowns <= 2;
        }

        public boolean getsRobbed() {
            int outlaws = 0;
            for (Town town : outlawTowns) {
                outlaws += town.getSoldiers() + town.getCitizens() + town.peons;
            }
            int notOutlawTowns = enemyTowns.size() + myTowns.size() - outlawTowns.size();
            int outlawsPerTown = outlaws / notOutlawTowns;
            return outlawsPerTown - corsairs * 5 > 0;
        }

        public boolean hasMostGold() {
            for (Town town : enemyTowns) {
                if (gold < town.gold) {
                    return false;
                }
            }
            return true;
        }
    }

    private void printCommand(String command) {
        System.out.println(command);
        System.exit(0);
    }
}

Sadece haydutlara karşı savaşırken bir NPE'niz var. Bu kod parçacığı: for (Town town : enemyPlayerTowns)hiçbir şey alamıyor, bu nedenle Town richestTown = null;eşdeğeriniz boş kalıyor.
Thrax

@Thrax Teşekkür ederim, şu an tarafından düzeltilmelidir :)
CommonGuy

6

Politikacı, Java

v3

Güncelleme: Can sıkıcı yorum ve daha iyi planlama eklendi.

Güncelleme: Çok daha az tren alır (corsairs) ve ekonomiyi (piyonlar) geliştirmeye odaklanır.

Güncelleme: Birkaç parametre ayarlandı.

Güncelleme: Çok daha sık saldırır. Bilim adamlarını daha fazla dinler.

İki hedefi var.

  1. Sınırsız altın

  2. Sınırsız ordular.

import java.util.ArrayList;
import java.util.List;

public class Politician {

    private static final int SOLDIER_COST = 11;
    private static final int AMBASSADOR_COST = 22;
    private static final int SCIENTIST_COST = 22;
    private static final int TRAIN_COST = 14;
    private static final int ARCHITECT_COST = 17;
    private static final int CONVERSION_COST = 50;
    private static final double MIN_SOLDIER_RATIO = .75;
    private static final int MIN_PEOPLE = 30;
    private static final int MIN_ARCHITECTS = 13;
    private static final int MAX_PEOPLE = 200;
    int round;
    int phase;
    int playerID;
    int thisTownID;

    List<State> states;
    List<State> myStates;
    List<State> otherStates;

    State thisState;

    public Politician(String... args) {
        args = args[0].split(";");

        round = Integer.parseInt(args[0]);
        phase = Integer.parseInt(args[1]);
        playerID = Integer.parseInt(args[2]);
        thisTownID = Integer.parseInt(args[3]);

        states = new ArrayList<>();
        myStates = new ArrayList<>();
        otherStates = new ArrayList<>();

        for (int i = 4; i < args.length; i++){
            states.add(new State(args[i]));
        }


        for (State state : states){
            if (state.isMine()){
                myStates.add(state);
                if (state.isThisTown()){
                    thisState = state;
                }
            } else {
                otherStates.add(state);
            }
        }
    }

    public static void main(String[] args){
        if (args.length == 0) {
            System.out.println("8 8 8 26 4 1 13 32");
        } else {
            try {
                System.out.println(new Politician(args).conquer());
            } catch (Exception e){
                System.out.println("We, the enslaved people, declare Politician the winner.");
            }
        }
    }

    private String conquer() {

        switch (phase){
            case 2:
                return steal();
            case 3:
                return conscript();
            case 6:
                return bribe();
            case 7:
                return orderAttack();
            case 8:
                return topSecret();
            case 9:
                return handouts();
            case 11:
                return roadConstruction();
            default:
                throw new IllegalStateException();//Civil war!!!
        }
    }

    private String steal() {
        State bestState = otherStates.stream().max((a, b) -> a.profit() - b.profit()).get();
        return "S " + bestState.getId() + " " + thisState.getTrains();
    }

    private String conscript() {
        int gold = thisState.getFreeGold();

        int neededTrains = Math.max(neededTrains() - thisState.getTrains(), 0);
        neededTrains = Math.min(neededTrains, thisState.getRegularPeople());
        neededTrains = Math.min(neededTrains, gold / TRAIN_COST);
        thisState.regularPeople -= neededTrains;
        gold -= neededTrains * TRAIN_COST;

        int neededSoldiers = soldiersNeeded();
        neededSoldiers = Math.min(gold / SOLDIER_COST, neededSoldiers);
        int neededAmbassadors = Math.min(neededSoldiers, (gold - 200 - 10 * thisState.getCorpses() -
                CONVERSION_COST * thisState.getAmbassadors()) / (CONVERSION_COST + AMBASSADOR_COST));
        neededAmbassadors = Math.min(maxSoldiers() - thisState.getAmbassadors(), neededAmbassadors);
        neededSoldiers -= neededAmbassadors;
        thisState.regularPeople -= neededSoldiers;
        gold -= neededSoldiers * SOLDIER_COST;

        neededAmbassadors += (int) Math.max(Math.round(Math.ceil(thisState.getRegularPeople() / 50.0) -
                thisState.getAmbassadors() - neededAmbassadors), 0);
        neededAmbassadors = Math.min(gold / AMBASSADOR_COST, neededAmbassadors);
        thisState.regularPeople -= neededAmbassadors;
        gold -= neededAmbassadors * AMBASSADOR_COST;

        int neededScientists = (int) Math.max(Math.round(Math.ceil(thisState.getCorpses() / 10.0) -
                thisState.getScientists()), 0);
        neededScientists = Math.min(gold / SCIENTIST_COST, neededScientists);
        thisState.regularPeople -= neededScientists;
        gold -= neededScientists * SCIENTIST_COST;

        int neededArchitects = 0;

        if (thisState.getRegularPeople() > MIN_PEOPLE){
            int freePeople = thisState.getRegularPeople() - MIN_PEOPLE;

            neededArchitects = Math.max(MIN_ARCHITECTS - thisState.getArchitects(), 0);
            neededArchitects = Math.min(neededArchitects, freePeople);
            neededArchitects = Math.min(neededArchitects, gold / ARCHITECT_COST);
            freePeople -= neededArchitects;
            gold -= neededArchitects * ARCHITECT_COST;

            if (freePeople + MIN_PEOPLE > MAX_PEOPLE){

                if (freePeople + MIN_PEOPLE > MAX_PEOPLE){
                    freePeople = freePeople + MIN_PEOPLE - MAX_PEOPLE;
                }

                neededAmbassadors += Math.min(gold / AMBASSADOR_COST, freePeople);
                neededAmbassadors = Math.min(neededAmbassadors, maxSoldiers() - thisState.getAmbassadors());
                gold -= neededAmbassadors * AMBASSADOR_COST;
                freePeople -= neededAmbassadors;

                neededSoldiers += Math.min(gold / SOLDIER_COST, freePeople);
            }

        }

        int neededAirmen = neededSoldiers / 3;
        int neededSailors = neededSoldiers / 3;
        int neededPrivates = neededSoldiers / 3;


        return "R " + neededAirmen + " " + neededSailors + " " + neededPrivates + " " + neededTrains + " " +
                neededAmbassadors + " " + neededScientists + " " + neededArchitects;
    }

    private int neededTrains() {
        int totalOutlaws = 0;
        int totalStates = myStates.size();
        for (State state : otherStates){
            if (state.isOutlaw()){
                totalOutlaws += state.getTotalCitizens();
            } else {
                totalStates++;
            }
        }
        return (int) Math.round(Math.ceil(.2 * totalOutlaws / totalStates));
    }

    private int soldiersNeeded(){
        int soldiers = (int) ((MIN_SOLDIER_RATIO * thisState.getRegularPeople() - thisState.getTotalSoldiers()) /
                        (MIN_SOLDIER_RATIO + 1));
        soldiers = Math.max(soldiers, minSoldiers() + 5 - thisState.getTotalSoldiers());
        soldiers = Math.max(soldiers, maxSoldiers() / 2 - thisState.getTotalSoldiers());
        soldiers = Math.max(soldiers, 0);
        return soldiers;
    }

    private String bribe() {
        int soldiersToConvert = Math.min(thisState.ambassadors, (thisState.getGold() - 200 - 10 *
                thisState.getCorpses()) / CONVERSION_COST);
        soldiersToConvert = Math.max(soldiersToConvert, 0);
        State toughest = otherStates.stream().max((a,b) -> a.getTotalSoldiers() - b.getTotalSoldiers()).get();
        soldiersToConvert = Math.min(soldiersToConvert, toughest.getTotalSoldiers());
        int airmen = (int) ((1.0 * toughest.getAirmen() / toughest.getTotalSoldiers()) * soldiersToConvert);
        soldiersToConvert -= airmen;
        int sailors = (int) ((1.0 * toughest.getSailors() / toughest.getTotalSoldiers()) * soldiersToConvert) * 3 / 2;
        soldiersToConvert -= sailors;
        int privates = soldiersToConvert;
        return "C " + toughest.getId() + " " + airmen + " " + sailors + " " + privates;
    }

    private String orderAttack() {
        if (round < 99 && otherTowns.size() < 2){
            return "W";
        }
        int soldiers = thisState.getFreeSoldiers();
        otherStates.sort((a,b) -> b.getRegularPeople() / Math.max(b.getTotalSoldiers(), 1) - a.getRegularPeople() / Math.max(a.getTotalSoldiers(), 1));
        if (otherStates.get(0).getTotalSoldiers() < soldiers){//Attack!!!!
            int airmen = (int) (((thisState.getAirmen()*1.0) / thisState.getTotalSoldiers()) * soldiers);
            int sailors = (int) (((thisState.getSailors()*1.0) / thisState.getTotalSoldiers()) * soldiers);
            int privates = (int) (((thisState.getPrivates()*1.0) / thisState.getTotalSoldiers()) * soldiers);
            return "A " + otherStates.get(0).getId() + " " + airmen + " " + sailors + " " + privates;
        }
        return getWaitString();
    }

    private String handouts() {

        State poorestState = null;
        int goldOfPoorestTown = Integer.MAX_VALUE;

        for (State state : myStates){
            if (state.getGold() < goldOfPoorestTown){
                poorestState = state;
                goldOfPoorestTown = state.getGold();
            }
        }
        if (thisState.getGold() <= goldOfPoorestTown){
            return getWaitString();
        }
        return "T " + poorestState.getId() + " " + (thisState.getGold() - poorestState.getGold())  / 2;
    }

    private String topSecret() {
        return "R " + thisState.getCorpses();
    }

    private String roadConstruction() {
        int airportPriority = thisState.getAirmen() + thisState.getAmbassadors() + thisState.getScientists();
        int highwayPriority = thisState.getSailors() + thisState.getPrivates();
        int railroadPriority = thisState.getTrains() + thisState.getRegularPeople();
        int palacePriority = 5;//Why would we build a palace???
        if (airportPriority > highwayPriority && airportPriority > railroadPriority && airportPriority >
                palacePriority && thisState.getGold() > 200){
            return "B T";
        } else if (highwayPriority > railroadPriority && highwayPriority > palacePriority && thisState.getGold() > 200){
            return "B B";
        } else if (railroadPriority > palacePriority && thisState.getGold() > 200){
            return "B E";
        } else if (thisState.getGold() > 500){
            return "B P";
        } else {
            return getWaitString();
        }
    }

    private int maxSoldiers(){
        int max = 0;
        for (State state : otherStates){
            if (state.getTotalSoldiers() > max){
                max = state.getTotalSoldiers();
            }
        }
        return max;
    }

    private int minSoldiers(){
        int min = Integer.MAX_VALUE;
        for (State state : otherStates){
            if (state.getTotalSoldiers() < min){
                min = state.getTotalSoldiers();
            }
        }
        return min;
    }

    private class State {

        private final int ownerId;
        private final int id;
        private final int gold;
        private final int corpses;
        private final int airmen;
        private final int sailors;
        private final int privates;
        private final int trains;
        private final int ambassadors;
        private final int scientists;
        private final int architects;
        private int regularPeople;
        private final int airports;
        private final int highways;
        private final int railroads;
        private final int palaces;

        public State(String string){
            String[] args = string.split("_");
            ownerId = Integer.parseInt(args[0]);
            id = Integer.parseInt(args[1]);
            gold = Integer.parseInt(args[2]);
            corpses = Integer.parseInt(args[3]);
            airmen = Integer.parseInt(args[4]);
            sailors = Integer.parseInt(args[5]);
            privates = Integer.parseInt(args[6]);
            trains = Integer.parseInt(args[7]);
            ambassadors = Integer.parseInt(args[8]);
            scientists = Integer.parseInt(args[9]);
            architects = Integer.parseInt(args[10]);
            regularPeople = Integer.parseInt(args[11]);
            airports = Integer.parseInt(args[12]);
            highways = Integer.parseInt(args[13]);
            railroads = Integer.parseInt(args[14]);
            palaces = Integer.parseInt(args[15]);
        }
        public int getOwnerId() {
            return ownerId;
        }
        public int getId() {
            return id;
        }
        public int getGold() {
            return gold;
        }
        public int getCorpses() {
            return corpses;
        }
        public int getAirmen() {
            return airmen;
        }
        public int getSailors() {
            return sailors;
        }
        public int getPrivates() {
            return privates;
        }
        public int getTrains() {
            return trains;
        }
        public int getAmbassadors() {
            return ambassadors;
        }
        public int getScientists() {
            return scientists;
        }
        public int getArchitects() {
            return architects;
        }
        public int getRegularPeople() {
            return regularPeople;
        }
        public int getAirports() {
            return airports;
        }
        public int getHighways() {
            return highways;
        }
        public int getRailroads() {
            return railroads;
        }
        public int getPalaces() {
            return palaces;
        }
        public int getTotalBuildings() {
            return getAirports() + getHighways() + getRailroads() + getPalaces();
        }
        public int getTotalSoldiers() {
            return getAirmen() + getSailors() + getPrivates();
        }
        public int getTotalUnits() {
            return getTotalSoldiers() + getTrains() + getAmbassadors() + getScientists() + getArchitects();
        }
        public int getTotalCitizens() {
            return getTotalUnits() + getRegularPeople();
        }
        public boolean isMine(){
            return getOwnerId() == playerID;
        }
        public boolean isThisTown(){
            return id == thisTownID;
        }
        public int neededGold(){
            return 2 * getTotalUnits() - getTotalSoldiers();
        }
        public int getFreeGold(){
            return gold - neededGold();
        }

        public int getFreeSoldiers() {
            int soldiers = Math.max((int) (getTotalSoldiers() - regularPeople * MIN_SOLDIER_RATIO), 0);
            soldiers = Math.min(soldiers, getTotalSoldiers() - minSoldiers() - 5);
            soldiers = Math.min(soldiers, getTotalSoldiers() - maxSoldiers() / 2);
            soldiers = Math.max(soldiers, 0);
            return soldiers;
        }

        public boolean isOutlaw() {
            return ownerId == -1;
        }

        public int income() {
            return 5 * regularPeople + 10 * trains + 2 * (airmen + ambassadors + scientists) * airports + 2 * (sailors +
                    privates) * highways + 2 * (trains + regularPeople) * railroads + 10 * palaces;
        }

        public int wages() {
            return airmen + sailors + privates + 2 * (trains + ambassadors + scientists + architects);
        }

        public int profit() {
            return income() - wages();
        }
    }

    private static String getWaitString(){
        switch ((int) (Math.random() * 7)){
            case 0:
                return "We will win!";
            case 1:
                return "Winny the Pooh, Winny the Pooh";
            case 2:
                return "Who washed Washington's white woolen underwear when Washington's laundry woman, went west?";
            case 3:
                return "What's up doc?";
            case 4:
                return "Why is this taking so long?";
            case 5:
                return "Wool is better than cotton.";
            case 6:
                return "Will I win?";
            case 7:
                return "What's your favorite color?";
            default:
                return "What! This message should not be being printed.";
        }
    }

}

açıklama

İki hedefi var.

  1. Sınırsız altın
  2. Sınırsız ordular.

Altın nasıl alınır:

Politikacı, sadece havaalanları, otoyolları ve demiryolları inşa etmek için mimarları işe alır. Para yığınları oldukça çabuk dökülmeye başlar. Vergileri artırdıktan sonra, Politikacı'nın sınırsız parası var.

Ordular nasıl alınır:

Bu biraz daha zor. Sınırlı insanlarla, sadece küçük bir ordu elde edebilirsiniz. Büyükelçilerle, daha büyük orduları bile işe alabilir, ancak hala yeterince büyük değiller. Bazı tefekkürlerden sonra Politikacı, diğer ulusları fethetmenin ve halkı köleleştirmenin ona oldukça büyük ordular verdiğini anladı. Fakat onlar hala yeterince büyük değiller. Bazı bilim adamlarını işe aldıktan sonra, ona ölüleri yetiştirmenin sırrını keşfettiklerini söylediler, ne yazık ki, dirilişten sonra artık asker değiller. Derin tefekkürden sonra Politikacı bunun kendi yararına olduğunu anlar ve yükselen ölüleri daha fazla asker ve büyükelçi olan elçi olarak tutar.


Ne yazık ki, bu politikacı - her politikacı gibi - hepsi boş sözler ve Sehtimian'a dayanamıyor. (30. turda, sondan diğerine canlı kaybetti)
Thrax,

Şimdi dünyaya hükmetti, tebrikler!
Thrax

@ Thrax Ve o hala!
TheNumberOne

Etkilendim ... tüm Politikacılar gibi ... o değişime çok uyarlanabilir :)
Moogie

Savaş çok şiddetli, ama siyasetçi şimdilik üste çıkmadı!
Thrax

5

Huzur, Lua

Din yoluyla Serenity'ye ulaşmaya odaklanır. Kafirleri dönüştürmeye ve yeni tapınaklar inşa ederek inancını genişletmeden önce şehirlerin kritik bir duruma ulaşmasını beklemeye çalışıyor.

function explode(d,p)
  local t, ll; t={}; ll=0
  if(#p == 1) then return {p} end
    while true do
      l=string.find(p,d,ll,true)
      if l~=nil then table.insert(t, string.sub(p,ll,l-1)); ll=l+1
      else table.insert(t, string.sub(p,ll)); break
      end
    end
  return t
end

function soldiers(t)
  local s
  s = t["WARLOCKS"] + t["CRUSADERS"] + t["AMAZONS"]
  return s
end

function reserve(t)
  local s
  s = t["GOLD"] - (3 * soldiers(t))
  return s
end

parameters = {"PLAYER", "TOWN", "GOLD", "CORPSES", "WARLOCKS", "CRUSADERS", "AMAZONS", 
"CORSAIRS", "BISHOPS", "NECROMANCERS", "ARCHITECTS", "PEONS", "TEMPLES", "BARRACKS", 
"ESTATES", "PALACES"}

if (#arg < 1) then
  print("5 5 5 10 10 1 3 59")  
else

  args = explode(";", arg[1])

  local round = tonumber(args[1])
  local phase = tonumber(args[2])
  local playerID = tonumber(args[3])
  local thisTownID = tonumber(args[4])
  local thisTown = {}
  local towns = {}
  local enemyTowns = {}
  local myTowns = {}
  local output = "W"
  local stock = 200
  local peons = 33
  local bishops = 20

  for i=5,#args,1 do
    local town = explode("_", args[i])
    towns[town[2]] = {}
    for key, value in pairs(town) do 
      towns[town[2]][parameters[key]] = tonumber(value)
    end
  end

  for i, town in pairs(towns) do 
    if town["PLAYER"] == playerID then
      if town["TOWN"] == thisTownID then thisTown = town end
      table.insert(myTowns, town)
    else
      table.insert(enemyTowns, town)
    end
  end

  if phase == 2 then
    local richestTown
    for i, town in pairs(myTowns) do
      if richestTown == nil then richestTown = town end
      if richestTown["GOLD"] > town["GOLD"] then richestTown = town end
    end
    if thisTown["CORSAIRS"] > 0 then output = "S "..richestTown["TOWN"].." "..thisTown["CORSAIRS"] end
  elseif phase == 3 then 
    local necromancers = 0
    local architects = 0
    if thisTown["NECROMANCERS"] < 1 then necromancers = 1 end
    if thisTown["ARCHITECTS"] < 1 then architects = 1 end
    if reserve(thisTown) > stock and thisTown["PEONS"] > peons then output = "R 0 0 0 0 "..math.max(0, math.min(thisTown["BISHOPS"] - bishops, math.min(thisTown["PEONS"] - peons, math.floor((reserve(thisTown) - stock) / 20)))).." "..necromancers.." "..architects end
  elseif phase == 6 then
    local biggestTown
    for i, town in pairs(enemyTowns) do
      if biggestTown == nil then biggestTown = town end
      if soldiers(biggestTown) > soldiers(town) then biggestTown = town end  
    end
    local units = math.min(thisTown["BISHOPS"], math.floor((reserve(thisTown) - stock) / 50))
    if (reserve(thisTown) > stock) then output = "C "..biggestTown["TOWN"].." "..math.floor(units/3).." "..math.floor(units/3).." "..math.floor(units/3) end
  elseif phase == 7 then 
    for i, town in pairs(enemyTowns) do
      if soldiers(town) <= 3 and soldiers(thisTown) >= 9 then output = "A "..town["TOWN"].." 3 3 3"; break end
    end
  elseif phase == 8 then
    if thisTown["CORPSES"] > 0 and thisTown["NECROMANCERS"] > 0 then output = "R "..math.min(thisTown["NECROMANCERS"] * 5, thisTown["CORPSES"]) end
  elseif phase == 9 then
    local smallestTown, poorestTown
    for i, town in pairs(myTowns) do
      if smallestTown == nil then smallestTown = town end
      if poorestTown == nil then poorestTown = town end
      if soldiers(smallestTown) < soldiers(town) then smallestTown = town end  
      if poorestTown["GOLD"] < town["GOLD"] then poorestTown = town end  
      if (soldiers(thisTown) - soldiers(smallestTown) >= 18) then output = "M "..thisTown["TOWN"].." 3 3 3" break end
      if (thisTown["GOLD"] - poorestTown["GOLD"] >= 600) then output = "T "..thisTown["TOWN"].." 300" break end
    end
  elseif phase == 11 then
     if reserve(thisTown) > (stock + 200) then output = "B T" end
  end

  print(output)

end

Koş lua Serenity.lua(Lua 5.2 gerektirir)


5

Zealotlar (Python)

(CarpetPython'un koduna göre.)

Mümkün olduğunca açgözlü tapınaklar inşa! Ölüleri yükselt! Kâfir dönüştürün!

import sys
from random import *
from operator import itemgetter

(PLAYER, TOWN, GOLD, CORPSES, WARLOCKS, CRUSADERS, AMAZONS, 
CORSAIRS, BISHOPS, NECROMANCERS, ARCHITECTS, PEONS, 
TEMPLES, BARRACKS, ESTATES, PALACES) = range(16)

def getstrength(t):
    return t[WARLOCKS]+t[CRUSADERS]*1.5+t[AMAZONS]/1.5

if len(sys.argv) < 2:
    print 20, 5, 5, 10, 8, 5, 7, 40
else:
    parts = sys.argv[1].split(';')
    turn, phase, me, thistown = [int(parts.pop(0)) for i in range(4)]
    towns = [[int(v) for v in town.split('_')] for town in parts]
    enemy = [t for t in towns if t[PLAYER] != me]
    mytowns = [t for t in towns if t[PLAYER] == me]
    here = [t for t in mytowns if t[TOWN] == thistown][0]
    otherids = [t[TOWN] for t in enemy]
    strength = sorted(enemy, key=getstrength)
    rich = sorted(enemy, key=itemgetter(GOLD))

    output = ''
    if phase == 2:
        output = 'S %s %s' % (rich[-1][TOWN], here[CORSAIRS])
    elif phase == 3:
        Warlocks=Crusaders=Amazons=Corsairs=Bishops=Necromancers=Architects=0
        if here[CORPSES] > 5*here[NECROMANCERS]:
            Necromancers = 1
        if here[PEONS] > 50*here[BISHOPS]:
            Bishops = 1
        if here[WARLOCKS] < strength[0][CRUSADERS]:
            Warlocks = 2
            Amazons = 2
        if here[WARLOCKS] < here[AMAZONS]:
            Warlocks += 1
        if here[GOLD] > 200:
            Architects = 1
        if rich[-1][GOLD] > 100+2*here[GOLD]:
            Corsairs = 1
        output = 'R %s %s %s %s %s %s %s' % (Warlocks,Crusaders,Amazons,Corsairs,Bishops,Necromancers,Architects)
    elif phase == 6:
        if here[GOLD] > 300:
            output = 'C %s %s %s %s' % (strength[0][TOWN],here[GOLD]/300,here[GOLD]/300,here[GOLD]/300)
    elif phase == 7:
        target = strength[0]
        if getstrength(target) < getstrength(here)*3/5:
            output = 'A %s %s %s 0' % (target[TOWN],here[WARLOCKS]*3/4,target[AMAZONS])
    elif phase == 8:
        if here[CORPSES] > 10:
            output = 'R %s' % (here[NECROMANCERS]*5)
    elif phase == 9:
        pass  # move people or gold here
    elif phase == 11 and here[GOLD] > 300:
        output = 'B T'   # Build a temple!

    print output if output else 'W'

6
Bu bana Java gibi gözükmüyor.
Ypnypn

5
Sanırım piton demek
istedin

@Thrax, eksik kolonu kastediyor
rorlork

@soktinpk: Evet, bu python; Java'yı nasıl aldım bilmiyorum.
MegaTom

@ TheBestOne Ben düzelttim.
MegaTom

4

Komutan, Java

Komutan, denetleyiciyle birlikte oluşturduğum 2 varsayılan bottan biri (diğeri hiçbir şey yapmayan Uyuyan). Komutan bir fatih ve kaynaklarının her birini tahakküm altına almak için kullanmaya çalışacak.

import java.util.ArrayList;
import java.util.List;

public class Commander {

    int round;
    int phase;
    int playerID;
    int thisTownID;

    List<Town> towns;
    List<Town> myTowns;
    List<Town> otherTowns;

    Town thisTown;

    public static void main(String[] args){
        if (args.length == 0) {
            System.out.println("15 10 12 10 7 5 1 40");
        } else {
            new Commander().conquer(args[0].split(";"));
        }
    }

    private void conquer(String[] args) {

        round = Integer.parseInt(args[0]);
        phase = Integer.parseInt(args[1]);
        playerID = Integer.parseInt(args[2]);
        thisTownID = Integer.parseInt(args[3]);

        towns = new ArrayList<>();
        myTowns = new ArrayList<>();
        otherTowns = new ArrayList<>();

        for (int i = 4; i < args.length; i++){
            towns.add(new Town(args[i]));
        }

        for (Town town : towns){
            if (town.isMine()){
                myTowns.add(town);
                if (town.isThisTown()){
                    thisTown = town;
                }
            } else {
                otherTowns.add(town);
            }
        }

        if (phase == 2) {               // Steal
            //Command : S destinationId corsairs
            steal();
        } else if (phase == 3) {        // Recruit
            //Command : R warlocks crusaders amazons corsairs bishops necromancers architects
            recruit()   ;
        } else if (phase == 6) {        // Convert
            //Command : C destinationId warlocks crusaders amazons 
            convert();
        } else if (phase == 7) {        // Attack
            //Command : A destinationId warlocks crusaders amazons
            attack();   
        } else if (phase == 8) {        // Resurrect
            //Command : R corpses
            resurrect();    
        } else if (phase == 9) {        // Move
            //Command : M destinationId warlocks crusaders amazons corsairs bishops necromancers architects
            move();
        } else if (phase == 11) {       // Build
            //Command : B building building building... (T: Temple, B: Barracks, E: Estate, P: Palace)
            build();
        }
    }

    private void steal() {
        Town richestTown = otherTowns.stream().max((a,b) -> a.gold - b.gold).get();
        System.out.println("S " + richestTown.getId() + " " + thisTown.getCorsairs());
    }

    private void recruit() {

        int maxUnitsToRecruits = Math.floorDiv(thisTown.getPeons() - thisTown.getUnits(), 2);
        int goldAvailable = thisTown.getGold() - (thisTown.getUnits() * 5);
        int unitsRecruited = 0;
        int cost = 10;
        int[] recruits = new int[3];
        int i = 0;
        int necromancers = Math.max(0, 5 - thisTown.getNecromancers());
        while (goldAvailable >= 0 && unitsRecruited <= maxUnitsToRecruits) {
             i = (i >= recruits.length - 1 ? 0 : i+1);
             recruits[i]++;
             unitsRecruited++;
             goldAvailable-=cost;
        }
        if (unitsRecruited > 0) {
            System.out.println("R " + recruits[0] + " " + recruits[1] + " " + recruits[2] + " 0 0 " +  necromancers + " 0");
        } else {
            System.out.println("W");
        }
    }

    private void convert() {

        Town biggestTown = otherTowns.stream().max((a,b) -> a.getCitizens() - b.getCitizens()).get();
        int goldAvailable = thisTown.getGold() - (thisTown.getUnits() * 5);
        int bishopsAvailable = thisTown.getBishops();
        int unitsConverted = 0;
        int cost = 50;
        int[] converts = new int[3];
        int i = 0;
        while (goldAvailable >= 0 && unitsConverted <= bishopsAvailable) {
             i = (i >= converts.length - 1 ? 0 : i+1);
             converts[i]++;
             goldAvailable-=cost;
        }
        System.out.println("C " + biggestTown.getId() + " " + converts[0] + " " + converts[1] + " " + converts[2]);  
    }

    private void attack() {

        Town lessDefendedTown = otherTowns.stream().max((a,b) -> a.getSoldiers() - b.getSoldiers()).get();
        int neededWarlocks =  thisTown.getWarlocks() - lessDefendedTown.getWarlocks();
        int neededCrusaders = thisTown.getCrusaders() - lessDefendedTown.getCrusaders();
        int neededAmazons = thisTown.getAmazons() - lessDefendedTown.getAmazons() ;

        if (neededWarlocks > 0 && neededCrusaders > 0 && neededAmazons > 0) {
            System.out.println("A " + lessDefendedTown.getId() + " " + (lessDefendedTown.getWarlocks() + 1) + " " + (lessDefendedTown.getCrusaders() + 1) + " " + (lessDefendedTown.getAmazons() + 1));  
        } else {
            System.out.println("W");
        }

    }

    private void move() {
        System.out.println("W");
    }

    private void resurrect() {
        int goldAvailable = thisTown.getGold() - (thisTown.getUnits() * 5);
        int corpsesAvailable = thisTown.getCorpses();
        int availableNecromancers = thisTown.getNecromancers();
        int raiseCapacity = availableNecromancers * 5;
        int raisedCorpses = 0;
        while (corpsesAvailable >= 0 && raiseCapacity >= 0 && goldAvailable >= 0) {
            raisedCorpses++;
            corpsesAvailable--;
            goldAvailable -= 20;
            raiseCapacity--;
        }
        if (raisedCorpses > 0) {
            System.out.println("R " + raisedCorpses);
        } else {
            System.out.println("W");
        }
    }

    private void build() {
        int goldAvailable = thisTown.getGold() - (thisTown.getUnits() * 5);
        if (goldAvailable >= 400) {
            System.out.println("B B");
        } else {
            System.out.println("W");
        }
    }

    private class Town {

        private final int ownerId;
        private final int id;
        private final int gold;
        private final int corpses;
        private final int warlocks;
        private final int crusaders;
        private final int amazons;
        private final int corsairs;
        private final int bishops;
        private final int necromancers;
        private final int architects;
        private final int peons;
        private final int temples;
        private final int barracks;
        private final int estates;
        private final int palaces;

        public Town(String string){
            String[] args = string.split("_");
            ownerId = Integer.parseInt(args[0]);
            id = Integer.parseInt(args[1]);
            gold = Integer.parseInt(args[2]);
            corpses = Integer.parseInt(args[3]);
            warlocks = Integer.parseInt(args[4]);
            crusaders = Integer.parseInt(args[5]);
            amazons = Integer.parseInt(args[6]);
            corsairs = Integer.parseInt(args[7]);
            bishops = Integer.parseInt(args[8]);
            necromancers = Integer.parseInt(args[9]);
            architects = Integer.parseInt(args[10]);
            peons = Integer.parseInt(args[11]);
            temples = Integer.parseInt(args[12]);
            barracks = Integer.parseInt(args[13]);
            estates = Integer.parseInt(args[14]);
            palaces = Integer.parseInt(args[15]);
        }
        public int getOwnerId() {
            return ownerId;
        }
        public int getId() {
            return id;
        }
        public int getGold() {
            return gold;
        }
        public int getCorpses() {
            return corpses;
        }
        public int getWarlocks() {
            return warlocks;
        }
        public int getCrusaders() {
            return crusaders;
        }
        public int getAmazons() {
            return amazons;
        }
        public int getCorsairs() {
            return corsairs;
        }
        public int getBishops() {
            return bishops;
        }
        public int getNecromancers() {
            return necromancers;
        }
        public int getArchitects() {
            return architects;
        }
        public int getPeons() {
            return peons;
        }
        public int getTemples() {
            return temples;
        }
        public int getBarracks() {
            return barracks;
        }
        public int getEstates() {
            return estates;
        }
        public int getPalaces() {
            return palaces;
        }
        public int getBuildings() {
            return getTemples() + getBarracks() + getEstates() + getPalaces();
        }
        public int getSoldiers() {
            return getWarlocks() + getCrusaders() + getAmazons();
        }
        public int getUnits() {
             return getSoldiers() + getCorsairs() + getBishops() + getNecromancers() + getArchitects();
        }
        public int getCitizens() {
            return getUnits() + getPeons();
        }
        public boolean isMine(){
            return getOwnerId() == playerID;
        }
        public boolean isThisTown(){
            return id == thisTownID;
        }

    }

}

4

Tereyağı

Bu tereyağı önceki tereyağı ile aynı şekilde hareket eder. Önceki tereyağı aksine, bu nadiren hızlı bir şekilde zengin olur. Ne yazık ki, Genç Küpeler, Lannisters ile birlikte, waffle'larındaki tereyağı gibidir. Bu nedenle, tereyağı hızla tüketilir.

import java.util.ArrayList;
import java.util.List;

public class Butter {

    int round;
    int phase;
    int playerID;
    int thisTownID;

    List<Town> towns;
    List<Town> myTowns;
    List<Town> otherTowns;

    Town thisTown;

    public Butter(String... args) {
        args = args[0].split(";");

        round = Integer.parseInt(args[0]);
        phase = Integer.parseInt(args[1]);
        playerID = Integer.parseInt(args[2]);
        thisTownID = Integer.parseInt(args[3]);

        towns = new ArrayList<>();
        myTowns = new ArrayList<>();
        otherTowns = new ArrayList<>();

        for (int i = 4; i < args.length; i++){
            towns.add(new Town(args[i]));
        }

        for (Town town : towns){
            if (town.isMine()){
                myTowns.add(town);
                if (town.isThisTown()){
                    thisTown = town;
                }
            } else {
                otherTowns.add(town);
            }
        }
    }

    public static void main(String[] args){
        if (args.length == 0) {
            System.out.println("12 12 12 12 13 13 13 13");
        } else {
            System.out.println(new Butter(args[0]).spread());
        }
    }

    private String spread() {

        if (phase == 2) {               // Steal
            //Command : S destinationId corsairs
            return steal();
        } else if (phase == 3) {        // Recruit
            //Command : R warlocks crusaders amazons corsairs bishops necromancers architects
            return recruit()    ;
        } else if (phase == 6) {        // Convert
            //Command : C destinationId warlocks crusaders amazons
            return convert();
        } else if (phase == 7) {        // Attack
            //Command : A destinationId warlocks crusaders amazons
            return attack();
        } else if (phase == 8) {        // Resurrect
            //Command : R corpses
            return resurrect();
        } else if (phase == 9) {        // Move
            //Command : M destinationId warlocks crusaders amazons corsairs bishops necromancers architects
            return move();
        } else if (phase == 11) {       // Build
            //Command : B building building building... (T: Temple, B: Barracks, E: Estate, P: Palace)
            return build();
        }
        throw new IllegalStateException(phase + "");
    }

    private String steal() {
        if (thisTown.getCorsairs() <= 0){
            return "W";
        }
        int mostGold = Integer.MIN_VALUE;
        Town richestTown = null;
        for (Town town : otherTowns){
            if (town.getGold() > mostGold){
                mostGold = town.getGold();
                richestTown = town;
            }
        }
        return "S " + richestTown.getId() + " " + thisTown.getCorsairs();
    }

    private String recruit() {
        int gold = thisTown.getFreeGold();

        int peons = thisTown.getPeons();
        int warlocks = thisTown.getWarlocks();
        int crusaders = thisTown.getCrusaders();
        int amazons = thisTown.getAmazons();
        int corsairs = thisTown.getCorsairs();
        int bishops = thisTown.getBishops();
        int necromancers = thisTown.getNecromancers();
        int architects = thisTown.getArchitects();

        int totalPeople = peons+warlocks+crusaders+amazons+corsairs+bishops+necromancers+architects;
        int averagePeople = totalPeople / 8;
        int extraPeons = peons - averagePeople;
        if (extraPeons <= 0 || gold <= 0){
            return "W";
        }

        int warlocksToAdd = warlocks < averagePeople ? 0 : warlocks - averagePeople;
        int crusadersToAdd = crusaders < averagePeople ? 0 : crusaders - averagePeople;
        int amazonsToAdd = amazons < averagePeople ? 0 : amazons - averagePeople;
        int corsairsToAdd = corsairs < averagePeople ? 0 : corsairs - averagePeople;
        int bishopsToAdd = bishops < averagePeople ? 0 : bishops - averagePeople;
        int necromancersToAdd = necromancers < averagePeople ? 0 : necromancers - averagePeople;
        int architectsToAdd = architects < averagePeople ? 0 : architects - averagePeople;

        warlocksToAdd = warlocksToAdd * 11 > gold ? gold / 11 : warlocksToAdd;
        gold -= warlocksToAdd * 11;
        crusadersToAdd = crusadersToAdd * 11 > gold ? gold / 11 : crusadersToAdd;
        gold -= crusadersToAdd * 11;
        amazonsToAdd = amazonsToAdd * 11 > gold ? gold / 11 : amazonsToAdd;
        gold -= amazonsToAdd * 11;
        corsairsToAdd = corsairsToAdd * 14 > gold ? gold / 14 : corsairsToAdd;
        gold -= corsairsToAdd * 14;
        bishopsToAdd = bishopsToAdd * 22 > gold ? gold / 22 : bishopsToAdd;
        gold -= bishopsToAdd * 22;
        necromancersToAdd = necromancersToAdd * 22 > gold ? gold / 22: necromancersToAdd;
        gold -= necromancersToAdd * 22;
        architectsToAdd = architectsToAdd * 17 > gold ? gold / 17 : architectsToAdd;
        gold -= architectsToAdd * 17;

        warlocksToAdd = warlocksToAdd > extraPeons ? extraPeons : warlocksToAdd;
        extraPeons -= warlocksToAdd;
        crusadersToAdd = crusadersToAdd > extraPeons ? extraPeons : crusadersToAdd;
        extraPeons -= crusadersToAdd;
        amazonsToAdd = amazonsToAdd > extraPeons ? extraPeons : amazonsToAdd;
        extraPeons -= amazonsToAdd;
        corsairsToAdd = corsairsToAdd > extraPeons ? extraPeons : corsairsToAdd;
        extraPeons -= corsairsToAdd;
        bishopsToAdd = bishopsToAdd > extraPeons ? extraPeons : bishopsToAdd;
        extraPeons -= bishopsToAdd;
        necromancersToAdd = necromancersToAdd > extraPeons ? extraPeons : necromancersToAdd;
        extraPeons -= necromancersToAdd;
        architectsToAdd = architectsToAdd > extraPeons ? extraPeons : architectsToAdd;

        return "R " + warlocksToAdd + " " + crusadersToAdd + " " + amazonsToAdd + " " + corsairsToAdd + " " +
                bishopsToAdd + " " + necromancersToAdd + " " + architectsToAdd;
    }

    private String convert() {
        return "W";
    }

    private String attack() {
        for (Town town : otherTowns){
            if (town.getSoldiers() * 4 < thisTown.getSoldiers()){
                return "A " + town.getId() + " " + thisTown.getWarlocks() / 2 + " " + thisTown.getCrusaders() / 2 + " "
                        + thisTown.getAmazons() / 2;
            }
        }
        return "W";
    }

    private String move() {
        int totalWarlocks = 0;
        int totalCrusaders = 0;
        int totalAmazons = 0;
        int totalCorsairs = 0;
        int totalBishops = 0;
        int totalNecromancers = 0;
        int totalArchitects = 0;
        for (Town town : myTowns){
            totalWarlocks += town.getWarlocks();
            totalCrusaders += town.getCrusaders();
            totalAmazons += town.getAmazons();
            totalCorsairs += town.getCorsairs();
            totalBishops += town.getBishops();
            totalNecromancers += town.getNecromancers();
            totalArchitects += town.getArchitects();
        }
        int averageWarlocks = totalWarlocks / myTowns.size();
        int averageCrusaders = totalCrusaders / myTowns.size();
        int averageAmazons = totalAmazons / myTowns.size();
        int averageCorsairs = totalCorsairs / myTowns.size();
        int averageBishops = totalBishops / myTowns.size();
        int averageNecromancers = totalNecromancers / myTowns.size();
        int averageArchitects = totalArchitects / myTowns.size();

        Town worstTown = null;
        int biggestDifference = Integer.MIN_VALUE;
        for (Town town : myTowns){
            int difference = 0;
            difference += town.getWarlocks() < averageWarlocks ? averageWarlocks - town.getWarlocks() : 0;
            difference += town.getCrusaders() < averageCrusaders ? averageCrusaders - town.getCrusaders() : 0;
            difference += town.getAmazons() < averageAmazons ? averageAmazons - town.getAmazons() : 0;
            difference += town.getCorsairs() < averageCorsairs ? averageCorsairs - town.getCorsairs() : 0;
            difference += town.getBishops() < averageBishops ? averageBishops - town.getBishops() : 0;
            difference += town.getNecromancers() < averageNecromancers ? averageNecromancers - town.getNecromancers() :
                    0;
            difference += town.getArchitects() < averageArchitects ? averageArchitects - town.getArchitects() : 0;
            if (difference > biggestDifference){
                worstTown = town;
                biggestDifference = difference;
            }
        }
        int neededWarlocks = worstTown.getWarlocks() < averageWarlocks ? averageWarlocks - worstTown.getWarlocks() : 0;
        int neededCrusaders = worstTown.getCrusaders() < averageCrusaders ? averageCrusaders - worstTown.getCrusaders()
                : 0;
        int neededAmazons = worstTown.getAmazons() < averageAmazons ? averageAmazons - worstTown.getAmazons() : 0;
        int neededCorsairs = worstTown.getCorsairs() < averageCorsairs ? averageCorsairs - worstTown.getCorsairs() : 0;
        int neededBishops = worstTown.getBishops() < averageBishops ? averageBishops - worstTown.getBishops() : 0;
        int neededNecromancers = worstTown.getNecromancers() < averageNecromancers ? averageNecromancers - worstTown.
                getNecromancers() : 0;
        int neededArchitects = worstTown.getArchitects() < averageArchitects ? averageArchitects - worstTown.
                getArchitects() : 0;
        return "M " + worstTown.getId() + " " + neededWarlocks + " " + neededCrusaders + " " + neededAmazons + " " +
                neededCorsairs + " " + neededBishops + " " + neededNecromancers + " " + neededArchitects;
    }

    private String resurrect() {
        return "R " + thisTown.getCorpses();
    }

    private String build() {
        if (thisTown.getGold() > 500){
            return "B P";
        }
        if (thisTown.getGold() > 200){
            return "B T";
        }
        return "W";
    }

    private class Town {

        private final int ownerId;
        private final int id;
        private final int gold;
        private final int corpses;
        private final int warlocks;
        private final int crusaders;
        private final int amazons;
        private final int corsairs;
        private final int bishops;
        private final int necromancers;
        private final int architects;
        private final int peons;
        private final int temples;
        private final int barracks;
        private final int estates;
        private final int palaces;

        public Town(String string){
            String[] args = string.split("_");
            ownerId = Integer.parseInt(args[0]);
            id = Integer.parseInt(args[1]);
            gold = Integer.parseInt(args[2]);
            corpses = Integer.parseInt(args[3]);
            warlocks = Integer.parseInt(args[4]);
            crusaders = Integer.parseInt(args[5]);
            amazons = Integer.parseInt(args[6]);
            corsairs = Integer.parseInt(args[7]);
            bishops = Integer.parseInt(args[8]);
            necromancers = Integer.parseInt(args[9]);
            architects = Integer.parseInt(args[10]);
            peons = Integer.parseInt(args[11]);
            temples = Integer.parseInt(args[12]);
            barracks = Integer.parseInt(args[13]);
            estates = Integer.parseInt(args[14]);
            palaces = Integer.parseInt(args[15]);
        }
        public int getOwnerId() {
            return ownerId;
        }
        public int getId() {
            return id;
        }
        public int getGold() {
            return gold;
        }
        public int getCorpses() {
            return corpses;
        }
        public int getWarlocks() {
            return warlocks;
        }
        public int getCrusaders() {
            return crusaders;
        }
        public int getAmazons() {
            return amazons;
        }
        public int getCorsairs() {
            return corsairs;
        }
        public int getBishops() {
            return bishops;
        }
        public int getNecromancers() {
            return necromancers;
        }
        public int getArchitects() {
            return architects;
        }
        public int getPeons() {
            return peons;
        }
        public int getTemples() {
            return temples;
        }
        public int getBarracks() {
            return barracks;
        }
        public int getEstates() {
            return estates;
        }
        public int getPalaces() {
            return palaces;
        }
        public int getBuildings() {
            return getTemples() + getBarracks() + getEstates() + getPalaces();
        }
        public int getSoldiers() {
            return getWarlocks() + getCrusaders() + getAmazons();
        }
        public int getUnits() {
            return getSoldiers() + getCorsairs() + getBishops() + getNecromancers() + getArchitects();
        }
        public int getCitizens() {
            return getUnits() + getPeons();
        }
        public boolean isMine(){
            return getOwnerId() == playerID;
        }
        public boolean isThisTown(){
            return id == thisTownID;
        }
        public int neededGold(){
            return 2 * getUnits() - getSoldiers();
        }
        public int getFreeGold(){
            return gold - neededGold();
        }

    }

}

4

Sehtimianer, Java

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;

public class Sehtimianer {
private static final int GOLD_MAX_DEBT = 200;
private static final int BIRTH_ROUND = 5;
private static final int ZOMBIE_WAKING_CHANCE = 10;
private static final int NECRO_RAISE_CAPACITY = 5;
private static final int DEMON_SUMMON_CHANCE = 10;
private static final int BISHOP_PRAYER_CAPACITY = 50;
private static final int CORSAIR_SURVEILLANCE_RATIO = 5;

public static final int GOLD_PER_WARLOCK = -1;
public static final int GOLD_PER_CRUSADER = -1;
public static final int GOLD_PER_AMAZON = -1;
public static final int GOLD_PER_CORSAIR = -2;
public static final int GOLD_PER_BISHOP = -2;
public static final int GOLD_PER_NECRO = -2;
public static final int GOLD_PER_ARCHITECT = -2;
public static final int GOLD_PER_PEON = 5;

public static final int GOLD_PER_RESURRECTION = 20;
public static final int GOLD_PER_CONVERSION = 50;
public static final int GOLD_PER_STEAL = 10;

public static final int GOLD_RECRUIT_WARLOCK = 10;
public static final int GOLD_RECRUIT_CRUSADER = 10;
public static final int GOLD_RECRUIT_AMAZON = 10;
public static final int GOLD_RECRUIT_CORSAIR = 12;
public static final int GOLD_RECRUIT_BISHOP = 20;
public static final int GOLD_RECRUIT_NECRO = 20;
public static final int GOLD_RECRUIT_ARCHITECT = 15;
public static final int GOLD_RECRUIT_DEFAULT = 20;

public static final int GOLD_PER_TEMPLE = 2;
public static final int GOLD_PER_BARRACKS = 2;
public static final int GOLD_PER_ESTATE = 2;
public static final int GOLD_PER_PALACE = 10;

public static final int GOLD_COST_BUILDING = 200;

public static final int COMPLETION_PER_ARCHITECT = 8;
public static final int COMPLETION_NEEDED = 100;
public static final int ARCHITECTS = (int) Math.ceil(1.0 * COMPLETION_NEEDED / COMPLETION_PER_ARCHITECT);

int round;
int phase;
int playerID;
int thisTownID;

List<Town> towns;
List<Town> myTowns;
List<Town> playerTowns;
List<Town> outlawTowns;

Town thisTown;

public static void main(String[] args) {
    if (args.length == 0) {
        System.out.println("9 9 9 24 5 2 13 29");
    } else {
        new Sehtimianer().actions(args[0].split(";"));
    }
}

private void actions(String[] args) {

    round = Integer.parseInt(args[0]);
    phase = Integer.parseInt(args[1]);
    playerID = Integer.parseInt(args[2]);
    thisTownID = Integer.parseInt(args[3]);

    towns = new ArrayList<Town>();
    myTowns = new ArrayList<Town>();
    playerTowns = new ArrayList<Town>();
    outlawTowns = new ArrayList<Town>();

    for (int i = 4; i < args.length; i++) {
        towns.add(new Town(args[i]));
    }

    for (Town town : towns) {
        if (town.isMine()) {
            myTowns.add(town);
            if (town.isThisTown()) {
                thisTown = town;
            }
        } else {
            if (town.getOwnerId() == -1) {
                outlawTowns.add(town);
            } else {
                playerTowns.add(town);
            }
        }
    }
    if (outlawTowns.size() == 0 && playerTowns.size() == 0) {
        System.out.print("WIN : D");
        return;
    }

    if (phase == 2) {
        steal();
    } else if (phase == 3) {
        recruit();
    } else if (phase == 6) {
        convert();
    } else if (phase == 7) {
        attack();
    } else if (phase == 8) {
        resurrect();
    } else if (phase == 9) {
        move();
    } else if (phase == 11) {
        build();
    }
}

private List<Town> calcStrongestPlayers() {
    if (playerTowns.size() == 0) {
        return outlawTowns;
    }

    Map<Integer, Integer> playerTownCount = new HashMap<Integer, Integer>();
    Integer count;
    int maxCount = 0;
    for (Town town : playerTowns) {
        count = playerTownCount.get(town.getOwnerId());
        if (count == null) {
            count = Integer.valueOf(1);
        } else {
            count = Integer.valueOf(count + 1);
        }
        playerTownCount.put(town.getOwnerId(), count);

        if (count > maxCount) {
            maxCount = count;
        }
    }
    Set<Integer> strongestPlayers = new HashSet<Integer>();
    for (Entry<Integer, Integer> entry : playerTownCount.entrySet()) {
        if (entry.getValue() == maxCount) {
            strongestPlayers.add(entry.getKey());
        }
    }

    return playerTowns.stream().filter(a -> strongestPlayers.contains(a.getOwnerId())).collect(Collectors.toList());
}

private void steal() {
    // S destinationId corsairs
    List<Town> afterFilter = calcStrongestPlayers().stream().filter(a -> a.getGold() > 0).collect(Collectors.toList());
    if (afterFilter.size() == 0) {
        afterFilter = calcStrongestPlayers();
    }
    Town poorestTown = afterFilter.stream().min((a, b) -> a.gold - b.gold).get();
    System.out.println("S " + poorestTown.getId() + " " + thisTown.getCorsairs());
}

private boolean willAttackSoon() {
    Town strongestTown;
    if (playerTowns.size() > 0) {
        strongestTown = playerTowns.stream().max((a, b) -> a.getSoldiers() - b.getSoldiers()).get();
        if ((thisTown.getSoldiers() + thisTown.getBishops()) / 3 <= strongestTown.getSoldiers()) {
            return false;
        }
    }

    strongestTown = calcStrongestPlayers().stream().max((a, b) -> a.getSoldiers() - b.getSoldiers()).get();

    int deltaWarlocks = thisTown.getWarlocks() - (strongestTown.getWarlocks() + strongestTown.getAmazons());
    int deltaCrusaders = thisTown.getCrusaders() - (strongestTown.getCrusaders() + strongestTown.getWarlocks());
    int deltaAmazons = thisTown.getAmazons() - (strongestTown.getAmazons() + strongestTown.getCrusaders());

    return (deltaWarlocks + deltaCrusaders + deltaAmazons) > 0;
}

private void recruit() {
    // R warlocks crusaders amazons corsairs bishops necros architects
    int peonsAvailable = Math.max(0, thisTown.getPeons() - round);

    int corsairNeed = calcCorsairsNeeded(thisTown);
    int goldForNecros = Math.min(thisTown.getCorpses(), thisTown.getNecros() * NECRO_RAISE_CAPACITY) * GOLD_PER_RESURRECTION;
    int goldAvailable = thisTown.getGold() - thisTown.getBishops() * GOLD_PER_CONVERSION - goldForNecros - GOLD_COST_BUILDING + calcWages(thisTown)
            - (calcCashflow(thisTown) < GOLD_MAX_DEBT ? (corsairNeed * CORSAIR_SURVEILLANCE_RATIO * GOLD_PER_STEAL) : 0);
    int corsairGoldAvailable = thisTown.getGold() + calcWages(thisTown) - goldForNecros;
    boolean onlyCorsair = false;
    if (goldAvailable < 0) {
        if (corsairGoldAvailable > 0) {
            onlyCorsair = true;
            goldAvailable = corsairGoldAvailable;
        } else {
            System.out.println("W");
            return;
        }
    }

    int necroNeed = Math.max(0, (int) Math.ceil(1.0 * thisTown.getCorpses() / NECRO_RAISE_CAPACITY) - thisTown.getNecros());
    necroNeed = Math.max(necroNeed, Math.min(peonsAvailable, calcOtherNecrosNeeded() / 3));
    int architectNeed = Math.max(0, ARCHITECTS - thisTown.getArchitects());

    int necros = 0;
    if (!onlyCorsair) {
        int necroCost = GOLD_RECRUIT_NECRO + GOLD_PER_RESURRECTION * NECRO_RAISE_CAPACITY - GOLD_PER_NECRO;
        necros = Math.min(necroNeed, goldAvailable / necroCost);
        goldAvailable -= necros * necroCost;
        peonsAvailable -= necros;
    }

    if (willAttackSoon()) {
        corsairNeed = calcCorsairSpread(thisTown) * 2 - thisTown.getCorsairs();
    }
    corsairNeed = (int) Math.max(corsairNeed, calcOtherCorsairsNeeded());

    int corsairCost = GOLD_RECRUIT_CORSAIR - GOLD_PER_CORSAIR;
    int corsairs = Math.min(corsairNeed, peonsAvailable);
    corsairs = Math.min(corsairs, goldAvailable / corsairCost);
    goldAvailable -= corsairs * corsairCost;
    peonsAvailable -= corsairs;

    int architects = 0;
    if (!onlyCorsair) {
        int architectCost = GOLD_RECRUIT_ARCHITECT - GOLD_PER_ARCHITECT;
        architects = Math.min(architectNeed, peonsAvailable);
        architects = Math.min(architects, goldAvailable / architectCost);
        goldAvailable -= architects * architectCost;
        peonsAvailable -= architects;
    }

    int bishops = 0;
    if (!onlyCorsair) {
        int peonParts;
        if (round <= 50) {
            peonParts = 20;
        } else if (round <= 70) {
            peonParts = 15;
        } else if (round <= 90) {
            peonParts = 10;
        } else if (round <= 95) {
            peonParts = 5;
        } else {
            peonParts = 3;
        }
        int peonsLeft = Math.max(0, thisTown.getPeons() - (necros + corsairs + architects));
        bishops = (int) Math.min(Math.min(peonsAvailable, peonsLeft / peonParts), goldAvailable / (GOLD_RECRUIT_BISHOP + GOLD_PER_CONVERSION - GOLD_PER_BISHOP));
    }

    if (corsairs > 0 || bishops > 0 || necros > 0 || architects > 0) {
        System.out.println("R 0 0 0 " + corsairs + " " + bishops + " " + necros + " " + architects);
    } else {
        System.out.println("W");
    }
}

private int calcCashflow(Town town) {
    int taxes = (town.getSurvivingPeons() * GOLD_PER_PEON);
    taxes += ((town.getWarlocks() + town.getBishops() + town.getNecros()) * (town.getTemple() * GOLD_PER_TEMPLE));
    taxes += ((town.getCrusaders() + town.getAmazons()) * (town.getBarracks() * GOLD_PER_BARRACKS));
    taxes += ((town.getSurvivingPeons() + town.getCorsairs()) * (town.getEstate() * GOLD_PER_ESTATE));
    taxes += (town.getPalace() * GOLD_PER_PALACE);

    int wages = calcWages(town);

    return taxes + wages;
}

private int calcWages(Town town) {
    int wages = (town.getWarlocks() * GOLD_PER_WARLOCK);
    wages += (town.getCrusaders() * GOLD_PER_CRUSADER);
    wages += (town.getAmazons() * GOLD_PER_AMAZON);
    wages += (town.getCorsairs() * GOLD_PER_CORSAIR);
    wages += (town.getBishops() * GOLD_PER_BISHOP);
    wages += (town.getNecros() * GOLD_PER_NECRO);
    wages += (town.getArchitects() * GOLD_PER_ARCHITECT);
    return wages;
}

private int calcCorsairSpread(Town calcTown) {
    int outlaws = 0;
    for (Town town : outlawTowns) {
        outlaws += town.getPopulation();
    }

    return (int) Math.ceil(1.0 * Math.floorDiv(outlaws, (playerTowns.size() + myTowns.size())) / CORSAIR_SURVEILLANCE_RATIO);
}

private int calcCorsairsNeeded(Town town) {
    return Math.max(0, calcCorsairSpread(town) - town.getCorsairs());
}

private int calcFreeCorsairs(Town town) {
    return Math.max(0, town.getCorsairs() - calcCorsairSpread(town));
}

private int calcOtherNecrosNeeded() {
    int necrosNeed = 0;
    for (Town town : myTowns) {
        if (town == thisTown) {
            continue;
        }
        necrosNeed += Math.max(0, (int) Math.ceil(1.0 * town.getCorpses() / NECRO_RAISE_CAPACITY) - town.getNecros());
    }
    int necrosAvailable = Math.max(0, thisTown.getNecros() - (int) Math.ceil(1.0 * thisTown.getCorpses() / NECRO_RAISE_CAPACITY));
    return Math.max(0, necrosNeed - necrosAvailable);
}

private int calcOtherCorsairsNeeded() {
    int corsairsNeed = 0;
    for (Town town : myTowns) {
        if (town == thisTown) {
            continue;
        }
        corsairsNeed += calcCorsairsNeeded(town);
    }
    return Math.max(0, corsairsNeed - calcFreeCorsairs(thisTown));
}

private void convert() {
    // C destinationId warlocks crusaders amazons
    final int MIN_CONVERT_PERCENTAGE = 10;

    int goldAvailable = thisTown.getGold() - thisTown.getCorpses() * GOLD_PER_RESURRECTION - GOLD_COST_BUILDING
            - (calcCashflow(thisTown) < GOLD_MAX_DEBT ? (calcCorsairsNeeded(thisTown) * CORSAIR_SURVEILLANCE_RATIO * GOLD_PER_STEAL) : 0);
    if (goldAvailable < 0) {
        System.out.println("W");
        return;
    }

    final int canConvert = Math.min(thisTown.getBishops(), goldAvailable / GOLD_PER_CONVERSION);
    if (canConvert == 0) {
        System.out.println("W");
        return;
    }

    List<Town> useTowns = calcStrongestPlayers();

    List<Town> afterFilter = useTowns.stream().filter(a -> a.getSoldiers() > canConvert / MIN_CONVERT_PERCENTAGE).collect(Collectors.toList());
    if (afterFilter.size() == 0) {
        if (playerTowns.size() > 0) {
            useTowns = playerTowns;
        } else {
            useTowns = outlawTowns;
        }
    }
    afterFilter = useTowns.stream().filter(a -> a.getSoldiers() > canConvert).collect(Collectors.toList());
    float getNear = 1.0f;
    while (afterFilter.size() == 0) {
        getNear -= 0.1f;
        final float toLower = getNear;
        afterFilter = useTowns.stream().filter(a -> a.getSoldiers() > canConvert * toLower).collect(Collectors.toList());
    }
    Town smallestTown = afterFilter.stream().min((a, b) -> a.getSoldiers() - b.getSoldiers()).get();

    Town convertTown;
    if (smallestTown.getSoldiers() < canConvert / MIN_CONVERT_PERCENTAGE) {
        convertTown = useTowns.stream().max((a, b) -> a.getSoldiers() - b.getSoldiers()).get();
    } else {
        convertTown = smallestTown;
    }

    int leftToConvert = canConvert;
    int warlocks = Math.min(leftToConvert, convertTown.getWarlocks());
    leftToConvert -= warlocks;
    int crusaders = Math.min(leftToConvert, convertTown.getCrusaders());
    leftToConvert -= crusaders;
    int amazons = Math.min(leftToConvert, convertTown.getAmazons());
    leftToConvert -= amazons;

    System.out.println("C " + convertTown.getId() + " " + warlocks + " " + crusaders + " " + amazons);
}

private void attack() {
    // A destinationId warlocks crusaders amazons

    Town strongestTown;
    if (playerTowns.size() > 0) {
        strongestTown = playerTowns.stream().max((a, b) -> a.getSoldiers() - b.getSoldiers()).get();
        if (thisTown.getSoldiers() / 3 <= strongestTown.getSoldiers()) {
            System.out.println("W");
            return;
        }
    }

    strongestTown = calcStrongestPlayers().stream().max((a, b) -> a.getSoldiers() - b.getSoldiers()).get();

    int warlockNeed = strongestTown.getWarlocks() + strongestTown.getAmazons();
    int crusaderNeed = strongestTown.getCrusaders() + strongestTown.getWarlocks();
    int amazonNeed = strongestTown.getAmazons() + strongestTown.getCrusaders();
    int deltaWarlocks = thisTown.getWarlocks() - warlockNeed;
    int deltaCrusaders = thisTown.getCrusaders() - crusaderNeed;
    int deltaAmazons = thisTown.getAmazons() - amazonNeed;

    if ((deltaWarlocks + deltaCrusaders + deltaAmazons) > 0) {
        // calc Needed Troops
        int warlocks = Math.min(thisTown.getWarlocks(), warlockNeed);
        int crusaders = Math.min(thisTown.getCrusaders(), crusaderNeed);
        int amazons = Math.min(thisTown.getAmazons(), amazonNeed);
        if ((warlocks + crusaders + amazons) == 0) {
            warlocks = 1;
            crusaders = 1;
            amazons = 1;
        } else {
            while (deltaWarlocks < 0 || deltaCrusaders < 0 || deltaAmazons < 0) {
                if (deltaWarlocks < 0) {
                    deltaCrusaders += deltaWarlocks;
                    crusaders -= deltaWarlocks;
                    deltaWarlocks = 0;
                }
                if (deltaCrusaders < 0) {
                    deltaAmazons += deltaCrusaders;
                    amazons -= deltaCrusaders;
                    deltaCrusaders = 0;
                }
                if (deltaAmazons < 0) {
                    deltaWarlocks += deltaAmazons;
                    warlocks -= deltaAmazons;
                    deltaAmazons = 0;
                }
            }
        }
        System.out.println("A " + strongestTown.getId() + " " + warlocks + " " + crusaders + " " + amazons);
    } else {
        System.out.println("W");
    }
}

private void resurrect() {
    // R corpses
    int goldAvailable = thisTown.getGold();
    if (goldAvailable < 0) {
        System.out.println("W");
        return;
    }

    int raise = Math.min(thisTown.getCorpses(), goldAvailable / GOLD_PER_RESURRECTION);
    if (raise > 0) {
        System.out.println("R " + raise);
    } else {
        System.out.println("W");
    }
}

private void move() {
    if (myTowns.size() == 1) {
        System.out.println("W");
        return;
    }

    // M destinationId warlocks crusaders amazons corsairs bishops necros architects
    // T DestinationId Gold

    int thisStolenGold = calcCorsairsNeeded(thisTown) * CORSAIR_SURVEILLANCE_RATIO * GOLD_PER_STEAL;
    int thisGoldAvailable = Math.max(-GOLD_MAX_DEBT, thisTown.getGold() - thisStolenGold);
    int thisCashFlow = calcCashflow(thisTown);

    if (thisGoldAvailable + thisCashFlow <= 0) {
        // Give up the town
        Town sendToTown = myTowns.stream().filter(a -> a.getId() != thisTown.getId()).max((a, b) -> a.getSoldiers() - b.getSoldiers()).get();
        System.out.print("M " + sendToTown.getId() + " " + thisTown.getWarlocks() + " " + thisTown.getCrusaders() + " " + thisTown.getAmazons() + " " + thisTown.getCorsairs() + " "
                + thisTown.getBishops() + " " + thisTown.getNecros() + " " + thisTown.getArchitects());
        return;
    }
    thisGoldAvailable += thisCashFlow;

    int thisCostOfBishop = thisTown.getTemple() * GOLD_PER_TEMPLE + GOLD_PER_BISHOP;
    int thisCostOfNecro = thisTown.getTemple() * GOLD_PER_TEMPLE + GOLD_PER_NECRO;
    int thisCostOfWarlock = thisTown.getTemple() * GOLD_PER_TEMPLE + GOLD_PER_WARLOCK;
    int thisCostOfCrusader = thisTown.getBarracks() * GOLD_PER_BARRACKS + GOLD_PER_CRUSADER;
    int thisCostOfAmazon = thisTown.getBarracks() * GOLD_PER_BARRACKS + GOLD_PER_AMAZON;
    int thisCostOfCorsair = thisTown.getEstate() * GOLD_PER_ESTATE + GOLD_PER_CORSAIR;

    int thisCorsairsAvailable = calcFreeCorsairs(thisTown);
    int thisNecrosAvailable = Math.max(0, thisTown.getNecros() - (int) Math.ceil(1.0 * thisTown.getCorpses() / NECRO_RAISE_CAPACITY));
    int thisBishopsAvailable = Math.max(0, thisTown.getBishops() - (int) Math.ceil(1.0 * thisTown.getPeons() / BISHOP_PRAYER_CAPACITY));
    int thisArchitectsAvailable = Math.max(0, thisTown.getArchitects() - ARCHITECTS);

    int strongestTownSoldiers = 0;
    if (playerTowns.size() > 0) {
        Town strongestTown = playerTowns.stream().max((a, b) -> a.getSoldiers() - b.getSoldiers()).get();
        strongestTownSoldiers = strongestTown.getSoldiers();
    }
    int thisSoldiersAvailable = Math.max(0, thisTown.getSoldiers() - strongestTownSoldiers);
    int thisWarlocksAvailable = thisSoldiersAvailable / 3;
    thisSoldiersAvailable -= thisWarlocksAvailable;
    int thisCrusadersAvailable = thisSoldiersAvailable / 2;
    thisSoldiersAvailable -= thisCrusadersAvailable;
    int thisAmazonsAvailable = thisSoldiersAvailable;
    int warlockDelta = thisWarlocksAvailable - thisTown.getWarlocks();
    int crusaderDelta = thisCrusadersAvailable - thisTown.getCrusaders();
    int amazonDelta = thisAmazonsAvailable - thisTown.getAmazons();
    while (warlockDelta > 0 || crusaderDelta > 0 || amazonDelta > 0) {
        if (warlockDelta > 0) {
            thisWarlocksAvailable -= warlockDelta;
            thisCrusadersAvailable += warlockDelta;
            crusaderDelta += warlockDelta;
            warlockDelta = 0;
        }
        if (crusaderDelta > 0) {
            thisCrusadersAvailable -= crusaderDelta;
            thisAmazonsAvailable += crusaderDelta;
            amazonDelta += crusaderDelta;
            crusaderDelta = 0;
        }
        if (amazonDelta > 0) {
            thisAmazonsAvailable -= amazonDelta;
            thisWarlocksAvailable += amazonDelta;
            warlockDelta += amazonDelta;
            amazonDelta = 0;
        }
    }

    // Calc loosing income for each x the town sends
    int tempThisGoldAvailable = thisGoldAvailable;
    if (thisCostOfCorsair > 0) {
        thisCorsairsAvailable = Math.min(thisCorsairsAvailable, tempThisGoldAvailable / thisCostOfCorsair);
        tempThisGoldAvailable -= thisCorsairsAvailable * thisCostOfCorsair;
    } // else dont plus the gold - would get too complicated
    if (thisCostOfWarlock > 0) {
        thisWarlocksAvailable = Math.min(thisWarlocksAvailable, tempThisGoldAvailable / thisCostOfWarlock);
        tempThisGoldAvailable -= thisWarlocksAvailable * thisCostOfWarlock;
    }
    if (thisCostOfCrusader > 0) {
        thisCrusadersAvailable = Math.min(thisCrusadersAvailable, tempThisGoldAvailable / thisCostOfCrusader);
        tempThisGoldAvailable -= thisCrusadersAvailable * thisCostOfCrusader;
    }
    if (thisCostOfAmazon > 0) {
        thisAmazonsAvailable = Math.min(thisAmazonsAvailable, tempThisGoldAvailable / thisCostOfAmazon);
        tempThisGoldAvailable -= thisAmazonsAvailable * thisCostOfAmazon;
    }
    if (thisCostOfNecro > 0) {
        thisNecrosAvailable = Math.min(thisNecrosAvailable, tempThisGoldAvailable / thisCostOfNecro);
        tempThisGoldAvailable -= thisNecrosAvailable * thisCostOfNecro;
    }
    if (thisCostOfBishop > 0) {
        thisBishopsAvailable = Math.min(thisBishopsAvailable, tempThisGoldAvailable / thisCostOfBishop);
        tempThisGoldAvailable -= thisBishopsAvailable * thisCostOfBishop;
    }

    boolean checkGoldNeed;
    boolean needsGold;
    for (int i = 0; i < 2; i++) {
        checkGoldNeed = i == 0;
        for (Town town : myTowns) {
            if (town == thisTown) {
                continue;
            }
            needsGold = false;

            int costOfBishop = town.getTemple() * GOLD_PER_TEMPLE + GOLD_PER_BISHOP;
            int costOfNecro = town.getTemple() * GOLD_PER_TEMPLE + GOLD_PER_NECRO;
            int costOfWarlock = town.getTemple() * GOLD_PER_TEMPLE + GOLD_PER_WARLOCK;
            int costOfCrusader = town.getBarracks() * GOLD_PER_BARRACKS + GOLD_PER_CRUSADER;
            int costOfAmazon = town.getBarracks() * GOLD_PER_BARRACKS + GOLD_PER_AMAZON;
            int costOfCorsair = town.getEstate() * GOLD_PER_ESTATE + GOLD_PER_CORSAIR;

            int corsairsNeed = calcCorsairsNeeded(town);
            int sendCorsairs = Math.min(corsairsNeed, thisCorsairsAvailable);
            int goldStolen = corsairsNeed * CORSAIR_SURVEILLANCE_RATIO * GOLD_PER_STEAL;
            int goldAvailable = town.getGold() - goldStolen;
            int goldAvailableWithCorsairs = Math.max(-GOLD_MAX_DEBT, goldAvailable + sendCorsairs * CORSAIR_SURVEILLANCE_RATIO * GOLD_PER_STEAL);
            goldAvailable = Math.max(-GOLD_MAX_DEBT, goldAvailable);
            int cashflow = calcCashflow(town);
            if (goldAvailable + cashflow < 0) {
                needsGold = true;
            }
            tryToSwim: if (goldAvailableWithCorsairs < 0) {
                int potentialCashflow = cashflow + sendCorsairs * costOfCorsair;
                if (goldAvailableWithCorsairs + potentialCashflow >= 0) {
                    break tryToSwim;
                } else {
                    int potentialGoldAvailable = goldAvailableWithCorsairs + potentialCashflow;
                    if (costOfWarlock > 0) {
                        potentialGoldAvailable += thisWarlocksAvailable * costOfWarlock;
                    }
                    if (costOfCrusader > 0) {
                        potentialGoldAvailable += thisCrusadersAvailable * costOfCrusader;
                    }
                    if (costOfAmazon > 0) {
                        potentialGoldAvailable += thisAmazonsAvailable * costOfAmazon;
                    }
                    if (costOfNecro > 0) {
                        potentialGoldAvailable += thisNecrosAvailable * costOfNecro;
                    }
                    if (costOfBishop > 0) {
                        potentialGoldAvailable += thisBishopsAvailable * costOfBishop;
                    }
                    if (potentialGoldAvailable >= 0) {
                        System.out.print("M " + town.getId() + " " + thisWarlocksAvailable + " " + thisCrusadersAvailable + " " + thisAmazonsAvailable + " " + sendCorsairs + " "
                                + thisBishopsAvailable + " " + thisNecrosAvailable + " 0");
                        return;
                    }
                }

                // Last hope, check if enough gold can rescue the town from revolt
                int goldNeeded = -(town.getGold() - goldStolen + cashflow);
                if (thisGoldAvailable >= goldNeeded) {
                    System.out.println("T " + town.getId() + " " + goldNeeded);
                    return;
                }
                System.out.println("W");
                continue;
            }

            if (checkGoldNeed && !needsGold) {
                continue;
            }

            goldAvailable = goldAvailableWithCorsairs;
            goldAvailable += cashflow + sendCorsairs * costOfCorsair;
            int sendNecros = 0;
            int sendBishops = 0;
            int sendWarlocks = 0;
            int sendCrusaders = 0;
            int sendAmazons = 0;
            int sendArchitects = 0;

            int soldiersNeed = Math.max(0, strongestTownSoldiers - town.getSoldiers());
            int lastNeededSoldiers = 0;
            while (soldiersNeed > 0 && (thisWarlocksAvailable > 0 || thisCrusadersAvailable > 0 || thisAmazonsAvailable > 0) && soldiersNeed != lastNeededSoldiers) {
                lastNeededSoldiers = soldiersNeed;
                if (thisWarlocksAvailable > 0) {
                    goldAvailable += costOfWarlock;
                    if (goldAvailable < 0) {
                        goldAvailable -= costOfWarlock;
                    } else {
                        soldiersNeed--;
                        thisWarlocksAvailable--;
                        sendWarlocks++;
                    }
                }
                if (thisCrusadersAvailable > 0) {
                    goldAvailable += costOfCrusader;
                    if (goldAvailable < 0) {
                        goldAvailable -= costOfCrusader;
                    } else {
                        soldiersNeed--;
                        thisCrusadersAvailable--;
                        sendCrusaders++;
                    }
                }
                if (thisAmazonsAvailable > 0) {
                    goldAvailable += costOfAmazon;
                    if (goldAvailable < 0) {
                        goldAvailable -= costOfAmazon;
                    } else {
                        soldiersNeed--;
                        thisAmazonsAvailable--;
                        sendAmazons++;
                    }
                }
            }

            int necrosNeed = Math.max(0, (int) Math.ceil(1.0 * town.getCorpses() / NECRO_RAISE_CAPACITY) - town.getNecros());
            int necrosCanAfford = costOfNecro < 0 ? Math.min(necrosNeed, goldAvailable / -costOfNecro) : necrosNeed;
            if (necrosCanAfford > 0) {
                sendNecros = Math.min(necrosCanAfford, thisNecrosAvailable);
                goldAvailable += sendNecros * costOfNecro;
            }

            int bishopsNeed = Math.max(0, (int) Math.ceil(1.0 * town.getPeons() / BISHOP_PRAYER_CAPACITY) - town.getBishops());
            int bishopsCanAfford = costOfBishop < 0 ? Math.min(bishopsNeed, goldAvailable / -costOfBishop) : bishopsNeed;
            if (bishopsCanAfford > 0) {
                sendBishops = Math.min(bishopsCanAfford, thisBishopsAvailable);
                goldAvailable += sendBishops * costOfBishop;
            }

            int architectsNeed = Math.max(0, (int) Math.ceil(1.0 * COMPLETION_NEEDED / COMPLETION_PER_ARCHITECT) - thisTown.getArchitects());
            int architectsCanAfford = Math.min(architectsNeed, goldAvailable / Math.abs(GOLD_PER_ARCHITECT));
            sendArchitects = Math.min(architectsCanAfford, thisArchitectsAvailable);

            if (sendWarlocks > 0 || sendCrusaders > 0 || sendAmazons > 0 || sendCorsairs > 0 || sendBishops > 0 || sendNecros > 0 || sendArchitects > 0) {
                System.out.print("M " + town.getId() + " " + sendWarlocks + " " + sendCrusaders + " " + sendAmazons + " " + sendCorsairs + " " + sendBishops + " " + sendNecros + " "
                        + sendArchitects);
                return;
            }
        }
    }

    System.out.println("W");
}

private void build() {
    // B building building building...
    // (T: Temple, B: Barracks, E: Estate, P: Palace)

    int goldAvailable = thisTown.getGold() - (calcCashflow(thisTown) < GOLD_MAX_DEBT ? (calcCorsairsNeeded(thisTown) * CORSAIR_SURVEILLANCE_RATIO * GOLD_PER_STEAL) : 0);
    if (goldAvailable >= GOLD_COST_BUILDING) {
        char building = 'E';
        int templeUnits = thisTown.getWarlocks() + thisTown.getBishops() + thisTown.getNecros();
        int barracksUnits = thisTown.getCrusaders() + thisTown.getAmazons();
        int estateUnits = thisTown.getCorsairs() + thisTown.getPeons();
        if (templeUnits > barracksUnits) {
            if (templeUnits > estateUnits) {
                building = 'T';
            }
        } else {
            if (barracksUnits > estateUnits) {
                building = 'B';
            }
        }
        System.out.println("B " + building);
    } else {
        System.out.println("W");
    }
}

private class Town {

    private final int ownerId;
    private final int id;
    private final int gold;
    private final int corpses;
    private final int warlocks;
    private final int crusaders;
    private final int amazons;
    private final int corsairs;
    private final int bishops;
    private final int necros;
    private final int architects;
    private final int peons;
    private final int temple;
    private final int barracks;
    private final int estate;
    private final int palace;

    public Town(String string) {
        String[] args = string.split("_");
        ownerId = Integer.parseInt(args[0]);
        id = Integer.parseInt(args[1]);
        gold = Integer.parseInt(args[2]);
        corpses = Integer.parseInt(args[3]);
        warlocks = Integer.parseInt(args[4]);
        crusaders = Integer.parseInt(args[5]);
        amazons = Integer.parseInt(args[6]);
        corsairs = Integer.parseInt(args[7]);
        bishops = Integer.parseInt(args[8]);
        necros = Integer.parseInt(args[9]);
        architects = Integer.parseInt(args[10]);
        peons = Integer.parseInt(args[11]);
        temple = Integer.parseInt(args[12]);
        barracks = Integer.parseInt(args[13]);
        estate = Integer.parseInt(args[14]);
        palace = Integer.parseInt(args[15]);
    }

    public int getOwnerId() {
        return ownerId;
    }

    public int getId() {
        return id;
    }

    public int getGold() {
        return gold;
    }

    public int getCorpses() {
        return corpses;
    }

    public int getWarlocks() {
        return warlocks;
    }

    public int getCrusaders() {
        return crusaders;
    }

    public int getAmazons() {
        return amazons;
    }

    public int getCorsairs() {
        return corsairs;
    }

    public int getBishops() {
        return bishops;
    }

    public int getNecros() {
        return necros;
    }

    public int getArchitects() {
        return architects;
    }

    public int getPeons() {
        return peons;
    }

    public int getSurvivingPeons() {
        int peons = this.peons;
        int zombies = Math.floorDiv(corpses, ZOMBIE_WAKING_CHANCE);
        peons = Math.max(0, peons - zombies);
        int demons = Math.floorDiv(peons - (bishops * BISHOP_PRAYER_CAPACITY), DEMON_SUMMON_CHANCE);
        peons = Math.max(0, peons - demons);
        if (round % BIRTH_ROUND == 0) {
            peons += Math.floorDiv(peons, 2);
        }
        return peons;
    }

    public int getTemple() {
        return temple;
    }

    public int getBarracks() {
        return barracks;
    }

    public int getEstate() {
        return estate;
    }

    public int getPalace() {
        return palace;
    }

    public int getSoldiers() {
        return getWarlocks() + getCrusaders() + getAmazons();
    }

    public int getUnits() {
        return getSoldiers() + getCorsairs() + getBishops() + getNecros() + getArchitects();
    }

    public int getPopulation() {
        return getUnits() + getPeons();
    }

    public boolean isMine() {
        return getOwnerId() == playerID;
    }

    public boolean isThisTown() {
        return id == thisTownID;
    }
}
}

Böyle bir şey üzerinde çalışıyordum. Bunun çılgınca zengin olacağını söylemek doğru muyum?
TheNumberOne

Evet, gerçekten çok fazla gelir elde ediyor xD
Sehtim

3

Machiavelli, Python 2

Lord Machiavelli, başarılı olmak için gerekli politika ve askeri alanlarda deneyimlidir. Aldatıcı stratejisini yönlendiren karmaşık bir mantık geliştirdi, şimdi planı ilerledikçe gölgelerden izliyor ...

import sys, re
from random import *
from operator import itemgetter
import cPickle

(PLAYER, TOWN, GOLD, CORPSES, WARLOCKS, CRUSADERS, AMAZONS, 
CORSAIRS, BISHOPS, NECROMANCERS, ARCHITECTS, PEONS, 
TEMPLES, BARRACKS, ESTATES, PALACES) = range(16)

def getfighters(t): return sum(t[WARLOCKS:WARLOCKS+3])
def threat(t): return t[2] + sum(t[4:12])*12 + sum(t[12:16])*200
def spyon(t): return ( t[2] + min(30,t[3])*5 + t[11]*10 + 
    sum(t[12:16])*200 - getfighters(t)*20 )
def needs(t): return [bandits/5+1, t[PEONS]/50+1, t[CORPSES]/5+1, 7]
def wants(t): return [max(0, g-h) for g,h in zip(needs(t), t[7:11])]
def helpcheck(t): return sum(wants(t))

def choose(frequency, picks, span):
    'Return <picks> counts using samples from <frequency> in list <span>'
    choices = [choice(frequency) for i in range(picks)]
    return [choices.count(i) for i in range(span)]

if len(sys.argv) < 2:
    print 5, 15, 10, 20, 3, 4, 7, 36
else:
    parts = sys.argv[1].split(';')
    turn, phase, me, thistown = [int(parts.pop(0)) for i in range(4)]
    towns = [map(int, re.split(r'_', town)) for town in parts]
    # Analysis:
    enemy = [t for t in towns if t[PLAYER] != me]
    mytowns = [t for t in towns if t[PLAYER] == me]
    here = [t for t in mytowns if t[TOWN] == thistown][0]
    otherids = [t[TOWN] for t in enemy]
    fighters = sorted(enemy, key=getfighters)
    rich = sorted(enemy, key=itemgetter(GOLD))
    threats = sorted(enemy, key=threat)
    attractive = sorted(enemy, key=spyon)
    # Useful numbers:
    avgfighters = sum(map(getfighters, enemy)) / len(enemy)
    wages = getfighters(here) + sum(here[CORSAIRS:CORSAIRS+4]) * 2
    outlaws = sum(sum(t[4:12]) for t in towns if t[PLAYER] == -1)
    freetowns = len([t for t in towns if t[PLAYER] != -1])
    bandits = outlaws / freetowns
    # Depends on above
    needhelp = sorted(mytowns, key=helpcheck)
    needhelp.remove(here)

    try:
        plans = cPickle.load(open('Machiavelli.txt', 'rb'))
    except:
        plans = {}
    bribes, raises, gobuild = plans.get(thistown, (0,0,''))

    output = 'W'
    if phase == 2:
        output = 'S %s 100' % rich[-1][TOWN]  # take from the rich ...
    elif phase == 3:
        # Decide strategy here:
        cash = here[GOLD] - wages
        forces = getfighters(here)
        raises = min(here[NECROMANCERS]*5, here[CORPSES], cash/20)
        cash -= raises * 20
        bribes = trainftr = trainextra = 0
        gobuild = ''
        if forces < avgfighters:
            bribes = min(here[BISHOPS], cash/50)
            cash -= bribes * 50
            trainftr = min(max(0, here[PEONS]-30), cash/10)
            cash -= trainftr * 10
        if cash > 200 and turn % 2 == 0:
            gobuild = choice('EEB')
            cash -= 200
        bribes2 = min(here[BISHOPS] - bribes, cash/50)
        cash -= bribes2 * 50
        bribes += bribes2
        trainextra = min(max(0, here[PEONS]-30), cash/50)
        # Write plan to file:
        plans[thistown] = (bribes, raises, gobuild)
        cPickle.dump(plans, open('Machiavelli.txt', 'wb'), -1)

        # Output recruitment decision:
        if trainftr + trainextra:
            getutil = wants(here)
            if sum(getutil) > trainextra:
                utilbias = ( [0]*getutil[0]*3 + [1]*getutil[1]*3 + 
                            [2]*(getutil[2]) + [3]*(getutil[3]) )
                getutil = choose(utilbias, trainextra, 4)
            getftr = choose([0,1,1,2], trainftr, 3)
            getpers = getftr + getutil
            if sum(getutil) < trainextra:
                othernum = trainextra - sum(getutil)
                others = choose([0,1,1,2,3,4,6], othernum, 7)
                getpers = [p+q for p,q in zip(getpers, others)]
            output = 'R %u %u %u %u %u %u %u' % tuple(getpers)
    elif phase == 6:
        if bribes:
            soldiers = choose([0,1,2], bribes, 3)
            target = fighters[-1][TOWN]
            output = 'C %s %s %s %s' % tuple([target] + soldiers)
    elif phase == 7:
        if getfighters(here) > avgfighters * 1.3:
            myarmy = here[WARLOCKS : WARLOCKS+3]
            raiders = sum(myarmy) / 2
            for n in range(raiders):
                force = [min(myarmy[i], n) for i in (0,1,2)]
                if sum(force) >= raiders:
                    break
            for target in attractive[::-1]:
                if raiders > getfighters(target) * 2.5:
                    output = 'A %s %s %s %s' % tuple([target[TOWN]] + force)
                    break
    elif phase == 8:
        if raises:
            output = 'R %s' % raises
    elif phase == 9:
        if needhelp:
            town = needhelp[-1]
            excess = [max(0, g-h) for g,h in zip(here[7:11], needs(here))]
            send = [min(g, h) for g,h in zip(excess, wants(town))]
            if sum(send) > 0:
                output = 'M %u 0 0 0 %u %u %u %u' % tuple([town[TOWN]] + send)
    elif phase == 11:   
        if gobuild:
            output = 'B %s' % gobuild
    print output

2

Hükümdar (Yakut)

Monarch bir kraldan öte bir şey, bu yüzden ordusunun rakiplerini ezebileceğinden ve ezici gücünü gösterebileceğinden emin olmadan başkalarıyla savaşmayacak. Bu arada, üssünde rahatlaştı ve önemsiz böceklerden haraç istedi. Elbette, Ruby ve Ruby'leri sever.

$BONUS = 1.5
class Town

  attr_accessor :player, :town, :gold, :corpses, :warlocks, :crusaders, :amazons, 
    :corsairs, :bishops, :necromancers, :architects, :peons, :temples, :barracks, 
    :estates, :palaces

  def initialize(arg)
    args = arg.split("_")
    @player = args[0].to_i
    @town = args[1].to_i
    @gold = args[2].to_i
    @corpses = args[3].to_i
    @warlocks = args[4].to_i
    @crusaders = args[5].to_i
    @amazons = args[6].to_i
    @corsairs = args[7].to_i
    @bishops = args[8].to_i
    @necromancers = args[9].to_i
    @architects = args[10].to_i
    @peons = args[11].to_i
    @temples = args[12].to_i
    @barracks = args[13].to_i
    @estates = args[14].to_i
    @palaces = args[15].to_i
  end  
  def soldiers
    @warlocks + @crusaders + @amazons
  end 
  def units
    self.soldiers + @corsairs + @bishops + @necromancers + @architects
  end  
  def citizens
    self.units + @peons
  end  
  def buildings
    @temples + @barracks + @estates + @palaces
  end
  def cash
    @gold - (self.units * 2) - 50
  end
  def flesh
    @peons - (self.units * 2 / 5)
  end
end

def stronger(aW, aC, aA, dW, dC, dA)
  aW - [[0, aW - dW].max, dA].min + ([[0, aW - dW].max, dA].min * $BONUS) + aC - [[0, aC - dC].max, dW].min + ([[0, aC - dC].max, dW].min * $BONUS) + aA - [[0, aA - dA].max, dC].min + ([[0, aA - dA].max, dC].min * $BONUS)  > dW - [[0, dW - aW].max, aA].min + ([[0, dW - aW].max, aA].min * $BONUS) + dC - [[0, dC - aC].max, aW].min + ([[0, dC - aC].max, aW].min * $BONUS) + dA - [[0, dA - aA].max, aC].min + ([[0, dA - aA].max, aC].min * $BONUS) 
end

if ARGV.size < 1 
  puts "12 12 12 8 2 2 2 50"
else
  args = ARGV[0].split(";")

  round = args[0].to_i
  phase = args[1].to_i
  thisPlayer = args[2].to_i
  thisTownId = args[3].to_i
  towns, myTowns, enemyTowns = Array.new, Array.new, Array.new

  args[4..-1].each {|arg|arg.split(";").each {|t|towns.push(Town.new(t))}}
  towns.each {|town|town.player == thisPlayer ? myTowns.push(town) : enemyTowns.push(town)}
  thisTown = towns[towns.index{|t|t.town == thisTownId}]
  strongestTown = enemyTowns.sort{|x,y|y.soldiers<=>x.soldiers}.fetch(0)  
  weakestTown = enemyTowns.sort{|x,y|x.soldiers<=>y.soldiers}.fetch(0)  
  baseTown = myTowns.sort{|x,y|y.peons<=>x.peons}.fetch(0)    

  case phase
  when 2
    puts "S " + strongestTown.town.to_s + " " + thisTown.corsairs.to_s
  when 3
    if (thisTown.cash > 90)
      recruits = [[(thisTown.cash - 90) / 10, thisTown.flesh].min / 5, 0].max
      puts "R " + recruits.to_s + " " + recruits.to_s + " " + (recruits*3).to_s + " " + [0, 2 - thisTown.corsairs].max.to_s + " " + [0, 2 - thisTown.bishops].max.to_s + " " + [0, 2 - thisTown.necromancers].max.to_s + " " + [0, 2 - thisTown.architects].max.to_s
    else
      puts "W"
    end
  when 6
    converts = [[thisTown.cash / 50, thisTown.bishops].min / 5, 0].max
    puts "C " + strongestTown.town.to_s + " " + (converts*3).to_s + " " + converts.to_s + " " + converts.to_s
  when 7
    if round > 10
      if stronger(thisTown.warlocks / 6, thisTown.crusaders / 6, thisTown.amazons / 6, strongestTown.warlocks, strongestTown.crusaders, strongestTown.amazons)
        puts "A " + strongestTown.town.to_s + " " +  (thisTown.warlocks/4).to_s + " " + (thisTown.crusaders/4).to_s + " " + (thisTown.amazons/4).to_s
      elsif stronger(thisTown.warlocks / 6, thisTown.crusaders / 6, thisTown.amazons / 6, weakestTown.warlocks, weakestTown.crusaders, weakestTown.amazons)
        puts "A " + weakestTown.town.to_s + " " +  (thisTown.warlocks/4).to_s + " " + (thisTown.crusaders/4).to_s + " " + (thisTown.amazons/4).to_s
      else
        puts "W"
      end
    else
      puts "W"
    end
  when 8
    puts "R 10"
  when 9
    if thisTown.town != baseTown.town
      if thisTown.soldiers > 0 
        puts "M " + baseTown.town.to_s + " " + thisTown.warlocks.to_s + " " + thisTown.crusaders.to_s + " " + thisTown.amazons.to_s
      else
        puts "T " + baseTown.town.to_s + " " + thisTown.cash
      end
    else
      puts "W"
    end
  when 11
    if thisTown.town == baseTown.town and thisTown.cash > 200 
      puts "B B" 
    else
      puts "W"
    end
  else
    puts "W"
  end
end

Bu betiği çalıştırmak için bir Ruby 1.9.3 yorumlayıcısına ihtiyacınız var.

Çalıştır: ruby Monarch.rb


1

Sadece bir cevapta 30000 işaret yazabilirim xD İşte bulduğum hatalarım:

Moogie bunu zaten bildirdi: int totalConvertible = (warlocksConvertible + crusadersConvertible + amazonsConvertible);

executeMovement: if (source.getCorsairs() >= corsairsCount) {

executeTheft: Hedef yerine Kaynak kullanılır. Fakat hesaplamaların doğru olup olmadığını kontrol edebilir misiniz? Benim tavsiyem:int goldReserve = destination.getGold() + GOLD_MAX_DEBT > 0 ? destination.getGold() + GOLD_MAX_DEBT : GOLD_MAX_DEBT - Math.abs(destination.getGold());

İşe Alım ihalesinde bir hata vardı, eğer şehir yeterli piyonu olmasaydı, işe alımlarını karşılayabiliyorlarsa, piyonlara sahip olduklarından daha fazlasını işe alabilirlerdi. Bu yüzden kullanabildiğim piyonları ve altını ilgilendiren yöntemi yeniden yazdım:

private void executeRecruitment(Command support) {

    Town source = support.getSource();
    try {
        String[] args = support.getArgs();

        if (support.getCommand().equals("R") && args.length == 7) {
            int goldAvailable = source.getGold();
            if (goldAvailable <= 0) {
                return;
            }

            int warlocksCount = Math.max(0, Integer.parseInt(args[0]));
            int crusadersCount = Math.max(0, Integer.parseInt(args[1]));
            int amazonsCount = Math.max(0, Integer.parseInt(args[2]));
            int corsairsCount = Math.max(0, Integer.parseInt(args[3]));
            int bishopsCount = Math.max(0, Integer.parseInt(args[4]));
            int necromancersCount = Math.max(0, Integer.parseInt(args[5]));
            int architectsCount = Math.max(0, Integer.parseInt(args[6]));

            int originalWarlocksCount = warlocksCount;
            int originalCrusadersCount = crusadersCount;
            int originalAmazonsCount = amazonsCount;
            int originalCorsairsCount = corsairsCount;
            int originalBishopsCount = bishopsCount;
            int originalNecromancersCount = necromancersCount;
            int originalArchitectsCount = architectsCount;

            int unitsToRecruits = warlocksCount + crusadersCount + amazonsCount + corsairsCount + bishopsCount + necromancersCount + architectsCount;
            int peonsAvailable = source.getPeons();
            int recruitableUnits = Math.min(unitsToRecruits, peonsAvailable);
            if (recruitableUnits != unitsToRecruits) {
                RandomNumberGenerator random = new RandomNumberGenerator();
                int[] recruits = random.genNumberWithLimits(recruitableUnits, new int[] { warlocksCount, crusadersCount, amazonsCount, corsairsCount, bishopsCount, necromancersCount,
                        architectsCount });
                warlocksCount = recruits[0];
                crusadersCount = recruits[1];
                amazonsCount = recruits[2];
                corsairsCount = recruits[3];
                bishopsCount = recruits[4];
                necromancersCount = recruits[5];
                architectsCount = recruits[6];
            }

            int wouldCost;
            int index = 1;
            boolean tooExpensive = true;
            do {
                wouldCost = warlocksCount * GOLD_RECRUIT_WARLOCK + crusadersCount * GOLD_RECRUIT_CRUSADER + amazonsCount * GOLD_RECRUIT_AMAZON + corsairsCount * GOLD_RECRUIT_CORSAIR
                        + bishopsCount * GOLD_PER_BISHOP + necromancersCount * GOLD_RECRUIT_NECROMANCER + architectsCount * GOLD_RECRUIT_ARCHITECT;
                if (goldAvailable < wouldCost) {
                    RandomNumberGenerator random = new RandomNumberGenerator();
                    int[] recruits = random.genNumberWithLimits(recruitableUnits - index, new int[] { originalWarlocksCount, originalCrusadersCount, originalAmazonsCount, originalCorsairsCount,
                            originalBishopsCount, originalNecromancersCount, originalArchitectsCount });
                    warlocksCount = recruits[0];
                    crusadersCount = recruits[1];
                    amazonsCount = recruits[2];
                    corsairsCount = recruits[3];
                    bishopsCount = recruits[4];
                    necromancersCount = recruits[5];
                    architectsCount = recruits[6];
                } else {
                    tooExpensive = false;
                }
                index++;
            } while (tooExpensive);

            int recruted = warlocksCount + crusadersCount + amazonsCount + corsairsCount + bishopsCount + necromancersCount + architectsCount;
            if (recruted > 0) {
                source.setWarlocks(source.getWarlocks() + warlocksCount);
                source.setCrusaders(source.getCrusaders() + crusadersCount);
                source.setAmazons(source.getAmazons() + amazonsCount);
                source.setCorsairs(source.getCorsairs() + corsairsCount);
                source.setBishops(source.getBishops() + bishopsCount);
                source.setNecromancers(source.getNecromancers() + necromancersCount);
                source.setArchitects(source.getArchitects() + architectsCount);
                source.setPeons(source.getPeons() - recruted);
                source.setGold(source.getGold() - wouldCost);

                if (GAME_MESSAGES)
                    System.out.println(source.getOwner().getDisplayName() + " recruted " + recruted + " units (" + warlocksCount + " Wa / " + crusadersCount + " Cr / " + amazonsCount + " Am / "
                            + corsairsCount + " Co / " + bishopsCount + " Bi / " + necromancersCount + " Ne / " + architectsCount + " Ar)");
            }
        } else if (support.getCommand().equals("W")) {
            // Do nothing
        } else {
            if (DEBUG)
                System.out.println("Phase " + phase + " (Recruitment) : Invalid command by " + source.getOwner().getDisplayName() + "{" + source.getId() + "}");
        }
    } catch (Exception e) {
        if (DEBUG) {
            System.out.println("Exception in executeRecruitment() by " + source.getOwner().getDisplayName());
            e.printStackTrace();
        }
    }
}

Vay, denetleyiciyi kontrol etmek için zaman ayırdığınız için çok teşekkürler (Teşekkürler @Moogie). Düzeltmelerinizi yaptım ve birkaç saat içinde birkaç deneme oyunu yayınlayacağım.
Thrax
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.