KOTH: Warring Towns


22

Endgültige Ergebnisse sind da!

Einführung

Das Game Takes ist stark von Manus Game of Town inspiriert . Es spielt sich in einer Welt voller Schwerter und Magie ab. Der König, der den gesamten Kontinent regierte, ist gerade gestorben, und die Herren der vielen Stadtstaaten streiten sich jetzt um das Territorium. Sie sind einer dieser Herren und Ihr Ziel ist es, jede einzelne Stadt zu erobern und zu regieren.

Prinzip

Die Leute sind in 8 Klassen unterteilt :

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)

Wenn das Spiel beginnt, regierst du über eine Stadt. In jeder Stadt leben 100 Menschen . Sie müssen sie auf diese 8 Kategorien aufteilen.

Dann beginnt das eigentliche Spiel, das rundenbasiert ist. Eine Runde besteht aus 12 Phasen , von denen 7 interaktiv sind (Bots nach einem Befehl fragen). Die nächste Phase beginnt, wenn die vorherige Phase von jeder Stadt ausgeführt wurde (Phase 1: Stadt 1, Stadt 2, Stadt 3 ...; Phase 2: Stadt 1, Stadt 2, Stadt 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

Die Steuerung stellt Ihnen die Eingabe über Befehlsargumente zur Verfügung, Ihr Programm muss sie über stdout ausgeben.

Syntax

Ausgabe (Vorbereitung)
Bevor das Spiel startet, ruft der Controller Sie auf, ohne Argumente einzureichen. Das bedeutet, dass Sie Ihre 100 Personen in die 8 Kategorien einteilen müssen.

Sie müssen Folgendes ausgeben: Warlocks Crusaders Amazons Corsairs Bishops Necromancers Architects Peons

Zum Beispiel: 15 10 12 10 7 5 1 40.

Jede Stadt beginnt auch mit 500 Gold- und 5 Leichen.

Eingabe
Jedes Mal, wenn Ihr Programm aufgerufen wird, erhält es Argumente in folgendem Format: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;...

Beispiel Eingabe 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;...

Hier sehen Sie, es ist die 1. Runde, 2. Phase, Sie sind Spieler 1 in Stadt 1. Sie haben 700 Gold, 5 Leichen, 15 Hexenmeister, 10 Kreuzfahrer, 12 Amazonen, 10 Korsare, 7 Bischöfe, 5 Nekromanten, 1 Architekt, 40 Peons, 0 Tempel, 1 Kaserne, 0 Anwesen und 2 Paläste.

Ausgabe

Siehe Gameplay.

Gameplay

Alle Phasen

Befehl W = WAIT

Ungültiger Befehl = WAIT

Phase 1: Steuern erhöhen

Das Einkommen richtet sich nach Ihrer Bevölkerung und Ihren fertiggestellten Gebäuden:

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

Phase 2: Geld stehlen

Während dieser Phase können Sie Geld von einer Stadt stehlen, indem Sie Korsaren schicken. Jeder Corsair kann bis zu 10 Gold stehlen (dh 12 Corsairs können bis zu 120 Gold stehlen). Wenn die Zielstadt nicht genug Gold hat, stehlen Ihre Korsaren alles, bis zur maximalen Schuldenhöhe von 200 Gold . Wenn Sie versuchen, mehr Corsairs zu senden, als Sie besitzen, verwendet das Programm alle verfügbaren Corsairs.

Befehlssyntax :S DestinationId Corsairs

Phase 3: Rekrutieren von Truppen

Hier können Sie Ihre Peons trainieren, indem Sie etwas Gold ausgeben. Sie können so viele Einheiten rekrutieren, wie Sie möchten, solange Sie über genügend Peons und Gold verfügen. Wenn Sie versuchen, mehr zu rekrutieren, als Sie tatsächlich können, rekrutiert das Spiel nach dem Zufallsprinzip, bis alles ausgegeben wurde. Das Programm berücksichtigt Ihre maximalen Quoten (wenn Sie versuchen, 10 Kreuzfahrer und 5 Amazonen mit nur 8 Schülern zu rekrutieren, werden beispielsweise 6 Kreuzfahrer und 2 Amazonen rekrutiert und nicht 8 Amazonen oder 8 Hexenmeister).

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

Befehlssyntax :R Warlocks Crusaders Amazons Corsairs Bishops Necromancers Architects

Phase 4: Löhne zahlen

Die Gehälter werden nach Ihrer Bevölkerungszahl berechnet:

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

Phase 5: Versuchen Sie Revolt

Wenn Ihr Kontostand negativ ist, verlieren Sie die Kontrolle über Ihre Stadt an die Outlaws . Nach einem Aufstand wird das Gold der Stadt auf den Startwert zurückgesetzt: 500 Gold . Die Bevölkerung wird auf dem aktuellen Niveau gehalten.

Phase 6: Soldaten bekehren

Jeder Ihrer Bischöfe kann 1 feindlichen Soldaten (Hexenmeister, Kreuzritter oder Amazon) aus einer ausgewählten Stadt gegen eine Gebühr von 50 Gold pro Einheit umwandeln. Die umgebauten Einheiten schließen sich den in Ihrer Stadt stationierten Streitkräften an. Wie bei der Rekrutierung wird das Programm unter Einhaltung der Quoten nach dem Zufallsprinzip konvertiert, wenn Sie nicht genügend Gold oder Bischöfe zur Verfügung haben.

Befehlssyntax :C DestinationId Warlocks Crusaders Amazons

Phase 7: Stadt angreifen

Sie können eine Armee von Hexenmeistern, Kreuzfahrern und Amazonen schicken, um eine Stadt zu erobern. Wenn Sie versuchen, mehr zu senden, als Sie haben, sendet das Programm alle.

Die Soldaten erhalten einen Kampfbonus von 1,5 nach folgendem Muster: Mage > Range > Melee > Mage(dh ein Hexenmeister, der gegen einen Amazon kämpft, erhält 1,5 Kraft). Nur die Einheiten, die darüber hinausgehen, erhalten diesen Bonus (dh ein Hexenmeister, der gegen einen Hexenmeister und einen Amazonen kämpft, erhält diesen Bonus nicht). Der Bonus wird sowohl der Offensive als auch der Defensive zugerechnet.

Die Verluste werden zufällig auf die Einheiten des Siegers verteilt, je nach der geringeren Gesamtstärke (dh Angriffsstärke: 12 vs. Verteidigungsstärke: 14, Verteidigung gewinnt und verliert 12 Einheiten). Der Verlierer verliert alle seine Einheiten. Jede tote Einheit wird zu den Leichen der angegriffenen Stadt hinzugerechnet. Wenn die Offensive gewinnt, wird die Stadt erobert und gehört nun dem Angreifer. Er behält auch das Gold, die Leichen und die Peons, die in dieser Stadt waren. Korsare, Bischöfe, Totenbeschwörer und Architekten fliehen vor möglicher Unterdrückung.

Die Verteidigung bekommt nichts.

Befehlssyntax :A DestinationId Warlocks Crusaders Amazons

Phase 8: Leichen erheben

Jeder deiner Nekromanten kann bis zu 5 Peons wiederbeleben, indem er Leichen verbraucht und Gold ausgibt. Jeder auferstandene Peon kostet 1 Leiche und 20 Gold. Wenn Sie versuchen, mehr als möglich wiederzubeleben, gibt das Programm alles aus, was Sie haben.

Befehlssyntax :R Corpses

Phase 9: Armee oder Tribut bewegen

Sie können Einheiten in eine andere Stadt senden. Wenn Sie versuchen, mehr zu senden, als Sie haben, sendet das Programm alle.

Befehlssyntax :M DestinationId Warlocks Crusaders Amazons Corsairs Bishops Necromancers Architects

Oder Sie können Gold senden, indem Sie die Schiffe von Corsairs chartern. Jeder Korsar kann bis zu 200 Goldstücke transportieren . Wenn Sie versuchen, mehr zu senden, als Sie haben, sendet das Programm das, was Sie haben.

Befehlssyntax :T DestinationId Gold

Phase 10: Gegen Bedrohungen verteidigen

Mehrere Bedrohungen, die deiner Stadt schaden könnten:

  • Zombies: Die Toten sind nicht immer so tot, wie sie aussehen. 10% (mit Fußboden) der Leichen in Ihrer Stadt werden erwachen und Gehirne essen. Jeder Zombie frisst 1 Peon und wandert dann ins Nichts (Leichen beider Zombies und gegessener Peons werden verzehrt).
  • Dämonen: Eure Peons müssen Predigten hören, sonst rufen sie Dunkle Geister an. Jeder Ihrer Bischöfe deckt den Bedarf von bis zu 50 Peons. 10% Ihrer Ketzer (Peons im Übermaß) bringen Dämonen hervor. Dämonen töten jeweils 1 Peon und kehren in die Hölle zurück.
  • Banditen: Outlaws wohnen in der Nachbarschaft. Die Gesamtbevölkerung der Outlaws wird gerecht zwischen den Städten aufgeteilt und zum Diebstahl von Reichtum geschickt. Ihre einzige Verteidigung sind Ihre Corsair-Patrouillen. Jeder Corsair kann bis zu 5 Outlaws stoppen. Jeder Verbrecher, der nicht gestoppt wurde, stiehlt deiner Stadt 10 Gold (die maximale Stadtschuld beträgt 200 Gold).

Zu Beginn des Spiels wird mindestens 1 Stadt der Outlaws (100 Einwohner) generiert, danach 1 weitere für jeweils 5 Spieler (dh 1-4 Spieler: 1 Outlaws, 5-9 Spieler: 2 Outlaws ...). Geächtete können mit erkannt werdenid = -1

Phase 11: Gebäude bauen

In dieser Phase schreitet der Bau der Gebäude in Ihrer Stadt entsprechend der Anzahl der Architekten voran. Jeder Architekt erhöht die Fertigstellung eines einzelnen Gebäudes um 8%. Wenn ein Gebäude 100% erreicht, ist es fertiggestellt und kann in der nächsten Phase "Steuern" Einnahmen generieren. Die Konstruktionswarteschlange wird automatisch verwaltet (Wer zuerst kommt, mahlt zuerst).

Sie können dann auch mit dem Bau anderer Gebäude beginnen (BuildingId = Letter in Klammern):

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

Sie können mit dem Bau beliebig vieler Gebäude beginnen. Wenn Sie nicht über genügend Gold verfügen, werden Gebäude ignoriert. Der Bau Ihrer neuen Gebäude beginnt erst in der nächsten Runde.

Befehlssyntax :B BuildingId BuildingId BuildingId ...

Phase 12: Kinder machen

Alle fünf Runden (Runde 5, 10, 15 ...) werden neue Peons geboren und sind bereit zu kämpfen. Jedes Peonenpaar macht 1 Peon (dh 23 Peons erzeugen 11 neue Peons).

Regeln

  • Bots sollten nicht geschrieben werden, um bestimmte andere Bots zu schlagen oder zu unterstützen.
  • Das Schreiben in Dateien ist erlaubt. Bitte schreibe an "yoursubmissionname.txt", der Ordner wird vor Spielbeginn geleert. Andere externe Ressourcen sind nicht zulässig.
  • Ihr Beitrag hat 1 Sekunde Zeit, um zu antworten (pro Stadt).
  • Stellen Sie Befehle zum Kompilieren und Ausführen Ihrer Übermittlungen bereit.

Gewinnen

Gewinner ist der mit den meisten Städten nach 100 Runden. Wenn ein Spieler alle Städte erobert, stoppt das Spiel und er gewinnt. Wenn mehrere Spieler die gleiche Anzahl von Städten haben, zählt die Gesamtbevölkerung, dann die Menge an Gold.

Regler

Sie finden den Controller auf Github. Es enthält auch 2 Beispielbots, die in Java geschrieben wurden. Öffnen Sie es in Eclipse, platzieren Sie die kompilierten Bots im Stammordner und fügen Sie dem Steuerungsprogramm eine Klasse hinzu (genau wie die Samplebots).

Kämpfe

Die Kampfformel sieht ungefähr so ​​aus:

Für jede Soldatenklasse (Hexenmeister, Kreuzritter, Amazon):

  • Berechnen Sie das Gleichgewicht zwischen Angriff und Verteidigung (dh wer hat mehr von jeder Klasse und wie viele mehr?)
  • Sehen Sie für die überschüssigen Soldaten (dh Wert des positiven Gleichgewichts), wie viele "schwache Ziele" (siehe Phase 7-Diagramm) es gibt.
  • Multiplizieren Sie die Kampfstärke der berechtigten Soldaten (dh "schwache Ziele" im Vergleich zu "überzähligen Soldaten") mit dem Bonus und addieren Sie den Rest mit einer Kampfstärke von 1.

Sie können hier einen Simulator ausprobieren: http://ideone.com/ArJosE (ändern Sie einfach die Werte der Soldaten, Sie erhalten Boni und Gesamtstärken)

Hier einige Testfälle:

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

Endgültige Ergebnisse

Durchschnitt von 10 Spielen. Syntax :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)

Ergebnisse von 10 Spielen: http://pastebin.com/GdufEYjm

Komplette Protokolle von 2 Spielen: http://pastebin.com/GQDZ0JdY & http://pastebin.com/m3UBTDuC

Gut gespielt, der Kampf zwischen Politikern und Oppotunisten war sehr eng.


Durch die Erhöhung der Anzahl der Spielerinteraktionen erhoffe ich mir eine Diversifizierung der Strategien. Ein einfacher Bot kann jedoch in sehr wenigen Zeilen erreicht werden.
Thrax

The total Outlaws population is divided equitably between towns and sent to steal wealth.Wie viele Banditen gibt es insgesamt?
MegaTom

@MegaTorn Am Anfang gibt es eine Stadt mit Outlaws für 5 Spieler (mindestens 1) und jeweils 100 Personen. Im Laufe des Spiels können dann Outlaws durch Revolten auftauchen oder von anderen Spielern getötet werden.
Thrax

Woher wissen wir, wie viele Gebäude eine gegnerische Stadt hat? Der Controller scheint diese Informationen nicht zu senden. Dies ist notwendig, um zu bestimmen, wie viel Steuern erhoben werden, um zu bestimmen, ob ein erfolgreicher Angriff tatsächlich dazu führen kann, dass Löhne nicht gezahlt werden können und die Stadt umgehend einer Revolution ausgeliefert wird
Moogie

Wenn eine Stadt in Phase 5 fällt, können andere Spielerstädte diese Stadt übernehmen? Wenn ja, werden die Populationsklassentypen beibehalten? Dh: Wenn sie 20/20/40 Kämpfer in Hexenmeistern, Kreuzfahrern, Amazonen hatten, ist dies das, was Sie kämpfen müssen, um diese Stadt einzunehmen?
Logic Knight

Antworten:


8

Opportunist, Java v2

Er versucht, Chancen zu nutzen, während sie sich präsentieren ... aber wenn sich am Ende des Spiels niemand präsentiert (und er immer noch im Streit ist), wird er alles geben.

UDPATE:

Einige der Ideen von durron597 wurden übernommen. Stoppen Sie jetzt die Rekrutierung von Bischöfen, wenn Sie in der Lage sind, die Streitkräfte des stärksten Gegners vollständig umzuwandeln, und konzentrieren Sie sich stattdessen auf den Kauf von Soldaten.

Auch v1 hatte ein anfängliches Handicap, bei dem die anfängliche Bevölkerungsverteilung nicht 100 betrug ... nur 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;
}
}

So führen Sie es aus: 1. Legen Sie es in das moogiesoft-Verzeichnis ab. 2. Im übergeordneten Verzeichnis: java moogiesoft.Opportunist


Wow! Das tut ziemlich gut!
TheNumberOne

Das ist natürlich großartig, aber ich denke, Sie könnten es geringfügig verbessern, indem Sie 1. aufhören, Bischöfe zu kaufen, wenn Sie mehr Bischöfe als alle anderen haben, die Truppen zusammen haben, 2. Outlaw-Städte angreifen, bevor Sie 100 werden, wenn sie nicht verteidigt sind und es keine anderen Bots gibt. Sollte Ihr Endergebnis viel höher machen.
Durron597

Danke, das sind gute Vorschläge. Ich werde mich bemühen, sie aufzunehmen :)
Moogie

Gut gemacht, die Strategie von Opportunist war wirklich interessant!
Thrax

@Thrax danke für die Herausforderung! Aus meinen Experimenten hat der Zufall einen großen Einfluss darauf, wie gut der Opportunist spielt. Es kann in den ersten Nahkampfrunden leicht überflutet werden. Normalerweise von Zealot.
Moogie

8

Aegis, Java

Aegis versucht auf Nummer sicher zu gehen und darauf zu warten, dass andere Spieler gegeneinander kämpfen, während sie einen schönen Wohnblock voller luxuriöser Anwesen bauen. Da Gold eine kostbare Ressource ist, rekrutiert Aegis genug Korsare, um von seinen Nachbarn zu stehlen und sein hart verdientes Geld zu schützen.

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

}

Kompilieren mit javac Aegis.java

Laufen Sie mit java Aegis


8

Der junge Graf, Python 2

Version 3.1

Aktualisieren:

Die Mutter des jungen Grafen wird seine Kriegstreiberei nicht länger ertragen. Stattdessen soll er in der Stadt bauen. Der Earl hat jetzt Wirtschaftsberater und viele Tabellenkalkulationen. Er wünscht sich ein einfacheres Leben, wenn er nur die Zimmermädchen verfolgen kann.

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

Leistungsüberprüfung

Im Spielwettbewerb hat sich der neueste Earl gut geschlagen. In 2 von 10 Spielen konnte er gegen die Spielerstädte gewinnen, erstarrte dann aber, als es Zeit war, die Banditenstädte zu erobern. Ich habe diesen Fehler behoben - ich hätte nie gedacht, dass er so weit kommen würde ;-). Im Nachhinein hätte ich den Controller herunterladen und den Earl testen sollen.

Herzlichen Glückwunsch an @Moogie und @TheBestOne zu den besten Einsendungen. Es ist eine Schande, dass nur einer gewinnen kann. Sie sind beide sehr gut.

Wenn es mehr Spiele gibt, würde ich gerne sehen, wie der reparierte Earl gegen die beiden Champions überlebt. Ich hoffe, @Thrax hat dafür etwas Zeit frei.



Ich werde noch 3 Spiele mit dem neuen Earl spielen, um die Ergebnisse zu sehen. Ich halte auch das Git auf dem Laufenden, wenn Sie es selbst testen möchten. (und ich bin fast fertig mit der Arbeit an der nächsten KOTH, erwarte sehr bald eine neue!)
Thrax

Hier sind die Ergebnisse: 1. Outlaw(12, 6671, 2233682) 2. YoungEarl(3, 6346, 208215) 3. Politician(1, 96, 0)dann 1. YoungEarl(16, 2514, 72315)und endlich 1. Politician(16, 1562, 53467). YoungEarl macht in der Tat einen ziemlich guten Job.
Thrax

Vielen Dank, Thrax. Der Earl scheint es verstanden zu haben. Besser spät als nie, oder?
Logic Knight

Da auch Moogie & TheBestOne noch auf der Flucht sind, werde ich versuchen, 100 Spiele für ein anderes Kopfgeld zu spielen. (Ich bin ein bisschen knapp bei der Reputation, ich brauche mindestens das Doppelte, was ich bereits ausgegeben habe, dh 300 Wiederholungen)
Thrax

6

TheLannisters (Java)

Ich wähle diesen Namen, weil diese Vorlage höllisch reich wird. Auch der Satz TheLannisters gave birth to 30 childrenklingt komisch: D

Bearbeiten: Es wartet nun lange mit Angriffen und nervt die Spieler, indem es ihre Soldaten stiehlt. Es kann auch jede Art von Einheit rekrutieren.

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);
    }
}

Sie haben eine NPE, wenn Sie nur gegen Outlaws kämpfen. Dieses Snippet: for (Town town : enemyPlayerTowns)Bekommt nichts, also Town richestTown = null;bleibt dein oder ein gleichwertiges null.
Thrax

@Thrax Danke, sollte jetzt behoben sein :)
CommonGuy

6

Politiker, Java

v3

Update: Ärgerlicher Kommentar und bessere Planung hinzugefügt.

Update: Rekrutiert weniger Züge (Korsaren) und konzentriert sich auf den Aufbau der Wirtschaft (Peons).

Update: Einige Parameter wurden überarbeitet.

Update: Greift viel häufiger an. Hört gerne Wissenschaftler mehr.

Er hat zwei Ziele.

  1. Unbegrenztes Gold.

  2. Unbegrenzte Armeen.

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

}

Erläuterung

Er hat zwei Ziele.

  1. Unbegrenztes Gold.
  2. Unbegrenzte Armeen.

So bekommen Sie Gold:

Der Politiker beauftragt lediglich Architekten mit dem Bau von Flughäfen, Autobahnen und Eisenbahnen. Haufenweise Geld fließt ziemlich schnell ein. Nach der Erhöhung der Steuern hat der Politiker unbegrenztes Geld.

Wie man Armeen bekommt:

Das ist etwas schwieriger. Mit begrenzten Leuten kann man nur eine kleine Armee erreichen. Mit Botschaftern kann er noch größere Armeen engagieren, die aber noch nicht groß genug sind. Nach einigem Nachdenken fand der Politiker heraus, dass er durch die Eroberung anderer Nationen und die anschließende Versklavung des Volkes ziemlich große Armeen erhält. Sie sind aber noch lange nicht groß genug. Nachdem sie einige Wissenschaftler eingestellt hatten, sagten sie ihm, sie hätten das Geheimnis der Auferweckung entdeckt. Leider seien sie nach der Auferstehung keine Soldaten mehr. Nach eingehender Betrachtung stellt der Politiker fest, dass dies zu seinem Vorteil ist, und stellt die auferstandenen Toten als Botschafter ein, die ad infinitum noch mehr Soldaten einstellen.


Leider ist dieser Politiker - wie jeder Politiker - alles leere Versprechen und kann Sehtimianer nicht standhalten. (Verlorene Runde 30, vorletzter am Leben)
Thrax

Jetzt herrscht es über die Welt, Glückwunsch!
Thrax

@Thrax Und er ist es immer noch!
TheNumberOne

Ich bin beeindruckt ... wie alle Politiker ... er ist sehr anpassungsfähig zu ändern :)
Moogie

Der Kampf ist heftig, aber der Politiker hat es vorerst nicht geschafft!
Thrax

5

Gelassenheit, Lua

Konzentriert sich darauf, Gelassenheit durch Religion zu erreichen. Versucht, die Ungläubigen zu bekehren und darauf zu warten, dass die Städte einen kritischen Zustand erreichen, bevor sie ihren Glauben durch den Bau neuer Tempel ausbauen.

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

Laufen mit lua Serenity.lua(benötigt Lua 5.2)


5

Die Zeloten (Python)

(Basierend auf CarpetPythons Code.)

Baue so gemeine Tempel wie möglich! Erwecke die Toten! Konvertiere die Ungläubigen!

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
Dies scheint mir nicht Java zu sein.
Ypnypn

5
Ich denke, Sie meinten Python
soktinpk

@ Thrax du meinst fehlende Doppelpunkt
Lorork

@soktinpk: Ja, das ist Python. Ich weiß nicht, wie ich zu Java gekommen bin.
MegaTom

@TheBestOne Ich habe es behoben.
MegaTom

4

Kommandant, Java

Commander ist einer der beiden Standard-Bots, die ich zusammen mit dem Controller erstellt habe (der andere ist Sleeper, der nichts tut). Kommandant ist ein Eroberer und er wird versuchen, alle seine Ressourcen zu nutzen, um die vollständige Herrschaft zu erlangen.

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

Butter

Diese Butter verhält sich ähnlich wie die vorherige Butter. Im Gegensatz zur vorherigen Butter wird diese ungewöhnlich schnell reich. Leider mögen die Young Earls zusammen mit den Lannisters Butter auf ihren Waffeln. Daher wird Butter schnell verbraucht.

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

Ich habe an so etwas gearbeitet. Bin ich richtig zu sagen, das wird verrückt reich?
TheNumberOne

Ja, es wird wirklich sehr viel Einkommen xD
Sehtim

3

Machiavelli, Python 2

Lord Machiavelli verfügt über Erfahrung in den Bereichen Politik und Militär, die für einen Erfolg erforderlich sind. Er hat eine komplexe Logik entwickelt, die seine gerissene Strategie lenkt. Jetzt beobachtet er aus dem Schatten, wie sich sein Plan entfaltet ...

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

Monarch (Rubin)

Monarch ist mehr als nur ein König, daher wird er erst gegen andere kämpfen, wenn er sicher ist, dass seine Armee seine Gegner niederschlagen und seine überwältigende Macht zeigen kann. In der Zwischenzeit wird er in seiner Basis gemütlich und bittet die unbedeutenden Insekten um Tribut. Anf natürlich mag er Ruby und Rubies.

$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

Zum Ausführen dieses Skripts benötigen Sie einen Ruby 1.9.3-Interpreter.

Laufen mit: ruby Monarch.rb


1

Ich kann nur 30000 Zeichen in eine Antwort schreiben. XD Hier sind meine Fehler, die ich gefunden habe:

Moogie hat dies bereits gemeldet: int totalConvertible = (warlocksConvertible + crusadersConvertible + amazonsConvertible);

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

executeTheft: Verwendete Quelle anstelle des Ziels. Aber können Sie prüfen, ob die Berechnung dann korrekt ist? Meine Empfehlung wäre:int goldReserve = destination.getGold() + GOLD_MAX_DEBT > 0 ? destination.getGold() + GOLD_MAX_DEBT : GOLD_MAX_DEBT - Math.abs(destination.getGold());

Und executeRecruitment hatte den Fehler, dass wenn die Stadt nicht genug Peons hatte, sie mehr als Peons rekrutieren konnten, wenn sie sich die Rekrutierung leisten konnten. Also habe ich die Methode umgeschrieben, dass es sich um Peons und Gold handelt:

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();
        }
    }
}

Wow, vielen Dank, dass Sie sich die Zeit genommen haben, den Controller zu überprüfen (Danke auch an @Moogie). Ich habe Ihre Korrekturen angewendet und werde in wenigen Stunden mehrere Testspiele ausführen.
Thrax
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.