나를 죽이지 않는 것…


106

개요

이것은 누가 가장 오래 살아남을 수 있는지에 대한 봇 전투입니다. 이 봇은 공격을 받아 힘을 증가 시키므로 촬영하기 전에 신중하게 생각해야합니다.

매 턴마다 공격하거나 방어 할 봇을 선택할 수 있습니다. 공격하면 생명력이 떨어지고 힘이 증가합니다. 마지막 봇 스탠딩이 승리합니다.

각 봇은 1000의 생명과 10의 힘으로 시작합니다.

공격 당했을 때 :

  • 공격자의 힘이 당신의 삶에서 공제됩니다.
  • 당신의 힘이 1 증가합니다.

따라서 첫 턴에 2 개의 봇에 의해 공격을 받으면 생명력이 980이고 힘이 12입니다.

방어하기로 선택한 경우 :

  • 당신의 힘은 1만큼 낮아집니다
  • 이번 턴에 대한 모든 공격은 절반으로 줄어 듭니다
  • 공격을 받으면 각 공격자마다 1의 힘이 아닌 2의 힘을 얻습니다.

따라서 첫 턴에서 방어하고 두 봇에 의해 공격을 받으면 생명력이 990, 힘이 13입니다. 방어하고 공격받지 않으면 1000의 생명력을 가지지 만 9의 힘을 얻습니다.

턴이 끝날 때 당신의 힘이 1보다 낮 으면 1로 설정됩니다. 당신의 인생이 1 미만이라면, 당신은 죽습니다.

입출력

봇은 턴당 한 번 호출됩니다. 각 턴마다 1 초의 시간 제한이 있습니다.

머리 글자

봇을 처음 호출하면 인수가 주어지지 않습니다. 로 응답하십시오 ok. 이것은 봇이 응답하도록하기 위해서만 수행됩니다. 그렇지 않으면 플레이어 목록에 추가되지 않습니다.

각 차례

매 턴마다 봇에는 게임의 모든 봇에 대한 정보가 명령 줄 인수로 제공됩니다. 이러한 인수의 예는 다음과 같습니다.

1 0,1000,10,1 1,995,11,D

첫 번째 주장은 봇의 고유 ID입니다. 그런 다음 공백으로 구분 된 봇 목록이 나타납니다. 각 봇의 형식은 다음과 같습니다.

id,life,power,lastAction

lastAction어떤 봇이 공격 D했는지, 방어 X했는지, 이것이 첫 번째 턴인지를 나타내는 정수일 수 있습니다 . 나머지는 모두 정수입니다.

위의 예에서, 당신은 1마지막 차례에 봇 과 방어입니다. 봇 0은 당신을 공격했고 여전히 건강 / 힘을 시작하고 있습니다.

각 턴의 출력은 매우 간단합니다. 공격하려는 봇을 정수 (예 : 0또는 3)로 출력하거나 D방어하기 만하면 됩니다. 유효하지 않은 명령으로 간주되는 데드 또는 존재하지 않는 봇을 공격하지 마십시오. 유효하지 않은 명령은 1의 전력을 잃게됩니다.

토너먼트 구조

각 게임은 체력이 1000이고 파워가 10 인 모든 봇으로 구성됩니다. 모든 봇의 작업이 동시에 수행됩니다. 게임의 최대 턴 수는 1000입니다.

턴이 끝날 때 한 봇이 살아남 으면 (라이프> 0) 한 점을 획득하고 다른 게임을 시작합니다. 턴 제한에 도달하고 여러 봇이 살아 있으면 아무도 점수를 얻지 못합니다 . 남은 봇이 모두 같은 턴에 죽으면 아무도 점수를 얻지 못합니다.

토너먼트는 15 개의 게임으로 구성됩니다. 마지막에 가장 많은 점수를 얻은 사람이 승리합니다! 동점은 각 원 게임에서 남은 생명의 합계에 의해 깨집니다.

상태

봇은 이름이 지정된 직접 하위 폴더 state( "Hero"는 쓸 수 있음 state/hero.whatever) 에서 이름이 지정된 단일 파일에서만 읽거나 쓸 수 있습니다 . 이 파일의 크기 는 1024 2 바이트를 초과하지 않아야 합니다. 시간 제한을 준수하십시오. 프로그램은 응답 만하는 것이 아니라 1 초 이내에 종료 되어야합니다 .

이 파일은 토너먼트 전에 지워지지 만 게임 간 게임은 유지됩니다. 모든 봇 식별자 ( id)도 게임간에 동일하게 유지됩니다.

제어 장치

아래는 토너먼트 컨트롤러 ( Stronger.java)입니다. 기본적으로 최종 결과 (정렬 된 플레이어 목록, 상단에있는 승자) 만 출력하는데 꽤 오래 걸릴 수 있습니다. 얼지 않고 조용합니다. 보다 자세한 턴 바이 턴 출력을 원하면 -log실행시 인수를 추가하십시오 .

봇을 추가하려면 다음 두 가지 옵션이 있습니다.

  • 명령을 인수로 추가하십시오 ( java Stronger -log "python bot.py")

  • defaultPlayers[]소스에 명령을 추가하십시오 ( "python bot.py")

Hero , BullyCoward이 답변에서 찾을 수 있으며 득점 목적으로 사용됩니다.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class Stronger {

    static final String[] defaultPlayers = {
                                "java Hero",
                                "java Bully",
                                "java Coward"
                                };
    final int timeout = 1000;
    final int startLife = 1000;
    final int startPower = 10;
    final int numRounds = 15;

    boolean log = false;
    List<Player> players;

    public static void main(String[] args){
        new Stronger().run(args);
    }

    void run(String[] args){
        init(args);
        for(int i=0;i<numRounds;i++){
            Collections.shuffle(players);
            runGame();
        }
        Collections.sort(players);
        for(Player player : players)
            System.out.println(player.toString());
    }

    void runGame(){
        log("Player Count: " + players.size());
        for(Player player : players)
            player.reset();
        int turn = 0;
        while(turn++ < startLife){
            if(aliveCount() < 2)
                break;
            log("Turn " + turn);
            List<Player> clones = new ArrayList<Player>();
            for(Player player : players)
                clones.add(player.copy());
            for(Player player : players){
                if(player.life < 1 || player.timedOut)
                    continue;               
                String[] args = new String[players.size()+1];
                args[0] = "" + player.id;
                for(int i=1;i<args.length;i++)
                    args[i] = players.get(i-1).toArgument();
                String reply = getReply(player, args);
                Player clone = player.findCopyOrMe(clones);
                if(reply.equals("T")){
                    clone.timedOut = true;
                    clone.life = 0;
                }
                clone.lastAction = reply.trim();
            }

            for(Player player : players){
                if(player.life < 1 || player.timedOut)
                    continue;               
                Player clone = player.findCopyOrMe(clones);
                if(clone.lastAction.equals("D")){
                    clone.power--;
                }else{
                    try{
                        int target = Integer.parseInt(clone.lastAction);
                        for(Player t : players)
                            if(t.id == target && t.life < 1)
                                throw new Exception();
                        for(Player tclone : clones){
                            if(tclone.id == target){
                                int atk = player.power; 
                                if(tclone.lastAction.equals("D")){
                                    atk -= player.power / 2;
                                    tclone.power++;
                                }
                                tclone.life -= atk;
                                tclone.power++;
                            }
                        }
                    } catch (Exception e){
                        log(player.cmd + " returned an invalid command: (" + clone.lastAction + ")");
                        clone.power--;
                    }
                }
            }
            players = clones;
            for(Player player : players){
                if(player.power < 1)
                    player.power = 1;
                log(player.life + "\t\t" + player.power + "\t\t(" + player.id + ")\t" + player.cmd);
            }
            log("\n");
        }

        if(aliveCount() == 1)
            for(Player player : players)
                if(player.life > 0){
                    player.scoreRounds++;
                    player.scoreLife += player.life;
                }
    }

    void log(String msg){if(log)System.out.println(msg);}

    String getReply(Player player, String[] args){
        try{
            List<String> cmd = new ArrayList<String>();
            String[] tokens = player.cmd.split(" ");
            for(String token : tokens)
                cmd.add(token);
            for(String arg : args)
                cmd.add(arg);
            ProcessBuilder builder = new ProcessBuilder(cmd);
            builder.redirectErrorStream();
            long start = System.currentTimeMillis();
            Process process = builder.start();
            Scanner scanner = new Scanner(process.getInputStream());
            process.waitFor();          
            String reply = scanner.nextLine();
            scanner.close();
            process.destroy();
            if(System.currentTimeMillis() - start > timeout)
                return "T";
            return reply;
        }catch(Exception e){
            e.printStackTrace();
            return "Exception: " + e.getMessage();
        }
    }

    void init(String[] args){
        players = new ArrayList<Player>();
        for(String arg : args){
            if(arg.toLowerCase().startsWith("-log")){
                log = true;
            }else{
                Player player = createPlayer(arg);
                if(player != null)
                    players.add(player);
            }
        }
        for(String cmd : defaultPlayers){
            Player player = createPlayer(cmd);
            if(player != null)
                players.add(player);
        }
    }

    Player createPlayer(String cmd){
        Player player = new Player(cmd);
        String reply = getReply(player, new String[]{});
        log(player.cmd + " " + reply);
        if(reply != null && reply.equals("ok"))
            return player;
        return null;
    }

    int aliveCount(){
        int alive = 0;;
        for(Player player : players)
            if(player.life > 0)
                alive++;
        return alive;
    }

    static int nextId = 0;  
    class Player implements Comparable<Player>{
        int id, life, power, scoreRounds, scoreLife;
        boolean timedOut;
        String cmd, lastAction;

        Player(String cmd){
            this.cmd = cmd;
            id = nextId++;
            scoreRounds = 0;
            scoreLife = 0;
            reset();
        }

        public Player copy(){
            Player copy = new Player(cmd);
            copy.id = id;
            copy.life = life;
            copy.power = power;
            copy.scoreRounds = scoreRounds;
            copy.scoreLife = scoreLife;
            copy.lastAction = lastAction;
            return copy;
        }

        void reset(){
            life = startLife;
            power = startPower;
            lastAction = "X";
            timedOut = false;
        }

        Player findCopyOrMe(List<Player> copies){
            for(Player copy : copies)
                if(copy.id == id)
                    return copy;
            return this;
        }

        public int compareTo(Player other){
            if(scoreRounds == other.scoreRounds)
                return other.scoreLife - scoreLife;
            return other.scoreRounds - scoreRounds;
        }

        public String toArgument(){
            return id + "," + life + "," + power + "," + lastAction;  
        }

        public String toString(){
            String out = "" + scoreRounds + "\t" + scoreLife;
            while(out.length() < 20)
                out += " ";
            return out + "(" + id + ")\t" + cmd;
        }
    }
}

규칙

  • 최대 2 개의 봇을 입력 할 수 있습니다 . 플레이에서 하나를 제거하여 세 번째를 입력하려면 게시물을 삭제하십시오.

  • 메타 분석을 통해 봇을 타겟팅하거나 다른 방법으로 꼽을 수 없습니다. 봇이 제공 한 정보 만 사용하십시오. 여기에는 자신의 봇이 포함되어 있으므로 충돌하는 두 개의 봇을 입력 할 수 없습니다.

  • 컨트롤러 또는 다른 봇의 작동을 방해하지 마십시오.

  • 봇은 컨트롤러 또는 다른 봇을 인스턴스화하거나 달리 실행할 수 없습니다.

결과

(2015-05-22 00 : 00 : 00Z 현재 제출 된 봇)

이 라운드는 조금 더 나아졌으며, 두 번의 게임 만 1000 턴에 멈췄습니다. 랄프 마샬의 산타 야나 에게 첫 승리를 거두며 3 승을 거둔 유일한 봇이었습니다. 충분하지 않았기 때문에 그는 또한 Tactician 과 3 위를 차지했습니다 . Stormcrow는 Phantom Menace 와 함께 두 번째로 좋은 첫 번째 게시물입니다. 전체적으로 우리는 새로운 회원들에 의해 매우 멋진 공연을했으며 상위 6 곳은 5 개 미만의 게시물을 가진 사람들에게 전달되었습니다. 축하합니다. 사이트에 오신 것을 환영합니다!

0 승을 거둔 봇은 공간을 절약하기 위해 표시되지 않습니다. 위의 타임 스탬프 이전에 게시 된 모든 봇은 실행되었으므로 내 봇이 보이지 않으면 아무 것도 얻지 못했습니다.

Wins    Life(tiebreaker)  Name

3       561               perl Santayana.pl
2       850               java PhantomMenace
2       692               perl Tactician.pl
2       524               java Wiisniper
1       227               java Tank
1       184               java Velociraptor
1       7                 java Coward
1       3                 java IKnowYou

Sorta 스케치 병렬 컨트롤러 ( 기타 ) :

import java.lang.ProcessBuilder.Redirect;
import java.nio.file.FileSystems;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicInteger;

public class Stronger {

    static final String[] defaultPlayers = {
                                "java Hero",
                                "java Bully",
                                "java Coward",
                                "java Psycho",
                                "./monte.out",
                                "java Analyst",
                                "java Guardian",
                                "java Revenger",
                                "python precog.py",
                                //"python snappingTurtle.py",
                                "python beserker.py",
                                "./suprise.out",
                                //"python boxer.py",
                                "python defense.py",
                                "java Tank",
                                "java IKnowYou",
                                //"java BroBot",
                                "java Equaliser",
                                "java Velociraptor",
                                //"java AboveAverage",
                                "java PhantomMenace",
                                "java Wiisniper",
                                //"python semiRandom.py",
                                "/usr/bin/perl tactition.pl",
                                "/usr/bin/perl santayana.pl",
                                //"java GlitchUser"
                                "/usr/local/bin/Rscript opportunity.R",
                                "/usr/local/bin/scala Bandwagoner",
                                };
    final int timeout = 5000;
    final int startLife = 1000;
    final int startPower = 10;
    final int numRounds = 20;

    boolean log = true;
    List<Player> players;

    public static void main(String[] args){
        new Stronger().run(args);
    }

    void run(String[] args){
        init(args);
        for(int i=1;i<=numRounds;i++){
            if(log) System.out.println("Begining round "+ i);
            Collections.shuffle(players);
            runGame();
        }
        Collections.sort(players);
        for(Player player : players)
            System.out.println(player.toString());
    }

    void runGame(){
        log("Player Count: " + players.size());
        for(Player player : players)
            player.reset();
        int turn = 0;
        while(turn++ < startLife){
            if(aliveCount() < 2)
                break;
            log("Turn " + turn);
            List<Player> clones = new ArrayList<Player>();
            for(Player player : players)
                clones.add(player.copy());
            AtomicInteger count=new AtomicInteger(players.size());
            for(Player player : players){
                new Thread(() -> {
                    if(player.life >= 1 && !player.timedOut){
                        String[] args = new String[players.size()+1];
                        args[0] = "" + player.id;
                        for(int i=1;i<args.length;i++)
                            args[i] = players.get(i-1).toArgument();
                        String reply = getReply(player, args);
                        Player clone = player.findCopyOrMe(clones);
                        if(reply.equals("T")){
                            clone.timedOut = true;
                            clone.life = 0;
                        }
                        clone.lastAction = reply.trim();
                    }
                    synchronized(count){
                        count.decrementAndGet();
                        count.notify();
                    }
                }).start();
            }
            synchronized(count){
                while(count.get() > 0){
                    //System.out.println(count);
                    try{
                        count.wait();
                    }catch(InterruptedException e){
                    }
                }
            }

            for(Player player : players){
                if(player.life < 1 || player.timedOut)
                    continue;               
                Player clone = player.findCopyOrMe(clones);
                if(clone.lastAction.equals("D")){
                    clone.power--;
                }else{
                    try{
                        int target = Integer.parseInt(clone.lastAction);
                        for(Player t : players)
                            if(t.id == target && t.life < 1)
                                throw new Exception();
                        for(Player tclone : clones){
                            if(tclone.id == target){
                                int atk = player.power; 
                                if(tclone.lastAction.equals("D")){
                                    atk -= player.power / 2;
                                    tclone.power++;
                                }
                                tclone.life -= atk;
                                tclone.power++;
                            }
                        }
                    } catch (Exception e){
                        log(player.cmd + " returned an invalid command: (" + clone.lastAction + ")");
                        clone.power--;
                    }
                }
            }
            players = clones;
            for(Player player : players){
                if(player.power < 1)
                    player.power = 1;
                log(player.life + "\t\t" + player.power + "\t\t" + player.lastAction + "\t\t(" + player.id + ")\t" + player.cmd);
            }
            log("\n");
        }

        if(aliveCount() == 1)
            for(Player player : players)
                if(player.life > 0){
                    player.scoreRounds++;
                    player.scoreLife += player.life;
                }
    }

    void log(String msg){if(log)System.out.println(msg);}

    String getReply(Player player, String[] args){
        try{
            List<String> cmd = new ArrayList<String>();
            String[] tokens = player.cmd.split(" ");
            for(String token : tokens)
                cmd.add(token);
            for(String arg : args)
                cmd.add(arg);
            ProcessBuilder builder = new ProcessBuilder(cmd);
            builder.directory(FileSystems.getDefault().getPath(".", "bin").toFile());
            //builder.redirectError(Redirect.PIPE);
            long start = System.currentTimeMillis();
            Process process = builder.start();
            Scanner scanner = new Scanner(process.getInputStream());
            process.waitFor();          
            String reply = scanner.nextLine();
            scanner.close();
            process.destroy();
            if(System.currentTimeMillis() - start > timeout)
                return "T";
            return reply;
        }catch(Exception e){
            //e.printStackTrace();
            return "Exception: " + e.getMessage();
        }
    }

    void init(String[] args){
        players = new ArrayList<Player>();
        for(String arg : args){
            if(arg.toLowerCase().startsWith("-log")){
                log = true;
            }else{
                Player player = createPlayer(arg);
                if(player != null)
                    players.add(player);
            }
        }
        for(String cmd : defaultPlayers){
            Player player = createPlayer(cmd);
            if(player != null)
                players.add(player);
        }
    }

    Player createPlayer(String cmd){
        Player player = new Player(cmd);
        String reply = getReply(player, new String[]{});
        log(player.cmd + " " + reply);
        if(reply != null && reply.equals("ok"))
            return player;
        return null;
    }

    int aliveCount(){
        int alive = 0;;
        for(Player player : players)
            if(player.life > 0)
                alive++;
        return alive;
    }

    static int nextId = 0;  
    class Player implements Comparable<Player>{
        int id, life, power, scoreRounds, scoreLife;
        boolean timedOut;
        String cmd, lastAction;

        Player(String cmd){
            this.cmd = cmd;
            id = nextId++;
            scoreRounds = 0;
            scoreLife = 0;
            reset();
        }

        public Player copy(){
            Player copy = new Player(cmd);
            copy.id = id;
            copy.life = life;
            copy.power = power;
            copy.scoreRounds = scoreRounds;
            copy.scoreLife = scoreLife;
            copy.lastAction = lastAction;
            return copy;
        }

        void reset(){
            life = startLife;
            power = startPower;
            lastAction = "X";
            timedOut = false;
        }

        Player findCopyOrMe(List<Player> copies){
            for(Player copy : copies)
                if(copy.id == id)
                    return copy;
            return this;
        }

        public int compareTo(Player other){
            if(scoreRounds == other.scoreRounds)
                return other.scoreLife - scoreLife;
            return other.scoreRounds - scoreRounds;
        }

        public String toArgument(){
            return id + "," + life + "," + power + "," + lastAction;  
        }

        public String toString(){
            String out = "" + scoreRounds + "\t" + scoreLife;
            while(out.length() < 20)
                out += " ";
            return out + "(" + id + ")\t" + cmd;
        }
    }
}

2
@Tim 봇 목록은 공백으로 구분됩니다. 각 봇의 통계는 쉼표로 구분됩니다.
Geobits

3
@Mark 현재 봇은 약 반 수비 지향적이며 반 공격입니다. 수비 봇은 한 번의 승리도 없습니다. 나는 그것이 장려 동의 약간의 방어를하지만, 침략의 장점은 순수 방어 것입니다 수없는 전혀 포인트를 승리. 당신이 유일한 생존자 인 경우에만 포인트를 얻 습니다.
Geobits

8
제출물이 더 많아 봇이 어떻게 쌓이는 지 궁금한 사람이 있다면, "비공식"테스트 실행의 결과는 다음과 같습니다. 3-809-Hero; 2-593- 벨로시 랩터; 1-471- 서프라이즈 봇; 1-433-Coward; 1-371- 산타 야나; 1-364- 와이즈 니퍼; 1-262- 분석 제; 1-230- 벌리; 1-132- 이퀄라이저; 1-71-IKnowYou; 0-0-프리 코그, Berserker, BroBot, SemiRandom, MonteBot, Tactician, SnappingTurtle, Psycho, Revenger, Opportunity, PhantomMenace, Tank, Boxer, Guardian, AboveAverage, DefensiveBot. Opportunity, AboveAvg, BroBot, Boxer 및 SemiRandom의 잘못된 명령이 많이 있습니다.
OJFord

3
나는 원래 컨트롤러보다 게임을 더 빠르게 실행하는 병렬 버전의 컨트롤러를 가지고 있습니다. 누군가 관심이 있다면 게시 할 수 있습니다 ...
Others

3
@Manu 각 봇이 동시에 실행되지 않는 한 중요하지 않습니다. 병렬 버전에는 여전히 모든 봇이 한 턴을 끝내고 다음 봇으로 이동한다고 가정합니다. 내가 말했듯이 게시 한 경우 사용하기 전에 확인하겠습니다.
Geobits

답변:


25

C ++-몬테 봇

다수의 랜덤 게임을 시뮬레이션하고 죽지 않을 가능성이 가장 큰 움직임을 선택합니다.

컴퓨터가 당신을 위해 전략을 만들 수있을 때 왜 전략을 생각하십니까?

참고 : 최적의 성능을 위해 이것을 -O3 플래그로 컴파일하십시오.

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

//Monte Carlo method constants
const unsigned int total_iters=100000; //total number of simulations
double time_limit=0.7; //approximate CPU time the program is allowed to run before outputting the current best solution
const unsigned int check_interval=4096-1;

unsigned int num_players,my_bot;
const int DEFEND=-1,FIRST=-2,DEAD=-3;
struct Bot{
    short int life,power,lastAttack;
    inline bool is_alive(void){
        return life>0;
    }
    inline void damage(short int dmg){
        life-=dmg;
        if(life<0)life=0;
    }
    inline void charge(short int p){
        power+=p;
        if(power<1)power=1;
    }
    inline bool is_attacking(void){
        return lastAttack>=0;
    }
};
int main(int argc,char*argv[]){
    clock_t start=clock();
    if(argc==1){
        printf("ok");
        return 0;
    }

    srand(time(NULL));

    num_players=argc-2;
    sscanf(argv[1],"%u",&my_bot);

    Bot bots[num_players];
    for(unsigned int i=0;i<num_players;++i){
        char buf[16];
        unsigned int id;
        short int life,power;
        sscanf(argv[i+2],"%u,%hd,%hd,%s",&id,&life,&power,buf);
        Bot &cur_bot=bots[id];
        cur_bot.life=life;
        cur_bot.power=power;
        if(strcmp(buf,"D")==0)cur_bot.lastAttack=DEFEND;
        else if(strcmp(buf,"X")==0)cur_bot.lastAttack=FIRST;
        else sscanf(buf,"%hd",&cur_bot.lastAttack);
    }

    //let the other bots kill each other while we accumulate more power
    if(bots[my_bot].life>750){
        printf("D");
        return 0;
    }

    Bot cur_state[num_players];
    unsigned int won[num_players+1],visited[num_players+1];
    for(int i=0;i<num_players+1;++i){
        won[i]=0;
        visited[i]=0;
    }

    //unsigned long long int sim_length=0;
    for(unsigned int iter=0;iter<total_iters;++iter){
        //ensure that we do not exceed the time limit
        if(iter&check_interval==check_interval){
            clock_t cur_time=clock();
            if((double)(cur_time-start)/(double)CLOCKS_PER_SEC>=time_limit){
                break;
            }
        }
        int first_move=FIRST;
        memcpy(cur_state,bots,sizeof(Bot)*num_players);

        //simulate random moves in the game until
        //a. the player dies, or
        //b. the player is the only one alive
        while(true){
            //++sim_length;
            //check if our bot died
            if(!cur_state[my_bot].is_alive()){
                ++visited[first_move+1];
                break;
            }
            //check if our bot is the only bot left alive
            bool others_alive=false;
            for(unsigned int i=0;i<num_players;++i){
                if(i!=my_bot&&cur_state[i].is_alive()){
                    others_alive=true;
                    break;
                }
            }
            if(!others_alive){
                ++won[first_move+1];
                ++visited[first_move+1];
                break;
            }

            Bot new_bots[num_players];
            memcpy(new_bots,cur_state,sizeof(Bot)*num_players);

            //generate random moves for all players
            bool defend[num_players];
            int possible_moves[num_players+2];
            unsigned int num_moves;
            for(unsigned int i=0;i<num_players;++i){
                num_moves=0;
                if(cur_state[i].is_alive()){
                    possible_moves[num_moves++]=DEFEND;
                    for(unsigned int j=0;j<num_players;++j){
                        if(j!=i&&cur_state[j].is_alive()){
                            possible_moves[num_moves++]=j;
                        }
                    }
                    new_bots[i].lastAttack=possible_moves[rand()%num_moves];
                    defend[num_players]=(new_bots[i].lastAttack==DEFEND);
                }else new_bots[i].lastAttack=DEAD;
            }
            if(first_move==FIRST)first_move=new_bots[my_bot].lastAttack;

            //simulate outcome of moves
            for(unsigned int i=0;i<num_players;++i){
                if(cur_state[i].is_alive()&&new_bots[i].is_attacking()){
                    new_bots[i].charge(-1);
                    int victim=new_bots[i].lastAttack;
                    if(defend[victim]){ //if victim is defending
                        new_bots[victim].charge(2);
                        new_bots[victim].damage(cur_state[i].power/2);
                    }else{
                        new_bots[victim].charge(1);
                        new_bots[victim].damage(cur_state[i].power);
                    }
                }
            }
            memcpy(cur_state,new_bots,sizeof(Bot)*num_players);
        }
    }
    //printf("%f\n",(double)sim_length/(double)total_iters);
    double win_rate=-1;
    int best_move=DEFEND;
    for(int i=0;i<num_players+1;++i){
        if(i-1!=my_bot){
            double cur_rate=(double)won[i]/(double)visited[i];
            if(cur_rate>win_rate){
                win_rate=cur_rate;
                best_move=i-1;
            }
        }
    }
    if(best_move==DEFEND)printf("D");
    else printf("%d",best_move);

    //clock_t end=clock();
    //fprintf(stderr,"%f\n",(double)(end-start)/(double)CLOCKS_PER_SEC);

    return 0;
}

C-몬테 파 스터

또한이 봇은 멀티 스레딩을 활용하여 더 빠르게 실행되도록 만들 수 있습니다. 그러나 봇이 시간 초과되기 전에 (판단 플랫폼에서) 평가할 수있는 반복 횟수를 사전에 알 수 없으므로이 봇 (아래 코드 포함)을이 경쟁에 사용하지 않습니다.

아래 코드는 호기심을위한 것입니다.

참고 : 최적의 성능을 위해 -O3 및 -fopenmp 플래그로이를 컴파일하십시오.

#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAX_PLAYERS 32

//Monte Carlo method constants
const unsigned int total_iters=60000; //total number of simulations

unsigned int num_players,my_bot;
const int DEFEND=-1,FIRST=-2,DEAD=-3;
struct Bot{
    short int life,power,lastAttack;
};
int main(int argc,char*argv[]){
    clock_t start=clock();
    if(argc==1){
        printf("ok");
        return 0;
    }

    srand(time(NULL));

    num_players=argc-2;
    sscanf(argv[1],"%u",&my_bot);

    struct Bot bots[MAX_PLAYERS];
    int A;
    for(A=0;A<num_players;++A){
        char buf[16];
        unsigned int id;
        short int life,power;
        sscanf(argv[A+2],"%u,%hd,%hd,%s",&id,&life,&power,buf);
        struct Bot *cur_bot=&bots[id];
        cur_bot->life=life;
        cur_bot->power=power;
        if(strcmp(buf,"D")==0)cur_bot->lastAttack=DEFEND;
        else if(strcmp(buf,"X")==0)cur_bot->lastAttack=FIRST;
        else sscanf(buf,"%hd",&cur_bot->lastAttack);
    }

    //let the other bots kill each other while we accumulate more power
    if(bots[my_bot].life>750){
        printf("D");
        return 0;
    }

    struct Bot cur_state[MAX_PLAYERS];
    unsigned int won[MAX_PLAYERS+1],visited[MAX_PLAYERS+1];
    for(A=0;A<num_players+1;++A){
        won[A]=0;
        visited[A]=0;
    }

    //unsigned long long int sim_length=0;
    int iter;
    #pragma omp parallel for //strangely, the code fails to compile if a variable length array is used in the loop
    for(iter=0;iter<total_iters;++iter){
        //note that we cannot break this loop when we use #pragma omp parallel
        //there is therefore no way to check if we're close to exceeding the time limit

        int first_move=FIRST;
        memcpy(cur_state,bots,sizeof(struct Bot)*num_players);

        //simulate random moves in the game until
        //a. the player dies, or
        //b. the player is the only one alive
        int sim_length=0;
        while(1){
            //++sim_length;
            //check if our bot died
            if(cur_state[my_bot].life<=0){
                ++visited[first_move+1];
                break;
            }
            //check if our bot is the only bot left alive
            int others_alive=0;
            int i;
            for(i=0;i<num_players;++i){
                if(i!=my_bot&&cur_state[i].life>0){
                    others_alive=1;
                    break;
                }
            }
            if(!others_alive){
                ++won[first_move+1];
                //won[first_move+1]+=cur_state[my_bot].life;
                ++visited[first_move+1];
                break;
            }

            struct Bot new_bots[MAX_PLAYERS];
            memcpy(new_bots,cur_state,sizeof(struct Bot)*num_players);

            //generate random moves for all players
            char defend[MAX_PLAYERS];
            //int possible_moves[num_players+2];
            int possible_moves[MAX_PLAYERS+2];
            for(i=0;i<num_players;++i){
                if(cur_state[i].life>0){
                    int j,num_moves=0;
                    possible_moves[num_moves++]=DEFEND;
                    for(j=0;j<num_players;++j){
                        if(j!=i&&cur_state[j].life>0){
                            possible_moves[num_moves++]=j;
                        }
                    }
                    new_bots[i].lastAttack=possible_moves[rand()%num_moves];
                    defend[i]=(new_bots[i].lastAttack==DEFEND);
                }else new_bots[i].lastAttack=DEAD;
            }
            if(first_move==FIRST)first_move=new_bots[my_bot].lastAttack;

            //simulate outcome of moves
            for(i=0;i<num_players;++i){
                if(cur_state[i].life>0&&new_bots[i].lastAttack>=0){
                    new_bots[i].power-=1;
                    if(new_bots[i].power<=0)new_bots[i].power=1;
                    int victim=new_bots[i].lastAttack;
                    if(defend[victim]){ //if victim is defending
                        new_bots[victim].power+=2;
                        new_bots[victim].life-=cur_state[i].power/2;
                    }else{
                        new_bots[victim].power+=1;
                        new_bots[victim].life-=cur_state[i].power;
                    }
                    if(new_bots[victim].life<0)new_bots[victim].life=0;
                }
            }
            memcpy(cur_state,new_bots,sizeof(struct Bot)*num_players);
        }
    }
    //printf("%f\n",(double)sim_length/(double)total_iters);
    double win_rate=-1;
    int best_move=DEFEND;
    for(A=0;A<num_players+1;++A){
        if(A-1!=my_bot){
            double cur_rate=(double)won[A]/(double)visited[A];
            if(cur_rate>win_rate){
                win_rate=cur_rate;
                best_move=A-1;
            }
        }
    }
    if(best_move==DEFEND)printf("D");
    else printf("%d",best_move);
    //fprintf(stderr,"%.3f%% chance (based on %d samples)\n",(double)won[best_move+1]/(double)visited[best_move+1]*100.,total_iters);

    //clock_t end=clock();
    //fprintf(stderr,"%f\n",(double)(end-start)/(double)CLOCKS_PER_SEC);

    return 0;
}

2
흥미로운 전략. 대략 20 명의 상대와 시뮬레이션하는 데 얼마나 걸립니까?
Ralph Marshall

2
@RalphMarshall 소수의 적에게는 6 만 번의 시뮬레이션 (0.03 초에서 0.2 초까지)을 신속하게 수행 할 수 있지만 20 명의 적 (평균 10 초)에서는 매우 느리게 진행됩니다. 바라건대, 알고리즘을 조기에 종료하면 여전히 실행 가능한 솔루션이 생성됩니다.
Potatomato

이 봇에 대한 멀티 스레딩 지원을 추가하여 프로그램을 더 빠르게 실행하는 것을 고려하고 있지만 봇 시간이 초과되기 전에 심사 컴퓨터가 얼마나 많은 반복을 평가할 수 있을지 모르겠습니다. 봇이 최적의 반복 횟수를 실행할 수 있도록 프로파일 링을 수행하기 위해 첫 번째 게임을 희생 할 것입니다.
Potatomato

23

자바 사이코

이 미친 정신병자가 무엇을할지 말하지 않습니다. 죽은 봇이나 심지어 자신을 공격 할 수도 있습니다.

import java.util.Random;

public class Psycho {
    public static void main(String[] args) {
        if(args.length < 1){
            System.out.print("ok");
            System.exit(0);
        }

        Random rnd = new Random();
        rnd.setSeed( System.currentTimeMillis() );

        String[] tokens = args[ rnd.nextInt(args.length) ].split(",");
        String target = tokens[0];

        System.out.print(target);
    }
}


19

스칼라-밴드와 고너

Bandwagoner는 명예 나 원칙에 관심이 없습니다. Bandwagoner는 가장 약하거나 강한 것을 피하면서 낮게 누워 있습니다. Bandwagoner는 관심을 끌지 않기 위해 컨센서스 대상을 대상으로 군중과 함께합니다.

import scala.util.Try

object Bandwagoner {
    case class PlayerStatus(life:Int, power:Int, lastAction:Option[Int])

    def main(args:Array[String]):Unit={
        if(args.length==0)
            println("ok")
        else{
            val myId=args(0).toInt
            val everyonesStatus=(for(action <- args.tail) yield{
                val id :: life :: power :: lastAction :: Nil = action.split(",").toList
                (id.toInt, new PlayerStatus(life.toInt, power.toInt, Try(lastAction.toInt).toOption))
            }).toMap
            println(bandwagon(myId, everyonesStatus(myId), everyonesStatus.filter(_._1 != myId)))
        }
    }

    def bandwagon(myId:Int, self:PlayerStatus, opponents:Map[Int, PlayerStatus]):String={
        val alive=opponents.filter(_._2.life > 0)
        //If their is only one opponent left
        if(alive.size==1){
            val (opponentId, opponent)=alive.head
            //Get win projection
            val willWin=opponent.life/(self.power*1.0) <= self.life/(opponent.power*1.0)
            //If I'm stronger attack, otherwise defend
            if(willWin) opponentId.toString() else "D"

        }
        //Otherwise
        else if(alive.size > 0){
            //If I'm the strongest or weakest
            if(alive.map(_._2.life).max < self.life || alive.map(_._2.life).min > self.life){
                //If I have a good opportunity in terms or power, or passivity
                if(alive.map(_._2.power).max * 1.5 < self.power || !alive.exists(_._2.lastAction.isDefined)){
                    //Attack
                    alive.maxBy(_._2.power)._1.toString()
                }
                //Otherwise
                else 
                    //Lay low
                    "D"
            }
            //Otherwise, BANDWAGON
            else{
                //Obviously we dont want to attack dead opponents, or ourself
                val validTargets=opponents.flatMap(_._2.lastAction).filter(alive.contains(_)).filter(_ != myId)
                if(validTargets.size == 0)
                    "D"
                else
                    //Select the most targeted opponent (Sorry)
                    validTargets.groupBy(i => i).mapValues(_.size).maxBy(_._2)._1.toString()
            }
        }
        //Just to be safe..
        else 
            "D"
    }
}

첫 줄에 왜 "scala.util의 멤버가 아닙니다"라는 어리석은 오류가 발생하는지 아십니까? 인터넷 검색으로 나를 잃었습니다. 저장소에서 2.9.2 표준 스칼라 설치를했습니다.
Geobits

@Geobits는 내 것보다 오래된 스칼라 버전이므로 2.11을 실행 중입니다. 업그레이드가 옵션이 아닌 경우 알려 주시면 작동하도록 코드를 수정하겠습니다.
기타

2
알았어 문서에서 "Since 2.1.0"을 "Since 2.1.0"으로
읽었

18

자바 복수 자

복수자는 말다툼을위한 말다툼에 관심이 없습니다. 그러나 공격을 받으면 복수 추구 할 것입니다 !

public class Revenger {
    public static void main(String[] args) {
        if(args.length < 1){
            System.out.print("ok");
            System.exit(0);
        }

        String me = args[0], target = "D";
        int last_attacker_power = -1;

        for(int i=1; i<args.length; ++i){
            String[] tokens = args[i].split(",");
            int power = Integer.parseInt(tokens[2]);
            int life  = Integer.parseInt(tokens[1]);

            if( tokens[3].equals(me)
             && power>last_attacker_power
             && life>0  ){
                target = tokens[0];
                last_attacker_power = power;
            }
        }

        System.out.print(target);
    }
}

4
참고 : 대상이 죽은 후에도 공격을 중단하지 않습니다.
Geobits

26
@Geobits 아하지만 복수는 최고의 요리입니다 .. 이미 죽었습니까? : p 고의가 아니었다; 업데이트되었습니다.
OJFord

17

자바-영웅, 깡패 및 겁쟁이

이 3 개의 봇은 예제로 포함되어 있지만 득점 토너먼트에서 뛸 입니다. 그들은 모두 단순한 행동을합니다.

영웅

영웅은 단순히 모든 턴 에서 가장 많은 생명 을 가진 사람을 공격 합니다.

public class Hero {
    public static void main(String[] args) {
        if(args.length < 1){
            System.out.print("ok");
            System.exit(0);
        }
        String me = args[0], target="D";
        int best=0;
        for(int i=1;i<args.length;i++){
            String[] tokens = args[i].split(",");
            int life = Integer.valueOf(tokens[1]);
            if(life > 0 && life >= best && !tokens[0].equals(me)){
                best = life;
                target = tokens[0];
            }
        }
        System.out.print(target);
    }
}

곯리다

한편, 깡패는 매 턴마다 생명 이 가장 적은 사람을 공격 합니다.

public class Bully {
    public static void main(String[] args) {
        if(args.length < 1){
            System.out.print("ok");
            System.exit(0);
        }
        String me = args[0], target="D";
        int best=Integer.MAX_VALUE;
        for(int i=1;i<args.length;i++){
            String[] tokens = args[i].split(",");
            int life = Integer.valueOf(tokens[1]);
            if(life > 0 && life <= best && !tokens[0].equals(me)){
                best = life;
                target = tokens[0];
            }
        }
        System.out.print(target);
    }
}

겁쟁이

겁쟁이는 자신의 생명이 500 이하가 될 때까지 방어 만합니다. 그는 매 턴마다 가장 힘적은 사람을 공격 합니다.

public class Coward {
    public static void main(String[] args) {
        if(args.length < 1){
            System.out.print("ok");
            System.exit(0);
        }
        String me = args[0], action="D";
        int best=Integer.MAX_VALUE;
        for(int i=1;i<args.length;i++){
            String[] tokens = args[i].split(",");
            if(tokens[0].equals(me)){
                if(Integer.valueOf(tokens[1]) > 500){
                    System.out.print("D");
                    System.exit(0);
                }
            }
        }       
        for(int i=1;i<args.length;i++){
            String[] tokens = args[i].split(",");
            int power = Integer.valueOf(tokens[2]);
            if(power <= best && !tokens[0].equals(me) && Integer.valueOf(tokens[1]) > 0){
                best = power;
                action = tokens[0];
            }
        }
        System.out.print(action);
    }
}

즐겨!


7
영웅의 기술이 매우 효과적인 기술이라는 것이 흥미 롭습니다. 더 정교한 '봇'(예 : MonteBot, Analyst)에 대해서도 마찬가지입니다. 단순한 예일까요, 아니면 통찰력에 근거한 것입니까?
OJFord

1
아니요, 방금 제가 생각했던 처음 세 가지를 예로 들었습니다. 솔직히 말해서 그것이 잘 될 것이라고는 생각하지 않았습니다.
Geobits

16

펄-전술가

이것은 Let 'em Fight 봇의 편집으로 시작되었지만 새로운 항목으로 입력하기로 결정한 내용을 충분히 변경했습니다. 새로운 논리는 다음과 같습니다

  • 이전 턴에 아무도 공격하지 않았다면, 생명력이 가장 높은 상대를 공격하십시오. 이것은 내가 아직 살아있는 한 아무도 다른 사람을 공격하지 않는 결말을 막아야합니다.
  • 누군가 마지막 턴에 나를 공격했다면, 가장 강력한 공격자를 선택하여 반격하십시오.
  • 우리가 두 개의 봇으로 떨어지거나 평균 이하의 강도라면, 가장 높은 생명력으로 상대를 공격하십시오.
  • 내 자신의 정격 전력이 평균보다 낮은 경우 내 힘을보다 합리적인 수준으로 높이기 위해 공격하십시오.
  • 그렇지 않으면 내 시간을 불쾌하게

나는 몇 가지 승리를 거두었지만 여전히 내 입장에서 눈에 띄지 않는 다른 Java 봇에 대해 로컬로 테스트했습니다.

#!/usr/bin/perl

use strict;
use warnings;

# First round
if (!@ARGV) {
    print "ok\n";
    exit;
}

my ($self, @rest) = @ARGV;

my ($myAction, $myPower, $myLife,
    $myMaxAttacker, $myMaxAttackerId, 
    $maxLife, $maxLifeId, 
    $maxPower, $maxPowerId,
    $totLife, $totPower, $living, $amWeak, $numAttackers) = ('D');

# First, get a situation report
for (@rest) {
    my ($id, $life, $power, $action) = split(',');

    # Let the dead rest in peace
    next unless $life>0;

    if ($id == $self) {
        # Keep track of my own power and life for later comparison
        $myPower = $power;
        $myLife = $life;
        next;
    }

    $living++;
    $numAttackers++ if ($action ne 'D');
    $totPower += $power;
    $totLife += $life;

    if ($action == $self) {
        # Bastard hit me!
        if ($power > $myMaxAttacker) {
            $myMaxAttacker = $power;
            $myMaxAttackerId = $id;
        }
    }

    # If you're going to pick a fight, go for the biggest
    # guy in the room.
    if ($life > $maxLife) {
        $maxLife = $life;
        $maxLifeId = $id;
    }

    # Or, go for the guy with the biggest gun
    if ($power > $maxPower) {
        $maxPower = $power;
        $maxPowerId = $id;
    }
}

# If I'm being hit any attacks are back at the strongest attacker,
# otherwise simply the healthiest opponent overall
my $preferredTarget = $myMaxAttackerId;
$preferredTarget = $maxLifeId unless defined $preferredTarget;

# Check to see if I have below-average life, in which case it's time to get moving
$amWeak = $myLife < $totLife/$living;

# Now figure out what to do
if (!$numAttackers) {
    # Everybody is standing around, so let's mix it up
    $myAction = $preferredTarget;
} elsif (defined $myMaxAttackerId) {
    # My momma told me never to stand there and be hit
    $myAction = $myMaxAttackerId;
} elsif ($amWeak || $living == 1) {
    # Either we're down to two bots, or I'm fairly weak. Atack!!!
    $myAction = $preferredTarget;
} elsif ($myPower < $totPower/$living) {
    # Just lash out at random so we do not lose all of
    # our power through permanent defense
    $myAction = $preferredTarget;
} else { 
    # Work up some courage/power by drinking beer
    # in the corner. Use the default defensive action in this case.
    # Else clause exists just for debugging.
}

print "$myAction\n";

펄-산타 야나

역사를 기억하지 못하는 사람들은 일찍 죽거나 그와 같은 일부 사람들이 죽을 운명에 처해 있습니다. 이 봇은 모든 라운드에서 각 봇의 전체 강도 기록을 유지하고 항상 가장 강한 것을 공격하여 컨테스트의 멀티 라운드 특성을 활용하려고합니다. 이론적으로 이것은 모든 봇이 분쇄 리드로 나가는 것을 막아야하지만 물론 내가 살아있는 동안에 만 통계를 수집 하므로이 봇이 수명이 짧으면 통계가 그리 좋지 않을 것입니다.

#!/usr/bin/perl

use strict;
use warnings;

# First round
if (!@ARGV) {
    print "ok\n";
    exit;
}

# Read in our multi-round/multi-game state information
my $state;
if (open STATE, "state/santayana.out") {
    $state = <STATE>;
    close STATE;
}

# Stuff the historical data into a hash keyed by opponent ID
my %state;
my @state = $state ? split(' ', $state) : ();
for (@state) {
    my ($id, $life, $power) = split ',';
    $state{$id} = [$life, $power];
}

my ($self, @rest) = @ARGV;

my ($maxLife, $maxLifeId, $living) = (0, undef, 0);

# First, get a situation report
for (@rest) {
    my ($id, $life, $power, $action) = split(',');

    # Let the dead rest in peace
    next unless $life > 0;

    $living++;

    # Update the historical hash with latest information
    my $aref = $state{$id};
    if ($aref) {
        $$aref[0] += $life * ($action eq 'D' ? 1 : 1.5);
        $$aref[1] += $power;
    } else {
        $state{$id} = [$life, $power];
    }

    next if ($id == $self);

    # Our target is based on the historically
    # strongest opponent, independent of current state,
    # unless they are actually dead
    if ($life > 0 && $state{$id}->[0] > $maxLife) {
        $maxLife = $state{$id}->[0];
        $maxLifeId = $id;
    }
}

# Write out the latest state for next time around
if (open STATE, ">state/santayana.out") {
    print STATE join(" ", map { join ",", $_, $state{$_}->[0], $state{$_}->[1] } sort { $state{$b}->[0] <=> $state{$a}->[0]} keys %state);
    close STATE;
}

# Now figure out what to do
if (defined $maxLifeId) {
    # Should always be defined, but who knows
    print "$maxLifeId\n";
} else {
    print "D\n";
}

다른 항목 (Let 'em Fight)으로 삭제 한 것이 확실하므로 두 개의 봇만 있어야하지만 그렇지 않은 경우 해당 봇을 무시하고이 두 가지만 사용하십시오. 감사.
랄프 마샬

6
최신 스코어 보드에서 1 위와 3 위를 차지한 것을 축하합니다 :)
Geobits

가장 훌륭한! 이것은 큰 도전이었습니다.
랄프 마샬

14

자바 가디언

보호자는 약자를 보호합니다. 그는 자신의 마지막 턴에서 가장 약한 살아있는 봇 (자신을 제외하고)을 선택하여 공격 할 것입니다. 그러나 그는 공격하지 않을 정도로 똑똑합니다.

1) 자신 ( 괴롭힘 아닌 한 , 그는 가치가 있다고 생각합니다.)

2) 자신을 공격하는 봇

3) 죽은 봇

4) 남은 생명이 10 명 미만인 봇 (유망한 교훈을 얻은 사람)

가디언은 필요한 경우 같은 플레이어를 반복해서 선택합니다. "가장 약한 플레이어"와 "그를 선택한 사람"의 관계는 목록의 첫 번째 항목 (즉, 무작위)으로 이동합니다.

public class Guardian{
    public static void main (String[] args){
        if(args.length == 0){
            System.out.print("ok");
            System.exit(0);
        }

        String myId = args[0];
        int lowestLife = Integer.MAX_VALUE;
        int life = Integer.MIN_VALUE;
        String[] tokens = {};
        String opposingId = "";
        String weakestOpponent = "";
        String lastTarget = "";

        for(int i=1; i<args.length; i++){
            tokens = args[i].split(",");
            opposingId = tokens[0];
            life = Integer.parseInt(tokens[1]);
            lastTarget = tokens[3];
            if(life < lowestLife && life > 0 &&
                !opposingId.equals(myId) &&
                !opposingId.equals(lastTarget)){
                weakestOpponent = opposingId;
            }
        }

        for(int i=1; i<args.length; i++){
            tokens = args[i].split(",");
            opposingId = tokens[0];
            life = Integer.parseInt(tokens[1]);
            lastTarget = tokens[3];
            if (lastTarget.equals(weakestOpponent) &&
                life > 10){
                System.out.println(opposingId);
                System.exit(0);
            }
        }

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

1
로봇다른 로봇 의 수많은 오타와 실수를 수정하십시오 . 나는 그들 중 어느 것도 그대로 컴파일 할 수 없습니다.
Geobits

나는 그것이 괴롭힘을 당 했다면 그것이 행한 일, 즉 D efend에 대해 생각해야한다고 생각 합니다.
user3819867 2016 년

오류가 수정되었습니다. @ user3819867, 나는 그것을 추가하는 것에 대해 생각했지만 Guardian은 모든 비용, 심지어는 비용을 지불해도 약자를 보호 할 것입니다.
Xynariz

13

자바-분석가

공격 한 경우 5를 곱하고 분석가를 공격 한 경우 25를 곱하여 각 적의 위협을 결정합니다. 동점 인 경우, 생명력이 가장 적은 플레이어를 공격합니다.

코드의 대부분은 Geobits의 답변에서 빌 렸습니다.

public class Analyst {
    public static void main(String[] args) {
        if (args.length < 1) {
            System.out.println("ok");
            System.exit(0);
        }
        String me = args[0], that = "D";
        int maxThreat = 200;
        for (int i = 1; i < args.length; i++) {
            String[] player = args[i].split(",");
            int threat = Integer.parseInt(player[2]) * 100
                         * (!player[3].equals("D") ? 5 : 1)
                         * (player[3].equals(me) ? 5 : 1)
                         - Integer.parseInt(player[1]);
            if (threat > maxThreat && Integer.parseInt(player[1]) > 0 && !player[0].equals(me)) {
                maxThreat = threat;
                that = player[0];
            }
        }
        System.out.println(that);
    }
}

12

파이썬 2, 거북 거북

껍질에 숨 깁니다 다시 (그들은 죽은 아니라면), 다음 껍질로 돌아갑니다 그것을 마지막 턴을 공격하는 최초의 사람을 무는 나온다
과 실행python snapping_turtle.py <input>

import sys
class snapping_turtle:
    def bitey(self,command):


        if len(command) <=1:
            return 'ok'
        else:
            last_turn = list(command)
            bot_to_bite = -1
            me = last_turn[0]
            for k in xrange(0,len(last_turn)):
                #bot_action = last_turn.split(',')

                if len(last_turn[k]) ==1:
                    pass
                else:
                    bot_action = last_turn[k].split(',')
                    # If they hit me
                    if bot_action[3] == me:
                        # And if they're still alive, hit them
                        if int(bot_action[1]) > 0:
                            bot_to_bite = bot_action[0]
                            break
                        #Otherwise, stay in my shell
                        else:
                            pass

            if bot_to_bite > -1:
                return bot_to_bite
            else:
                return 'D'

print snapping_turtle().bitey(sys.argv[1:])

파이썬 2, 버서커

버서커 스매쉬! 충분한 힘을 얻을 때까지 자신을 공격 한 다음 가장 가까운 생물을 공격하기 시작합니다. 어떤 이유에서든 누가 맞아야하는지 파악할 수없는 경우에도 적중합니다.

편집 : Berserker의 분노 임계 값을 50에서 25로 변경했습니다. 그렇지 않으면 아무것도하기 전에 스스로 제거 할 수 있기 때문에 ...

로 실행 python Berserker.py <input>

import sys
class Berserker:
    def rage(self,command):


        if len(command) <=1:
            return 'ok'
        else:
            last_turn = list(command)
            bot_to_smash = -1
            me = last_turn[0]
            my_power = last_turn[int(me)].split(',')[2]
            for k in xrange(0,len(last_turn)):
                #bot_action = last_turn.split(',')

                if len(last_turn[k]) ==1:
                    pass
                else:
                    bot_action = last_turn[k].split(',')
                    if int(my_power) < 25:
                        #Too weak! Need make stronger for smashing!
                        bot_to_smash = me
                        break
                    else:
                        #Now strong! Smash! Not smash broken things!
                        if bot_action[0] != me and bot_action[1] > 0:
                            bot_to_smash = bot_action[0]

            if bot_to_smash > -1:
                return bot_to_smash
            else:
                #Confused! Don't like! MORE POWER!
                return me

print Berserker().rage(sys.argv[1:])

12

R-기회

이 봇은을 사용하여 호출해야합니다 Rscript Opportunity.R. D봇 중 하나가 연속으로 두 번 공격하고 있다는 것을 인식하지 않는 한 , 상대방이 자신을 방어 할 가능성이 적은 (즉 , 과거에 가장 적게 사용했던) 적은 사람을 공격하는 기억을 유지합니다. 공격자가 할 수있는 것보다 빠르게 죽일 수있는 경우 공격 로봇을 자체적으로 공격하거나 공격하는 로봇.

args <- commandArgs(TRUE)
if(length(args)){
    myid <- as.integer(args[1])
    data <- as.data.frame(do.call(rbind,strsplit(args[-1],",")),stringsAsFactors=FALSE)
    colnames(data) <- c('id','health','power','last')
    data$id <- as.integer(data$id)
    data$health <- as.integer(data$health)
    data$power <- as.integer(data$power)
    data <- data[order(data$id),]
    if(all(data$last=="X")){
        cat(data$last,file="state/opportunity.txt",sep="\n")
        cat(sample(data$id[data$id!=myid],1))
        }else{
            past <- as.matrix(read.table("state/opportunity.txt",sep=" "))
            lastturn <- data$last
            lastturn[data$health<1] <- "X"
            lastturn[nchar(lastturn)>1] <- "E" #If a bot returned anything else than an integer
            past <- cbind(past,lastturn)
            cat(apply(past,1,paste,collapse=" "),sep="\n",file="state/opportunity.txt")
            who_bully_me <- sapply(apply(past,1,rle),function(x)ifelse(tail(x$v,1)==myid,tail(x$l,1),0))
            if(any(who_bully_me>1)){
                bullyid <- which.max(who_bully_me)-1
                if(data$health[data$id==bullyid]%/%data$power[data$id==myid]<=data$health[data$id==myid]%/%data$power[data$id==bullyid]){
                    cat(bullyid)
                    }else{cat("D")}
                }else{
                    defend <- rowSums(past=="D")
                    defend[past[,ncol(past)]=="X"] <- NA
                    defend[myid+1] <- NA
                    choice <- which(defend%in%min(defend,na.rm=TRUE)) -1
                    if(length(choice)>1) choice <- sample(choice,1)
                    cat(choice)
                }
        }
}else{
    cat("ok")
    }

좋은. R에서 솔루션을 시작했지만 훨씬 좋습니다.
Alex A.

좋은 전략을 생각할 수 있다면 주저하지 말고 링에 새로운 R 봇을 입력하십시오 (필요한 경우에도 내 코드 중 일부를 다시 사용할 수 있습니다)! 줄리아 봇이 궁금합니다 (줄리아에서 가끔 골프를 치기 때문에).
plannapus

아마도 줄리아에서 기회를 줄 것입니다. 격려해 주셔서 감사합니다. :)
Alex A.

10

파이썬 2-복서

복서 봇은 주로 경비를 유지하고, 더킹하고 직조합니다. 때때로 그것은 잘 방어하지 못하는 강한 상대에게 빠른 b 또는 크로스를 보내며, 시간이 지남에 따라 그들을 착용하기를 바라고 있습니다.

import sys, re, random
if sys.argv[1:]:
    rows = [map(int, re.sub('[DX]', '-1', b).split(',')) for b in sys.argv[2:]]
    bots = dict((r.pop(0),r) for r in rows if r[1]>0 and r[0]!=int(sys.argv[1]))
    target = max(bots, key=lambda b: bots[b][0]-300*(bots[b][2]==-1))
    print target if random.randint(1,100) > 70 else 'D'
else:
    print 'ok'

업데이트 : 일부 잘못된 출력을 일으키는 버그가 수정되었습니다.


4
354 자? 이것이 무엇입니까, 코드 골프? ;)
Casey Kuball

1
@Darthfett이 : 많은 자바 제출이 근처에있다해서, 모두가 쓰레기 보일러 비슷한 양의 자신의 코드에 필요 의미하지 않는다 ...
counterclockwis을 설정하는 것을 정지

11
권투 선수는 마른 몸입니다-그는 쉽게 싸우는 무게를 만납니다. 그는 이해력과 람다의 건강한 식단을 즐깁니다. 당신은 정적 타이핑 버거를 먹거나 버팀대 튀김을 먹어 치우지 않을 것입니다.
Logic Knight

4
@CarpetPython 간결함을위한 간결함은 장황함만큼 나쁘다.
Kroltan

9

C-서프라이즈 봇

첫 번째 턴이 혼란스럽고 방어한다고 가정합니다. 그 후 마지막 턴을 방어하지 않은 사람을 공격하십시오.

이 답변은 어리석은 일이지만 C로 답변을 작성하기위한 다소 일반적인 플랫폼을 작성하고 싶었습니다.

//What doesn't kill me...
//SurpriseBot

#include "stdio.h"
#include "string.h"
#include "stdlib.h"

int myself;

typedef struct s_Bot {
    int id;
    int life;
    int power;
    /* -1 is defending */
    int lastAction;
} Bot;

int compare_bots(const void* a, const void* b) {
    Bot one = *(Bot*)a;
    Bot two = *(Bot*)b;

    /* Never, ever target myself */
    if (one.id == myself) {
        return 1;
    }
    else if (two.id == myself) {
        return -1;
    }

    /* Also, don't target any bot that is dead */
    if (one.life < 1) {
        return 1;
    }
    else if (two.life < 1) {
        return -1;
    }

    /* Prefer those who did not defend last turn */
    /* They'll never see it coming!              */
    if (one.lastAction >= 0 && two.lastAction < 0) {
        return -1;
    }
    else if (one.lastAction < 0 && two.lastAction >= 0) {
        return 1;
    }

    /* Try to target the lowest health */
    if (one.life < two.life) {
        return -1;
    }
    else if (one.life > two.life) {
        return 1;
    }

    /* Try to target the more powerful bot */
    if (one.power < two.power) {
        return 1;
    }
    else if (one.power > two.power) {
        return -1;
    }
    else return 0;
}

int main(int argc, char** argv) {
    if (argc == 1) {
        printf("ok");
    }

    else {
        int quit = 0;
        myself = atoi(argv[1]);

        /* Populate a list of all bots */
        int num = argc - 2;
        Bot bots[num];

        int i;
        for (i = 0; i < num; i++) {
            char buf[100];
            sscanf(argv[2 + i], "%d,%d,%d,%s", &bots[i].id, &bots[i].life, &bots[i].power, buf);
            switch (buf[0]) {
                case 'X':
                    /* Assume the first turn is a bloodbath and we don't want any part of it */
                    printf("D");
                    quit = 1;
                    break;
                case 'D':
                    bots[i].lastAction = -1;
                    break;
                default:
                    sscanf(buf, "%d", &bots[i].lastAction);
                    break;
            }
            if (quit) {
                goto done;
            }
        }

        qsort(bots, num, sizeof(Bot), compare_bots);

        printf("%d", bots[0].id);
    }

done:
    return 0;
}

9

파이썬 2-프리 코그

Precog는 과거 동작 빈도를 기준으로 다른 사람의 움직임을 예측 한 다음 몇 가지 시뮬레이션을 시도하고 점수를 최대화하는 시뮬레이션을 선택합니다. 특히 신뢰할 수는 없지만 ... ESP는 실제가 아닙니다. :디

import json, sys
from random import choice

#'S'/'W' = attack high/low power (strong/weak)
#'H'/'F'  = attack high/low health (hale/frail)
#'A' = attack defender (armor)
#'R' = attack random (it doesn't know)
#'D' = defend

amin = lambda x: x.index(min(x))
amax = lambda x: x.index(max(x))

def pick(history, ids, action):
    if action == 'D':
        return 'D'
    if action == 'R' or len(history['all'][-1][action]) < 1:
        return choice(ids)
    return choice(history['all'][-1][action])

args = sys.argv
if len(args) == 1:
    print 'ok'
    sys.exit()
me = args[1]

def notme(l):
    tmp = list(l)
    try:
        tmp.remove(me)
    except ValueError:
        pass
    return tuple(tmp)

args = args[2:]
try:
    with open('precog.state') as f:
        history = json.load(f)
except (IOError, ValueError):
    history = {}
if len(history) == 0:
    history = {'all':[]}

args = [a.split(',') for a in args]
ids,hps,pows,acts = zip(*args)
hps,pows = map(int,hps), map(int,pows)

for i,h,p,a in args:
    if a == 'X': #most people will try not to attack armored
        history[i] = {'a':'SWHFRD','health':[],'power':[],'score':[]}
    elif acts == 'D':
        history[i]['a'] += 'D'
    else:
        for x in 'SWHFA':
            if a in history['all'][-1][x]:
                history[i]['a'] += x
                break
        else:
            history[i]['a'] += 'R'
    history[i]['health'] += int(h),
    history[i]['power'] += int(p),
    history[i]['score'] += int(h)*int(p),

history['all'] += {'S':[ids[amax(pows)]],
                   'W':[ids[amin(pows)]],
                   'H':[ids[amax(hps)]],
                   'F':[ids[amin(hps)]],
                   'A':[ids[i] for i in filter(lambda x:acts[x]=='D',range(len(acts)))]},

with open('precog.state','w') as f:
    json.dump(history,f)

scores = dict(zip('SWHFRAD',[0]*7))
for _ in range(50):
    for act in 'SWHFRAD':
        _score = {}
        p,h,a = dict(zip(ids,pows)),dict(zip(ids,hps)),{i:0 for i in ids}
        opp = {i:choice(history[i]['a']) for i in ids if i != me}
        opp[me] = act
        m = {o:[1,2][opp[o]=='D'] for o in opp}
        for o in opp:
            if opp[o] != 'D':
                if o == me:
                    target = pick(history, notme(ids), opp[o])
                else:
                    target = pick(history, ids, opp[o])
                h[target] -= p[o]/m[target]
                a[target] += 1
        for o in opp:
            p[o] += m[o] * a[o]
            _score[o] = p[o] * h[o]
        scores[act] += _score.pop(me) - sum(_score.values())

target = pick(history, notme(ids), scores.keys()[amax(scores.values())])
if target == me:
    target = choice(notme(ids))
print target

2
이 봇은 때때로 이미 죽은 다른 봇을 공격하는 것 같습니다. 그것은 봇이 내 테스트에 포함 된 시간의 50 %로 테스트 봇과의 모든 시간에서 승리했기 때문에 그렇지 않으면 다소 강한 봇입니다.
Potatomato

9

bash-CopyCat

CopyCat은 강력하고 건강하며 공격적인 사람들을 존경하며 그랬던 것처럼 공격합니다. 그녀가 "노출"을 가졌을 때, 대부분의 봇들이 여기에서 공격하고 있다면, 그녀는 더 강해지거나 다른 봇들이 공격을 멈추지 않는 한 자신을 방어하거나 약한 사람들을 공격하기 시작합니다.

간단히 실행하십시오 /bin/bash copycat.sh

#!/bin/bash

if [[ "$1" == "" ]]; then echo "ok"; exit; fi

debug() {
    #echo "$(date): $*" >> copycat.log 
    return;
}

me=$1; shift
meAsTarget=0
myAction="D" #better than an invalid command
topBot=-1
topBotAwe=0
worstBot=-1
worstBotAwe=100
aliveBots=0

myMostWeakAttacker=-1
mmwaAwe=0

if [[ -e "./state/copycat.state" ]]; then
    . ./state/copycat.state
fi

for rawBot 
do
    if [[ "$rawBot" == "" ]]; then continue; fi
    if [[ $(echo $rawBot | grep -Fo ',' | wc -l) -ne 3 ]]; then continue; fi

    bot=(${rawBot//,/ })
    id=${bot[0]}; life=${bot[1]}; power=${bot[2]}; lastAction=${bot[3]}

    printf "%d\n" "$lastAction" > /dev/null 2>&1
    if [[ "$?" -ne 0 && "$lastAction" != "D" ]]; then continue; fi

    if [[ "$life" -le 0 ]]; then continue; fi
    ((aliveBots++))

    awesomeness=$(( 2 * (((life/10) * power) / (life/10 + power)) ))
    if [[ "$id" -eq "$me" ]]; then
        myLastAction="$lastAction"
        myAwe="$awesomeness"
    else
        lastBot=$id
    fi

    if [[ "$awesomeness" -gt "$topBotAwe"
        && "$lastAction" != "D"
        && "$lastAction" != "$me" ]]; then
            topBot=$id
            topBotAwe=$awesomeness
            topBotTarget=$lastAction
    fi

    if [[ "$awesomeness" -lt "$worstBotAwe" ]]; then
        worstBot=$id
        worstBotAwe=$awesomeness
    fi

    if [[ "$lastAction" -eq "$me" ]]; then
        ((meAsTarget++))
        if [[ "$awesomeness" -lt "$mmwaAwe" ]]; then
            myMostWeakAttacker=$id
            mmwaAwe=$awesomeness
        fi
    fi
done

backupStrategy() {
    if [[ "$myMostWeakAttacker" != "-1" && "$mmwaAwe" -lt "$myAwe" ]]; then
        debug "attacking my most weak attacker ($myMostWeakAttacker) who is weaker then me"
        myAction=$myMostWeakAttacker
    elif [[ "$worstBot" != "-1" && "$worstBot" != "$me" ]]; then
        debug "attacking the worst bot $worstBot"
        myAction=$worstBot
    elif [[ "$myMostWeakAttacker" != "-1" ]]; then
        debug "attacking my most weak attacker $myMostWeakAttacker"
        myAction=$myMostWeakAttacker
    else
        debug "no one is attacking me anymore; attacking the last ones"
        myAction=$lastBot
    fi
}

if [[ "$meAsTarget" -gt "$((aliveBots/2))" ]]; then
    #hit-and-run
    if [[ "$myLastAction" == "D" && "$myAwe" -gt "$worstBotAwe" ]]; then
        debug "I am still under fire, but not the worst one.."
        backupStrategy
    else
        debug "I was attacked to much; defending now (attack level: $meAsTarget)"
        myAction="D"
        meAsTarget=$((meAsTarget-aliveBots/2))
    fi
elif [[ "$topBotTarget" != "" ]]; then
    myAction=$topBotTarget

    for rawBot
    do
        if [[ "$rawBot" == "" ]]; then break; fi
        bot=(${rawBot//,/ })
        if [[ "${bot[0]}" -eq "$topBotTarget" ]]; then
            if [[ "${bot[1]}" -le 0 ]]; then
                backupStrategy
            else
                debug "copying strategy from bot $topBot attacking $myAction"
            fi
            break
        fi
    done
else
    backupStrategy
fi

if ! [[ -d "./state" ]]; then mkdir -p "./state"; fi
cat <<EOF_STATE > "./state/copycat.state"
topBotTarget="$topBotTarget"
meAsTarget="$meAsTarget"
EOF_STATE

echo "$myAction"
exit 0

그녀의 약점 : 그녀는 자신이 찾는 것처럼 결코 나아지지 않을 것입니다. :()


8

파이썬 3 디펜 시브 봇

봇은 현재 힘으로 죽일 수있는 가장 높은 힘을 가진 적을 찾으려고합니다. 그렇지 않으면 방어하십시오. 로 실행python DefensiveBot.py id bot1 etc

import sys

def resolve(bots, power, life):
    highPowerCanKill = -1
    highPower = 0
    for i in bots:
        if int(i[1]) < int(power):
            if(int(i[2]) > int(highPower)) and (int(i[1]) > 0):
                highPower = i[2]
                highPowerCanKill = i[0]
    if highPowerCanKill != -1:
        return highPowerCanKill
    else:
        return "D"

args = sys.argv
if len(args) == 1:
    print("ok")
    sys.exit()
fileName = str(__file__).split('\\')
fileName = fileName[len(fileName)-1]
myId = args[1]

bots = []

for i in args:
    i = i.split(',')
    if len(i) == 1:
        continue
    if i[0] == myId:
        power = i[2]
        life = i[1]
        continue
    elif i[0] == fileName:
        continue

    bots.append(i)

kill = resolve(bots, power, life)
print(kill)

이것은 인수없이 올바르게 실행되지 않는 것 같습니다. 봇을 처음 호출하면 인수가 주어지지 않습니다. 로 응답하십시오 ok . 이것은 봇이 응답하도록하기 위해서만 수행됩니다. 그렇지 않으면 플레이어 목록에 추가되지 않습니다.
Geobits

@Geobits가 수정되었습니다.
Elias Benevedes

좋아, 실행되지만 외부 인쇄가 진행 중입니다. 유효한 응답을 제공하기 위해 28 행과 32 행을 주석 처리해야합니다. 그렇지 않으면 그냥 죽습니다.
Geobits

봇을 타겟팅하기 전에 봇이 활성화되어 있는지 확인할 수도 있습니다. 이것은 종종 죽은자를 목표로하며, 무효 한 행동으로 간주되어 힘을 떨어 뜨립니다.
Geobits

한숨을 쉬었다 . 나는 이것이 마지막 수정이 아니라고 생각합니다. P
Elias Benevedes

8

자바 탱크

탱크는 생각하지 않고, 신경 쓰지 않고, 그가 본 첫 번째 로봇을 공격합니다! 그러나 그는 자신이나 죽은 사람을 공격하지 않을 정도로 똑똑합니다.

public class Tank{
    public static void main (String[] args){
        if(args.length == 0){
            System.out.print("ok");
            System.exit(0);
        }

        String myId = args[0];
        int life = Integer.MIN_VALUE;
        String[] tokens = {};
        String opposingId = "";

        for(int i=1; i<args.length; i++){
            tokens = args[i].split(",");
            opposingId = tokens[0];
            life = Integer.parseInt(tokens[1]);
            if(life > 0 && !opposingId.equals(myId)){
                System.out.println(opposingId);
                System.exit(0);
            }
        }
        System.out.println("D");
    }
}

1
다른 봇에서 언급했듯이, 이것은 그대로 컴파일되지 않습니다.
Geobits

8

자바-팬텀 위협

안녕하세요! 이것이 Code Golf의 첫 번째 게시물입니다. 나는 C # 녀석이므로 프랑스어를 용서하십시오. Hero 및 Coward 샘플 코드의 일부를 사용했습니다.

내 봇은 정치적인 태도를 가진 단순한 사람입니다. 대부분의 경우 그는 로비에서 커피를 마시고 계획을 준비하면서 자신을 숨 깁니다. 그러나 기회가 생기고 이익의 전망이 충분히 강해지면 편안한 안락 의자에서 뛰어 내려 신문을 버리고 돈을 간다.

그는 그에게 해를 끼친 후에 자신을 변호합니다. 그렇지 않으면 그는 진정한 영웅처럼 행동합니다 (그것은 또한 매우 안전하기 때문에 정치적 결정입니다). 경쟁자가 3 명일 때 승리합니다.

그는 몇 가지 기본 원칙을 따릅니다. 모든 심각한 정치인은 깨지지 않는 원칙과 명확하게 정의 된 프로필을 가져야합니다 ...

자신 외에는 다른 사람을 도와주지 마십시오! (자아)

영광은 죽음을 의미합니다! (회의론자)

당신이 죽은 후에는 아무것도 없습니다! (무신론자)

public class PhantomMenace {
    public static void main(String[] args) {
        if(args.length < 1)
        {
            System.out.print("ok");
            System.exit(0);
        }

           String me = args[0], target="D", secondTarget="D", worstTarget="D";
           int best=0;
           int attackerCount = 0;
           int numBots= 0;
           int secondBest=0;
           int worst=0;

        for(int i=1;i<args.length;i++)
        {
            String[] tokens = args[i].split(",");
            int life = Integer.valueOf(tokens[1]);
            if(life > 0 && life >= best)
            {
                secondBest = best;
                secondTarget = target;
                best = life;
                target = tokens[0];

            }
            else if(life > 0 && life >= secondBest)
            {
                secondBest= life;
                secondTarget = tokens[0];
            }

            if(life > 0 && life <= best)
            {
            worst = life;
            worstTarget = tokens[0];
            }
            // count incoming attacks
            if(tokens[3].equals(me))
            attackerCount++;
            // count living bots
            if(life>0)
            numBots++;
        }

        // activate offensive regime?!
        if(numBots<5)
        {
            if(target.equals(me))
              System.out.print(secondTarget);
            else
              System.out.print(target);
        }
        else
        {
          if(worstTarget.equals(me))
            System.out.print("D");
          if(target.equals(me))
            System.out.print("D");
          else if(attackerCount>0)
            System.out.print("D");
          else
            System.out.print(target);
        }

    }
}

1
아주 좋고 현재 2 위입니다. 사이트에 오신 것을 환영합니다 :)
Geobits

오, 고마워, 그것은 놀랍지 만 나는 내 로봇을 믿는 것을 멈추지 않았다는 것을 인정해야한다 : P.
Stormcrow

7

알아요-Java

모든 적을 분석하고이 정보를 사용하여 방어력을 향상시킵니다. 불행히도, 공격을하는 경향이 있습니다.

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


public class IKnowYou {
    final static int LINES = 40;
    Bot me;
    final List<Bot> bots = new ArrayList<>();
    final List<Bot> livingEnemies = new ArrayList<>();
    final File file = new File("state/IKnowYou");
    final long lineCount;

    public static void main(String[] args) {
        if(args.length < 1){
            System.out.print("ok");
            System.exit(0);
        }
        new IKnowYou(args).run();
    }

    public IKnowYou(String[] args) {
        for (int i = 1; i < args.length; i++) {
            Bot bot = new Bot(args[i], args[0]);
            bots.add(bot);
            if (bot.isMe) {
                me = bot;
            } else if (bot.life > 0) {
                livingEnemies.add(bot);
            }
        }
        lineCount = lineCount();
    }

    void run() {
        if (me.lastAction.equals("X")) {
            createFile();
            updateFile();
            System.out.println(livingEnemies.get(0).id);
            System.exit(0);
        }
        if (lineCount % LINES != 0) {
            updateFile();
        }
        if (underAttack()) {
            System.out.println("D");            
        } else {
            for (Bot bot : livingEnemies) {
                if (bot.lastAction.equals(me.id)){
                    System.out.println(bot.id);
                    return;
                }
            }
            int maxP = 0;
            Bot maxPowerBot = null;
            for (Bot bot : livingEnemies) {
                if (bot.power > maxP){
                    maxP = bot.power;
                    maxPowerBot = bot;
                }
            }
            System.out.println(maxPowerBot.id);
        }
    }

    void createFile() {
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {}
        }
    }

    void updateFile() {
        List<Bot> oldBots = new ArrayList<>();
        if (me.lastAction.equals("X")) {
            for (Bot bot : bots) {
                Bot copyBot = bot.copy();
                bot.life = 1000;
                bot.power = 10;
                oldBots.add(copyBot);
            }
        } else {
            String oldState = "";
            try (BufferedReader input = new BufferedReader(new FileReader(file))) {
                String line;
                while ((line = input.readLine()) != null && !line.equals("\n")) {
                    oldState = line;
                }
            } catch (Exception e) {}
            String[] parts = oldState.split(" ");
            for (int i = 0; i < parts.length; i++) {
                oldBots.add(new Bot(parts[i]));
            }
        }
        List<List<String>> ids = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            ids.add(new ArrayList<String>());
        }
        int maxL = -1, minL = 1001, maxP = 0;
        for (Bot bot : oldBots) {
            if (bot.life > maxL) {
                ids.get(0).clear();
                maxL = bot.life;
                ids.get(0).add(bot.id);
            } else if (bot.life == maxL) {
                ids.get(0).add(bot.id);
            }
            if (bot.life < minL) {
                ids.get(1).clear();
                minL = bot.life;
                ids.get(1).add(bot.id);
            } else if (bot.life == minL) {
                ids.get(1).add(bot.id);
            }
            if (bot.power > maxP) {
                ids.get(2).clear();
                maxP = bot.power;
                ids.get(2).add(bot.id);
            } else if (bot.power == maxP) {
                ids.get(2).add(bot.id);
            }
        }
        StringBuilder[] output = new StringBuilder[3];
        for (int i = 0; i < 3; i++) {
            output[i] = new StringBuilder();
        }
        output[0].append("maxL");
        output[1].append("minL");
        output[2].append("maxP");
        for (Bot bot : bots) {
            if (bot.isMe) 
                continue;
            for (int i = 0; i < 3; i++) {
                if (ids.get(i).contains(bot.lastAction)) {
                    output[i].append(' ').append(bot.id);
                }
            }
        }
        try(FileWriter wr = new FileWriter(file, true)) {
            for (int i = 0; i < 3; i++) {
                output[i].append('\n');
                wr.append(output[i].toString());
            }
            StringBuilder sb = new StringBuilder();
            for (Bot bot : bots) {
                sb.append(bot.id).append(',').append(bot.life).append(',').append(bot.power).append(' ');
            }
            wr.append(sb.toString().trim() + "\n");
        } catch (IOException e) {}
    }

    boolean underAttack() {
        Bot attacker = null;
        for (Bot bot : bots) {
            if (bot.lastAction.equals(me.id)) {
                if (attacker != null) {
                    return true;
                } else {
                    attacker = bot;
                }
            }
        }

        int maxL = 0, minL = 1001, maxP = 0;
        for (Bot bot : bots) {
            if (bot.life > maxL)
                maxL = bot.life;
            if (bot.life < minL)
                minL = bot.life;
            if (bot.power > maxP)
                maxP = bot.power;
        }
        if ((me.life < maxL && me.life > minL && me.power < maxP) || livingEnemies.size() == 1) {
            return false;
        }
        List<Map<String, Integer>> stats = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            stats.add(new HashMap<String, Integer>());
        }
        for (Bot bot : bots) {
            for (int i = 0; i < 3; i++) {
                stats.get(i).put(bot.id, 0);
            }
        }
        try (BufferedReader input = new BufferedReader(new FileReader(file))) {
            String line;
            while ((line = input.readLine()) != null) {
                if (line.startsWith("m")) {
                    int map = line.startsWith("maxL") ? 0 : line.startsWith("minL") ? 1 : 2;
                    String[] parts = line.split(" ");
                    for (int i = 1; i < parts.length; i++) {
                        int count = stats.get(map).get(parts[i]);
                        stats.get(map).put(parts[i], count+1);
                    }
                }
            }
        } catch (Exception e) {}
        for (int i = 0; i < 3; i++) {
            if ((me.life == maxL && i == 0) || (me.life == minL && i == 1) || (me.power == maxP && i == 2)) {
                for (String id : stats.get(i).keySet()) {
                    int count = stats.get(i).get(id);
                    if (count / ((float)lineCount / 4) > 0.65) {
                        for (Bot bot : bots) {
                            if (bot.id.equals(id)) {
                                if (bot.life > 0) {
                                    return true;
                                } else {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
        return false;
    }

    long lineCount() {      
        try (LineNumberReader  lnr = new LineNumberReader(new FileReader(file))) {
            lnr.skip(Long.MAX_VALUE);
            return lnr.getLineNumber();
        } catch (IOException e) {
            return 0;
        }
    }

    class Bot {
        String id, lastAction;
        int life, power;
        boolean isMe;

        public Bot() {}

        public Bot(String bot, String myId) {
            String[] parts = bot.split(",");
            id = parts[0];
            life = Integer.valueOf(parts[1]);
            power = Integer.valueOf(parts[2]);
            lastAction = parts[3];
            isMe = id.equals(myId);
        }

        public Bot(String oldBot) {
            String[] parts = oldBot.split(",");
            id = parts[0];
            life = Integer.valueOf(parts[1]);
            power = Integer.valueOf(parts[2]);
        }

        Bot copy() {
            Bot bot = new Bot();
            bot.id = id;
            bot.lastAction = lastAction;
            bot.life = life;
            bot.power = power;
            bot.isMe = isMe;
            return bot;
        }
    }
}

7

자바-벨로시 랩터

Velociraptor는 악의적 인 킬러입니다. 그녀는 잠재적 인 먹이를 관찰하면서 공격을받을 때까지 기다립니다. 그녀는 빠른 살인을하면서 가장 빠르게 살해 할 수있는 목표물을 제거합니다. 그녀의 공격을 시작한 후에 랩터는 두려움을 알지 못하고 그녀가 유일한 생존자가 될 때까지 피해자를 계속 데리고 갈 것입니다.

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class Velociraptor {

    public static void main(String[] args) {
        if (args.length < 1) {
            System.out.print("ok");
            System.exit(0);
        }
        Velociraptor raptor = new Velociraptor(args);
        System.out.print(raptor.determineVictim());
    }

    private final String observationsFilePath = "state/velociraptor.txt";
    private final File observationsFile = new File(observationsFilePath);

    private int id, life, power, round;
    private List<Bot> preyList;
    private Map<Integer, Integer> preyDefendCounts;

    public Velociraptor(String[] preyStates) {
        loadObservations();
        observePrey(preyStates);
        saveObservations();
    }

    private void observePrey(String[] preyStates) {
        this.id = Integer.valueOf(preyStates[0]);
        preyList = new ArrayList<>();
        for (int i = 1; i < preyStates.length; i++) {
            String[] tokens = preyStates[i].split(",");
            int preyId = Integer.valueOf(tokens[0]);
            int preyLife = Integer.valueOf(tokens[1]);
            int preyPower = Integer.valueOf(tokens[2]);
            String lastAction = tokens[3];

            if (preyId == this.id) {
                this.life = preyLife;
                this.power = preyPower;
            } else if (preyLife > 0) {
                Bot prey = new Bot();
                prey.id = preyId;
                prey.life = preyLife;
                prey.power = preyPower;
                prey.lastAction = lastAction;
                preyList.add(prey);
                //Clever girl!
                if (prey.lastAction.equals("D")) {
                    int preyDefendCount = preyDefendCounts.getOrDefault(prey.id, 0);
                    preyDefendCount++;
                    preyDefendCounts.put(prey.id, preyDefendCount);
                }
            }
        }
    }

    public String determineVictim() {
        if (this.life == 1000) { //lay in wait until attacked
            return "D";
        }
        double fastestKill = 1000; //max game rounds
        Bot victim = null;
        for (Bot prey : preyList) {
            int preyDefendCount = preyDefendCounts.getOrDefault(prey.id, 0);
            double effectiveMultiplier = 1 - (.5 * preyDefendCount / round);
            double turnsToKill = prey.life / (this.power * effectiveMultiplier);
            //target whoever can be killed fastest
            //in case of tie, kill the prey with more power first
            if (turnsToKill < fastestKill || (victim != null && turnsToKill == fastestKill && prey.power > victim.power)) {
                fastestKill = turnsToKill;
                victim = prey;
            }
        }
        return String.valueOf(victim.id);
    }

    private void loadObservations() {
        preyDefendCounts = new HashMap<>();
        if (observationsFile.exists()) {
            try (Scanner scanner = new Scanner(observationsFile)) {
                round = Integer.valueOf(scanner.nextLine());
                while (scanner.hasNext()) {
                    String line = scanner.nextLine();
                    String[] tokens = line.split(",");
                    int preyId = Integer.valueOf(tokens[0]);
                    int preyDefendCount = Integer.valueOf(tokens[1]);
                    preyDefendCounts.put(preyId, preyDefendCount);
                }

            } catch (FileNotFoundException ex) {
                System.out.println(ex.getMessage());
            }
        }
        round++;
    }

    private void saveObservations() {
        if (!observationsFile.exists()) {
            try {
                observationsFile.createNewFile();
            } catch (IOException ex) {
                System.out.println(ex.getMessage());
            }
        }
        try (PrintWriter writer = new PrintWriter(observationsFile)) {
            writer.println(round);
            if (preyDefendCounts != null) {
                preyDefendCounts.entrySet().stream().forEach(entry -> writer.println(entry.getKey() + "," + entry.getValue()));
            }
        } catch (FileNotFoundException ex) {
            System.out.println(ex.getMessage());
        }
    }

    private class Bot {

        public int id, life, power;
        public String lastAction;
    }
}

7

파이썬 3-세미 랜덤

공격 및 방어 후 이전의 강점 변경에 따른 가중치를 기반으로 공격과 방어 중에서 선택합니다. 공격을 선택하면 가장 강한 플레이어를 공격합니다. 강도는로 정의됩니다 life * power.

3 개의 예제 봇에 대해서는 거의 이길 수 없습니다. 아마 야생에서 ...

import sys, random

def get_goodness(r,d):
    if len(d)==0:
        return 0
    return sum(v/(r-k+5) for k,v in d.items())/sum(1/(r-k+5) for k,v in d.items())

def get_att_chance(r,ad,dd,b):
    ag=get_goodness(r,ad)+500+p/2/len(b)
    dg=get_goodness(r,dd)+500    
    return ag/(ag+dg)

args=sys.argv
if len(args)==1:
    print("ok")
    with open('state/semirandom.txt','w') as f:
        f.write('-1\n1000\n10\n{}\n{}\n"S"\n')
    sys.exit()
me=int(args[1])
b=[]
for ae in args[2:]:
    if ae[-1] in 'DX':    
        ae=ae[:-1]+'-1'
    ae=ae.split(',')
    if int(ae[0])!=me:
        b+=[[int(ae[i]) for i in range(4)]]
    else:
        l,p=int(ae[1]),int(ae[2])
with open('state/semirandom.txt','r') as f:
    data=f.read()
co,lo,po,ad,dd,h=map(eval,data.split('\n')[:-1])
r=len(ad)+len(dd)
vc=l*p-lo*po
if co==0:
    ad[r]=vc
if co==1:
    dd[r]=vc   
ll=sum([be[1] for be in b])
em=ll/p/len(b)/(1000-r)*2
target_id=max(b,key=lambda be:be[1]*be[2])[0]
if random.random()<em:
    action=0
else:
    if random.random()<get_att_chance(r,ad,dd,b):
        action=0
    else:
        action=1        
if action==0:
    act=str(target_id)
else:
    act='D'
with open('state/semirandom.txt','w') as f:
    f.write('{}\n{}\n{}\n{}\n{}\n"{}"\n'.format(action,l,p,ad,dd,h+act))        
print(act)

7

자바-로마 거북이

Roman Tortoise는 근처에있는 사람을 공격하지만, 겁쟁이가 아니기 때문에 무작위로 다른 봇을 공격하기로 결정합니다. 때때로 (50 분의 1) 용서가 나타납니다.

import java.util.NoSuchElementException;
import java.util.Random;

public class RomanTortoise {

    public static void main(String[] args) {
        Random r = new Random();
        if(args.length < 1){
            System.out.print("ok");
            System.exit(0);
        }
        try{
            String me = args[0];
            try{
            if(args[1].split(",")[3].equals("X"))
            {
                 System.out.print("D");
                 System.exit(0);
            }
            }
            catch(NoSuchElementException nse)
            {

            }
            for(int i = 1; i<args.length; i++)
            {
                try{
                    String[] tokens = args[i].split(",");
                    if(tokens.length>3)
                    {
                        String lastAction = tokens[3];

                        if(lastAction.equals(me) && (Integer.parseInt(tokens[1])>0))
                        {
                            //probably attack that bot
                            if(r.nextInt()%50 != 0)
                            {
                                System.out.print(tokens[0]);
                                System.exit(0);
                            }
                        }
                    }
                }
                catch(NoSuchElementException nse)
                {

                }
            }
            if(r.nextInt()%2 == 0)
            {
                for(int i = 0; i<100; i++)
                {
                    try{
                        int j = (r.nextInt() % (args.length-1)) + 1;
                        String[] tokens = args[j].split(",");
                        if(tokens.length>3)
                        {
                            if(Integer.valueOf(tokens[1])>0)
                            {
                                System.out.print(tokens[0]);
                                System.exit(0);
                            }
                        }
                    }
                    catch(NoSuchElementException nse)
                    {

                    }
                }
            }
        }
        catch(Exception e){}
        System.out.print("D");
        System.exit(0);
    }

}

블록에 NoSuchElementException던져지지 않은 것처럼 보일 때 특별한 이유 가 try있습니까? 아니면 뭔가 빠졌습니까?
TNT

@TNT는 더 이상 없습니다. 배열의 요소 중 하나에 액세스 할 때 때때로 예외가 발생했습니다. 내 버그를 수정하지만, 단지에서 시도 캐치를 왼쪽 - 죄송합니다보다 안전 :
euanjt

7

자바-BroBot

BroBot은 점진적으로 작은 값보다 큰 공격을 가한 적이 BroBot을 공격하기로 결정하지 않는 한 가장 강력한 상대를 공격합니다.

public class BroBot {
    public static void main(String[] args) {
        if (args.length == 0) {
            System.out.println("ok");
            return;
        }

        int health = 0, id = Integer.parseInt(args[0]);
        for (int k = 1; k < args.length; k++) {
            if (Integer.parseInt(args[k].split(",")[0]) == id) {
                health = Integer.parseInt(args[k].split(",")[1]);
                break;
            }
        }

        String action = "";
        for (String s : args) {
            if (!s.contains(",")) continue;
            String[] botInfo = s.split(",");
            int botId = Integer.parseInt(botInfo[0]);
            if (botId == id) continue;
            if (!botInfo[3].equals("D")) {
                try {
                    if (Integer.parseInt(botInfo[3]) == id && Integer.parseInt(botInfo[2]) >= health / 4) {
                        action = "D";
                        break;
                    }
                } catch (NumberFormatException ex) {
                    continue;
                }
            }
        }

        if (action.isEmpty()) {
            int max = 0;
            for (String s : args) {
                if (!s.contains(",")) continue;
                String[] botInfo = s.split(",");
                if (Integer.parseInt(botInfo[0]) == id ||
                    Integer.parseInt(botInfo[1]) <= 0) continue;
                int attack = Integer.parseInt(botInfo[2]);
                if (attack > max) {
                    attack = max;
                    action = botInfo[0];
                }
            }
        }
        System.out.println(action);
    }
}

자바-SisBot

언니가없는 형제는 무엇입니까? 많은 것들 ...하지만 요점 옆에 있습니다. 더 똑똑한 봇이기 때문에 SisBot은 각 봇의 마지막 동작을 저장하고 현재 및 마지막 동작을 분석하며 움직입니다. 그녀의 건강과 힘이 충분히 높으면 특정 수치 이상의 파워 스탯을 가진 다른 봇은 그녀를 공격하기로 결정하지 않습니다. 이 경우 공격과 방어 사이를 전환하거나 공격자의 힘이 실제로 높으면 바로 방어 할 수 있습니다.

import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

public class SisBot {
    private static final Path directoryPath = Paths.get("state");
    private static final Path filePath = Paths.get("state" + java.io.File.separator + "SisBot.txt");
    private List<Bot> botList;
    private List<String> fileContents;
    private int id, health, power, turn;

    public SisBot(String[] args) throws IOException {
        if (args.length == 0) {
            createSaveFile();
            System.out.println("ok");
            System.exit(0);
        }
        fileContents = Files.readAllLines(filePath, Charset.defaultCharset());
        for (int k = 1; k < args.length; k++) {
            if (args[k].split(",")[3].equals("X")) {
                Files.write(filePath, "".getBytes());
                fileContents.clear();
                break;
            }
        }
        getBots(args);
        makeMove();
        writeBots();
    }

    private void createSaveFile() throws IOException {
        if (!Files.exists(filePath)) {
            if (!Files.exists(directoryPath))
                Files.createDirectory(directoryPath);
            Files.createFile(filePath);
        }
        else
            Files.write(filePath, "".getBytes());
    }

    private void getBots(String[] args) {
        id = Integer.parseInt(args[0]);
        botList = new ArrayList<Bot>();
        for (int k = 1; k < args.length; k++) {
            String[] botInfo = args[k].split(",");
            if (Integer.parseInt(botInfo[0]) != id && Integer.parseInt(botInfo[1]) > 0)
                botList.add(new Bot(args[k]));
            else if (Integer.parseInt(botInfo[0]) == id) {
                health = Integer.parseInt(botInfo[1]);
                power = Integer.parseInt(botInfo[2]);
            }
        }
    }

    private void makeMove() throws IOException {
        if (fileContents.isEmpty()) {
            System.out.println(botList.get((int)(Math.random()*botList.size())).getId());
            return;
        }
        getLastAction();
        String action = "";
        int maxHealth = 0, maxPower = 0;
        for (Bot b : botList) {
            if (power >= 40 && health >= 250) {
                if (b.getPower() > maxPower && (!b.getAction().equals("D") || botList.size() == 1)) {
                    maxPower = b.getPower();
                    action = String.valueOf(b.getId());
                }
            }
            else if (b.getAction().equals(String.valueOf(id)) && b.getLastAction() != null && b.getLastAction().equals(String.valueOf(id))) {
                System.out.println(health % 2 == 0 ? b.getId() : "D");
                return;
            }
            else if (b.getAction().equals(String.valueOf(id)) && b.getPower() > 50) {
                System.out.println("D");
                return;
            }
            else {
                if (b.getHealth() > maxHealth) {
                    maxHealth = b.getHealth();
                    action = String.valueOf(b.getId());
                }
            }
        }
        System.out.println(action);
    }

    private void getLastAction() {
        boolean endNext = false;
        for (String s : fileContents) {
            if (s.startsWith("Turn")) {
                turn = Integer.parseInt(s.split(" ")[1]);
                if (endNext)
                    break;
                else {
                    endNext = true;
                    continue;
                }
            }
            if (s.isEmpty()) break;
            String[] botInfo = s.split(",");
            for (Bot b : botList) {
                if (b.getId() == Integer.parseInt(botInfo[0]))
                    b.setLastAction(botInfo[4]);
            }
        }
    }

    private void writeBots() throws IOException {
        StringBuilder sb = new StringBuilder();
        String s = System.lineSeparator();
        sb.append("Turn " + ++turn + s);
        for (Bot b : botList) {
            b.setLastAction(b.getAction());
            sb.append(b.toString() + s);
        }
        sb.append(s);
        for (String str : fileContents)
            sb.append(str + s);
        Files.write(filePath, sb.toString().getBytes());
    }

    public static void main(String[] args) throws IOException {
        new SisBot(args);
    }

    private class Bot {
        private int id, health, power;
        private String action, lastAction;

        public Bot(String info) {
            String[] botInfo = info.split(",");
            id = Integer.parseInt(botInfo[0]);
            health = Integer.parseInt(botInfo[1]);
            power = Integer.parseInt(botInfo[2]);
            action = botInfo[3];
        }

        public int getId() {
            return id;
        }

        public int getHealth() {
            return health;
        }

        public int getPower() {
            return power;
        }

        public String getAction() {
            return action;
        }

        public void setLastAction(String lastAction) {
            this.lastAction = lastAction;
        }

        public String getLastAction() {
            return lastAction;
        }

        @Override
        public String toString() {
            return new StringBuilder()
                    .append(id).append(",")
                    .append(health).append(",")
                    .append(power).append(",")
                    .append(action).append(",")
                    .append(lastAction).toString();
        }
    }
}

나는 정말로 다른 언어를 배워야합니다 ... : P


선택한 대상이 이미 죽었는지 확인해야합니다.
랄프 마샬

나는 이미 그것을 가지고 있다고 생각했지만 ... 다시 여기에 게시하기 전에 다른 전략을 만들었습니다. 찾아 주셔서 감사합니다.
TNT

6

자바 이퀄라이저

방어는 분명히 가장 효과적인 전략 (: P)이지만,이 사람은 거인을 넘어 설 때까지 사람들을 머리 위로 튕기는 것이 재미있을 것 같다고 생각합니다. 그러나 항상 방어하는 사람들을 조이십시오. 그들은이 사람에게서 힘을 얻지 못합니다.

public class Equaliser {
    public static void main (String[] args) {
        if (args.length == 0) {
            System.out.print("ok");
            System.exit(0);
        }

        String myId = args[0];
        String[] tokens;
        int life, power;
        int lowestPower = Integer.MAX_VALUE;
        String lowest = "";
        int lowestLife = 1000;
        int myLife = 0;

        for (int i=1; i<args.length; i++) {
            tokens = args[i].split(",");
            life = Integer.parseInt(tokens[1]);
            power = Integer.parseInt(tokens[2]);
            if (!tokens[0].equals(myId)) {
                if (life > 0 && power < lowestPower && !tokens[3].equals("D")) {
                    lowest = tokens[0];
                    lowestPower = power;
                }
                lowestLife = Math.min(life, lowestLife);
            } else {
                myLife = life;
            }
        }

        if (myLife < lowestLife*5/4) {
            // IT'S TIME TO DEFEND!
            System.out.println("D");
        } else if (lowestPower != Integer.MAX_VALUE) {
            System.out.println(lowest);
        } else {
            // Them buffed up perma-defenders don't need no power
            System.out.println("D");
            // And if you can't beat 'em, join 'em
        }
    }
}

6

Java-Wiisniper-리플렉스 에이전트

간단한 휴리스틱을 사용하여 가장 위험한 봇을 식별 한 다음 공격하는 간단한 반사 에이전트.

public class Wiisniper {
    public static void main(String[] args) {
        if(args.length < 1){
            System.out.print("ok");
            System.exit(0);
        }
        String me = args[0], target="D";
        double bestRatio = Integer.MIN_VALUE;

        String[] tokens = args[Integer.valueOf(me)].split(",");
        double myLife = Integer.valueOf(tokens[1]);
        double myPower = Integer.valueOf(tokens[2]);

        for(int i=1;i<args.length;i++){
            tokens = args[i].split(",");
            double life = Integer.valueOf(tokens[1]);
            double power = Integer.valueOf(tokens[2]);
            double ratio = myLife/power - life/myPower;
            if(tokens[3].equals(me)) //attacks my bot
                ratio = ratio * 5;
            if(life > 0 && power > 0 && !tokens[0].equals(me) && myPower > 0 && ratio > bestRatio){
                bestRatio = ratio;
                target = tokens[0];
            }
        }
        System.out.print(target);
    }
}

6

자바-평균 이상

자신의 통계를 상위 사 분위수로 유지하려고합니다. 적의 행동을 예측하기 위해 예측 기술을 사용합니다.

import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

public class AboveAverage {

    private static final String FILE_NAME = "state" + File.separator + "AboveAverage";

    private File file = new File(FILE_NAME);
    private List<Bot> bots = new ArrayList<>();
    private Bot me;
    private List<List<Bot>> history = new ArrayList<>();
    private String[] args;

    public AboveAverage(String[] args) {
        this.args = args;
        this.bots = readBotArray(args);
        bots.stream().filter(bot -> bot.isMe).forEach(bot -> me = bot); //Intellij told me to do this...
        if (!file.exists()){
            try {
                file.getParentFile().mkdirs();
                file.createNewFile();
            } catch (IOException ignored) {}
        }
        readHistory();
        updateFile();
    }

    private List<Bot> readBotArray(String[] args){ //First parameter is my id.
        List<Bot> bots = new ArrayList<>();
        String myId = args[0];
        for (String arg : args) {
            if (arg.equals(myId)) {    // `==` not `.equals()`
                continue;
            }
            Bot bot = new Bot(arg, myId);
            bots.add(bot);
        }
        bots.sort(Comparator.comparingDouble((Bot a) -> a.life).reversed());
        return bots;
    }

    private void updateFile() {
        PrintStream out;
        try {
            out = new PrintStream(new FileOutputStream(file, true), true);
            for (String s : args){
                if (!s.matches("\\d+|\\d+,-?\\d+,\\d+,(\\d+|D)")){
                    s.replaceAll("(\\d+,-?\\d+,\\d+,).*", "$1Invalid");
                }
                out.print(s + " ");
            }
            out.println();
        } catch (FileNotFoundException ignored) {}
    }

    private void readHistory() {
        try {
            Scanner scanner = new Scanner(file);
            while (scanner.hasNextLine()){
                String line = scanner.nextLine().trim();
                if (line.length() > 0) {
                    history.add(readBotArray(line.split("\\s+")));
                }
            }
        } catch (FileNotFoundException ignored) {}
    }

    public static void main(String[] args) throws FileNotFoundException {
        if(args.length < 1){
            System.out.print("ok");
            System.exit(0);
        }
        try {
            System.out.print(new AboveAverage(args).normalize());
        } catch (Exception e){
            Writer writer = new StringWriter();
            PrintWriter printWriter = new PrintWriter(writer);
            e.printStackTrace(printWriter);
            String s = writer.toString();
            System.out.print("error: " + s.replace("\n", " | "));
        }
    }

    String normalize() {
        if (history.size() == 0 || me.lastAction.equals("X")){
            return "D";
        }

        if (bots.stream().mapToInt(bot -> (bot.life + me.power - 1)/me.power).sum() < me.life/bots.stream().mapToInt(bot -> bot.power).sum()){
            return bots.stream().max(Comparator.comparingInt(a->a.power)).get().id;
        }

        List<Bot> bestHistory = history.stream().max((a,b) -> {
            int differenceA = 0;
            int differenceB = 0;
            for (int i = 0; i < a.size(); i++){
                if (!a.get(i).equals(bots.get(i))){
                    differenceA++;
                }
                if (!b.get(i).equals(bots.get(i))){
                    differenceB++;
                }
            }
            if (differenceA != differenceB){
                return differenceA - differenceB;
            }
            for (int i = 0; i < a.size(); i++){
                differenceA += Math.abs(bots.get(i).life - a.get(i).life) + Math.abs(bots.get(i).power - a.get(i).power) * 10;
                differenceB += Math.abs(bots.get(i).life - b.get(i).life) + Math.abs(bots.get(i).power - b.get(i).power) * 10;
            }
            return differenceA - differenceB;
        }).get();


        int i = history.indexOf(bestHistory) + 1;
        List<Bot> after = i == history.size() ? bots : history.get(i);

        Map<Bot, String> actions = new HashMap<>();
        for (Bot bot : bots){
            if (bot.equals(me)){
                continue;
            }
            after.stream().filter(future -> future.equals(bot)).forEach(future -> actions.put(bot, future.lastAction));
        }

        List<String> myActions = new ArrayList<>();
        myActions.add("D");
        myActions.add("InvalidChoice");
        myActions.addAll(bots.stream().map(bot -> bot.id).collect(Collectors.toList()));

        Map<String,List<Bot>> scenarios = new HashMap<>();
        for (String action : myActions){
            List<Bot> simulatedBots = bots.stream().map(Bot::copy).collect(Collectors.toList());  //IntelliJ told me to (kind of) golf these lines.
            actions.put(me, action);
            simulatedBots.stream().filter(bot -> actions.get(bot).equals("D")).forEach(Bot::defend);
            simulatedBots.stream().filter(bot -> !actions.get(bot).equals("D")).forEach(bot -> bot.attack(actions.get(bot), simulatedBots));
            scenarios.put(action, simulatedBots);
        }

        return scenarios.keySet().stream().min(Comparator.comparingInt((String action) -> {
            List<Bot> scenario = scenarios.get(action);
            Bot me = scenario.stream().filter(a->a.isMe).findAny().get();
            scenario.removeIf(a->a.life<1||a.equals(me));
            scenario.sort(Comparator.comparingInt(a->a.life));
            int bestLife = scenario.get(scenario.size() * 3 / 4).life;
            scenario.sort(Comparator.comparingInt(a->a.power));
            int bestPower = scenario.get(scenario.size() * 3 / 4).power;
            scenario.add(me);
            return Math.abs(me.power - bestPower)*20 + Math.abs(me.life - bestLife);
        })).get();
    }

    class Bot {
        String id, lastAction;
        int life, power;
        boolean isMe;
        boolean isDefending = false;

        public Bot() {}

        public Bot(String bot, String myId) {
            String[] parts = bot.split(",");
            id = parts[0];
            life = Integer.valueOf(parts[1]);
            power = Integer.valueOf(parts[2]);
            lastAction = parts[3];
            isMe = id.equals(myId);
        }

        Bot copy() {
            Bot bot = new Bot();
            bot.id = id;
            bot.lastAction = lastAction;
            bot.life = life;
            bot.power = power;
            bot.isMe = isMe;
            return bot;
        }

        void defend(){
            this.isDefending = true;
            this.power--;
        }

        void attack(int power){
            if (isDefending) {
                this.power += 2;
                this.life -= power / 2;
            } else {
                this.power++;
                this.life -= power;
            }
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Bot bot = (Bot) o;

            return id.equals(bot.id);

        }

        @Override
        public int hashCode() {
            return id.hashCode();
        }

        void attack(String attackId, List<Bot> bots) {
            if (life < 1){
                return;
            }
            Bot attacked = bots.stream().filter((Bot a) -> a.id.equals(attackId)).findFirst().orElse(null);
            if (attacked == null){
                power--;
                return;
            }
            if (attacked.life < 1){
                power--;
                return;
            }
            attacked.attack(power);
        }
    }
}

사용 state/whatever하지 않는 것으로 가정합니다 status. 또한 IndexOutOfBounds첫 차례 를 제외하고 는 보인다 .
OJFord

5

자바-젖꼭지

첫 번째 제출! \ o / 거대한 데이터 절약을 사용하고 패턴을 찾기 위해이 콘테스트의 봇에서 작업하고있었습니다. 기본적으로, 자신의 손해가 너무 낮아서 유용한 일을하기에는 너무 어렵다고 생각하면 자신을 보호 할 것입니다. 그렇지 않으면, 그는 더 위협적인 상대를 공격 할 것이며, 이는 상대를 죽이는 데 필요한 적중 횟수에 의해 결정되며, 이는 피해량입니다. 시도해 볼 수는 없지만 그는 좋은 일을 할 수 있다고 생각합니다!

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Pacifier
{
    private static final File DATA_FILE = new File("state"+File.separator+"Pacifier.whatever");
    public static void main(String[] args)
    {

        if(args.length==0)
        {

            if(DATA_FILE.exists())
            {
                try {
                    DATA_FILE.delete();
                } catch (Exception e) {System.out.println("D");System.exit(0);}
            }
            try{
                DATA_FILE.createNewFile();
            }catch (IOException e) {}
            System.out.println("ok");
            System.exit(0);
        }

        int ownId=0,ownHp=1,ownAt=1;
        String known = null;
        BufferedReader bf = null;

        try{
            bf=new BufferedReader(new FileReader(DATA_FILE));
            known=bf.readLine();
        }catch(Exception e){System.out.println("D");System.exit(0);}

        boolean firstTurn = known==null;
        String[] mk = null,iniData=null;
        if(!firstTurn)
        {       
            mk = known.split(" ");
            iniData = mk[0].split(",");
            iniData[1] = String.valueOf(Integer.parseInt(iniData[1])+1);

        }

        String[] datas = new String[args.length-1]; 
        boolean hasReseted = true;
        for(String s : args)
        {
            if(!s.contains(","))
                ownId=Integer.parseInt(s);

            else
            {
                String[] tmp = s.split(",");
                hasReseted=(Integer.parseInt(tmp[1])==1000)?hasReseted:false;
                if(Integer.parseInt(tmp[0])==ownId)
                {
                    ownHp=Integer.parseInt(tmp[1]);
                    ownAt=Integer.parseInt(tmp[2]);
                }
                int id=Integer.parseInt(tmp[0]);
                datas[id]=s;

                if(!firstTurn)
                {
                    if(tmp[3]!="D"){
                        int to =Integer.parseInt(mk[id+1].split(",")[4]);
                        int pa = Integer.parseInt(mk[id+1].split(",")[2]);
                        datas[id]+=","+(to+pa);
                    }
                    else
                        datas[id]+=","+Integer.parseInt(mk[id+1].split(",")[4]);
                }
                else
                    datas[id]+=",0";
            }
        }

        if(firstTurn||hasReseted)
        {
            iniData = new String[2];
            iniData[0]=ownId+"";
            iniData[1]="0";
        }

        int target=(ownId==0)?1:0;
        float best=-100.f;
        if(Integer.parseInt(iniData[1])<40
                &&Integer.parseInt(iniData[1])%3==0)
            target=-1;
        else
            for(String s:datas)
            {
                if(s!=null&&s.contains(","))
                {
                    String[] tmp = s.split(",");
                    int id = Integer.parseInt(tmp[0]);
                    float hp =Float.parseFloat(tmp[1]);
                    float at = Float.parseFloat(tmp[2]);

                    float curr=((hp/(float)ownAt)*at)*(0.1f*at);
                    float dangerOverall= Float.parseFloat(tmp[4])/(100*hp);
                    target=(curr*dangerOverall>=best
                            &&id!=ownId
                            &&hp>0)?Integer.parseInt(tmp[0]):target;
                    best=(curr*dangerOverall>=best
                            &&id!=ownId
                            &&hp>0)?curr:best;
                }
            }
        store(iniData,datas);
        System.out.println((target>=0)?target:"D");
    }

    private static void store(String[] iniData,String[] datas)
    {
        StringBuffer sb = new StringBuffer();
        sb.append(iniData[0]+","+iniData[1]);
        for(String s:datas)
        {
            if(s==null)
                break;
            sb.append(" "+s);
        }
        FileWriter fw = null;
        try{
            fw=new FileWriter(DATA_FILE);
            fw.write(sb.toString());
            fw.flush();
            fw.close();
        }catch(Exception e){e.printStackTrace();}
    }
}

그는 큰 뇌를 가지고 있지 않으므로 아무것도 기억하지 못하지만 좋은 일을 할 수 있다고 생각합니다. 재미있는 점 : 만약 그가 마지막으로 살아 있다면, 그는 시체를 걷어 차려 할 것이고, 좀비는 그를 두려워합니다!

편집하다 :

첫 번째 차례에 확인을 보냈고 샘플에 대해 테스트 했으므로 어려움을 겪고 있으며 조금 전에 일할 것입니다.

편집 2 :

그는 이제 몇 가지 데이터를 외우고 훨씬 더 잘하고 결코 이길 수는 없지만 실제로 매 시간마다 50 마력을 잃고 있습니다.

14 3170 java Bully
0 0 java Pacifier
0 0 java Hero
0 0 java Coward

더 이상 일어나지 않지만 (그는 실제로 몇 가지 포인트를 얻었습니다.)) 재밌었습니다 : D.

편집 3 :

올바른 파일 이름 사용 및 일부 개선. 꽤 잘 작동하며 많은 봇이 여기에있을 때 훨씬 좋습니다. :).


3

자바-메타 파이터

참고 : 작동하지 않는 경우 알려주십시오

메타 파이터는 모든 적을 개별 적으로 간주하지 않습니다. 그는 그들 모두를 전체로 간주합니다. 메타 파이터는 모든 적의 힘과 힘을 합하여 그와 비교합니다. 그런 다음 두 점수를 낮추는 데 가장 효과적인 움직임을 계산합니다. 약한 상대를 죽이면 힘과 힘이 동시에 낮아지기 때문에 도움이됩니다. 그러나 적을 공격하는 것이 힘을 빼앗는 것보다 더 유리한 힘을 줄 수 있다면, 그만한 가치가 없다고 결정하고 자신을 방어하거나 공격합니다. 메타 파이터는 상대방이 왜 자신과 전쟁을하는지 궁금합니다.

(BTW, Codegolf에 대한 나의 두 번째 항목)

package folder;

public class MetaFighter {
    public static void main(String[] args) {
        if(args.length < 1){
            System.out.print("ok");
            System.exit(0);
        }
        String me = args[0], target = "D";
    int weakestAmount = 2000, weakest = 0, totalLife = 0, totalPower = 0, threat = 0, enemies = 0;
    int life = 0,power = 0;
        for(int i = 1; i < args.length; i++){
        String[] data = args[i].split(",");
        if(me.equals(data[0])){
            life = Integer.parseInt(data[1]);
            power = Integer.parseInt(data[2]);
        }else{
            if(Integer.parseInt(data[1]) > 0){
                if(Integer.parseInt(data[1]) < weakestAmount){
                    weakest = Integer.parseInt(data[0]);
                    weakestAmount = Integer.parseInt(data[1]);
            }
            totalLife += Integer.parseInt(data[1]);
            totalPower += Integer.parseInt(data[2]);
            enemies++;
            }
        }
    }
    int powerV,totalPowerV,lifeV,totalLifeV,Defend = 0,AttackSelf = 0;
     powerV = power;
     totalPowerV = totalPower;
     lifeV = life;
     totalLifeV = totalLife;
    MetaFighter m = new MetaFighter();

    threat = m.calculateThreat(0, 0,totalLifeV,lifeV,powerV,totalPowerV, enemies);
    if (threat < 0){
        target = Integer.toString(weakest);
    }else{
    lifeV = lifeV - powerV;
    powerV++;
    AttackSelf = m.calculateThreat(0, 1,totalLifeV,lifeV,powerV,totalPowerV, enemies);  
     powerV = power;
     totalPowerV = totalPower;
    lifeV = life;
    totalLifeV = totalLife;
    Defend = m.calculateThreat(0, 2,totalLifeV,lifeV,powerV,totalPowerV, enemies);
    if(threat > AttackSelf && threat > Defend){
        target = Integer.toString(weakest);
    }
    if(Defend > AttackSelf && Defend > threat){
        target = "D";
    }
    if(AttackSelf > threat && AttackSelf > Defend){
        target = me;
    }
    if (Defend == threat){
        target = Integer.toString(weakest);
    }
    if (enemies < 3){
        target = Integer.toString(weakest);
    }
    }
    System.out.print(target);
    System.exit(0);
}
private int calculateThreat(int i, int s,int totalLifeV,int lifeV,int powerV, int totalPowerV, int enemies){
    if(totalLifeV > 0 && lifeV > 0){
        if(s == 0){
            totalLifeV += (0-powerV);
        }
        if (s != 2){
            lifeV += (0-totalPowerV);
        }else{
            lifeV += 0.5*(0-totalPowerV);
            powerV--;
        }
        powerV += enemies;
        totalPowerV++;
        i++;
    return calculateThreat(i, 0,totalLifeV,lifeV,powerV,totalPowerV, enemies);
    }
    if(lifeV > 0){
        return -1;
    }
    return i;
}

}

최종 편집 : 기능이 추가되어 3 개의 봇만 남은 경우 공격합니다.

가장 큰 약점 : 괴롭힘.


왜 메타 파이터는 "상대방이 자신과 전쟁을하는지 놀라운 이유"라고 생각하지만 자신을 공격하는 것을 고려하고 있습니까?
rudi

@rudi 그는 상대방이 왜 자신에게 유리하지 않은 방식으로 싸울 것인지 궁금합니다. 또한 이론적으로 그는 자신을 공격하지만 내 모든 테스트에서 결코 가지고 있지 않습니다.
colorado777

3

Python 2.7-GTA V의 Trevor Phillips와 Michael De Santa


2015 년 5 월 25 일 수정 : Michael De Santa의 첫 번째 버전이 추가되었습니다.
다음은 GTA V에 대한 경의입니다. GTA V의 3 명의 주인공 중 2 명을 나타내는 2 개의 Python 봇을 만들었습니다. Trevor Phillips와 Michael De Santa을 만나보세요. 트레버는 그에 대해 너무 미묘한 것이 없습니다. 마이클은 좋은 기억력과 명단을 가지고 있습니다. 일단 당신의 일이 계산됩니다.

Note1 : 시간이 있으면 Michael에게 더 많은 지능을 부여하고 프랭클린을 추가 할 수도 있습니다 (Travor를 대체하기 위해).

참고 2 : Michael은 꽤 괜찮은 것처럼 보입니다. 더 많은 아이디어가 있지만 이것을 내놓고 싶었습니다. 아마도 "더 나은"버전이 올 것입니다.

트레버 필립스

# "Computer gamers with their computer rigs. 
#  All they do is cry. 
#  They will never get the game."
#                         - Trevor Phillips.
#
import sys, random
from __builtin__ import str

# YES!!! I'm alive!!!
args=sys.argv
if len(args)==1:
    print("ok")
    sys.exit()

# Basic strategy: Hit whoever hits me or just anyone; sometimes brag a Trevor quote.
me=int(args[1])
botnrs=[]
action=''
quotes=["Now would you get me a f*cking drink! I'm not gonna ask you again!",
        "Grumble grumble grumble I've got my work grumble grumble grumble I've got my life, never the two shall meet.",
        "Well hello there beautiful. here go buy yourself something nice",
        "I'm driving, you can jerk me off if I get bored... I'm joking, you can suck me off.",
        "Do you want me to get my dick out again?!",
        "Floyd..we're having people over.  We need chips, dip, and prostitutes"]
for bot in args[2:]:
    nr,life,power,lastaction=bot.split(',')
    botnrs.append(nr)
    if lastaction==str(me):
        action=int(nr)
if action=='':
    action=int(random.choice(botnrs))
if random.random()<0.05:
    action=random.choice(quotes)
print(action)

마이클 데 산타

# Surviving is winning, Franklin, everything else is bullshit. 
# Fairy tales spun by people too afraid to look life in the eye. 
# Whatever it takes, kid: survive. 
#                                            - Michael De Santa.
#
import sys, pickle, re, operator

# List of power values for a certain bot in a given round range
def getpower( history, botid, roundrange ):
    return [sum([bot[2] for bot in history[i] if bot[0]==botid]) for i in roundrange]

# If you say nothing, I say "ok".
if len(sys.argv)==1:
    print("ok")
    historyfile=open('state/MichaelDeSanta.bin','w+')
    pickle.dump([[],{},0,0],historyfile)
    historyfile.close()
    sys.exit()

# Get data from file
myid=int(sys.argv[1])
historyfile=open('state/MichaelDeSanta.bin','r')
history,hitlist,botcount,roundnr=pickle.load(historyfile)
historyfile.close()
history.append([map(int,re.sub('[DX]','-1', bot).split(',')) for bot in sys.argv[2:]])

# Update hitlist:
if roundnr==0:
    hitlist=dict.fromkeys([bot[0] for bot in history[0]],0)

maxhealth=maxpower=[0,0]
for bot in history[roundnr]:
    if bot[0] != myid:
        if bot[1]<=0:
            hitlist[bot[0]]=0
        else:
            # If you hit me, you're on the list!
            if bot[3]==myid:
                hitlist[bot[0]]+=4
            # If I can kill you with one hit... You're on my list!
            if bot[1]<getpower(history,myid,[roundnr]):
                hitlist[bot[0]]+=1
            # If you're super healthy, you deserve PUNISHMENT!
            if bot[1]>maxhealth[1]:
                maxhealth=[bot[0],bot[1]]
            # If you're powerfull... Well... I'm not afraid!
            if bot[2]>maxpower[1]:
                maxpower=[bot[0],bot[1]]
hitlist[maxhealth[0]]+=3
hitlist[maxpower[0]]+=2

action=max(hitlist.iteritems(),key=operator.itemgetter(1))[0]
hitlist[action]-=1

# Save data to file
roundnr+=1
historyfile=open('state/MichaelDeSanta.bin','w+')
pickle.dump([history,hitlist,botcount,roundnr],historyfile)
historyfile.close()

# Wrap up and print the action
print(action)

2

자바 Patroclus

Patroclus는 공격적인 봇으로 영광을 추구합니다. 그는 (내가 그렇게 말하더라도) 상당히 좋은 기억을 가지고 있으며 영광을 찾는 가장 좋은 방법은 가장 공격적인 적을 공격하는 것이라고 믿습니다. 그는 모든 게임에서 지금까지 가장 많이 공격 한 사람을 기억하고 그의 큰 검으로 머리 위로 bo니다.

그의 가장 큰 약점은 방어에 대한 그의 카미카제 태도입니다. 아킬레스의 갑옷을 입을 때 누가 그것을 필요로합니까?

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;


public class Patroclus {

    final static File file = new File("state/Patroclus.txt");   
    static List<bot> enemies;
    static String me;

    public static void main(String[] args) {
            if(args.length < 1){
                if(file.exists())
                {
                    file.delete();
                }
                System.out.print("ok");
                System.exit(0);
            }
            me = args[0];
            enemies = new LinkedList<Patroclus.bot>();

            if(!file.exists())
            {
                createFile();               
                for(int i = 1; i<args.length; i++)
                {

                    String[] tokens = args[i].split(",");
                    bot newBot = new bot();
                    newBot.id = tokens[0];
                    newBot.life = Integer.valueOf(tokens[1]);
                    enemies.add(newBot);
                }               
            }
            else
            {

                openFile(args);

            }

            Collections.sort(enemies);
            Collections.reverse(enemies);

            String target = "D";
            for(int i = 0; (i<enemies.size()) && (i>-1); i++)
            {                               
                if(enemies.get(i).canAttack())
                {
                    target = enemies.get(i).id;
                    i = -10;
                }
            }
            saveFile();
            System.out.print(target);
            System.exit(0);
}


    private static void saveFile() {
        BufferedWriter writer;
        try {
            writer = new BufferedWriter(new FileWriter(file));
            for (bot b : enemies) {
                writer.write(b.toString());
                writer.write("#");
            }
            writer.flush();
            writer.close();
        } catch (IOException e) {           
        }
    }

    private static void openFile(String[] args) {       
            Scanner sc;
            try {
                sc = new Scanner(file);                     
                String[] lines = sc.next().split("#");

                for(int i = 0; i<lines.length; i++)
                {

                    bot newBot = new bot(lines[i]);


                    int j = 1;
                    for(; j<args.length && j>0; j++)
                    {
                        String[] tokens = args[j].split(",");
                        if(tokens[0].equals(newBot.id))
                        {
                            newBot.life=Integer.valueOf(tokens[1]);
                            if(newBot.life>0 && !tokens[3].equals("D"))
                            {
                                newBot.agression++;
                            }
                            j = -10;
                        }
                    }               
                    enemies.add(newBot);
                }           
            } catch (FileNotFoundException e) {
            }       
    }

    private static void createFile() {
        try {
            file.createNewFile();
        } catch (IOException e) {               
        }       
    }

    private static class bot implements Comparable<bot>
    {
        int agression, life;
        String id;

        public bot(String toParse)
        {
            String[] tokens = toParse.split(",");
            id = tokens[0];
            agression = Integer.valueOf(tokens[1]);
        }

        public bot()
        {
            this.agression = 0;
            this.life = 0;
            this.id = "D";
        }

        @Override
        public int compareTo(bot o) {
            if(this.agression>o.agression)
                return 1;
            else if (this.agression==o.agression)
                return 0;
            else
                return -1;
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append(id);
            sb.append(",");
            sb.append(agression);

            return sb.toString();
        }

        public Boolean canAttack()
        {
            return life>0 && !id.equals(me);
        }
    }
}

2

-편집증

전장에서 가장 활발한 사람과 계속 비교합니다.

struct Bot {
    id: i32,
    life: i32,
    power: i32,
    action: String,
}

fn main() {
    let args: Vec<_> = std::env::args().collect();
    if args.len() < 2 {
        print!("ok");
    } else {
        let id: i32 = args[1].to_string().trim().parse()
            .ok()
            .expect("Please type a number!");

        let mut target_bot = Bot { id:-1, life:-1, power:-1, action:"D".to_string() };
        let mut own_bot = Bot { id:id, life:0, power:1, action:"D".to_string() };

        for arg in args {
            let split: Vec<&str> = arg.split(",").collect();
            if split.len() == 4 {
                let bot_id: i32 = split[0].to_string().trim().parse()
                    .ok()
                    .expect("Please type a number!");
                let bot_life: i32 = split[1].to_string().trim().parse()
                    .ok()
                    .expect("Please type a number!");
                let bot_power: i32 = split[2].to_string().trim().parse()
                    .ok()
                    .expect("Please type a number!");
                let bot_action: String = split[3].to_string();

                let bot = Bot { id:bot_id, life:bot_life, power:bot_power, action:bot_action };

                if bot.id != id && bot.life > target_bot.life {
                    target_bot = bot;
                } else if bot.id == id {
                    own_bot = bot;
                }
            }
        }

        /* If I am not stronger than the strongest, defend */
        let turns_to_kill = target_bot.life/own_bot.power + 1;
        let turns_to_be_killed = own_bot.life/target_bot.power;

        if target_bot.id > -1 && turns_to_kill < turns_to_be_killed {
            print!("{}", target_bot.id);
        } else {
            print!("D");
        }
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.