Kasabaların Oyunu


34

Giriş

Oyun farklı kasabalara sahip küçük bir dünyada gerçekleşiyor. Kasabaların yöneticileri birbirlerinden nefret ediyorlar ve dünyaya hükmetmek istiyorlar. İnsanlar savaşçı ve alçak doğanlar olmak üzere iki gruba ayrılır. Ancak alçak doğanlar savaşçılara yükselebilir. Sen bu şehirlerden üçünün hükümdarısın.

Oynanış

Oyun başladığında, üç şehre hükmedersin. Her kasabada 100 kişi var. Onları şövalyelere ve alçaklara bölmek zorundasın.

Sonra asıl oyun sırayla başlar. Bir dönüş şöyle görünür: "Produce" knights=> execute command of first town=> execute command of next town(tüm şehirler için tekrarla) => try a rebellion.

  • Her seferinde , programın sana ait olan her şehir için çağrılacak . Ya edebilir bir kasaba saldırı , bir kasaba desteklemek ya da sadece bekleyin . Bu işlemler aynı anda değil sırayla gerçekleştirilir.
  • Her üçüncü turda, 2 lowborns başına bir şövalye elde edersiniz (23 lowborns => 11 knights). Lowborns miktarı aynı kalır.
  • Bir kasabadaki şövalyelerin 1.2'lik bir savunma bonusu vardır. Saldırıya uğrarsanız, şövalyeleriniz bu sayı ile çarpılacaktır (örneğin , saldırı sırasında 78 knightssahip olacaksınız 93 knights). Saldırıdan sonra, ekstra şövalyeler kaldırılacak (eğer 82 knightshayatta kalırsa , hala sahip olacaksın 78 knights).
  • Bir saldırıda, her şövalye ölmeden önce bir düşmanı öldürür. Örneğin: 30 knightssaldırı 100 knights(savunma bonusu olmadan) => 70 şövalye hayatta kalır.
  • Bir şövalyeyi, içindeki tüm şövalyeleri öldürerek yakalayabilirsiniz . Tüm alçak doğanlar artık size ait ve hayatta kalan şövalyeleriniz kasabada konuşlanmış durumda. Bir sonraki turda, diğer tüm kasabalarınıza ek olarak bu şehri yönetebilirsiniz .
  • Bir kasaba ele geçirildikten sonra, 2 tam tur için bir savunma bonusu olmayacaktır (çünkü kapılar kırılmıştır). Üçüncü turda kapılar tamir edilecektir.
  • Alçakların isyan etmesini önlemek için alçakların olduğu kadar en az yarım şövalyeye de ihtiyacınız var (bir kasabada 23 alçak aynı kasabada en az 12 şövalye gerekir). Aksi takdirde, alçaklar tüm şövalyeleri öldürecek ve kasaba "nötr" hale gelecektir (bir Oyuncu olmadan belirtilen bir lider olmadan -1).
  • Tarafsız kasabalar şövalyeleri "üretecek" fakat diğer kasabalara saldırmayacak veya destek vermeyecek.

Sözdizimi

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

Çıktı (hazırlık)
Oyun başlamadan önce, kontrol birimi tartışmasız gönderiminizi başlatır. Bu, 100 kişinizi (her kasaba için) şövalyelere ve alçak doğralara dağıtmanız gerektiği anlamına gelir. KnightCount KnightCount KnightCountÖrneğin çıktı almanız gerekir 95 80 95.

Girdi
Round;YourPlayerId;YourTownId;PlayerId_TownId_knights_lowborns;PlayerId_TownId_knights_lowborns;...
İlk turda, bu gibi bir şey olacak 1;2;2;0_0_100_0;1_1_50_50;2_2_80_20. Burada ilk raund olduğunu görüyorsunuz, 2. kasabada 2. sıradasınız. 80 şövalye ve 20 alçak var.

Oyunda daha sonra, bunun gibi bir şey olabilir 20;2;1;0_0_100_0;2_1_30_50;2_2_40_20. Hala oyuncu 2'sin (bu asla değişmiyor), ama şehir 1'i (şu an kontrol ediyorsun) ele geçirdin.

Çıktı
A TownId NumberOfKnights veya S TownId NumberOfKnightsveya W(beklemek için).
Örnek: A 2 100(100 şövalye ile 2. kasabaya saldır) veya S 3 2(2 şövalye ile 3. kasabaya destek).

kurallar

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

Kazanan

Kazanan, 100 turdan sonra en fazla kasabaya sahip olanıdır. Bir oyuncu bütün kasabaları yakalarsa oyun durur ve kazanır. Eğer birden fazla oyuncu aynı miktarda kasabaya sahipse, şövalyelerin sayısı ve sonra düşük sıraların sayısı sayılır.

kontrolör

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

Sonuçlar

Son sonuçlar için 10 oyun yaptım. Bu ortalama:

    Oyuncu Kasabaları 
 1. Kurtarıcı 37.5
 2. Şehtimianer 8.2
 3. Süper Üretici 5.4
 4. Sleeper 1.4
 5. Frankenstein 1.2
 6. Tereyağı 0.8 (daha fazla şövalye)
 7. TheKing 0.8 (daha az şövalyeler)
 8. Çıkış 0.6
 9. Kaplumbağa 0.5 (daha fazla şövalye)
10. SaldırıOn3 0.5 (daha az şövalye)
11. Demokrasi 0.3
12. HesaplananDosya 0.2
13. Devrimci 0.1

Burada örnek bir oyun okuyabilirsiniz: github'da örnek oyun


Bir kasaba zaman farz ABaşka bir kasaba destekler B, şövalyelerin verilen sayı sadece aktarılır Aiçin Bonlar sahibi tarafından kontrol edilir, bundan sonra, Bdoğru?
Zgarb

@Zgarb Correct :)
CommonGuy

Maçlar düzenliyor ve liderlik tablosu gösterecek misiniz?
Mantık Şövalye

@CarpetPython Tabii ki, zamanım olduğu anda onu
gönderiyorum

1
@Manu, KOTH'lerinizi sevdiğimi söylemeliyim. Bu benim türüm Codegolf.SE sorular. Ne zaman başvuruları kabul ediyorsun? Şimdi bir algoritma düşünmeye başlayacağım. Ayrıca, başka bir kural eklemelisin - kullanıcı başına maksimum gönderim sayısı.
Mark Gabriel,

Yanıtlar:


14

Python3, Kurtarıcı

from sys import argv
from math import ceil, floor

class OppressedTown:
    def __init__(self, owner_id, id, oppressors, oppressed):
        self.owner_id = owner_id
        self.id = id
        self.oppressors = oppressors
        self.oppressed = oppressed

    def get_free_oppressors(self):
        return self.oppressors - ceil(self.oppressed / 2)

    def get_needed_liberators(self):
        return ceil(self.oppressed / 2)

class LiberatedTown:
    def __init__(self, owner_id, id, liberators, liberated):
        self.owner_id = owner_id
        self.id = id
        self.liberators = liberators
        self.liberated = liberated

    def get_free_liberators(self):
        return self.liberators - ceil(self.liberated / 2)

    def get_needed_liberators(self):
        return ceil(self.liberated / 2)

    def is_safe(self):
        return self.liberators >= self.liberated * 2

    def get_unneeded_liberators(self):
        return self.liberators - self.liberated * 2

def safe_div(a, b):
    try:
        c = a / b
    except ZeroDivisionError:
        if a == 0:
            c = 0
        else:
            c = float("inf")
    return c

def main():
    if len(argv) == 1:
        print ("100 100 100")
    else:
        decision = decide()
        print (decision)

def decide():
    def needs_urgent_support(town):
        return town.get_needed_liberators() >= town.liberators and town.liberated > 0

    def can_beat(free_liberators, town):
        return free_liberators > town.oppressors * 1.2 + town.get_needed_liberators()

    def can_damage(free_liberators, town):
        return free_liberators > town.oppressors * 0.2

    args = argv[1].split(";")
    round = int(args[0])
    me = int(args[1])
    current_id = int(args[2])
    liberated_towns = []
    oppressed_towns = []

    for i in range(3, len(args)):
        infos = list(map(int, args[i].split("_")))
        if infos[0] != me:
            oppressed_towns.append(OppressedTown(infos[0], infos[1], infos[2], infos[3]))
        else:
            liberated_towns.append(LiberatedTown(infos[0], infos[1], infos[2], infos[3]))

    current_town = [town for town in liberated_towns if town.id == current_id][0]
    free_liberators = current_town.get_free_liberators()

    total_oppressors = sum(town.liberators for town in liberated_towns)
    total_oppressors = sum(town.oppressors for town in oppressed_towns)
    total_liberated = sum(town.liberated for town in liberated_towns)
    total_oppressed = sum(town.oppressed for town in oppressed_towns)

    oppressed_towns.sort(key=lambda town: safe_div(town.oppressed, town.oppressors), reverse=True)

    most_oppressed = oppressed_towns[-1]

    if free_liberators > 0:
        for town in liberated_towns:
            if town.id != current_id and needs_urgent_support(town):
                return "S {0} {1}".format(town.id, free_liberators // 2)

        if current_town.is_safe():
            free_liberators = current_town.get_unneeded_liberators()

            if free_liberators > 0:
                for town in oppressed_towns:
                    if can_beat(free_liberators, town):
                        if total_liberated <= total_oppressed or town.owner_id != -1 or not any(town.owner_id != -1 for town in oppressed_towns):
                            return "A {0} {1}".format(town.id, free_liberators)
                        else:
                            continue
                    else:
                        break

                for town in liberated_towns:
                    if not town.is_safe():
                        return "S {0} {1}".format(town.id, free_liberators)

                liberated_towns.sort(key=lambda town: (town.liberated, town.liberators), reverse=True)

##                if current_id == liberated_towns[0].id and total_oppressors > total_oppressors and can_damage(free_liberators, most_oppressed):
##                    return "A {0} {1}".format(most_oppressed.id, free_liberators)

                if current_id != liberated_towns[0].id:
                    return "S {0} {1}".format(liberated_towns[0].id, free_liberators)

    return "W"

main()

Bu botun tek amacı, en yaygın insanları ezici baskıcı boyunduruktan kurtarmak.


1
Bu Kurtarıcının veba olduğunu söylemeliyim: güçlü, hızlı ve ölümcül. Neredeyse koştuğum her simülasyonu kazandı, hatta Neutral Player'ı yenmek ... Still Butter güçlü bir meydan okuma.
Thrax

Ekmeği Tereyağının tiranlığından kurtardın. :( Tereyağı severim.
TheNumberOne

Dang! Kurtarıcı yenmek zor! Java'ya giriş yapanları denetleyiciye eklemeden önce göndereceğim bir giriş vardı ... ama şimdi bu giriş, kurtarıcı olmayanların geri kalanları gibi kazanamıyor! Denemek için başka bir fikrim var, bu yüzden hepsi kaybolmaz ...: meydan okuma için P + 1!
Moogie

aferin! seninki haklı bir zaferdi!
Moogie

11

Python 2, Kral

Kral, imparatorluğunun en yüksek kasabasına hükmetti ve tüm aşırı şövalyelerin kontrolündeki diğer şehirlerden kendisine gönderilmesini istedi. Yeterli şövalyesi olduğunda, bir düşman kasabasına saldıracak. Çok akıllı bir Kral değil, bu yüzden tarih okumamış veya davranışlarının sonuçlarını anlamıyor.

import sys
from random import *

PLAYER, TOWN, KNIGHTS, SERFS = range(4)

if len(sys.argv) < 2:
    print randint(20,100), randint(50,100), randint(70,100)
else:
    parts = sys.argv[1].split(';')
    turn, me, thistown = [int(parts.pop(0)) for i in range(3)]
    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]

    avgfree = sum(t[KNIGHTS]-t[SERFS]/2 for t in towns) / len(towns)
    free = here[KNIGHTS] - here[SERFS]/2
    last = mytowns[-1]
    if here == last:
        needed, target = min([(t[KNIGHTS]*1.2+t[SERFS]/2, t) for t in enemy])
        if free > needed+5:
            print 'A', target[TOWN], int(free+needed)/2 + 1
        else:
            print 'W'
    else:
        spare = max(0, free - avgfree)
        if spare:
            print 'S', last[TOWN], spare
        else:
            print 'W'

Bu kontrolör veya diğer botlarla denenmez.


+1 içinHe is not a very smart King, so has not studied history or understands the consequences of his actions.
Mark Gabriel

8

Javascript (Düğüm), İmparatorluk

Diğer kasabaları korkutmak için güçlü bir şekilde başlar. Kasabalar başkalarını yakalamak için birlikte çalışmaya çalışır. Birçok alçak doğanın bulunduğu şehirleri yakalamaya öncelik verir.

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

function startGame() {
  console.log('80 70 60');
}

function parseArgs(args) {
  var state = {
    players: [],
    towns: []
  };
  var argArray = args.split(';');
  state.currentTurn = parseInt(argArray.splice(0, 1)[0], 10);
  var myId = argArray.splice(0, 1)[0];
  var myTownId = parseInt(argArray.splice(0, 1)[0], 10);

  for(var townIndex = 0; townIndex < argArray.length; townIndex++) {
    var townArgs = argArray[townIndex].split('_');
    var playerId = townArgs[0];
    var townId = parseInt(townArgs[1], 10);
    var player = state.players[playerId];

    if(!player) {
      player = {
        towns: []
      };
      state.players[playerId] = player;
    }

    var town = {
      id: townId,
      knights: parseInt(townArgs[2], 10),
      lowborns: parseInt(townArgs[3], 10),
      player: player
    };

    state.towns[townId] = town;
    player.towns.push(town);
  }

  state.me = state.players[myId];
  state.currentTown = state.towns[myTownId];

  return state;
}

function getDefense(town) {
  return Math.floor(town.knights * 1.2) + Math.ceil(town.lowborns / 2) + 1;
}

function getAttackers(town) {
  return Math.max(town.knights - Math.ceil(town.lowborns / 2), 0);
}

function attackTown(town, strength) {
  console.log('A ' + town.id + ' ' + strength);
}

function supportTown(town, strength) {
  console.log('S ' + town.id + ' ' + strength);
}

function wait() {
  console.log('W');
}

function processTurn(gameState) {
  var attackers = getAttackers(gameState.currentTown);

  if(attackers > 0) {
    var totalAttackers = attackers;

    var helperIndex = (gameState.currentTown.id + 1) % gameState.towns.length;
    while(gameState.towns[helperIndex].player === gameState.me) {
      totalAttackers += getAttackers(gameState.towns[helperIndex]);
      helperIndex = (helperIndex + 1) % gameState.towns.length;
    }

    var bestTarget;

    for(var targetIndex = 0; targetIndex < gameState.towns.length; targetIndex++) {
      var targetTown = gameState.towns[targetIndex];
      if(targetTown.player !== gameState.me) {
        var defense = getDefense(targetTown);

        if(defense < totalAttackers) {
          if(!bestTarget) {
            bestTarget = targetTown;
          }
          else if(targetTown.lowborns > bestTarget.lowborns) {
            bestTarget = targetTown;
          }
          else if(getDefense(bestTarget) < defense) {
            bestTarget = targetTown;
          }
        }
      }
    }

    if(bestTarget) {
      return attackTown(bestTarget, Math.min(attackers, getDefense(bestTarget)));
    }

    var smallestTown;
    var smallestSize = gameState.currentTown.knights;

    for(var myTownIndex = 0; myTownIndex < gameState.me.towns.length; myTownIndex++) {
      var myTown = gameState.me.towns[myTownIndex];
      if(myTown.knights < smallestSize) {
        smallestTown = myTown;
        smallestSize = smallestTown.knights;
      }
    }

    if(smallestTown) {
      var supporters = Math.floor((smallestSize - gameState.currentTown.knights) / 2);
      supporters = Math.min(supporters, attackers);
      if(supporters > 0) {
        return supportTown(smallestTown, supporters);
      }
    }
  }

  wait();
}

if(process.argv.length <= 2) {
  startGame();
}
else {
  var gameState = parseArgs(process.argv[2]);  
  processTurn(gameState);
}

Çalıştır: düğüm imparatorluğu


1
Gönderiniz bazen kasabada olduğundan daha fazla şövalye gönderir ve şu anda kaybeder ...
CommonGuy

@Manu ayy, testlerimde, muhtemelen test için tüm rakip botları kurma şansım olmadığından hiçbir zaman (ya da en azından fark etmedim) karşılaşmadım. Bu özel hata şimdi düzeltilmelidir.
Spencer

Halen sabit değil ... bazen 0'a veya negatif şövalyelere saldırabilirsin ... Bunun sebebi hesaplaman knights - lowborns/2, ama 30 şövalye ve 90 alçak varsa, bu işe yaramaz. Lütfen getAttackers()işlevinizi düzeltin .
CommonGuy

Ayrıca, bazen negatif miktarda şövalye ile destek gönderirsiniz.
CommonGuy

@Manu aptalca hissediyorum, nihayet DEBUGdenetleyicideki GAME_MESSAGESbayrağı doğru olarak ayarlanmış olsa bile hataları yutmasına neden olan bayrağı fark ettim . Stratejimde bazı çalışmalar yapabileceğimi hissediyorum, özellikle şu an sahnede Liberator ile, ancak en son düzenlemeyle, testlerimi DEBUGüzerinde yaptığımda hiçbir hata görmüyorum
Spencer

8

Java, Frankenstein

Liberator'ü yok etmenin bir yolunu bulmaya çalışırken, küçük bir hata koduma girdi. Kod daha sonra rekabeti yok etmeye başladı. Demokrasi ekledikten ve oyuncuları yeniden düzenledikten sonra başarısızlığa başladı. Kodu inceleyerek stratejisini bulmaya çalıştım. Sonuç olarak, aşağıdaki kod yapıldı. En iyi oyuncuya saldırma ve yok etme eğilimindedir. En iyi oyuncu (lar) yok edildikten sonra bu, gerisini kolayca yok eder.

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Frankenstein {

    int round;
    int playerID;
    int thisTownID;

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

    private static final boolean DEBUG = true;

    Town thisTown;

    int scariestPlayerId = -1;
    int scariestPlayerRecord = -1;

    private static final String LOG_FILE_NAME = "EmperorLog.txt";

    private static final String DATA_FILE_NAME = "Emperor.txt";

    public static void main(String[] args){
        try {
            if (args.length == 0) {
                System.out.println("100 100 100");
                return;
            }
            Frankenstein frankenstein = new Frankenstein();
            String result = frankenstein.destroy(args[0].split(";"));
            frankenstein.saveScariestPlayer();
            System.out.println(result);
            if (DEBUG) {
                new PrintStream(new FileOutputStream(LOG_FILE_NAME, true)).print(args[0] + "\n" + result + "\n");
            }
        } catch (Exception e){
            if (DEBUG) {
                try {
                    e.printStackTrace(new PrintStream(new FileOutputStream(LOG_FILE_NAME, true)));
                } catch (FileNotFoundException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }

    private void saveScariestPlayer() throws FileNotFoundException {
        PrintStream out = new PrintStream(DATA_FILE_NAME);
        out.println(round);
        out.println(scariestPlayerId);
        out.println(scariestPlayerRecord);
    }

    private static int divide(int a, int b){
        if (a == 0){
            return 0;
        }
        if (b == 0){
            return 1000;
        }
        return a/b;
    }

    private String destroy(String[] args) {

        round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);
        thisTownID = Integer.parseInt(args[2]);
        towns = new ArrayList<>();
        myTowns = new ArrayList<>();
        otherTowns = new ArrayList<>();


        for (int i = 3; 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);
            }
        }

        loadScariestPlayer();
        updateScariestPlayer();

        if (thisTown.getFreeKnights() > 0){

            for (Town town : myTowns){
                if (town.needsHelp() && town.getFreeKnights() + thisTown.getFreeKnights() >= 0){
                    return "S " + town.getId() + " " + thisTown.getFreeKnights();
                }
            }

            Town bestTown = otherTowns.stream().max((a, b) -> divide(a.lowbornCount() * (scariestPlayerId == -1 || scariestPlayerId == a.ownerId ? a.lowbornCount() : 1), a.knightCount()) -
                    divide(b.lowbornCount() * (scariestPlayerId == -1 || scariestPlayerId == b.ownerId ? b.lowbornCount() : 1), b.knightCount())).get();

            if (bestTown.numberOfKnightsToConquer() <= thisTown.getFreeKnights()){
                return "A " + bestTown.getId() + " " + thisTown.getFreeKnights();
            }

            myTowns.sort((a,b) -> b.knightCount() - a.knightCount());
            myTowns.sort((a,b) -> b.lowbornCount() - a.lowbornCount());
            if (!myTowns.get(0).isThisTown()){
                return "S " + myTowns.get(0).getId() + " " + thisTown.getFreeKnights();
            }

        }

        return "W";

    }

    private void updateScariestPlayer() {
        Map<Integer, Integer> playerMap = new HashMap<>();
        int biggestPlayerId = -1;
        for (Town town : otherTowns){
            if (playerMap.containsKey(town.ownerId)){
                playerMap.put(town.ownerId, town.lowbornCount() + playerMap.get(town.ownerId));
            } else {
                playerMap.put(town.ownerId, town.lowbornCount());
            }
            if (biggestPlayerId == -1 || playerMap.get(town.ownerId) > playerMap.get(biggestPlayerId)){
                biggestPlayerId = town.ownerId;
            }
        }
        if (scariestPlayerId == -1 || scariestPlayerRecord == -1 || !playerMap.containsKey(scariestPlayerId) || playerMap.get(biggestPlayerId) > scariestPlayerRecord){
            scariestPlayerId = biggestPlayerId;
            scariestPlayerRecord = playerMap.get(biggestPlayerId);
        }
    }

    private void loadScariestPlayer() {
        try {
            BufferedReader in = new BufferedReader(new FileReader(DATA_FILE_NAME));
            int turn = Integer.parseInt(in.readLine());
            if (turn != round || turn != round + 1){
                throw new Exception();
            }
            scariestPlayerId = Integer.parseInt(in.readLine());
            scariestPlayerRecord = Integer.parseInt(in.readLine());
        } catch (Exception e) {
            scariestPlayerId = -1;
            scariestPlayerRecord = -1;
        }
    }


    private class Town {
        final int ownerId;
        final int id;
        final int knights;
        final int lowborns;
        boolean defenseBonus;

        Town(String string) {
            String[] args = string.split("_");
            ownerId = Integer.parseInt(args[0]);
            id = Integer.parseInt(args[1]);
            knights = Integer.parseInt(args[2]);
            lowborns = Integer.parseInt(args[3]);
            defenseBonus = true;
        }

        int getId() {
            return id;
        }

        int knightCount() {
            return knights;
        }

        int lowbornCount() {
            return lowborns;
        }

        boolean isMine() {
            return ownerId == playerID;
        }

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

        int getFreeKnights() {
            return knights - lowborns / 2 - 1;
        }

        int numberOfKnightsToConquer() {
            if (defenseBonus) {
                return ((knights * 6) / 5) + (lowborns / 2) + 1;
            } else {
                return knights + lowborns/2 + 1;
            }
        }

        int numberOfKnightsToOverthrow(){
            if (defenseBonus) {
                return (((knights * 6) / 5) - (lowborns / 2)) + 1;
            } else {
                return knights - lowborns / 2 + 1;
            }
        }

        boolean needsHelp() {
            return getFreeKnights() < 0;
        }

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

İşte orijinal oyuncu:

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

public class Frankenstein {

    int round;
    int playerID;
    int thisTownID;

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

    Town thisTown;

    Player me;

    public static void main(String[] args) {
        if (args.length == 0) {
            System.out.println("100 100 100");
            return;
        }
        new Frankenstein().destroy(args[0].split(";"));
    }

    private static int divide(int a, int b){
        if (a == 0){
            return 0;
        }
        if (b == 0){
            return 1000000;
        }
        return a/b;
    }

    private void destroy(String[] args) {
        round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);
        thisTownID = Integer.parseInt(args[2]);
        towns = new ArrayList<>();
        myTowns = new ArrayList<>();
        otherTowns = new ArrayList<>();


        for (int i = 3; 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);
            }
        }

        players.stream().filter(player -> player.id == playerID).forEach(player -> me = player);

        if (thisTown.getFreeKnights() > 0){

            for (Town town : myTowns){
                if (town.needsHelp()){
                    System.out.println("S " + town.getId() + " " + thisTown.getFreeKnights() / 2);
                    return;
                }
            }

            Town richestTown = otherTowns.stream().max((a, b) -> divide(a.lowbornCount(), a.knightCount()) -
                    divide(b.lowbornCount(), b.knightCount())).get();

            if (richestTown.numberOfKnightsToConquer() < thisTown.getFreeKnights()){
                System.out.println("A " + richestTown.getId() + " " + thisTown.getFreeKnights());
                return;
            }

            otherTowns.sort((a,b) -> divide(b.lowbornCount() * b.owner.richness(), b.getFreeKnights()) -
                    divide(a.lowbornCount() * a.owner.richness(), a.getFreeKnights()));

            if (thisTown.getFreeKnights() >= otherTowns.get(0).numberOfKnightsToOverthrow() && !otherTowns.get(0).isNeutral()){
                System.out.println("A " + otherTowns.get(0).getId() + " " + otherTowns.get(0).numberOfKnightsToOverthrow());
                return;
            }

            myTowns.sort((a,b) -> b.knightCount() - a.knightCount());
            myTowns.sort((a,b) -> b.lowbornCount() - a.lowbornCount());
            if (!myTowns.get(0).isThisTown()){
                System.out.println("S " + myTowns.get(0).getId() + " " + thisTown.getFreeKnights());
                return;
            }

        }

        System.out.println("W");

    }


    private class Town {
        private final int ownerId;
        private final int id;
        private final int knights;
        private final int lowborns;
        private final Player owner;

        private Town(String string) {
            String[] args = string.split("_");
            ownerId = Integer.parseInt(args[0]);
            id = Integer.parseInt(args[1]);
            knights = Integer.parseInt(args[2]);
            lowborns = Integer.parseInt(args[3]);
            for (Player player : players){
                if (player.id == ownerId){
                    player.addTown(this);
                    owner = player;
                    return;
                }
            }
            owner = new Player(id);//This mistake makes my player perform really good for some reason.
            owner.towns.add(this);
        }

        private int getId() {
            return id;
        }

        private int knightCount() {
            return knights;
        }

        private int lowbornCount() {
            return lowborns;
        }

        private boolean isMine() {
            return ownerId == playerID;
        }

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

        private int getFreeKnights() {
            return knights - lowborns / 2 - 1;
        }

        private int numberOfKnightsToConquer() {
            return ((knights * 6) / 5) + (lowborns / 2) + 1;
        }

        private int numberOfKnightsToOverthrow(){
            return (((knights * 6) / 5) - (lowborns / 2)) + 1;
        }

        private boolean needsHelp() {
            return getFreeKnights() < 0;
        }

        private boolean isNeutral() {
            return owner.id == -1;
        }

    }

    List<Player> players = new ArrayList<>();

    private class Player{

        int id;

        List<Town> towns;

        int richness = 0;

        Player(int id){
            this.id = id;
            this.towns = new ArrayList<>();
            players.add(this);
        }

        void addTown(Town t){
            towns.add(t);
            richness += t.lowbornCount();
        }

        int richness(){
            return id == -1 ? (towns.size() > 0 ? 1 : 0) : richness;
        }

    }
}

20 oyun oynamıştım, Frankenstein'ın sadece 2 kez kazandığını, Liberator 17 kez kazandığını söylediğim için üzgünüm (evet, Revolutionnist, Nötr oyuncuyu 2. sırada kazanırken bir kez kazanmayı başardı).
Thrax

@Thrax Sabit !!!!!
TheNumberOne

7

Java, Kaplumbağa

Çekirdek yöntemleri için TheBestOne sayesinde, sadece algoritmayı değiştirdim (umarım iyidir). Bu bot temel olarak en tehlikeli düşman kasabasına rakip olmak için en iyi savunma kentini geliştirirken, diğer kasabalarda isyanı engellemek için yeterli şövalyeye sahipti.

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


public class Turtle {


    int round;
    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("34 34 34");
            return;
        }
        new Turtle().defend(args[0].split(";"));
    }

    private void defend(String[] args) {
        round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);
        thisTownID = Integer.parseInt(args[2]);
        towns = new ArrayList<>();
        myTowns = new ArrayList<>();
        otherTowns = new ArrayList<>();

        for (int i = 3; 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);
            }
        }

        Town bestDefendedTown = null;
        for (Town town : myTowns) {
            if (bestDefendedTown == null)
                bestDefendedTown = town;

            bestDefendedTown = bestDefendedTown.knightCount() >= town.knightCount() ? bestDefendedTown : town;
        }

        Town dangerousEnemyTown = null;
        for (Town town : otherTowns) {
            if (dangerousEnemyTown == null)
                dangerousEnemyTown = town;

            dangerousEnemyTown = dangerousEnemyTown.knightCount() >= town.knightCount() ? dangerousEnemyTown : town;
        }

        int missingKnights = dangerousEnemyTown.knightCount() - bestDefendedTown.knightCount() > 0 ? dangerousEnemyTown.knightCount() - bestDefendedTown.knightCount() : 0;
        int reinforcements = thisTown.getFreeKnights() - (missingKnights + 1) > 0 ? thisTown.getFreeKnights() - (missingKnights + 1) : thisTown.getFreeKnights(); 


        if (reinforcements > 0) {
            System.out.println("S " + bestDefendedTown.getId() + " " + reinforcements);
        } else {
            System.out.println("W");
        }
    }



    private class Town {
        private final int ownerId;
        private final int id;
        private final int knights;
        private final int lowborns;

        public Town(String string){
            String[] args = string.split("_");
            ownerId = Integer.parseInt(args[0]);
            id = Integer.parseInt(args[1]);
            knights = Integer.parseInt(args[2]);
            lowborns = Integer.parseInt(args[3]);
        }

        public int getId() {
            return id;
        }

        public int getOwner() {
            return ownerId;
        }

        public int knightCount() {
            return knights;
        }

        public int lowbornCount() {
            return lowborns;
        }

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

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

        private int getFreeKnights() {
            return knights - lowborns / 2 - 1;
        }
    }
}

Derleme: javac Turtle.java

Koşmak: java Turtle


Ben demek dangerousEnemyTown = dangerousEnemyTown.knightCount() >= town.knightCount() ? dangerousEnemyTown : town;istemedindangerousEnemyTown = bestDefendedTown.knightCount() >= town.knightCount() ? bestDefendedTown : town;
TheNumberOne

@ TheBestOne Bunu işaret ettiğiniz için teşekkür ederiz! Gönderim güncelleniyor.
Thrax

Ayrıca Kaplumbağamın her dönüşünü beklemesine neden olan bir NPE'yi düzelttim. Aslında, bu küçük Kaplumbağa şimdiye dek
Uyuyandı

7

Java 8, Politikacı

Gerçek bir politikacı gibi davranır. Çok kötü Crasher onu hala katlediyor.

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

public class Politician {

    int round;
    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("34 34 34");
            return;
        }
        new Politician().bribe(args[0].split(";"));
    }

    private void bribe(String[] args) {
        round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);
        thisTownID = Integer.parseInt(args[2]);
        towns = new ArrayList<>();
        myTowns = new ArrayList<>();
        otherTowns = new ArrayList<>();


        for (int i = 3; 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);
            }
        }

        Town biggestTown = otherTowns.stream().max((a,b) -> a.knights - b.knights).get();

        if (thisTown.getFreeKnights() <= 0){//Out of knights.
            System.out.println("W");//Waiting for taxes so can hire more knights.
        }

        System.out.println("S " + biggestTown.getId() + " " + thisTown.getFreeKnights());
    }


    private class Town {
        private final int ownerId;
        private final int id;
        private final int knights;
        private final int lowborns;

        public Town(String string){
            String[] args = string.split("_");
            ownerId = Integer.parseInt(args[0]);
            id = Integer.parseInt(args[1]);
            knights = Integer.parseInt(args[2]);
            lowborns = Integer.parseInt(args[3]);
        }

        public int getId() {
            return id;
        }

        public int getOwner() {
            return ownerId;
        }

        public int knightCount() {
            return knights;
        }

        public int lowbornCount() {
            return lowborns;
        }

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

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

        private int getFreeKnights() {
            return knights - lowborns / 2 - 1;
        }

    }
}

Derleme: javac Politician.java

Koşmak: java Politician


1
Rüşvet için +1, ama çok yaygın bir lieyöntemi kaçırdığınızı düşünüyorum
globby

6

Java 8, Tereyağı

Mümkün olduğu kadar eşit şekilde yayılır. Kasaba yeterince küçükse kasabayı boğar.

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

public class Butter {

    int round;
    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("34 34 34");
            return;
        }
        new Butter().spread(args[0].split(";"));
    }

    private void spread(String[] args) {
        round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);
        thisTownID = Integer.parseInt(args[2]);
        towns = new ArrayList<>();
        myTowns = new ArrayList<>();
        otherTowns = new ArrayList<>();


        for (int i = 3; 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);
            }
        }

        Town mySmallestTown = myTowns.stream().min((a, b) -> a.getFreeKnights() - b.getFreeKnights()).get();

        Town smallestEnemyTown = otherTowns.stream().min((a,b) -> a.knights - b.knights).get();

        if ((thisTown.getFreeKnights() - mySmallestTown.getFreeKnights())/2 > 0) {
            System.out.println("S " + mySmallestTown.getId() + " " + (thisTown.getFreeKnights() - mySmallestTown.getFreeKnights()) / 2);
        } else if (thisTown.getFreeKnights() / 2 > smallestEnemyTown.numberOfKnightsToConquer()){
            System.out.println("A " + smallestEnemyTown.getId() + " " + smallestEnemyTown.numberOfKnightsToConquer());
        } else {
            System.out.println("W");
        }
    }


    private class Town {
        private final int ownerId;
        private final int id;
        private final int knights;
        private final int lowborns;

        private Town(String string){
            String[] args = string.split("_");
            ownerId = Integer.parseInt(args[0]);
            id = Integer.parseInt(args[1]);
            knights = Integer.parseInt(args[2]);
            lowborns = Integer.parseInt(args[3]);
        }

        private int getId() {
            return id;
        }

        private int getOwner() {
            return ownerId;
        }

        private int knightCount() {
            return knights;
        }

        private int lowbornCount() {
            return lowborns;
        }

        private boolean isMine(){
            return ownerId == playerID;
        }

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

        private int getFreeKnights() {
            return knights - lowborns / 2 - 1;
        }

        private int numberOfKnightsToConquer(){
            return ((knights * 6) / 5) + (lowborns / 2) + 1;
        }

    }
}

Derleme: javac Butter.java

Koşmak: java Butter


6

Java, Devrimci

Sonuncusu, hala TheBestOne çekirdek yöntemlerine dayanıyor. Bu bot her kasabada isyanları kışkırtmaya çalışıyor, çünkü Neutral oyuncusu düşük seviyeli nüfusa göre belirli bir şövalyeyi öldürerek saldırgan. Elbette Nötr oyuncuya saldırmadı.

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


public class Revolutionist {


    int round;
    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("80 80 80");
            return;
        }
        new Revolutionist().inciteRebellion(args[0].split(";"));
    }

    private void inciteRebellion(String[] args) {
        round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);
        thisTownID = Integer.parseInt(args[2]);
        towns = new ArrayList<>();
        myTowns = new ArrayList<>();
        otherTowns = new ArrayList<>();

        for (int i = 3; 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);
            }
        }

        Town onEdgeTown = null;
        int edgeCounter = 100;
        for (Town town : otherTowns) {
            if (onEdgeTown == null)
                onEdgeTown = town;

            if (town.getFreeKnights() >= 0 && town.getFreeKnights() <= edgeCounter && town.getOwner() >= 0) {
                onEdgeTown = town;
                edgeCounter = town.getFreeKnights();
            }
        }

        int minimumRequiredKnights = (int) ((onEdgeTown.knightCount() * 1.2 - onEdgeTown.getMinimumKnights() + 2) * 1.2) ;


        if (thisTown.getFreeKnights() > minimumRequiredKnights && onEdgeTown.getOwner() >= 0)
            System.out.println("A " + onEdgeTown.getId() + " " + minimumRequiredKnights);
        else
            System.out.println("W");

    }



    private class Town {
        private final int ownerId;
        private final int id;
        private final int knights;
        private final int lowborns;

        public Town(String string){
            String[] args = string.split("_");
            ownerId = Integer.parseInt(args[0]);
            id = Integer.parseInt(args[1]);
            knights = Integer.parseInt(args[2]);
            lowborns = Integer.parseInt(args[3]);
        }

        public int getId() {
            return id;
        }

        public int getOwner() {
            return ownerId;
        }

        public int knightCount() {
            return knights;
        }

        public int lowbornCount() {
            return lowborns;
        }

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

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

        private int getFreeKnights() {
            return knights - lowborns / 2 - 1;
        }

        private int getMinimumKnights() {
            return lowborns / 2 + 1;
        }
    }
}

Derleme: javac Revolutionist.java

Koşmak: java Revolutionist


6

JAVA, Sehtimianer

TheBestOne'a tekrar teşekkürler, çekirdek yöntemlerini de kopyaladım; ) Bu benim ilk kez bir KingOfTheHill-CodeGame oynadığım için, umarım her şeyi doğru yaptım. Sehtimianers: D’i gururla sunarım: D

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Sehtimianer {

private static final String FILENAME = "Sehtimianer.txt";
private static final int AGGRESSIVE_ROUND_BORDER = 80;

int round;
int playerID;
int thisTownID;

List<Town> towns = new ArrayList<Town>();
List<Town> myTowns = new ArrayList<Town>();
List<Town> playerTowns = new ArrayList<Town>();
List<Town> neutralTowns = new ArrayList<Town>();
Map<Integer, Integer> townToPlayerMapping = new HashMap<Integer, Integer>();
boolean isAllowedToWriteMapping = true;

Town thisTown;

public static void main(String[] args) {
    if (args.length == 0) {
        // new File(FILENAME).delete();
        System.out.println("100 100 100");
        return;
    }
    new Sehtimianer().decide(args[0].split(";"));
}

private void decide(String[] args) {
    // final long start = System.currentTimeMillis();

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

    for (int i = 3; 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.getOwner() == -1) {
                neutralTowns.add(town);
            } else {
                playerTowns.add(town);
            }
        }
    }

    if (new File(FILENAME).exists()) {
        try {
            BufferedReader reader = new BufferedReader(new FileReader(FILENAME));
            String inputLine;
            String[] ids;
            while ((inputLine = reader.readLine()) != null) {
                ids = inputLine.split(";");
                if (ids.length == 1) {
                    Integer writingTownID = Integer.valueOf(ids[0]);
                    boolean townIsLost = true;
                    for (Town town : myTowns) {
                        if (town.getId() == writingTownID) {
                            townIsLost = false;
                            break;
                        }
                    }
                    isAllowedToWriteMapping = townIsLost || thisTownID == writingTownID;
                    continue;
                }
                townToPlayerMapping.put(Integer.valueOf(ids[0]), Integer.valueOf(ids[1]));
            }
            reader.close();

            for (Town town : towns) {
                if (!townToPlayerMapping.get(town.getId()).equals(town.getOwner())) {
                    town.setDefenseBonus(false);
                }
            }
        } catch (IOException e) {
            // Dont worry : )
        }
    }

    if (round == 1) {
        int maxKnights = 0;
        int maxKnightTownID = thisTownID;
        for (Town town : myTowns) {
            if (town == thisTown) {
                continue;
            }
            if (town.knightCount() > maxKnights) {
                maxKnights = town.knightCount();
                maxKnightTownID = town.getId();
            }
        }
        if (maxKnightTownID != thisTownID) {
            System.out.println("S " + maxKnightTownID + " " + thisTown.knightCount());
        }
    } else if (round % 3 == 2) {
        int myKnightIncome = 0;
        for (Town town : myTowns) {
            myKnightIncome += town.lowbornCount() / 2;
        }

        Map<Integer, Integer> playerKnightIncomeMap = new HashMap<Integer, Integer>();
        Map<Integer, Integer> playerTownCountMap = new HashMap<Integer, Integer>();
        List<Integer> nextRoundKnights = new ArrayList<Integer>();
        Map<Integer, Town> nextRoundKnightsToTownMapping = new HashMap<Integer, Town>();

        for (Town town : playerTowns) {
            fillDescisionMaps(town, nextRoundKnights, nextRoundKnightsToTownMapping, playerKnightIncomeMap, playerTownCountMap);
        }
        for (Town town : neutralTowns) {
            fillDescisionMaps(town, nextRoundKnights, nextRoundKnightsToTownMapping, playerKnightIncomeMap, playerTownCountMap);
        }

        Integer maxEnemyKnightIncome = 0;
        for (Integer knightIncome : playerKnightIncomeMap.values()) {
            if (knightIncome > maxEnemyKnightIncome) {
                maxEnemyKnightIncome = knightIncome;
            }
        }
        Integer maxEnemyTownCount = 0;
        for (Integer townCount : playerTownCountMap.values()) {
            if (townCount > maxEnemyTownCount) {
                maxEnemyTownCount = townCount;
            }
        }

        if (maxEnemyKnightIncome > myKnightIncome || (round > AGGRESSIVE_ROUND_BORDER && maxEnemyTownCount >= myTowns.size())) {
            Collections.sort(nextRoundKnights);
            int possibleHighest = 0;
            Town enemyTown;
            int enemyTownUpkeep;
            for (int i = nextRoundKnights.size() - 1; i >= 0; i--) {
                possibleHighest = nextRoundKnights.get(i);
                enemyTown = nextRoundKnightsToTownMapping.get(possibleHighest);
                enemyTownUpkeep = enemyTown.lowbornCount() / 2;
                if (enemyTownUpkeep > (possibleHighest - enemyTownUpkeep)) { // Substract the calculated Income for the next Turn
                    // Town will be lost because of revolution after captured -> Bad target
                    possibleHighest = 0;
                    continue;
                }
                if (round > AGGRESSIVE_ROUND_BORDER || enemyTown.lowbornCount() > 0) {
                    break;
                }
            }
            if (possibleHighest > 0) {
                Town attackedTown = nextRoundKnightsToTownMapping.get(possibleHighest);
                System.out.println("A " + attackedTown.getId() + " " + calcHowMuchKnightsShouldAttack(attackedTown, possibleHighest));
            }
        }
    }

    if (isAllowedToWriteMapping) {
        try {
            BufferedWriter writer = new BufferedWriter(new FileWriter(FILENAME));
            writer.write(thisTownID + "\n");
            for (Town town : towns) {
                writer.write(town.getId() + ";" + town.getOwner() + "\n");
            }
            writer.close();
        } catch (IOException e) {
            // Dont worry : )
        }
    }

    System.out.println("W");

    // long duration = System.currentTimeMillis() - start;
    // if (duration > 1000) {
    // throw new RuntimeException();
    // }
}

private void fillDescisionMaps(Town town, List<Integer> nextRoundKnights, Map<Integer, Town> nextRoundKnightsToTownMapping, Map<Integer, Integer> playerKnightIncomeMap,
        Map<Integer, Integer> playerTownCountMap) {
    int calculatedKnights = calcKnightsInNextRound(town);
    nextRoundKnights.add(calculatedKnights);
    nextRoundKnightsToTownMapping.put(calculatedKnights, town);

    Integer enemyKnightIncome = playerKnightIncomeMap.get(town.getOwner());
    if (enemyKnightIncome == null) {
        enemyKnightIncome = town.lowbornCount() / 2;
    } else {
        enemyKnightIncome = enemyKnightIncome + (town.lowbornCount() / 2);
    }
    playerKnightIncomeMap.put(town.getOwner(), enemyKnightIncome);

    Integer enemyTownCount = playerTownCountMap.get(town.getOwner());
    if (enemyTownCount == null) {
        enemyTownCount = Integer.valueOf(1);
    } else {
        enemyTownCount = enemyTownCount + 1;
    }
    playerTownCountMap.put(town.getOwner(), enemyTownCount);
}

private int calcKnightsInNextRound(Town enemyTown) {
    int knights = (int) ((double) enemyTown.knightCount() * (enemyTown.isDefenseBonus() ? 1.2 : 1));
    knights = thisTown.getFreeKnights() - knights;
    if (knights > 0) {
        knights += enemyTown.lowbornCount() / 2;
    } else {
        knights = 0;
    }
    return knights;
}

private int calcHowMuchKnightsShouldAttack(Town enemyTown, int possibleHighest) {
    if (round < AGGRESSIVE_ROUND_BORDER && thisTown.lowbornCount() == 0) {
        return thisTown.knightCount();
    }

    int spareKnights = possibleHighest - enemyTown.lowbornCount(); // Correct -> div 2 and mul 2
    int minShouldSend = thisTown.getFreeKnights() - (spareKnights / 2);

    return Math.max(minShouldSend, thisTown.knightCount() / 2);
}

private class Town {
    private final int ownerId;
    private final int id;
    private final int knights;
    private final int lowborns;
    private boolean defenseBonus;

    public Town(String string) {
        String[] args = string.split("_");
        ownerId = Integer.parseInt(args[0]);
        id = Integer.parseInt(args[1]);
        knights = Integer.parseInt(args[2]);
        lowborns = Integer.parseInt(args[3]);
        defenseBonus = true;
    }

    public boolean isDefenseBonus() {
        return defenseBonus;
    }

    public void setDefenseBonus(boolean defenseBonus) {
        this.defenseBonus = defenseBonus;
    }

    public int getId() {
        return id;
    }

    public int getOwner() {
        return ownerId;
    }

    public int knightCount() {
        return knights;
    }

    public int lowbornCount() {
        return lowborns;
    }

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

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

    private int getFreeKnights() {
        return knights - lowborns / 2 - 1;
    }
}
}

Şehtimistler bütün oyundan üstün olmaya ve sonunda bitirmeye çalışırlar. Umarım botum çok kötü olmaz:)


5

Java, Çıkış

TheBestOne çekirdek yöntemlerine dayanarak bir kez daha. Bu bot, belli bir şövalye nüfusuna ulaştığında, sahibinden bağımsız bir şekilde kentten şehire göç eder ve bu süreci tüm dünyayı dönene kadar tekrar eder.

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


public class Exodus {


    int round;
    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("100 100 100");
            return;
        }
        new Exodus().migrate(args[0].split(";"));
    }

    private void migrate(String[] args) {
        round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);
        thisTownID = Integer.parseInt(args[2]);
        towns = new ArrayList<>();
        myTowns = new ArrayList<>();
        otherTowns = new ArrayList<>();

        for (int i = 3; 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 (thisTown.knightCount() >= 100) {
           int nextTownId = thisTown.getId() + 1 > towns.size() - 1 ? 0 : thisTown.getId() + 1;
           Town nextTown = towns.get(nextTownId);
          if (nextTown.isMine()){
              System.out.println("S " + nextTown.getId() + " " + thisTown.knightCount()) ;
          } else {
              System.out.println("A " + nextTown.getId() + " " + thisTown.knightCount()) ;
          }
       } else {
           System.out.println("W") ;
       }
    }



    private class Town {
        private final int ownerId;
        private final int id;
        private final int knights;
        private final int lowborns;

        public Town(String string){
            String[] args = string.split("_");
            ownerId = Integer.parseInt(args[0]);
            id = Integer.parseInt(args[1]);
            knights = Integer.parseInt(args[2]);
            lowborns = Integer.parseInt(args[3]);
        }

        public int getId() {
            return id;
        }

        public int getOwner() {
            return ownerId;
        }

        public int knightCount() {
            return knights;
        }

        public int lowbornCount() {
            return lowborns;
        }

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

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

        private int getFreeKnights() {
            return knights - lowborns / 2 - 1;
        }
    }
}

Derleme: javac Exodus.java

Koşmak: java Exodus


5

Python 2, Demokrasi

Bu kral kral değil. Modern bir şey. Bu insanların kralı . Bu demokrasi. Yavaş, verimsiz ve bir şey yaptığında yanlış yapar.

import sys
from math import sqrt, ceil

class Town:
    def __init__(self, owner, ID, military, civilian):
        self.owner=owner
        self.id=ID
        self.isEnemy=(self.owner!=PlayerId)
        self.isCurrent=(self.id!=TownId)
        self.mil=military
        self.civ=civilian
        self.freeK=self.mil-self.civ/2
    def canBeat(self, other):
        otherPower    = int(ceil(other.mil*1.2))
        otherMinPower = int(ceil(other.freeK*1.2))
        selfPower     = self.freeK
        if selfPower<otherMinPower:
            return 0
        elif selfPower<otherPower or (selfPower-otherPower)*2-1<other.civ:
            return 1
        else:
            return 2
    def canMove(self, other):
        otherPower    = int(ceil(other.mil*1.2))
        otherMinPower = int(ceil(other.freeK*1.2))
        if otherPower<self.mil:
            return 2
        elif otherMinPower<=self.mil:
            return 1
        else:
            return 0

    def canDefend(self, other):
        return self.freeK>other.mil

def attack_weak():

    for town in EnemyTowns:
        if curr.canMove(town)==2:
            print "A", town.id, curr.mil
            exit()
    for town in EnemyTowns:
        if curr.canMove(town)==1:
            print "A", town.id, curr.mil
            exit()

    target=EnemyTowns[0]
    for et in EnemyTowns:
        if et.mil<target.mil and et.id!=-1:
            target=et
    print "A", target.id, curr.mil-1
    exit()


if len(sys.argv) < 2:
    print 96, 96, 96
else:
    Round, PlayerId, TownId, Towns = sys.argv[1].split(";", 3)
    Round=int(Round)
    PlayerId=int(PlayerId)
    TownId=int(TownId)
    Towns=[[int(i) for i in town.split("_")] for town in Towns.split(";")]
    Towns=[Town(i[0], i[1], i[2], i[3]) for i in Towns]
    MyTowns=[t for t in Towns if t.isEnemy==False]
    EnemyTowns=[t for t in Towns if t.isEnemy]
    GameStateEnd = [t for t in EnemyTowns if t.id!=-1]==[]
    curr=[town for town in MyTowns if town.isCurrent][0]

    support=[town for town in MyTowns if town.freeK<1]
    if support!=[]:
        for town in support:
            if town.id==curr.id:
                missing=town.freeK-int(ceil(town.civ/2))
                if town.civ<5:
                    attack_weak()
                elif town.freeK<-10:
                    attack_weak()
                else:
                    print "W"
                    exit()
        for town in support:
            if abs(town.freeK-2)<curr.freeK-2:
                print "S", town.id, abs(town.freeK-2)
                exit()
            else:
                if curr.freeK>10:
                    print "S", town.id, int(abs(town.freeK-2)*0.2)
                    exit()
    if GameStateEnd:
        attack_end()
    else:
        selection=EnemyTowns[:]
        selection.sort(key=(lambda x: (x.mil-x.civ) if x.civ>3 else x.mil/4))
        for s in selection:
            if curr.canBeat(s)==2 and s.civ>s.mil/2:
                NF=(int(ceil(s.mil*1.2))+s.civ/2+1)
                if curr.mil>NF:
                    print "A", s.id, NF+(curr.mil-NF)/3
                    exit()
    if curr.freeK>10:
        MyTowns.sort(key=lambda x: x.mil)
        print "S", MyTowns[-1].id, (curr.freeK-5)/5*3
        exit()
    print "W"
    exit()

Run python2 democracy.py. Demokrasinin Python 2 gerektirdiğini unutmayın .

Düzenleme: Kasaba nesnesini yazdırma konusunda düzeltilen hata


Bu bazen çıktılar <__main__.Town.
TheNumberOne

Düzeltmek
zorundasın

4

C ++ 11, Hesaplanan Dosya

Küçük Java ile birkaç şey denedikten sonra bildiğim ve istediklerimi elde edemediğim için C ++ 'da yeniden yazmayı ve dosya işlemeyi eklemeyi seçtim. Sorun şu ki, benim C ++ paslı ve çok daha iyi değil, bu yüzden bazı parçalar bir araya toplanmış ve google'da ilk çözüm, yani gerçekten kalite kodu değil ...

Yine de, o kadar emmek değil en azından çalışan bir sonuç elde edebildim, zaman zaman en az kazanır, ancak bu bilgisayarda diğer tüm gönderimleri çalıştıramadığım için mükemmel bir şekilde test edemiyorum. Muhtemelen hedeflemeyi tamamen yeniden yazacağım ve daha sonra bugün veya yarın başka bir cevap olarak ekleyeceğim.

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <cmath>
#include <ratio>
#include <fstream>
#include <algorithm>

using namespace std;


class Town {
public:
    Town(int owner, int townId, int knights, int population, int roundToDefBonus);
    int getOwner();
    int getId();
    int getKnights();
    int getPopulation();

    int getFreeKnights();
    int neededConquer();
    int getKnightsStable();
    int getRoundToDef();

    bool operator< (const Town &other) const  {
        return townId < other.townId;
    }
private:
    int owner;
    int townId;
    int knights;
    int population;
    int roundToDefBonus;
    double defBonus;
};

Town::Town(int inOwner, int inTownId, int inKnights, int inPopulation, int inRoundToDefBonus) {
    owner = inOwner;
    townId = inTownId;
    knights = inKnights;
    population = inPopulation;
    roundToDefBonus = inRoundToDefBonus;
    if(roundToDefBonus > 0) {
        defBonus = 1;
    }
    else{
        defBonus = 1.2;
    }
}

int Town::getOwner() {
    return owner;
}
int Town::getId() {
    return townId;
}
int Town::getKnights() {
    return knights;
}
int Town::getPopulation() {
    return population;
}
int Town::getFreeKnights() {
    return knights - population / 2;
}
int Town::neededConquer() {
    return max(static_cast<int>(ceil(knights * defBonus + population / 2)), 1);
}
int Town::getKnightsStable() {
    return population / 2;
}
int Town::getRoundToDef() {
    return roundToDefBonus;
}


int gameRound;
int myId;
int thisTownId;
Town* thisTown;

vector <Town> myTowns;
vector <Town> enemyTowns;

vector <Town> lastTime;

string turn();
Town* bestTarget(int knights);
Town* bestSafe(int knights);
Town* biggestTarget(int knights);
Town* biggestSafe(int knights);


string out(string, int, int);
string attack(Town*);
string safe(Town*);

bool sortTowns(const Town & t1, const Town & t2);

vector <string> stringSplit(string input, string delimeter);

int main(int argc, char* argv[]) {
    if(argc < 2){
        cout << "100 100 100";
        ofstream myFile;
        myFile.open("CalculatedFail.txt");
        myFile << "0\n";
        myFile.close();
    }
    else{
        if(argc == 2){

            string input = argv[1];
            vector <string> params = stringSplit(input, ";");

            gameRound = atoi(params.at(0).c_str());
            myId = atoi((params.at(1)).c_str());
            thisTownId = atoi(params.at(2).c_str());

            ifstream myfile("CalculatedFail.txt");
            if(myfile.is_open()){
                string line;

                getline(myfile, line);
                bool newRound = false;
                if(atoi(line.c_str()) > gameRound) {
                    newRound = true;
                }

                vector <string> oldVals;
                if(!newRound) {
                    while (getline(myfile, line)) {
                        oldVals = stringSplit(line, "_");

                        int playerId = atoi(oldVals.at(0).c_str());
                        int townId = atoi(oldVals.at(1).c_str());
                        int knights = atoi(oldVals.at(2).c_str());
                        int population = atoi(oldVals.at(3).c_str());
                        int roundToDefBonus = atoi(oldVals.at(4).c_str());

                        lastTime.push_back(Town(playerId, townId, knights, population, roundToDefBonus));
                        oldVals.clear();
                    }
                }
                else {
                    while (getline(myfile, line)) {
                        oldVals = stringSplit(line, "_");

                        int playerId = atoi(oldVals.at(0).c_str());
                        int townId = atoi(oldVals.at(1).c_str());
                        int knights = atoi(oldVals.at(2).c_str());
                        int population = atoi(oldVals.at(3).c_str());
                        int roundToDefBonus = atoi(oldVals.at(4).c_str());
                        if(roundToDefBonus) {   //if round def bonus > 0, decrement because new round
                            roundToDefBonus --;
                        }

                        lastTime.push_back(Town(playerId, townId, knights, population, roundToDefBonus));
                        oldVals.clear();
                    }

                }
                std::sort(lastTime.begin(), lastTime.end());
            }

            if(lastTime.size() > 0) {
                vector <string> values;
                for(int i = 3; i < params.size(); i++) {

                    values = stringSplit(params.at(i), "_");

                    int playerId = atoi(values.at(0).c_str());
                    int townId = atoi(values.at(1).c_str());
                    int knights = atoi(values.at(2).c_str());
                    int population = atoi(values.at(3).c_str());

                    int roundsToDef = lastTime.at(townId).getRoundToDef();
                    if(playerId != lastTime.at(townId).getOwner()) {
                        roundsToDef = 2;
                    }
                    if(playerId == myId){
                        if(thisTownId != townId)
                            myTowns.push_back(Town(playerId, townId, knights, population, roundsToDef));
                        else{
                            thisTown = new Town(playerId, townId, knights, population, roundsToDef);
                        }
                    }
                    else{
                        enemyTowns.push_back(Town(playerId, townId, knights, population, roundsToDef));
                    }
                    values.clear();
                }
            }
            else {
                vector <string> values;
                for(int i = 3; i < params.size(); i++) {

                    values = stringSplit(params.at(i), "_");

                    int playerId = atoi(values.at(0).c_str());
                    int townId = atoi(values.at(1).c_str());
                    int knights = atoi(values.at(2).c_str());
                    int population = atoi(values.at(3).c_str());

                    if(playerId == myId){
                        if(thisTownId != townId)
                            myTowns.push_back(Town(playerId, townId, knights, population, 0));
                        else{
                            thisTown = new Town(playerId, townId, knights, population, 0);
                        }
                    }
                    else{
                        enemyTowns.push_back(Town(playerId, townId, knights, population, 0));
                    }
                    values.clear();
                }
            }

            string tmp = turn();
            cout << tmp;

            ofstream writeFile("CalculatedFail.txt");
            if(writeFile.is_open()) {
                writeFile << gameRound <<"\n";

                writeFile << thisTown->getOwner() <<"_"<<thisTown->getId()<<"_"<<thisTown->getKnights()<<"_"<< thisTown->getPopulation()<<"_"<<thisTown->getRoundToDef()<<"\n";

                for(vector<Town>::size_type i = 0; i != myTowns.size(); i++) {
                    writeFile << myTowns[i].getOwner() <<"_"<<myTowns[i].getId()<<"_"<<myTowns[i].getKnights()<<"_"<< myTowns[i].getPopulation()<<"_"<<myTowns[i].getRoundToDef()<<"\n";
                }
                for(vector<Town>::size_type i = 0; i != enemyTowns.size(); i++) {
                    writeFile << enemyTowns[i].getOwner() <<"_"<<enemyTowns[i].getId()<<"_"<<enemyTowns[i].getKnights()<<"_"<< enemyTowns[i].getPopulation()<<"_"<<enemyTowns[i].getRoundToDef()<<"\n";
                }
            }

        }
        else{
            cout<<"error, wrong parameter";
        }

    }

    delete thisTown;

    return 0;
}




string turn() {
    Town* safeTarget;
    Town* attackTarget;
    if(thisTown->getFreeKnights() < 0) {    //evacuate
        safeTarget = biggestSafe(thisTown->getKnights());
        attackTarget = biggestTarget(thisTown->getKnights());

        if(safeTarget != nullptr && attackTarget != nullptr){
            if(safeTarget->getPopulation() > attackTarget->getPopulation()) {
                return out("S", safeTarget->getId(), thisTown->getKnights());
            }
            else {
                return out("A", attackTarget->getId(), thisTown->getKnights());
            }
        }
        if(safeTarget){
            return out("S", safeTarget->getId(), thisTown->getKnights());
        }
        if(attackTarget){
            return out("A", attackTarget->getId(), thisTown->getKnights());
        }
        Town* target = &myTowns.at(0);
        for(vector<Town>::size_type i = 1; i != myTowns.size(); i++) {
            if(target->getPopulation() < myTowns[i].getPopulation())
                target = &myTowns[i];
        }
        return out("S", target->getId(), thisTown->getKnights());

    }

    safeTarget = biggestSafe(thisTown->getFreeKnights());
    attackTarget = bestTarget(thisTown->getFreeKnights());


    if(safeTarget != nullptr && attackTarget != nullptr){
        if(safeTarget->getPopulation() > attackTarget->getPopulation()) {
            return safe(safeTarget);
        }
        else {
            return attack(attackTarget);
        }
    }
    if(safeTarget){
        return safe(safeTarget);
    }
    if(attackTarget){
        return attack(attackTarget);
    }

    return "W";
}

Town* bestTarget(int knights) {
    Town* target = nullptr;
    double ratio = -1;
    for(vector<Town>::size_type i = 0; i != enemyTowns.size(); i++) {
        if(enemyTowns[i].neededConquer() < knights) {
            if(enemyTowns[i].getPopulation() / enemyTowns[i].neededConquer() > ratio) {
                target = &enemyTowns[i];
                ratio = enemyTowns[i].getPopulation() / enemyTowns[i].neededConquer();
            }
        }
    }
    return target;
}

Town* biggestTarget(int knights) {
    Town* target = nullptr;
    int population = -1;
    for(vector<Town>::size_type i = 0; i != enemyTowns.size(); i++) {
        if(enemyTowns[i].neededConquer() < knights) {
            if(enemyTowns[i].getPopulation() > population) {
                target = &enemyTowns[i];
                population = target->getPopulation();
            }
        }
    }
    return target;
}

Town* biggestSafe(int knights) {
    Town* target = nullptr;
    int population = -1;
    for(vector<Town>::size_type i = 0; i != myTowns.size(); i++) {
        if(myTowns[i].getFreeKnights() < 0 && myTowns[i].getFreeKnights() + knights >= 0){
            if(myTowns[i].getPopulation() > population) {
                target = &myTowns[i];
                population = target->getPopulation();
            }
        }
    }
    return target;
}

string attack(Town* target){
    int knights;
    if(thisTown->getPopulation() > target->getPopulation()) {
        knights = target->neededConquer();
    }
    else{
        knights = thisTown->getFreeKnights();
    }
    return out("A", target->getId(), knights);
}
string safe(Town* target){
    int knights;
    if(thisTown->getPopulation() > target->getPopulation()) {
        knights = target->getFreeKnights() * -1;
    }
    else{
        knights = thisTown->getFreeKnights();
    }
    return out("S", target->getId(), knights);
}
string out(string order, int targedId, int knights) {
    stringstream tmp;
    tmp << order << " " << targedId << " " << knights;
    return tmp.str();
}

vector <string> stringSplit(string input, string delimeter) {
    stringstream tmp(input);
    vector <string> splitted;
    string pushThis;
    while (getline(tmp, pushThis, delimeter.at(0))){
        splitted.push_back(pushThis);
    }

    return splitted;
}

ile derlemek: g++ -std=c++11 CalculatedFail.cpp -o CalculatedFail.exe

google linux'da .exe yerine CalculatedFail.out olduğunu söylüyor, ancak test edemiyorum.

ve koş CalculatedFail.exe

def bonusunu kontrol etmek için bir dosya kullandığından, oyunu aynı anda birden çok kez çalıştırmak hatalara yol açabilir ...

umarım çok fazla sorun olmadan düzgün çalışır


Linux'ta bir dosya uzantısına sahip olmayacağından eminim.
TheNumberOne

Bunun Windows'ta Java Denetleyiciden çalışmasını sağlayamıyorum. Söylediğin gibi derledim. Komut satırından doğru çalışıyor.
TheNumberOne

Tamam ben aptal
arı

Kontrolörde bir sorun olduğunu düşünüyorum.
TheNumberOne

mh güncellenmiş sürümü denediniz mi? dün kazayla ilgili 2 farklı dosya ismim vardı. attackOn3 sürümü, temelde kazanmışsa, nadiren hatalara yol açar, ancak ikisi de sistemimdeki denetleyiciyle gayet iyi çalışıyor.
sthrandom

3

Java, Illuminati

Bunu okudum ve asla uygulanabilir bir strateji bulamayacağımı biliyordum, bu yüzden bizi yönetebilecek veya aldatmayacak kadar az temsil edilen kertenkele insanlarla oynamaya karar verdim. Diğer botlarla savaşmak yerine, bu sadece onları en sonunda terk etmeleri için onları işbirliğine zorlar. Bu bot aslında kalıcı bir hasar bırakmaz.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

public class Illuminati
{
    private static final String template = 
            "import java.io.File;import java.util.Scanner;import java.io.IOException;\n" +
            "public class <<NAME>> \n" +
            "{public static void main(String[] args) throws IOException {if(args.length == 0) {\n" +
            "System.out.println(\"35 35 35\");} else { File ill_data = new File(\"Illuminati.txt\");\n" + 
            "String order = new String();Scanner sc = new Scanner(ill_data);\n" +
            "while(sc.hasNextLine()){order = sc.nextLine();} sc.close(); int city = Integer.parseInt(order);" +
            "Illuminati.TurnDescriptor desc = new Illuminati.TurnDescriptor(args[0]);" +
            "int amt = desc.thistown.getFreeKnights(); System.out.println(\"S \" + city + \" \" + amt); }}}";

    private static final File datafile = new File("Illuminati.txt");

    private static final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

    public static void main(String[] args) throws IOException
    {
        if(args.length == 0)
        {
            if(compiler != null)
            {
                if(!datafile.exists())
                {
                    datafile.createNewFile();
                }

                File parentdir = datafile.getAbsoluteFile().getParentFile();
                List<File> torecompile = new ArrayList<File>();

                for(File f : parentdir.listFiles())
                {
                    if(!f.isDirectory())
                    {
                        if(f.getName().endsWith(".class") && !f.getName().contains("$") && !f.getName().equals("Illuminati.class"))
                        {
                            torecompile.add(f);
                        }
                    }
                }

                for(File f : torecompile)
                {
                    File newfile = new File(f.getName() + ".temp");
                    FileInputStream fis = new FileInputStream(f);
                    FileOutputStream fos = new FileOutputStream(newfile);
                    int val;
                    while((val = fis.read()) != -1)
                    {
                        fos.write(val);
                    }
                    fis.close();
                    fos.close();
                }

                List<File> tocompile = new ArrayList<File>();

                for(File f : torecompile)
                {
                    String classname = f.getName().substring(0, f.getName().length() - 6);
                    String code = template.replace("<<NAME>>", classname);
                    File temp = new File(classname + ".java");
                    FileOutputStream fos = new FileOutputStream(temp);
                    fos.write(code.getBytes());
                    fos.close();
                    tocompile.add(temp);
                }

                StandardJavaFileManager manager = compiler.getStandardFileManager(null, null, null);
                compiler.getTask(null, manager, null, null, null, manager.getJavaFileObjectsFromFiles(tocompile)).call();

                tocompile.forEach(file -> file.delete());

                System.out.println("34 34 34");
            }
            else
            {
                System.out.println("85 85 85");
            }
        }
        else
        {
            if(datafile.exists())
            {
                TurnDescriptor descriptor = new TurnDescriptor(args[0]);
                int knights = descriptor.thistown.getFreeKnights();
                int stockpile = descriptor.towns.stream()
                .filter(town -> town.owner == descriptor.thistown.owner)
                .mapToInt(town -> town.id)
                .max().getAsInt();
                PrintWriter pw = new PrintWriter(datafile);
                pw.println("" + stockpile);
                pw.close();
                if(descriptor.thistown.id != stockpile)
                {
                    System.out.println("S " + stockpile + " " + knights);
                }
                if(descriptor.round > 80 && (descriptor.round & 1) == 1) //If the round is greater than 80 and is odd
                {
                    if(descriptor.thistown.id == stockpile)
                    {
                        Town target = descriptor.towns.stream()
                        .filter(town -> town.owner != descriptor.playerid)
                        .findAny().get();

                        System.out.println("A " + target.id + " " + descriptor.thistown.getFreeKnights());
                    }
                }
                if(descriptor.round == 99) //Resume normal AI practices
                {
                    resetClassesFromCache();
                }
            }
            else //Man, now we have to actually do stuff
            {
                System.out.println("W"); //Just kidding! Suicide!
            }
        }
    }

    private static void resetClassesFromCache() throws IOException
    {
        File parentdir = datafile.getAbsoluteFile().getParentFile();

        for(File f : parentdir.listFiles())
        {
            if(!f.isDirectory())
            {
                if(f.getName().endsWith(".class.temp") && !f.getName().contains("$"))
                {
                    FileInputStream fis = new FileInputStream(f);
                    File out = new File(f.getName().substring(0, f.getName().length() - 5));
                    FileOutputStream fos = new FileOutputStream(out, false);

                    int val;
                    while((val = fis.read()) != -1)
                    {
                        fos.write(val);
                    }

                    fis.close();
                    fos.close();
                    f.delete();
                }
            }
        }
    }

    public static class Town
    {
        public final int owner;
        public final int id;
        public final int knights;
        public final int lowborns;

        public Town(String chunk)
        {
            String[] vals = chunk.split("_");
            owner = Integer.parseInt(vals[0]);
            id = Integer.parseInt(vals[1]);
            knights = Integer.parseInt(vals[2]);
            lowborns = Integer.parseInt(vals[3]);
        }

        public int getFreeKnights()
        {
            return knights - (lowborns/2) - 1;
        }
    }

    public static class TurnDescriptor
    {
        public final List<Town> towns;
        public final int round;
        public final int playerid;
        public final Town thistown;

        public TurnDescriptor(String s)
        {
            String[] info = s.split(";");
            round = Integer.parseInt(info[0]);
            playerid = Integer.parseInt(info[1]);
            final int townid = Integer.parseInt(info[2]);

            towns = new ArrayList<Town>();
            for(int i = 3; i < info.length; i++)
            {
                Town t = new Town(info[i]);
                towns.add(t);
            }

            thistown = towns.stream()
            .filter(town -> {return town.id == townid;})
            .findFirst().get();
        }
    }
}

2
Bu ilginç bir cevap olsa da, " Diğer dış kaynaklar yasaklandı ". Bu nedenle gönderiminiz yargılamaların dışında tutulur, ancak yine de onu affedeceğim;)
CommonGuy

3

Java, Süper Üretici

Benim dünyama geç kaldı, bu yüzden gönderimimi detaylandırmak için yeterli zamanım yok. Daha sonra nasıl çalıştığını açıklamayı planlayacağım.

Botun performansı zaman zaman kazandığı başlangıç ​​sırasına bağlı görünüyor ...

Kazanan turları arttırmaya yardımcı olacak bazı fikirlerim vardı ... ama zamanın azalıyor: P

package moogiesoft;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;



public class SuperProducer implements Serializable
{
    private static final int MAX_POSSIBLE_LOWBORNS_IN_TOWN = 50;
    /**
     * 
     */
    private static final long serialVersionUID = 8652887937499233654L;
    public final String FILE = this.getClass().getSimpleName()+".txt";
    int round;
    int playerID;
    int thisTownID;

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

    Map<Integer, Conquest> townOwnerShipMap = new HashMap<Integer, Conquest>();

    Town thisTown;
    private int targetOpponent = -1; // the id of the opponent that out towns will endevour to direct their attacks 
    private int maxOpponentTownSize; // the number of knights of the opponent town with the most knights
    private int avgOpponentTownSize; // the average number of knights in an opponent town
    private int midAvgMaxOpponentTownSize; // value 1/2 between average and max knights in an opponent town

    public static void main(String[] args){
        if (args.length == 0){
            new SuperProducer().sendStartingKnights();
        }
        else
        {
            new SuperProducer().letsDoIt(args[0].split(";"));
        }
    }

    private void sendStartingKnights()
    {
        // delete any stale state information
        File file = new File(FILE);
        file.delete();

        System.out.println("100 100 0");
    }

    private void letsDoIt(String[] args)
    {
        round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);
        thisTownID = Integer.parseInt(args[2]);
        towns = new ArrayList<>();
        myTowns = new ArrayList<>();
        otherTowns = new ArrayList<>();

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

        // load in stored state information
        File file = new File(FILE);
        if (file.exists())
        {
            try
            {
                ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
                townOwnerShipMap = (Map<Integer, Conquest>) ois.readObject();
                targetOpponent  = ois.readInt();
                ois.close();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }

        for (Town town : towns)
        {

            // update town conquest map
            Conquest conquest = townOwnerShipMap.remove(town.getId());
            if (conquest==null)
            {
                conquest = new Conquest(town.ownerId, -1);
                townOwnerShipMap.put(town.getId(),conquest);
            }
            else if (town.getOwner()!=conquest.getOwner())
            {
                conquest.setOwner(town.ownerId);
                conquest.setConquestRound(round-1);
            }
            town.setDefenceBonus(round-conquest.getConquestRound()>2);

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

        String response = "W";

        // this town has some knights to potentially command...
        if (thisTown.getKnightCount()>0)
        {
            // first round... consolidate into 1 super town
            if (round==1)
            {
                int thisTownIndex=myTowns.indexOf(thisTown);
                switch (thisTownIndex)
                {
                    case 1:
                    case 0:
                        // if we are the first town then move all knights into second town
                        if (myTowns.size()>1 && thisTown.getKnightCount()<200)
                        {
                            response = "S " + myTowns.get(thisTownIndex+1).getId() + " " + thisTown.getKnightCount();
                            break;
                        }
                    default:
                        // the third town does nothing!
                }
            }
            else 
            {
                // second round... go find some good starting towns to conquer
                if (round==2)
                {
                    // this town is a town able to attack
                    if (thisTown.getKnightCount()>100)
                    {
                        // If by some miracle we still own the town with no knights then re-inforce it.
                        Town superTown = myTowns.stream().filter(a->a.getKnightCount()==200).findFirst().get();
                        if (superTown!=null && superTown.getId()!=thisTown.getId())
                        {
                            response = "S " + superTown.getId() + " " + thisTown.getKnightCount();
                        }
                        else
                        {
                            // find the next most productive Town...
                            Town townToAttack = otherTowns.get(0);
                            for (Town town : otherTowns)
                            {
                                if (town.getLowbornCount()>townToAttack.getLowbornCount())
                                {
                                    townToAttack=town;
                                    if (townToAttack.getOwner()!=playerID)
                                    {
                                        targetOpponent=townToAttack.getOwner();
                                    }
                                }
                            }

                            // the town to attack is most likely the own we lost due to having no knights to begin with...
                            response = "A " + townToAttack.getId() + " " + thisTown.getKnightCount();
                        }
                    }
                    // else this is a conquered town so lets not do anything!
                }
                else if (round>97)
                {
                    int attackForce = thisTown.getFreeKnights()/4;
                    if (thisTown.getFreeKnights()>attackForce && attackForce>0)
                    {

                        boolean goFlag=false;
                        Town townToAttack = null;
                        for (Town town : towns)
                        {
                            // 
                            if (town==thisTown) goFlag=true;
                            else if (goFlag && town.getOwner()!=thisTown.getOwner())
                            {
                                if (town.getLowbornCount()==0)
                                {
                                    townToAttack=town;
                                    break;
                                }
                            }
                        }

                        if (townToAttack==null)
                        {
                            for (Town town : otherTowns)
                            {
                                if (town.getLowbornCount()==0)
                                {
                                    townToAttack=town;
                                    break;
                                }
                            }
                        }

                        if (round > 98 && townToAttack==null)
                        {
                            for (Town town : otherTowns)
                            {
                                attackForce = thisTown.getKnightCount()-town.getKnightCount()-town.getMinimumKnights()-1-thisTown.getMinimumKnights()-1;
                                if (attackForce>0)
                                {
                                    townToAttack=town;
                                    break;
                                }
                            }
                        }

                        if (townToAttack!=null)
                        {
                            response = "A " + townToAttack.getId() + " " + attackForce;
                        }
                        else
                        {
                            int thisTownIndex = myTowns.indexOf(thisTown);
                            int supportSize = Math.min(thisTown.getKnightCount()/4, thisTown.getFreeKnights());

                            if (supportSize>thisTown.getMinimumKnights() && thisTownIndex<myTowns.size()-1)
                            {
                                Town townToSupport = myTowns.get(thisTownIndex+1);
                                response = "S " + townToSupport.getId() + " " + (thisTown.getKnightCount()-thisTown.getKnightCount()/4);
                            }
                        }
                    }

                }

                // we are on non-beginning non-ending round...
                else
                {
                    // calculate statistics
                    IntSummaryStatistics statistics = otherTowns.stream().collect(Collectors.summarizingInt(Town::getKnightCount));
                    maxOpponentTownSize = statistics.getMax();
                    avgOpponentTownSize = (int) statistics.getAverage();
                    midAvgMaxOpponentTownSize = (maxOpponentTownSize+avgOpponentTownSize)/2;

                    if ((round-1)%3==1)
                    {
                        // find the next strongest town of our target Opponent that produces knights...
                        Town townToAttack = null;
                        for (Town town : otherTowns)
                        {
                            if (town.getLowbornCount() > 0 && town.getOwner() == targetOpponent && (townToAttack == null || town.getKnightCount()>townToAttack.getKnightCount()))
                            {
                                townToAttack=town;
                            }
                        } 


                        // target opponent cannot grow so choose another opponent...
                        // favour the weakest opponent that has has some towns that produces towns..
                        // otherwise favour the weakest opponent
                        if (townToAttack==null)
                        {
                            townToAttack=chooseNewOpponentToAttack();
                        }
                        targetOpponent=townToAttack.getOwner();

                        int minKnightsToLeaveAtThisTown = calculateDesiredKnightsAtTown(thisTown);
                        int minKnightsToLeftAtAttackedTownAfterBattle = calculateDesiredKnightsAtTown(townToAttack);

                        double defenceBonus = townToAttack.hasDefenceBonus()?1.2:1;
                        double defenderAttackStrength = townToAttack.getKnightCount() * defenceBonus;
                        int knightsNeededToWinAndEnsureNotAttackedNextRound =  minKnightsToLeftAtAttackedTownAfterBattle + (int) (defenderAttackStrength);
                        knightsNeededToWinAndEnsureNotAttackedNextRound = knightsNeededToWinAndEnsureNotAttackedNextRound + ((knightsNeededToWinAndEnsureNotAttackedNextRound-defenderAttackStrength - townToAttack.getMinimumKnights() < 0) ?townToAttack.getMinimumKnights():0);
                        int knightsLeftAtSortieingTownAfterAttacking = thisTown.getKnightCount()-knightsNeededToWinAndEnsureNotAttackedNextRound;

                        // if the sortieing town is sufficiently safe from another attack after it attempts to attack the other town will it try to attack  
                        if (knightsLeftAtSortieingTownAfterAttacking > thisTown.getMinimumKnights()*2 &&
                            knightsLeftAtSortieingTownAfterAttacking>minKnightsToLeaveAtThisTown &&
                            thisTown.getFreeKnights()>knightsNeededToWinAndEnsureNotAttackedNextRound)
                        {
                            response = "A " + townToAttack.getId() + " " + knightsNeededToWinAndEnsureNotAttackedNextRound;
                        }
                        // not safe... so lets support our other towns
                        else
                        {
                            int surplusKnights = thisTown.getKnightCount()-minKnightsToLeaveAtThisTown;

                            // this town has surplusKnights
                            if (surplusKnights>0)
                            {
                                int knightsAvailable = Math.min(surplusKnights, thisTown.getFreeKnights());

                                // find our weakest and strongest towns
                                Town myWeakestTown=null;
                                Town myStrongestTown=null;
                                for (Town town : myTowns)
                                {
                                    if (!(town.getKnightCount()==0 && round<50) && (myWeakestTown == null || town.getKnightCount()<myWeakestTown.getKnightCount()))
                                    {
                                        myWeakestTown=town;
                                    }
                                    if (!(town.getKnightCount()==0 && round<50) && ( myStrongestTown == null || town.getKnightCount()>myStrongestTown.getKnightCount()))
                                    {
                                        myStrongestTown=town;
                                    }
                                }

                                // see if my Weakest Town needs support
                                Town townToSupport = null;
                                int knightsToSend=0;
                                if (thisTown!=myWeakestTown)
                                {
                                    int desiredKnightsAtTown = calculateDesiredKnightsAtTown(myWeakestTown);

                                    if (myWeakestTown.getKnightCount()<desiredKnightsAtTown)
                                    {
                                        int deltaDesiredKnights = desiredKnightsAtTown-myWeakestTown.getKnightCount();
                                        knightsToSend = Math.min(knightsAvailable, deltaDesiredKnights);
                                        townToSupport=myWeakestTown;
                                    }
                                }

                                // no towns needed support so we will attempt to support the strongest town
                                if (townToSupport == null)
                                {
                                    if (thisTown!=myStrongestTown)
                                    {
                                        int desiredKnightsAtTown = calculateDesiredKnightsAtTown(myStrongestTown);
                                        if (myStrongestTown.getKnightCount()<desiredKnightsAtTown)
                                        {
                                            int deltaDesiredKnights = desiredKnightsAtTown-myStrongestTown.getKnightCount();
                                            knightsToSend = Math.min(knightsAvailable, deltaDesiredKnights);

                                            knightsToSend = knightsAvailable;
                                            townToSupport=myStrongestTown;
                                        }
                                    }
                                }

                                // support the chosen town if possible
                                if (townToSupport != null)
                                {
                                    response = "S " + townToSupport.getId() + " " + knightsToSend;
                                }
                            }
                        }
                    }
                }
            }
        }

        // save state information
        try
        {
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
            oos.writeObject(townOwnerShipMap);
            oos.writeInt(targetOpponent);
            oos.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        System.out.println(response);
    }

    // returns a town of the opponent that is deemed to be the most worthy
    private final Town chooseNewOpponentToAttack()
    {
        Town townToAttack=null;

        // calculate opponent sizes
        HashMap<Integer,Opponent> opponentMap = new HashMap<Integer, Opponent>();
        for (Town town : otherTowns)
        {
            Opponent opponent = opponentMap.get(town.getOwner());
            if (opponent == null)
            {
                opponent = new Opponent(town.getOwner());
                opponentMap.put(town.getOwner(), opponent);
            }
            opponent.addTown(town);
        }


        // create sorted list of opponents based on strength. 
        List<Integer> opponentsByStrength = new ArrayList<Integer>(opponentMap.keySet());
        opponentsByStrength.sort(new Comparator<Integer>()
        {
            public int compare(Integer o1, Integer o2)
            {
                Opponent left = opponentMap.get(o1);
                Opponent right = opponentMap.get(o2);

                return left.getTotalKnights()-right.getTotalKnights();
            }
        });

        // attempt to choose the weakest opponent's weakest town that has some ability to generate knights...
        out:
        for (Integer opponent : opponentsByStrength)
        {
            for (Town town : opponentMap.get(opponent).getTowns())
            {
                if (town.getOwner() !=-1 && town.getLowbornCount() > 0 && (townToAttack == null || town.getKnightCount()<townToAttack.getKnightCount()))
                {
                    townToAttack=town;
                    break out;
                }
            } 
        }

        // no opponents left with knights producing towns... just go for the weakest town.
        if (townToAttack == null)
        {
            for (Town town : otherTowns)
            {
                if (townToAttack == null || town.getKnightCount()<townToAttack.getKnightCount())
                {
                    townToAttack=town;
                }
            } 
        }

        return townToAttack;
    }

    // returns the number of knights that should make this town safe from attack
    final private int calculateDesiredKnightsAtTown(Town town)
    {
        int minimumKnightsWeWantInATown = avgOpponentTownSize;
        return minimumKnightsWeWantInATown + town.getLowbornCount()==0?0:(minimumKnightsWeWantInATown +(int) (((double) town.getLowbornCount() / MAX_POSSIBLE_LOWBORNS_IN_TOWN) * (midAvgMaxOpponentTownSize-minimumKnightsWeWantInATown)));
    }

    /** represents a conquest of a Town by a player */
    class Conquest implements Serializable
    {
        private static final long serialVersionUID = -1120109012356785962L;
        private int owner;
        private int conquestRound;
        public int getOwner()
        {
            return owner;
        }
        public void setOwner(int owner)
        {
            this.owner = owner;
        }
        public int getConquestRound()
        {
            return conquestRound;
        }
        public void setConquestRound(int conquestRound)
        {
            this.conquestRound = conquestRound;
        }
        public Conquest(int owner, int conquestRound)
        {
            super();
            this.owner = owner;
            this.conquestRound = conquestRound;
        }

    }

    /** represents an opponent in the simulation */
     private class Opponent implements Serializable
     {
         private int ownerId;
         private int totalKnights;
         private List<Town> towns = new ArrayList<SuperProducer.Town>();

         public void addTown(Town town)
         {
             totalKnights+=town.getKnightCount();
             towns.add(town);
         }

        public int getOwnerId()
        {
            return ownerId;
        }

        public int getTotalKnights()
        {
            return totalKnights;
        }

        public List<Town> getTowns()
        {
            return towns;
        }

        public Opponent(int ownerId)
        {
            super();
            this.ownerId = ownerId;
        }
     }

     /** represents a Town in the simulation */
     private class Town implements Serializable
    {
        private static final long serialVersionUID = 5011668142883502165L;
        private final int ownerId;
        private final int id;
        private final int knights;
        private final int lowborns;
        private boolean defenceFlag =true;

        public Town(String string){
            String[] args = string.split("_");
            ownerId = Integer.parseInt(args[0]);
            id = Integer.parseInt(args[1]);
            knights = Integer.parseInt(args[2]);
            lowborns = Integer.parseInt(args[3]);
        }

        public boolean hasDefenceBonus()
        {
            return defenceFlag;
        }

        public void setDefenceBonus(boolean defenceFlag)
        {
            this.defenceFlag = defenceFlag;
        }

        public int getId() {
            return id;
        }

        public int getOwner() {
            return ownerId;
        }

        public int getKnightCount() {
            return knights;
        }

        public int getLowbornCount() {
            return lowborns;
        }

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

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

        private int getFreeKnights() {
            return knights - lowborns / 2 - 1;
        }

        private int getMinimumKnights() {
            return lowborns / 2 + 1;
        }
    }
 }

Derleme: javac SuperProducer.java

Çalıştır: java moogiesoft.SuperProducer


2

C ++ 11, saldırı3

kodun kendisi pek güzel olmadı, ancak şimdi hedeflemek için başka bir yol kullanıyorum, muhtemelen daha sonra koda yorumlar ekleyeceğim.

Her ne kadar frankenstein ve kurtarıcı vs hala zor olsa da, sürekli olarak kazanamıyorum rağmen koşuyorum botlar ile tamam gibi görünüyor.

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <cmath>
#include <ratio>
#include <fstream>
#include <algorithm>

using namespace std;


class Town {
public:
    Town(int owner, int townId, int knights, int population, int roundToDefBonus);

    int getOwner();

    int getId();

    int getKnights();

    int getPopulation();

    int getFreeKnights();

    int neededConquer();

    int needRevolt();

    int getRoundToDef();

    bool operator<(const Town &other) const {
        return townId < other.townId;
    }

private:
    int owner;
    int townId;
    int knights;
    int population;
    int roundToDefBonus;
    double defBonus;
};

Town::Town(int inOwner, int inTownId, int inKnights, int inPopulation, int inRoundToDefBonus) {
    owner = inOwner;
    townId = inTownId;
    knights = inKnights;
    population = inPopulation;
    roundToDefBonus = inRoundToDefBonus;
    if (roundToDefBonus > 0) {
        defBonus = 1;
    }
    else {
        defBonus = 1.2;
    }
}

int Town::getOwner() {
    return owner;
}

int Town::getId() {
    return townId;
}

int Town::getKnights() {
    return knights;
}

int Town::getPopulation() {
    return population;
}

int Town::getFreeKnights() {
    return knights - population / 2;
}

int Town::neededConquer() {
    return max(static_cast<int>(ceil(knights * defBonus + population / 2)), 1);
}

int Town::needRevolt() {
    return knights * defBonus - population / 2;
}

int Town::getRoundToDef() {
    return roundToDefBonus;
}

#define maxRounds 100
#define newKnights 3

const int attackround = newKnights - 1;
const int getEmptyTowns = maxRounds - 5;

int gameRound;
int myId;
int thisTownId;
Town *thisTown;

vector<Town> myTowns;
vector<Town> enemyTowns;

vector<Town> lastTime;

string turn();

Town *bestGainTarget(int knights);

Town *bestSafe(int knights);

Town *biggestTarget(int knights);

Town *biggestSafe(int knights);

Town *weakTarget(int knights);


string out(string, int, int);

string attack(Town *);

string safe(Town *);

bool sortTowns(const Town &t1, const Town &t2);

vector<string> stringSplit(string input, string delimeter);

int getBiggestEnemyId();

int main(int argc, char *argv[]) {
    if (argc < 2) {
        cout << "100 100 100";
        ofstream myFile;
        myFile.open("attackOn3.txt");
        myFile << "0\n";
        myFile.close();
    }
    else {
        if (argc == 2) {

            string input = argv[1];
            vector<string> params = stringSplit(input, ";");

            gameRound = atoi(params.at(0).c_str());
            myId = atoi((params.at(1)).c_str());
            thisTownId = atoi(params.at(2).c_str());

            ifstream myfile("attackOn3.txt");
            if (myfile.is_open()) {
                string line;

                getline(myfile, line);
                bool newRound = false;
                if (atoi(line.c_str()) > gameRound) {
                    newRound = true;
                }

                vector<string> oldVals;
                if (!newRound) {
                    while (getline(myfile, line)) {
                        oldVals = stringSplit(line, "_");

                        int playerId = atoi(oldVals.at(0).c_str());
                        int townId = atoi(oldVals.at(1).c_str());
                        int knights = atoi(oldVals.at(2).c_str());
                        int population = atoi(oldVals.at(3).c_str());
                        int roundToDefBonus = atoi(oldVals.at(4).c_str());

                        lastTime.push_back(Town(playerId, townId, knights, population, roundToDefBonus));
                        oldVals.clear();
                    }
                }
                else {
                    while (getline(myfile, line)) {
                        oldVals = stringSplit(line, "_");

                        int playerId = atoi(oldVals.at(0).c_str());
                        int townId = atoi(oldVals.at(1).c_str());
                        int knights = atoi(oldVals.at(2).c_str());
                        int population = atoi(oldVals.at(3).c_str());
                        int roundToDefBonus = atoi(oldVals.at(4).c_str());
                        if (roundToDefBonus) {   //if round def bonus > 0, decrement because new round
                            roundToDefBonus--;
                        }

                        lastTime.push_back(Town(playerId, townId, knights, population, roundToDefBonus));
                        oldVals.clear();
                    }

                }
                std::sort(lastTime.begin(), lastTime.end());
            }

            if (lastTime.size() > 0) {
                vector<string> values;
                for (int i = 3; i < params.size(); i++) {

                    values = stringSplit(params.at(i), "_");

                    int playerId = atoi(values.at(0).c_str());
                    int townId = atoi(values.at(1).c_str());
                    int knights = atoi(values.at(2).c_str());
                    int population = atoi(values.at(3).c_str());

                    int roundsToDef = lastTime.at(townId).getRoundToDef();
                    if (playerId != lastTime.at(townId).getOwner()) {
                        roundsToDef = 2;
                    }
                    if (playerId == myId) {
                        if (thisTownId != townId)
                            myTowns.push_back(Town(playerId, townId, knights, population, roundsToDef));
                        else {
                            thisTown = new Town(playerId, townId, knights, population, roundsToDef);
                        }
                    }
                    else {
                        enemyTowns.push_back(Town(playerId, townId, knights, population, roundsToDef));
                    }
                    values.clear();
                }
            }
            else {
                vector<string> values;
                for (int i = 3; i < params.size(); i++) {

                    values = stringSplit(params.at(i), "_");

                    int playerId = atoi(values.at(0).c_str());
                    int townId = atoi(values.at(1).c_str());
                    int knights = atoi(values.at(2).c_str());
                    int population = atoi(values.at(3).c_str());

                    if (playerId == myId) {
                        if (thisTownId != townId)
                            myTowns.push_back(Town(playerId, townId, knights, population, 0));
                        else {
                            thisTown = new Town(playerId, townId, knights, population, 0);
                        }
                    }
                    else {
                        enemyTowns.push_back(Town(playerId, townId, knights, population, 0));
                    }
                    values.clear();
                }
            }

            string tmp = turn();
            cout << tmp;

            ofstream writeFile("attackOn3.txt");
            if (writeFile.is_open()) {
                writeFile << gameRound << "\n";

                writeFile << thisTown->getOwner() << "_" << thisTown->getId() << "_" << thisTown->getKnights() << "_" << thisTown->getPopulation() << "_" << thisTown->getRoundToDef() << "\n";

                for (vector<Town>::size_type i = 0; i != myTowns.size(); i++) {
                    writeFile << myTowns[i].getOwner() << "_" << myTowns[i].getId() << "_" << myTowns[i].getKnights() << "_" << myTowns[i].getPopulation() << "_" << myTowns[i].getRoundToDef() << "\n";
                }
                for (vector<Town>::size_type i = 0; i != enemyTowns.size(); i++) {
                    writeFile << enemyTowns[i].getOwner() << "_" << enemyTowns[i].getId() << "_" << enemyTowns[i].getKnights() << "_" << enemyTowns[i].getPopulation() << "_" << enemyTowns[i].getRoundToDef() << "\n";
                }
            }
        }
        else {
            cout << "error, wrong parameter";
        }
    }

    delete thisTown;

    return 0;
}


string turn() {
    Town *safeTarget;
    Town *attackTarget;
    if (thisTown->getFreeKnights() < 0) {    //evacuate
        safeTarget = biggestSafe(thisTown->getKnights());
        attackTarget = biggestTarget(thisTown->getKnights());

        if (safeTarget != nullptr && attackTarget != nullptr) {
            if (safeTarget->getPopulation() > attackTarget->getPopulation()) {
                return out("S", safeTarget->getId(), thisTown->getKnights());
            }
            else {
                return out("A", attackTarget->getId(), thisTown->getKnights());
            }
        }
        if (safeTarget) {
            return out("S", safeTarget->getId(), thisTown->getKnights());
        }
        if (attackTarget) {
            return out("A", attackTarget->getId(), thisTown->getKnights());
        }
        Town *target = &myTowns.at(0);
        for (vector<Town>::size_type i = 1; i != myTowns.size(); i++) {
            if (target->getPopulation() < myTowns[i].getPopulation())
                target = &myTowns[i];
        }
        return out("S", target->getId(), thisTown->getKnights());

    }

    safeTarget = biggestSafe(thisTown->getFreeKnights());
    if (gameRound % newKnights == attackround) {      //knights only get produced every 3 town, i want to conquer the best towns just before that so i get more reinforments and dont need to fight quite that much
        attackTarget = bestGainTarget(thisTown->getFreeKnights());
    }
    else {       //but if a town is easy to aquiere i still want it, e. g. because of revolution or someone weakened it so that it will revolte
        attackTarget = weakTarget(thisTown->getFreeKnights());
    }

    if (safeTarget != nullptr && attackTarget != nullptr) {
        if (safeTarget->getPopulation() > attackTarget->getPopulation()) {
            return safe(safeTarget);
        }
        else {
            return attack(attackTarget);
        }
    }
    if (safeTarget) {
        return safe(safeTarget);
    }
    if (attackTarget) {
        return attack(attackTarget);
    }

    if (gameRound > getEmptyTowns) {     //empty towns dont matter early on but still count to win score
        for (vector<Town>::size_type i = 0; i != enemyTowns.size(); i++) {
            if (enemyTowns[i].getPopulation() < 2) {
                if (enemyTowns[i].neededConquer() < thisTown->getFreeKnights()) {
                    return attack(&enemyTowns[i]);
                }
            }
        }
    }

    int biggestEnemy = getBiggestEnemyId();
    //if last round attack possible biggest other guy
    if (gameRound == maxRounds) {
        int targetKnights = -1;
        Town *target;
        for (vector<Town>::size_type i = 0; i != enemyTowns.size(); i++) {
            if (enemyTowns[i].getOwner() == biggestEnemy) {
                if (enemyTowns[i].neededConquer() < thisTown->getFreeKnights()) {
                    if (enemyTowns[i].getFreeKnights() > targetKnights) {
                        target = &enemyTowns[i];
                        targetKnights = target->getFreeKnights();
                    }
                }
            }
        }
        if (targetKnights > -1) {
            attack(target);
        }
    }
    //revolt from biggest other guy
    if (gameRound > 10) {        //most bots need a bit of time
        int targetPop = 0;
        Town *target;
        for (vector<Town>::size_type i = 0; i != enemyTowns.size(); i++) {
            if (enemyTowns[i].getOwner() == biggestEnemy) {
                if (enemyTowns[i].needRevolt() < thisTown->getFreeKnights()) {
                    if (enemyTowns[i].getPopulation() > targetPop) {
                        target = &enemyTowns[i];
                        targetPop = target->getPopulation();
                    }
                }
            }
        }
        if (targetPop != 0) {
            return attack(target);
        }
    }

    return "W";
}

Town *bestGainTarget(int knights) {
    Town *target = nullptr;
    int gain = -thisTown->getFreeKnights();
    int now = -thisTown->getFreeKnights();
    //int loses = thisTown->getFreeKnights();
    for (vector<Town>::size_type i = 0; i != enemyTowns.size(); i++) {
        int conquer = enemyTowns[i].neededConquer();
        if (conquer < knights && enemyTowns[i].getPopulation() > 0) {
            if (enemyTowns[i].getPopulation() * 2 *1.2 - conquer > gain) {
                if(enemyTowns[i].getPopulation() - conquer > now){
                    target = &enemyTowns[i];
                    now = target->getPopulation() - conquer;
                    gain = target->getPopulation() * 2 - conquer;
                }
            }
        }
    }
    return target;
}

Town *weakTarget(int knights) {     //maybe change it that it prefers targets with 0/40 over 24/50
    Town *target = nullptr;
    double population = 1;
    for (vector<Town>::size_type i = 0; i != enemyTowns.size(); i++) {
        if (enemyTowns[i].neededConquer() < knights) {
            if (enemyTowns[i].getKnights() < enemyTowns[i].getPopulation() / 2) {
                if (enemyTowns[i].getPopulation() > population) {
                    target = &enemyTowns[i];
                    population = target->getPopulation();
                }
            }
        }
    }
    return target;
}

Town *biggestTarget(int knights) {
    Town *target = nullptr;
    int population = -1;
    for (vector<Town>::size_type i = 0; i != enemyTowns.size(); i++) {
        if (enemyTowns[i].neededConquer() < knights) {
            if (enemyTowns[i].getPopulation() > population) {
                target = &enemyTowns[i];
                population = target->getPopulation();
            }
        }
    }
    return target;
}

Town *biggestSafe(int knights) {
    Town *target = nullptr;
    int population = -1;
    for (vector<Town>::size_type i = 0; i != myTowns.size(); i++) {
        if (myTowns[i].getFreeKnights() < 0 && myTowns[i].getFreeKnights() + knights >= 0) {
            if (myTowns[i].getPopulation() > population) {
                target = &myTowns[i];
                population = target->getPopulation();
            }
        }
    }
    return target;
}

int getBiggestEnemyId() {
    int players[enemyTowns.size() / 3 + 1];
    for (vector<Town>::size_type i = 0; i != enemyTowns.size(); i++) {
        if (enemyTowns[i].getOwner() != -1) {
            players[enemyTowns[i].getOwner()] = enemyTowns[i].getPopulation();
        }
    }
    int max = 0;
    for (int i = 1; i < enemyTowns.size() / 3 + 1; i++) {
        if (players[i] > players[max]) {
            max = i;
        }
    }
}

string attack(Town *target) {
    int knights;
    if (thisTown->getPopulation() > target->getPopulation()) {
        knights = target->neededConquer();
    }
    else {
        knights = thisTown->getFreeKnights();
    }
    return out("A", target->getId(), knights);
}

string safe(Town *target) {
    int knights;
    if (thisTown->getPopulation() > target->getPopulation()) {
        knights = target->getFreeKnights() * -1;
    }
    else {
        knights = thisTown->getFreeKnights();
    }
    return out("S", target->getId(), knights);
}

string out(string order, int targedId, int knights) {
    stringstream tmp;
    tmp << order << " " << targedId << " " << knights;
    return tmp.str();
}

vector<string> stringSplit(string input, string delimeter) {
    stringstream tmp(input);
    vector<string> splitted;
    string pushThis;
    while (getline(tmp, pushThis, delimeter.at(0))) {
        splitted.push_back(pushThis);
    }
    return splitted;
}

derle: g++ -std=c++11 attackOn3.cpp -o attackOn3.exe
ve çalıştırattackOn3.exe

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.