เกมแห่งเมือง


34

บทนำ

เกมดังกล่าวเกิดขึ้นในโลกใบเล็กที่มีเมืองต่าง ๆ ผู้ปกครองของเมืองต่างเกลียดชังซึ่งกันและกันและต้องการที่จะปกครองโลก ผู้คนถูกแบ่งออกเป็นสองกลุ่มคือนักรบและผู้ไร้บุตร อย่างไรก็ตาม lowborn สามารถเลี้ยงดูนักรบได้ คุณเป็นผู้ปกครองของสามเมืองเหล่านี้

เพลย์

เมื่อเกมเริ่มต้นคุณครองสามเมือง ในแต่ละเมืองมี 100 คน คุณต้องแบ่งพวกมันออกเป็นอัศวินและลูกน้อย

จากนั้นเกมจริงจะเริ่มขึ้นซึ่งเป็นแบบเลี้ยว เลี้ยวลักษณะเช่นนี้"Produce" knights=> execute command of first town=> execute command of next town(ซ้ำสำหรับทุกเมือง) try a rebellion=>

  • เปิดแต่ละโปรแกรมของคุณจะถูกเรียกสำหรับแต่ละเมืองที่เป็นของคุณ คุณสามารถโจมตีเมือง , สนับสนุนเมืองหรือเพียงแค่รอ การกระทำเหล่านี้จะถูกดำเนินการตามลำดับไม่พร้อมกัน
  • ทุกเทิร์นที่สามคุณจะได้รับอัศวินหนึ่งตัวต่อผู้ถือลูกน้อย 2 คน (23 ลูกหัวปี => 11 อัศวิน) ปริมาณของ lowborn ยังคงเหมือนเดิม
  • อัศวินในเมืองมีโบนัสการป้องกัน 1.2 หากคุณถูกโจมตีอัศวินของคุณจะถูกคูณด้วยหมายเลขนี้ (เช่นคุณมี78 knightsคุณจะมี93 knightsระหว่างการโจมตี) หลังจากการโจมตีอัศวินพิเศษจะถูกลบออก (ถ้า82 knightsคุณยังมีชีวิตรอดคุณจะยังมีอยู่78 knights)
  • ในการโจมตีอัศวินแต่ละคนจะฆ่าศัตรูก่อนที่เขาจะตาย ตัวอย่างเช่น: 30 knightsการโจมตี100 knights(โดยไม่มีโบนัสการป้องกัน) => 70 อัศวินเอาชีวิตรอด
  • คุณสามารถจับภาพเมืองโดยการฆ่าอัศวินทั้งหมดที่อยู่ภายในนั้น บรรดา lowborn เป็นของคุณและอัศวินผู้รอดชีวิตของคุณจะถูกส่งไปประจำการในเมือง เมื่อวันที่รอบต่อไปคุณสามารถปกครองเมืองนี้นอกจากทุกเมืองอื่น ๆ ของคุณ
  • หลังจากถูกยึดครองเมืองมันจะไม่ได้รับโบนัสการป้องกันเป็น 2 รอบเต็ม (เพราะประตูถูกทำลาย) ในเทิร์นที่สามประตูจะได้รับการซ่อมแซม
  • เพื่อป้องกันไม่ให้ lowborns กบฏคุณต้องมีอย่างน้อยครึ่งอัศวินมากเท่าที่มี lowborns (23 lowborns ในเมืองต้องมีอย่างน้อย 12 อัศวินในเมืองเดียวกัน) มิเช่นนั้นลูกน้อยจะฆ่าอัศวินทั้งหมดและเมืองจะกลายเป็น "เป็นกลาง" (โดยไม่มีหัวหน้าที่ระบุโดยผู้เล่นหมายเลขหนึ่ง-1)
  • เมืองที่เป็นกลางจะ "สร้าง" อัศวิน แต่จะไม่โจมตีหรือสนับสนุนเมืองอื่น

วากยสัมพันธ์

คอนโทรลเลอร์ให้ข้อมูลอินพุตโดยใช้อาร์กิวเมนต์คำสั่งโปรแกรมของคุณต้องเอาต์พุตผ่าน stdout

เอาท์พุท (การเตรียมการ)
ก่อนที่เกมจะเริ่มต้น ซึ่งหมายความว่าคุณต้องแจกจ่ายคน 100 คน (สำหรับแต่ละเมือง) ให้เป็นอัศวินและผู้ไร้บุตร คุณจำเป็นต้องส่งออกเช่นKnightCount KnightCount KnightCount95 80 95

ป้อนข้อมูลในรอบแรกนี้จะเป็นสิ่งที่ชอบ
Round;YourPlayerId;YourTownId;PlayerId_TownId_knights_lowborns;PlayerId_TownId_knights_lowborns;...
1;2;2;0_0_100_0;1_1_50_50;2_2_80_20ที่นี่คุณจะเห็นว่ามันเป็นรอบแรกคุณเป็นผู้เล่น 2 คนในเมือง 2 คุณมี 80 อัศวินและ 20 คนเกิดต่ำ

ต่อมาในเกมมันอาจเป็นอะไร20;2;1;0_0_100_0;2_1_30_50;2_2_40_20ก็ได้ คุณยังคงเป็นผู้เล่น 2 (สิ่งนี้ไม่มีวันเปลี่ยนแปลง) แต่คุณยึดครองเมือง 1 (ซึ่งคุณกำลังควบคุมอยู่ในตอนนี้)

เอาท์พุท
A TownId NumberOfKnightsหรือS TownId NumberOfKnightsหรือW(รอ)
ตัวอย่าง: A 2 100(โจมตีเมือง 2 ด้วย 100 อัศวิน) หรือS 3 2(สนับสนุนเมือง 3 ที่มี 2 อัศวิน)

กฎระเบียบ

  • ไม่ควรเขียนบอทเพื่อเอาชนะหรือสนับสนุนบอทอื่น ๆ โดยเฉพาะ
  • อนุญาตให้เขียนไฟล์ได้ โปรดเขียนถึง " yoursubmissionname .txt" โฟลเดอร์จะถูกลบออกก่อนที่เกมจะเริ่ม ทรัพยากรภายนอกอื่น ๆ ไม่ได้รับอนุญาต
  • ข้อมูลที่คุณส่งมี 1 วินาทีในการตอบกลับ (ต่อเมือง)
  • ให้คำสั่งเพื่อรวบรวมและเรียกใช้การส่งของคุณ

การชนะ

ผู้ชนะคือผู้ที่มีเมืองมากที่สุดหลังจากผ่าน 100 รอบ หากผู้เล่นยึดครองทุกเมืองเกมจะหยุดและเขาชนะ หากผู้เล่นหลายคนมีจำนวนเมืองเท่ากันจำนวนอัศวินจะนับ

ตัวควบคุม

คุณสามารถค้นหาคอนโทรลเลอร์บน GitHub ได้ นอกจากนี้ยังมี 2 บอตตัวอย่างที่เขียนใน Java เปิดใน Eclipse วางบอตที่คอมไพล์แล้วในโฟลเดอร์ root และเพิ่มคลาสลงในโปรแกรมควบคุม (เช่นเดียวกับ samplebots)

ผล

สำหรับผลลัพธ์สุดท้ายฉันวิ่ง 10 เกม นี่คือค่าเฉลี่ย:

    ผู้เล่น Towns 
 1. อิสรภาพ 37.5
 2. Sehtimianer 8.2
 3. SuperProducer 5.4
 4. ไม้หมอน 1.4
 5. Frankenstein 1.2
 6. เนย 0.8 (อัศวินมากขึ้น)
 7. TheKing 0.8 (อัศวินน้อยลง)
 8. อพยพ 0.6
 9. เต่า 0.5 (อัศวินมากขึ้น)
10. AttackOn3 0.5 (อัศวินน้อยลง)
11. ประชาธิปไตย 0.3
12. คำนวณเงินเต็ม 0.2
13. นักปฏิวัติ 0.1

คุณสามารถอ่านเกมตัวอย่างได้ที่นี่: เกมตัวอย่างบน GitHub


ฉันคิดว่าเมื่อเมือง Aหนึ่งสนับสนุนอื่นBจำนวนอัศวินที่กำหนดจะถูกโอนย้ายจากAไปยังBหลังจากนั้นพวกเขาถูกควบคุมโดยเจ้าของBถูกต้องหรือไม่
Zgarb

@Zgarb ถูกต้อง :)
สามัญซื้อ

คุณจะจัดการแข่งขันและแสดงกระดานผู้นำหรือไม่?
ลอจิกอัศวิน

@CarpetPython แน่นอนฉันโพสต์ทันทีที่ฉันมีเวลา
CommonGuy

1
@ มนูฉันต้องบอกว่าฉันรัก KOTHs ของคุณ นี่คือคำถามประเภท Codegolf.SE ของฉัน คุณยอมรับการส่งจนกระทั่งเมื่อใด ฉันจะเริ่มคิดถึงอัลกอริทึมทันที นอกจากนี้ฉันคิดว่าคุณควรเพิ่มกฎอื่น - จำนวนสูงสุดของการส่งต่อผู้ใช้
Mark Gabriel

คำตอบ:


14

Python3, อิสรภาพ

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

เป้าหมายเดียวของบอทนี้คือการปลดปล่อยคนที่พบบ่อยที่สุดจากแอกที่กดขี่ของทรราช


1
ฉันต้องบอกว่าผู้กู้อิสรภาพคนนี้เป็นโรคระบาด: แข็งแกร่งรวดเร็วและเป็นอันตรายถึงตาย มันชนะการแข่งขันเกือบทุกครั้งที่ฉันวิ่งแม้แต่เต้นผู้เล่นที่เป็นกลาง ... Still Butter ยังเป็นผู้ท้าชิงที่แข็งแกร่ง
Thrax

คุณปลดปล่อยขนมปังจากทรราชแห่งบัตเตอร์ :( ฉันชอบเนย
TheNumberOne

แดง! ผู้กู้อิสรภาพนั้นยากที่จะเอาชนะ! ฉันมีรายการฉันจะส่งก่อนที่ฉันจะเพิ่มผู้ที่ไม่ใช่จาวาเข้ากับตัวควบคุม ... แต่ตอนนี้รายการนั้นล้มเหลวที่จะชนะเช่นเดียวกับผู้ที่ไม่ได้เป็นผู้ปลดปล่อย! ฉันมีความคิดอื่นที่จะลองทำไม่ได้หายไป ... : P + 1 สำหรับความท้าทาย!
Moogie

ทำได้ดี! คุณเป็นชัยชนะที่สมควรได้รับ!
Moogie

11

Python 2, The King

กษัตริย์ครองเมืองหมายเลขสูงสุดของอาณาจักรของเขาและเรียกร้องให้อัศวินส่วนเกินทั้งหมดถูกส่งมาให้เขาจากเมืองอื่นภายใต้การควบคุมของเขา เมื่อเขามีอัศวินมากพอเขาจะโจมตีเมืองศัตรู เขาไม่ได้เป็นราชาที่ฉลาดมากดังนั้นจึงไม่ได้ศึกษาประวัติศาสตร์หรือเข้าใจถึงผลที่จะตามมาจากการกระทำของเขา

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'

นี่คือยังไม่ได้ทดสอบกับตัวควบคุมหรือบอทอื่น ๆ


+1 สำหรับHe is not a very smart King, so has not studied history or understands the consequences of his actions.
Mark Gabriel

8

Javascript (Node), เอ็มไพร์

เริ่มแข็งแกร่งเพื่อทำให้เมืองต่าง ๆ หวาดกลัว เมืองพยายามที่จะทำงานร่วมกันเพื่อจับภาพผู้อื่น จัดลำดับความสำคัญของการจับภาพเมืองที่มีคนเกิดมาหลายคน

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

Run: โหนดเอ็มไพร์


1
บางครั้งการส่งของคุณส่งอัศวินมากกว่าที่มีอยู่จริงในเมืองและดังนั้นจึงสูญเสียในขณะนี้ ...
CommonGuy

@Manu อุ๊ปส์ฉันไม่เคยเจอ (หรืออย่างน้อยก็สังเกตเห็น) ว่าในการทดสอบของฉันอาจเป็นเพราะฉันไม่ได้มีโอกาสที่จะตั้งค่าบอทของคู่ต่อสู้ทั้งหมดสำหรับการทดสอบ ข้อผิดพลาดนั้นควรได้รับการแก้ไขทันที
Spencer

มันยังคงไม่ได้รับการแก้ไข ... บางครั้งคุณโจมตีด้วย 0 หรือด้วยจำนวนอัศวินติดลบ ... เป็นเพราะคุณคำนวณknights - lowborns/2แต่ถ้าคุณมี 30 อัศวินและ 90 คนเกิดมาน้อยนี่ไม่ได้ผล โปรดแก้ไขgetAttackers()ฟังก์ชั่นของคุณ
CommonGuy

นอกจากนี้บางครั้งคุณส่งการสนับสนุนด้วยจำนวนอัศวินติดลบ
CommonGuy

@ มานูเอลฉันรู้สึกโง่ในที่สุดฉันก็สังเกตเห็นDEBUGธงในคอนโทรลเลอร์ที่ทำให้มันกลืนข้อผิดพลาดแม้ว่าจะGAME_MESSAGESตั้งค่าสถานะเป็นจริง ฉันรู้สึกเหมือนฉันยังคงสามารถใช้งานบางอย่างเกี่ยวกับกลยุทธ์ของฉันโดยเฉพาะอย่างยิ่งกับอิสรภาพในขณะนี้ในที่เกิดเหตุ แต่มีการแก้ไขล่าสุดฉันไม่เห็นข้อผิดพลาดใด ๆ เมื่อฉันเรียกใช้การทดสอบของฉันกับDEBUGบน
สเปนเซอร์

8

Java, Frankenstein

ในขณะที่พยายามหาวิธีทำลาย Liberator ความผิดพลาดเล็ก ๆ น้อย ๆ ก็สอดเข้าไปในโค้ดของฉัน รหัสนั้นเริ่มทำลายการแข่งขัน หลังจากเพิ่มประชาธิปไตยและจัดเรียงผู้เล่นใหม่มันเริ่มล้มเหลว ศึกษารหัสฉันพยายามค้นหากลยุทธ์ ดังนั้นรหัสต่อไปนี้ถูกสร้างขึ้น มันมีแนวโน้มที่จะโจมตีและทำลายผู้เล่นที่ดีที่สุด หลังจากผู้เล่นที่ดีที่สุดถูกทำลายสิ่งนี้จะทำลายส่วนที่เหลือได้อย่างง่ายดาย

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

นี่คือผู้เล่นเดิม:

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 เกมฉันเสียใจที่จะบอกว่า Frankenstein ชนะเพียง 2 ครั้งในขณะที่ Liberator ชนะ 17 ครั้ง (ใช่ Revolutionnist จัดการเพื่อให้ผู้เล่น Neutral ชนะครั้งเดียวในขณะที่ได้อันดับที่ 2)
Thrax

@Thrax แก้ไข !!!!!
TheNumberOne

7

Java, Turtle

ขอบคุณ TheBestOne สำหรับวิธีการหลักฉันเพิ่งเปลี่ยนอัลกอริทึม (ฉันหวังว่าไม่เป็นไร) บอทนี้ทำการอัพเกรดเมืองที่ได้รับการปกป้องที่ดีที่สุดเพื่อสู้กับเมืองศัตรูที่อันตรายที่สุดในขณะที่ยังคงมีอัศวินมากพอที่จะป้องกันการจลาจลในเมืองอื่น ๆ

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

รวบรวม: javac Turtle.java

วิ่ง: java Turtle


ฉันคิดว่าคุณหมายถึงdangerousEnemyTown = dangerousEnemyTown.knightCount() >= town.knightCount() ? dangerousEnemyTown : town;ไม่dangerousEnemyTown = bestDefendedTown.knightCount() >= town.knightCount() ? bestDefendedTown : town;
TheNumberOne

@TheBestOne ขอบคุณที่ชี้ให้เห็น! กำลังอัปเดตโพสต์ของฉัน
Thrax

ฉันยังแก้ไข NPE ที่ทำให้ Turtle ของฉันต้องรอในแต่ละรอบ ในความเป็นจริงนี้เต่าเล็ก ๆ น้อย ๆ เป็นเตียงนอนจนถึงขณะนี้ ...
Thrax

7

Java 8, นักการเมือง

ทำหน้าที่เหมือนนักการเมืองที่แท้จริง Crasher ที่แย่มากยังคงสังหารเขาอยู่

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

    }
}

รวบรวม: javac Politician.java

วิ่ง: java Politician


1
+1 สำหรับสินบน แต่ฉันคิดว่าคุณพลาดlieวิธีการที่เหมือนกันทั้งหมด
globby

6

Java 8, บัตเตอร์

กระจายตัวเองอย่างสม่ำเสมอเท่าที่จะทำได้ เทอร์สเมืองถ้าเมืองเล็กพอ

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

    }
}

รวบรวม: javac Butter.java

วิ่ง: java Butter


6

Java นักปฏิวัติ

วิธีสุดท้ายยังคงใช้วิธีการหลักของ TheBestOne บอทนี้พยายามปลุกระดมการก่อจลาจลในทุก ๆ เมืองเนื่องจากผู้เล่นที่เป็นกลางไม่เป็นอันตรายโดยการฆ่าอัศวินจำนวนหนึ่งเมื่อเทียบกับจำนวนประชากรที่เกิดใหม่ แน่นอนมันจะไม่โจมตีผู้เล่นที่เป็นกลาง

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

รวบรวม: javac Revolutionist.java

วิ่ง: java Revolutionist


6

JAVA, Sehtimianer

ขอขอบคุณ TheBestOne อีกครั้งฉันได้คัดลอกวิธีการหลักของเขาด้วยเช่นกัน ) นี่เป็นครั้งแรกที่ฉันได้เล่น KingOfTheHill-CodeGame ดังนั้นฉันหวังว่าฉันจะทำทุกอย่างถูกต้อง ฉันภูมิใจเสนอ Sehtimianers: 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;
    }
}
}

Sehtimianers พยายามที่จะเหนือกว่าเกมทั้งหมดและจบในตอนท้าย ฉันหวังว่าบอทของฉันจะไม่ทำสิ่งที่เลวร้ายเกินไป :)


5

Java, อพยพ

อีกครั้งขึ้นอยู่กับวิธีการหลัก TheBestOne บอทนี้จะโยกย้ายจากเมืองหนึ่งไปอีกเมืองหนึ่งเมื่อมันมีจำนวนอัศวินถึงระดับหนึ่งแล้วโดยไม่คำนึงถึงเจ้าของและทำซ้ำกระบวนการนี้จนกว่ามันจะเปลี่ยนโลกทั้งใบ

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

รวบรวม: javac Exodus.java

วิ่ง: java Exodus


5

Python 2 ประชาธิปไตย

ราชาองค์นี้ไม่ใช่ราชา มันเป็นสิ่งที่ทันสมัย มันเป็นพระมหากษัตริย์ของคน มันเป็นประชาธิปไตย มันช้าไม่มีประสิทธิภาพและเมื่อมันทำอะไรบางอย่างมันผิด

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

python2 democracy.pyวิ่ง โปรดทราบว่าประชาธิปไตยต้องการ Python 2 2

แก้ไข: แก้ไขข้อผิดพลาดเกี่ยวกับการพิมพ์วัตถุเมือง


บางครั้งผลลัพธ์<__main__.Townนี้
TheNumberOne

ต้องแก้ไข ...
Hannes Karppila

4

C ++ 11, คำนวณความผิดพลาด

หลังจากที่ฉันลองเล็ก ๆ น้อย ๆ พร้อมกับ Java เล็กน้อยฉันรู้และไม่สามารถบรรลุสิ่งที่ฉันต้องการได้ฉันเลือกที่จะเขียนใหม่ใน C ++ และเพิ่มการจัดการไฟล์ ปัญหาคือ C + + ของฉันค่อนข้างเป็นสนิมและไม่ดีขึ้นมากดังนั้นบางส่วนถูกตีด้วยกันและเป็นเพียงทางออกแรกใน google ดังนั้นจึงไม่ใช่รหัสที่มีคุณภาพจริงๆ ...

ยังฉันสามารถรับผลการทำงานอย่างน้อยที่ไม่ดูดมากมันชนะ atleast เป็นครั้งคราว แต่ฉันไม่สามารถทดสอบได้อย่างสมบูรณ์เพราะฉันไม่สามารถเรียกใช้การส่งอื่น ๆ ทั้งหมดในพีซีนี้ ฉันอาจจะเขียนการกำหนดเป้าหมายใหม่ทั้งหมดและจะเพิ่มเป็นคำตอบอื่นในวันนี้หรือพรุ่งนี้

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

รวบรวมกับ: g++ -std=c++11 CalculatedFail.cpp -o CalculatedFail.exe

google บอกบน linux ว่าเป็น CalculatedFail.out แทนที่จะเป็น. exe แต่ฉันไม่สามารถทดสอบได้

และเรียกใช้ CalculatedFail.exe

เนื่องจากใช้ไฟล์เพื่อตรวจสอบโบนัส def การรันเกมพร้อมกันหลายครั้งอาจทำให้เกิดข้อผิดพลาด ...

หวังว่ามันจะทำงานได้อย่างถูกต้องโดยไม่มีปัญหามาก


ฉันค่อนข้างมั่นใจใน Linux ว่ามันจะไม่มีนามสกุลไฟล์
TheNumberOne

ฉันไม่สามารถเรียกใช้สิ่งนี้จาก Java Controller บน Windows ฉันรวบรวมมันตามที่คุณพูด ทำงานอย่างถูกต้องจากบรรทัดคำสั่ง
TheNumberOne

ตกลงที่เป็นฉันงี่เง่าโง่ลืมเปลี่ยนชื่อของไฟล์ข้อความที่จุดเริ่มต้นของเกมฉันคิดว่ามันควร
wrok

ฉันคิดว่ามันมีปัญหากับคอนโทรลเลอร์
TheNumberOne

mh คุณลองรุ่นที่ปรับปรุงแล้วเหรอ? เมื่อวานนี้ฉันมีชื่อไฟล์ที่ต่างกัน 2 อันโดยบังเอิญ รุ่น AttackOn3 มักจะมีข้อผิดพลาดในการเปิดหากมันชนะโดยทั่วไปแล้ว แต่ทั้งคู่ก็ทำงานได้อย่างสมบูรณ์แบบด้วยคอนโทรลเลอร์ในระบบของฉัน
sthrandom

3

Java, Illuminati

ฉันอ่านสิ่งนี้และรู้ว่าฉันจะไม่สามารถใช้กลยุทธ์ที่มีศักยภาพได้ดังนั้นฉันจึงตัดสินใจเล่นจิ้งจกที่มีบทบาทต่ำต้อยซึ่งอาจมีหรือไม่มีกฎของเรา แทนที่จะต่อสู้กับบ็อตอื่น ๆ ตัวนี้จะรวมพวกมันเข้าด้วยกันเพื่อที่จะละทิ้งพวกมันในตอนท้าย บอทนี้ไม่ได้ทำให้เกิดความเสียหายถาวร

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
แม้ว่านี่จะเป็นคำตอบที่น่าสนใจ " ไม่อนุญาตให้ใช้แหล่งข้อมูลภายนอกอื่น ๆ " การส่งของคุณจึงถูกแยกออกจากการทดลอง แต่ฉันจะถอนมันออกไปอย่างไรก็ตาม)
CommonGuy

3

Java, SuperProducer

มันสายในส่วนของฉันของโลกดังนั้นฉันไม่มีเวลาเพียงพอที่จะทำอย่างละเอียดในการส่งของฉัน ฉันจะวางแผนที่จะอธิบายเกี่ยวกับวิธีการทำงานในภายหลัง

ประสิทธิภาพของบอทดูเหมือนจะขึ้นอยู่กับลำดับเริ่มต้นที่จะชนะบางครั้ง ...

ฉันมีความคิดบางอย่างที่จะช่วยเพิ่มรอบการชนะ ... แต่ได้เวลา: พี

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

คอมไพล์: javac SuperProducer.java

ทำงาน: java moogiesoft.SuperProducer


2

C ++ 11, โจมตี On3

โค้ดเองไม่ได้สวยกว่ามากนัก แต่ตอนนี้ฉันใช้วิธีอื่นในการกำหนดเป้าหมายอาจจะเพิ่มความคิดเห็นในโค้ดในภายหลัง

ดูเหมือนว่าจะโอเคกับบ็อตที่ฉันใช้อยู่ถึงแม้ว่ามันจะยังคงเป็นเรื่องยากเทียบกับแฟรงเกนสไตน์และอิสรภาพและไม่สามารถชนะได้อย่างต่อเนื่อง

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

รวบรวมกับ: g++ -std=c++11 attackOn3.cpp -o attackOn3.exe
และเรียกใช้attackOn3.exe

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.