Distanciamento para quatro homens

54

Distanciamento para 4 homens

Descrição

Você de alguma forma se viu em um impasse de quatro vias. Uma arma carregada repousa em suas mãos e algumas granadas estão presas no seu cinto.

O objetivo é ter mais saúde ao final de um impasse. Um impasse termina quando no máximo uma pessoa tem uma quantidade positiva de saúde.

Cada jogador tem vida 5e morre quando a saúde cai para / abaixo 0. O turno em que um jogador morre é o último turno em que um jogador pode sofrer dano.

Se houver um jogador ao vivo no final de um impasse, esse jogador vence. Caso contrário, o jogador com menos pontos de vida negativos ganha.

Ações

  • Atirar : Atire em alguém.

    • 2 dano se atirar em um inimigo vivo
    • 0 dano se atirar em um inimigo morto
    • health_at_start_of_turn+2danos se atirar em si mesmo. (Observe que isso deixará você com mais -2saúde.)
    • Se um inimigo atirar em você no mesmo turno em que você se atirar, você terminará o impasse com -4 de vida (você ainda recebe dano de outros jogadores no turno em que se mata).
    • Sua ação no turno seguinte será ignorada (e presumida Nothing).
  • Esquivar : Tente desviar do tiro de um único oponente.

  • Prepare : Solte sua granada e prepare-se para jogá-la.

    • Você só tem três turnos para jogá-lo antes de ser explodido ( 6dano a si mesmo,3 dano a todos os inimigos vivos)
    • Morrer com uma granada não jogada é equivalente a não jogar a granada por três turnos.
  • Jogue : jogue a granada em direção a alguém e torça pelo melhor.

    • O alvo recebe 8 dano se estiver vivo
    • Todos os outros (inclusive você) recebem 3dano se estiverem vivos
  • Nada : fique parado por um turno e observe todos morrerem.

Entrada

Seu programa receberá as seguintes informações:

  • A saúde de cada jogador
  • Uma lista de ações realizadas por esse jogador desde o início do confronto Abaixo está o formato das informações passadas por jogador:

    [Health],[Action 1],[Action 2],[Action 3],...
    

As ações serão dadas no formato especificado na seção Saída .

Você receberá 4 dessas strings, separadas por um espaço, e transmitidas como um único argumento. A ordem dessas seqüências de caracteres é:

[Player Info] [Opponent 1 Info] [Opponent 2 Info] [Opponent 3 Info]

As cadeias são passadas como o segundo argumento. O primeiro argumento contém um número inteiro que identifica exclusivamente o impasse que está sendo promulgado. É garantido que os impasses entre o mesmo conjunto de jogadores não sejam simultâneos. No entanto, vários impasses serão ocorrer ao mesmo tempo.

Por exemplo:

$./Player.bash 5 "3,S2,N 5,P,N 3,S0,N -2,S3,N"

Atualmente, o jogador e o segundo oponente têm 3 pontos de vida, o primeiro adversário tem 5 pontos de vida e o terceiro oponente tem -2 pontos de vida e está morto.

No primeiro turno:

  • Jogador 1 atirou no inimigo 2
  • Inimigo 1 preparou uma granada
  • Inimigo 2 atirador
  • O inimigo 3 atirou em si mesmo

No segundo turno:

  • Todos os jogadores não fizeram nada. (O jogador e o inimigo 2 não podem fazer nada desde que atiraram no turno anterior. O inimigo 3 está morto: ele fará Nothingo resto do impasse.)

O segundo argumento no início de um impasse é: 5 5 5 5.

Resultado

Um comando deve ser emitido no formato listado abaixo. Uma saída inválida é interpretada como 'Nothing'. Um comando que requer um alvo deve ser seguido por um número inteiro ( 0-3, 0representando o jogador e 1-3representando os inimigos 1-3).

  • S[target]: Dispara no alvo.
  • D[target]: Tenta se esquivar [alvo].
  • P: Prepare uma granada.
  • T[target]: Jogue a granada em [alvo].
  • N: Fazer nada.

Um comando que precisa de um alvo, mas é alimentado com um alvo que não está entre 0e que 3não é alimentado inteiramente com um alvo será assumido como alvo0 (o jogador).

Pontuação

No final de cada impasse, os jogadores recebem uma pontuação calculada pela seguinte fórmula:

35 + health at end of standoff 

No caso em que um jogador termina um impasse com a saúde negativa, eles vão receber uma pontuação abaixo de 35 . Os seguintes pontos também são recompensados ​​como um bônus:

  • Mais saúde: +4 pontos
  • Segundo maior número de pontos de vida: +2 pontos
  • Terceiro maior número de pontos de vida: +1 ponto.

Em caso de empate, o bônus mais baixo é concedido (se duas pessoas empatarem com mais pontos de vida, ambos receberão +2; se houver 3 pessoas com mais pontos de vida, +1 e se todos terminarem igualmente, +0).

A pontuação final é determinada calculando a média de todas as pontuações individuais.

Regras / Detalhes

  • A ordem dos eventos dentro de um turno é a seguinte:
    • Todos os jogadores fazem suas ações.
    • Jogadores com 0 ou menos pontos de vida morrem.
    • Granadas não lançadas que precisam explodir, explodirão (jogadores que acabaram de morrer ainda estão feridos, pois ainda é a vez em que eles morreram).
  • Nenhuma colaboração entre entradas.
  • Três * standoffs ocorrerão entre cada conjunto de 4 jogadores. (A ordem dos jogadores pode variar a cada impasse).
  • As entradas que consumirem quantidades excessivas de memória do espaço em disco serão desqualificadas.
  • Ler ou modificar arquivos que não sejam da sua entrada desqualificará a sua entrada.
  • Um caminhão, dirigido por um bêbado, atropelará todos os jogadores vivos após o 50thturno, se o impasse ainda não tiver terminado no final do 50thturno.
    • Este caminhão causa 20 de dano a todos os jogadores ao vivo.
  • Os impasses ocorrem rapidamente. Os programas são cortados após 1 segundo.
  • Seu programa será chamado a cada turno, mesmo depois que você morrer.
  • Você pode ler ou gravar arquivos apenas em seu diretório (se sua entrada for JohnDoe, você poderá salvar arquivos no diretório players / JohnDoe /); no entanto, esse NÃO será o diretório atual enquanto o script estiver em execução.
  • Os impasses ocorrerão em uma máquina executando o Arch Linux (versão 2014.08.01).

O controlador está disponível no GitHub .

Inclua o seguinte em sua postagem:

  • Um nome para o seu bot
  • Um comando shell para executar a entrada bot (ex. java Doe.java) Será passado pela linha de comando como um único argumento (java Doe.java 5 "-2,S0 -2,S1 -2,S2 5,N" )
  • Código do seu bot
  • Como o bot deve ser compilado (se aplicável)
  • Idioma (e versão, se aplicável, especialmente para python)

* O controlador está demorando muito para seis.

Placar

                      Observer 43.280570409982
                   MuhammadAli 43.134861217214
                         Osama 43.031983702572
                    LateBoomer 42.560275019099
                 SimpleShooter 42.412885154062
             LessSimpleShooter 42.3772
                           Neo 42.3738
                        Scared 42.3678
                     Richochet 42.3263
                   Equivocator 42.2833
  TwentyFourthsAndAHalfCentury 42.2640
                        Darwin 42.1584
                       HanSolo 42.1025
                        Coward 42.0458
           ManipulativeBastard 41.8948
                        Sadist 41.7232
                     Aggressor 41.7058
                 CourageTheDog 41.5629
                     Grenadier 40.9889
                     Bomberman 40.8840
                         Spock 40.8713
                        Sniper 40.6346
                 DONTNUKEMEBRO 39.8151
               PriorityTargets 39.6126
                     Hippolyta 39.2480
                     EmoCowboy 39.2069
                      Zaenille 39.1971
                 AntiGrenadier 39.1919
      PoliticallyCorrectGunman 39.1689
                 InputAnalyzer 39.1517
                      Rule0Bot 39.1000
                     BiasedOne 39.0664
                      Pacifist 39.0481
               StraightShooter 39.0292
                         Ninja 38.7801
                           MAD 38.2543
                        Monkey 37.7089
                   Label1Goto1 36.2131
Generated: 2014/08/22 03:56:13.470264860 UTC

Logs: no GitHub

es1024
fonte
11
Você tem exatamente uma granada ou muitas? Você pode ter várias granadas sendo preparadas ao mesmo tempo?
Isaacg
2
@Bob: Com certeza o EmoWolf foi adicionado às brechas padrão, que não são mais engraçadas . Embora uma entrada suicida possa não ser tão terrível assim.
es1024
3
Lição para todos: não beba e dirija.
Mark Gabriel
8
@ es1024 Onde o suicídio é realmente uma estratégia viável, uma submissão do tipo EmoWolf deve ser realmente permitida. Especialmente quando as ações disponíveis incluem explicitamente o suicídio! Não é tanto uma "brecha" agora, é? E não é realmente uma vantagem injusta, como a maioria dessas brechas é. Mas essa é apenas a minha opinião.
Bob
3
Com base na execução do controlador algumas vezes, parece bastante barulhento. Se esse concurso for encerrado, você provavelmente aumentará o número de execuções para facilitar um pouco.
Davis Yoshida

Respostas:

7

Observador

Esse cara analisa seus inimigos. O objetivo é sobreviver até que apenas um oponente "agressivo" seja deixado e depois matá-lo em um impasse épico.

Compilar: javac Observer.javaExecutar:java Observer arg0 arg1

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

class Observer {
    private static List<Integer> aggressiveEnemies = new ArrayList<>();
    private static List<Integer> enemyGrenadiers = new ArrayList<>();
    private static List<Integer> aliveEnemies = new ArrayList<>();

    public static void main(String[] args) {
        if (args[1].length() <= 7) { //first round
            Random rand = new Random();
            printResult("D" + (rand.nextInt(3) + 1));
        }
        String players[] = args[1].split(" ");

        if (truckIsOnWay(players[0])) {
            printResult("P");
        }       

        calcEnemyInfo(players);

        // end this standoff now
        if (truckWillHit(players[0])) {
            if (isGrenadier(players[0]))
                printResult("T" + aliveEnemies.get(0));
            else
                printResult("S0");
        }

        // shoot enemy who is not aggressive
        if (aggressiveEnemies.size() == 0) {
            printResult("S" + aliveEnemies.get(0));
        }

        // only one enemy to handle
        if (aggressiveEnemies.size() == 1) {
            String player = players[aggressiveEnemies.get(0)];
            if (isGrenadier(player)) {
                printResult("S" + aggressiveEnemies.get(0));
            } else if (shotLastTurn(player, aggressiveEnemies.get(0))) {
                //safe to shoot him without receiving damage
                printResult("S" + aggressiveEnemies.get(0));
            } else {
                printResult("D" + aggressiveEnemies.get(0));
            }
        }

        // multiple aggressive enemies
        if (enemyGrenadiers.size() > 0) {
            printResult("S" + enemyGrenadiers.get(0));
        } else {
            int id = aggressiveEnemies.get(0);
            for (int playerId : aggressiveEnemies) {
                if (!shotLastTurn(players[playerId], playerId)) {
                    id = playerId;
                }
            }
            printResult("D" + id);
        }
    }

    private static void printResult(String result) {
        System.out.print(result);
        System.exit(0);
    }

    private static boolean isAlive(String player) {
        return !(player.charAt(0) == '-' || player.charAt(0) == '0');
    }

    private static void calcEnemyInfo(String[] players) {
        for (int i = 1; i < players.length; i++) {
            if (isAlive(players[i])) {
                aliveEnemies.add(i);
                if (isAggressive(players[i], i)) {
                    aggressiveEnemies.add(i);
                }
                if (isGrenadier(players[i])) {
                    enemyGrenadiers.add(i);
                }
            }
        }
    }

    private static boolean truckIsOnWay(String player) {
        return player.length() - player.replace(",", "").length() == 48;
    }

    private static boolean truckWillHit(String player) {
        return player.length() - player.replace(",", "").length() == 49;
    }

    private static boolean isAggressive(String player, int id) {
        return (player.contains("S") || player.contains("P")) && !player.contains("S" + id);
    }

    private static boolean isGrenadier(String player) {
        return player.contains("P");
    }

    private static boolean shotLastTurn(String player, int id) {
        return player.charAt(player.length() - 2) == 'S' && !player.contains("S" + id);
    }
}
CommonGuy
fonte
!player.contains("S" + id)essa é uma condição necessária na função "isAggressive"? Um jogador suicida estará morto de qualquer maneira #
Cruncher
22

Granadeiro

As armas são superestimadas. O verdadeiro impasse de um escocês é assim:

  • Preparar
  • Jogue no inimigo com mais vida
  • Repita (se por algum milagre você ainda estiver vivo)

Embora isso pareça trivial, provavelmente não é uma estratégia terrível . Desde armas e granadas ambos têm um ciclo de dois por sua vez, este é de longe o mais eficiente 1 maneira de causar dano.

Claro, se todos os três oponentes atirarem em mim no primeiro round, não é bom. Mas também não haveria muito mais.

public class Grenadier {
    public static void main(String[] args) {
        if(args.length < 2)
            return;
        String[] list = args[1].split(" ");
        if(list.length < 4)
            return;

        if(list[0].charAt(list[0].length()-1) != 'P'){
            System.out.print("P");
            return;
        }

        int target = 1;
        for(int i=2;i<4;i++)
            if(list[i].charAt(0)>list[target].charAt(0))
                target = i;

        System.out.print("T"+target);
    }
}

Compile / execute da maneira Java padrão:

> javac Grenadier.java
> java Grenadier arg0 arg1

1 nota de rodapé sem sentido

Geobits
fonte
41
hahaha a nota de rodapé
proud haskeller
Acho que jogar uma granada e depois atirar é mais eficiente. A chance de você sobreviver 4 turnos com essa estratégia é incrivelmente baixa. Mas 3 talvez (sim, ambos tomam 2, mas a segunda vez para fotografar é após a ação, não antes)
Cruncher
@ Cruncher Você provavelmente está certo. Eric disse a mesma coisa no chat. Eu disse a ele que meu cara não acredita em armas e é muito teimoso para usar essa lógica, então ele postou essa estratégia. No entanto, ainda acredito que isso seja mais eficiente , se estamos falando estritamente do dano causado. Isso não significa que é mais eficaz em ganhar o jogo. Mesmo se eu morrer na terceira curva, minha segunda granada ainda dispara. Então, se eu viver até então, isso garante 6 ou mais danos a todos, o jogo acaba.
Geobits
@ Geobits agora que penso nisso, isso pode ser melhor. O que mais importa é o delta entre você e os oponentes. Quando a granada explode, você ganha +3 delta com quem jogou e +0 com o resto. Uma rede de +3. Tiroteio. Você ganha um delta de +2 com quem você dispara. +0 com o resto. Eu acho que o problema é que você -3 com pessoas que já estão mortas. Você deve atirar se alguém está morto :)
Cruncher
2
@codebreaker Nunca joguei. É uma referência da vida real .
Geobits
16

Regra número 0 de Asimov Bot - Python

Um robô não pode prejudicar a humanidade ou, por inação, permitir que a humanidade venha a prejudicar.

Bem direto, ele atacará o primeiro jogador que vê segurando uma granada para proteger a maioria dos humanos. Se ninguém é uma ameaça para a maioria dos humanos, ele não fará nada.

import sys

def total_humans_alive(humans):
  return sum([is_alive(human) for human in humans])

def is_alive(x):
  return int(x.split(",")[0]) > 0  

def is_threat_to_humanity(lastAction):
  return lastAction == "P"

action = "N"
threat_id = 1
humans = sys.argv[2].split()[1:];

if total_humans_alive(humans) == 3:
  for human in humans:
    if is_threat_to_humanity(human[-1]):
      action = "S" + str(threat_id)
      break
    threat_id= threat_id+ 1

print action

Execute-o como:

python rule0bot.py
William Barbosa
fonte
2
Seu robô é ilógico. Se o jogador que segura a granada lança, a humanidade recebe 8 + 3 + 3 + 3 = 17 de dano. Se você matá-lo com o tiro, a humanidade recebe 2 + 6 + 3 + 3 + 3 = 17 de dano. Nos dois cenários, quem quer que a granada exploda leva 8 e todos os outros 3 (a menos que eles estivessem mortos anteriormente). A humanidade como um todo não é afetada. Mesmo assim, gosto. +1: D
Geobits
4
Na verdade, o melhor cenário para a humanidade é a esperança da granada é lançada no robô;)
Geobits
11
@ Geobits Não tentar parar alguém que é uma ameaça é contra a natureza dos robôs. Ele tentará impedir alguém segurando uma granada para impedir que a maioria (outras duas) seja ferida. Você leu eu, robô? Essa lógica é apoiada por Little Lost Robot e The Evitable Conflict.
William Barbosa
Eu li, mas o que estou dizendo é que atirar neles não para por aqui. Se ele morrer enquanto segura a granada, ela ainda explode. Não apenas isso, mas a quantidade total de danos causados ​​à humanidade permanece a mesma. Você está causando dano direto a um humano sem ganho para a humanidade.
Geobits
2
+1 Discordo do voto de Kyle Kanos e quero anulá-lo. Além disso, Geobits está errado ao supor que isso não faz nada para ajudar a humanidade. Certamente, a humanidade pode não se sair melhor no pior cenário, mas se os outros dois jogadores atirarem na granada que empunha o ducha, então eles são melhores para isso.
FreeAsInBeer
14

Han Solo - Python

Han atirou primeiro. Nesse caso, ele atirará primeiro escolhendo o alvo mais próximo vivo.

import sys

def is_alive(player):
  return int(player.split(",")[0]) > 0

closest_living_target = 1;

for player in sys.argv[2].split()[1:]:
  if is_alive(player):
    action = "S" + str(closest_living_target)
    break

  closest_living_target = closest_living_target + 1

print action

Execute-o como:

python hansolo.py

Nota : Esta é a primeira coisa que escrevi em Python. Portanto, se você encontrar alguma prática incorreta específica para python, entre em contato.

William Barbosa
fonte
11
estilo pep8 sugere seu método deve seris_alive
Daenyth
4
@WilliamBarbosa dê uma olhada no pep8, é o guia de estilo python que todo mundo usa. legacy.python.org/dev/peps/pep-0008
Daenyth
2
Parabéns por ser o único bot com uma saúde média maior que 0, na rodada de 8/11.
Isaacg
6
IMO, "guias de estilo" são para cabeleireiros, não para programadores.
Kyle Kanos
2
@KyleKanos É bom ter alguma consistência, no entanto. Quer dizer, se metade dos desenvolvedores de um caso de projeto de uso camelo e os outros tipos de meio como este, o resultado será "blergh"
William Barbosa
12

EmoCowboy

Por que esperar para morrer? Apenas se mate agora. Esperemos que o resto dos tolos exploda um ao outro até muito menos que -2.

A pontuação será normalmente -2. Às vezes, -4, se as pessoas decidirem me matar. Raramente mais do que isso, o que significa que isso deve superar várias das inscrições atuais.

Pitão

print('S0')

python EmoCowboy.py

EDIT: Isso não é uma piada, e é geralmente por isso que essas submissões de emo são desaprovadas. Esta é uma estratégia legítima. Estar vivo é mortal!

Triturador
fonte
11

Pacifista

Ele é um cara de verdade, apenas foi pego pela multidão errada.

main = putStr "N"

Execute como runghc pacifist.hs, mas convém compilá-lo com -O3 se a eficiência for um problema.

killmous
fonte
11
Por favor, renomeie-o Luigi e vamos ver se ele ganhará alguma coisa!
William Barbosa
11
@WilliamBarbosa Luigi? Você disse Luigi ?
killmous
7
Lol como se -O3faz uma diferença.
tomsmeding
@tomsmeding É lento do runghclado. Na verdade, é 10 vezes mais lento na minha caixa Linux.
Ray
5
Isso implica a existência de violência, uma implicação nosso pacifista não está preparado para lidar com
killmous
9

Macaco - Python (Primeira entrada!)

Macaco vê macaco faz. Repetirá exatamente a última ação executada por um jogador aleatório.

import sys, random
targetData = sys.argv[2].split()[random.randint(0,3)]
print(targetData.split(',')[len(targetData.split(','))-1])

Pode ser executado assim: "python monkey.py args" Não são necessárias etapas extras.

Elias Benevedes
fonte
2
Espero que eles não estejam atirando em você! O Python suporta índices de matriz negativos, portanto você não precisa calcular o comprimento e subtrair um; basta usar -1diretamente.
comperendinous 11/08/14
@comperendinous Diga que sou S3 na lista deles. Se eu executar o S3, não vai me deixar bobo. Além disso, o índice -1 retornará o último elemento? Se sim, legal! Eu vou ter certeza de adicioná-lo.
Elias Benevedes
E não esqueça o primeiro argumento (inteiro). Você precisa argv[2]obter a história dos jogadores.
comperendinous
Só espero que você não seja correspondido com o Emo Cowboy.
Codebreaker
6

Simple Shooter - Perl (bug corrigido)

Este bot atira no oponente com mais vida. É uma estratégia muito simples, mas acho que tem uma chance decente de realmente se sair bem.

@history = map([split(",",$_)],split(" ",$ARGV[1]));
$target = 1;
for(2..3){
 if($history[$_][0] >= $history[$target][0]){$target = $_}
}
print "S$target"

Isto é como executá-lo usando algum exemplo de entrada:

perl simpleshooter.plx 7 "3,S2,N 5,P,N 3,S0,N -2,S3,N"
PhiNotPi
fonte
Uau. Simples e inteligente.
Soham Chowdhury
6

Spock, em Python 3.x

Esse código é mais um experimento embora (daí o nome de Spock porque ... ele é vulcano, e eles são muito bons nesse tipo de coisa), mas foi divertido construí-lo. O principal raciocínio por trás de todo esse código são suposições que um ser lógico e bom, como Spock, faria, se fossem dadas as regras do jogo:


O objetivo deste jogo é maximizar a pontuação, o que seria feito por todo mundo parado, o que não é possível, devido ao caminhão.

  • Uma das diretrizes que Spock deve seguir é impedir que o caminhão apareça, garantindo que todos, exceto um, estejam mortos antes que o caminhão apareça.

A maneira como Spock joga no resto do jogo pode ser resumida por sua famosa citação: " As necessidades de muitos superam as necessidades de poucos ". Em outras palavras, Spock precisa garantir que o menor dano seja sofrido, matando aqueles que o fazem. Como ele faz isso:

  • Se nenhum jogador tiver preparado uma granada, mire no jogador menos saudável que ainda estiver jogando.
  • Se houver jogadores que prepararam granadas, esses são os menos saudáveis.

O raciocínio é que, ao atingir os jogadores mais fracos, estamos encerrando as fontes de dano. O raciocínio por trás das granadas é que elas disparam independentemente e causam menos dano se não forem jogadas.


E assim esse bot funciona. Não testei extensivamente quanto a falhas de entrada (por favor, avise-me se algo der errado), mas estou confiante de que resolvi a maioria dos problemas. Baseei uma pequena parte do código do bot HanSolo, mas na maioria das vezes é uma bagunça de código emaranhada. Desfrutar.

def IsAlive(player):
  return int(player[1].split(",")[0]) > 0
def IsTarget(player, target_health):
  return int(player[1].split(",")[0]) < target_health
def HasGrenade(player):
  max_range = max(-4,-current_turn)
  for foo in range(-1,max_range,-1):
    if "P" in player[1].split(",")[foo]:
      for bar in range(-1,foo-1,-1):
        if player[1].split(",")[bar] not in ["T0", "T1", "T2", "T3"]:
          return True
  return False

import sys
info_list = sys.argv[2].split()
current_turn = len(info_list[0].split(","))
action = "N"

def Startgame():
  global action

  target = 1
  target_health = 5
  grenade_list=[]

  for player in zip(range(1,4),info_list[1:]):
    if HasGrenade(player):
      grenade_list.append(player)

  if not grenade_list:
    foo_list = []
    for player in zip(range(1,4),info_list[1:]):
      foo_list.append(player)
    target_list = foo_list
  else:
    target_list = grenade_list

  # Choose the least healthy player
  for player in target_list:
    if IsAlive(player) and IsTarget(player, target_health):
      target = player[0]
      target_health = int(player[1][0])

  action = "S" + str(target)

def Endgame(turn):
  global action

  if turn in [47, 49]:
    # Check if in 2 moves he can do enough damage
    rem_health = 0
    for player in zip(range(1,4),info_list[1:]):
      if IsAlive(player): rem_health += player[0]

    if rem_health < 5:
      Startgame() # It's lazy, but it should work
      return
    else:
      action = "P"
      return

  if turn in [48, 50]:
    # If Spock shot someone before, it needs to shoot again
    if info_list[0].split(",")[-1] in ["S0", "S1", "S2", "S3"]:
      Startgame()
      return
    else:
    # There's no rule against throwing grenades to dead bodies, so if
    # possible it will be thrown there.    
      target = 1
      target_health = 5

      foo_list = []
      for player in zip(range(1,4),info_list[1:]):
        foo_list.append(player)
      target_list = foo_list

      for player in target_list:
        if IsTarget(player, target_health):
          target = player[0]
          target_health = int(player[1][1])

      action = "T" + str(target)
      return

if current_turn > 46:
  Endgame(current_turn)
else:
  Startgame()

print(action)

Execute-o como:

python spock.py

12-08-2014 - Pequenas correções de erros em relação à detecção de granadas
14/08/2014 - Pequenas correções de erros em relação ao final do jogo, graças a isaacg por apontá-lo antes

Doktoro Reichard
fonte
Você não tem permissão para disparar mais de uma vez a cada duas rodadas. Leia as especificações sobre o disparo.
Isaacg
@isaacg Obrigado pelo lembrete (que explica o comportamento), mas parece haver alguns erros latentes. Por exemplo, neste Spock deveria ter atirado no InputAnalyser porque ele tinha uma granada viva (mesmo que Solo tivesse mais 2 pontos de vida).
Doktoro Reichard
Traceback (most recent call last): File "./players/Spock/Spock.py", line 87, in <module>: Endgame(current_turn) File "./players/Spock/Spock.py", line 79, in Endgame: if IsTarget(player, target_health): File "./players/Spock/Spock.py", line 4, in IsTarget: return int(player[1].split(",")[0]) < target_health TypeError: unorderable types: int() < str()
precisa saber é o seguinte
player[1][1]deveria ser int(player[1][1]).
Isaacg
@isaacg novamente, agradeço a ajuda. Eu teria feito isso antes, mas fui inundado de coisas. Spock foi finalmente construído com base em um conceito equivocado de como isso ocorreria, daí a pontuação relativamente mais baixa que ele obteve. Eu tenho algumas idéias para novos bots, mas com tantas agora tenho que ter certeza de que a idéia principal é original.
Doktoro Reichard
5

Atirador politicamente correto

Muito politicamente correto, pois não discrimina nada. Portanto, não é muito inteligente.

import random

array = ["P", "N", "S0", "S1", "S2", "S3", "D1", "D2", "D3", "T1", "T2", "T3"]

print(array[random.randrange(0,11)])

Realmente não importa quais argumentos são passados ​​para ele. python politicallycorrectgunman.py

Desfazer
fonte
Não acho que os colchetes devam fazer parte da saída. Talvez o @ es1024 possa confirmar isso. E você conhece random.choice? É ótimo para esse tipo de seleção.
comperendinous
não pode haver nada antes da ação e alvo na saída, embora nada depois é ignorado
es1024
Isso parece melhor @ es1024?
Desfazer
@Undo Sim, funciona perfeitamente agora
es1024
7
Você não poderia simplesmente usar random.choice(array)?
user2357112
5

Straight Shooter

Ele é uma parte treinada da cavalaria e fala em vários idiomas, mas, sendo cintilante, o Straight Shooter só pode ver o inimigo à sua frente. Sendo um cavalo, ele não entende que você precisa esperar entre os tiros.

print('S2')

Perl, Python 2/3, Ruby: este cavalo é realmente uma entrada poligonal.

Eu estou ganhando de qualquer maneira. Eu não posso perder. Você pode atirar em mim, mas não pode me matar. O senhor Ed não tem nada de errado comigo!

Para uma resposta que tenha um pouco mais de pensamento (e algum paradigma funcional), veja: Vigésimo quarto e meio século .

comperendinous
fonte
5

Anti-granadeiro

Granadas são ruins. Muito mal. Portanto, se alguém está preparando um, a melhor coisa a fazer é matá-lo. Caso contrário, apenas sairemos.

-- Antigrenadier
local args = {...}  -- command line arguments

match = args[2]     -- store the set of matches

-- why this isn't standard in Lua....
function string:split( inSplitPattern, outResults )
  if not outResults then
    outResults = { }
  end
  local theStart = 1
  local theSplitStart, theSplitEnd = string.find( self, inSplitPattern, theStart )
  while theSplitStart do
    table.insert( outResults, string.sub( self, theStart, theSplitStart-1 ) )
    theStart = theSplitEnd + 1
    theSplitStart, theSplitEnd = string.find( self, inSplitPattern, theStart )
  end
  table.insert( outResults, string.sub( self, theStart ) )
  return outResults
end

-- set up the players
players = match:split(" ")

-- search other players for someone who pulled a grenade
for i=2,#players do
   moves = players[i]
   -- test if person is alive
   if moves:sub(1,1) ~= "-" then
      -- cycle through all elements of the string
      for j=#moves,2,-1 do
         -- if found, shoot!
         if moves:sub(j,j) == "P" then
            print("S"..i-1)
            os.exit()
         end
      end
   end
end

-- otherwise we just relax
print("N")
Kyle Kanos
fonte
4

Ricochet - Perl

Estratégias simples parecem funcionar decentemente neste desafio, então aqui está outro. Atira em um jogador vivo aleatório. Ele tem o recurso adicional de cometer suicídio no final para evitar o caminhão.

@history = map([split(",",$_)],split(" ",$ARGV[1]));
$health = $history[0][0];
@options = ();
for(1..3){
 if($history[$_][0] > 0){
  push(@options,$_);
 }
}
$target = @options[int(rand(~~@options))];
if(~~@{$history[0]} == 50){
 $target = 0;
}
print"S$target";

Execute assim:

perl ricochet.plx 5 "-2,S0 -2,S1 -2,S2 5,N" 
PhiNotPi
fonte
4

Agressor

Puxa na primeira rodada, atira no oponente com maior vida útil na segunda rodada, atira no oponente com maior vida útil a partir de então.

#include <cstdio>
#include <cstring>

int main(int argc, char** argv){
   char* t;
   t = strtok(argv[2]," ");
   int len = strlen(t);
   int max = -50, maxP;
   for(int i=1;i<4;i++){
      int cur;
      t = strtok(NULL," ");
      if(t[0]=='-'){cur = -1*(t[1]-'0');}
      else{cur = t[0]-'0';}
      if(cur>max){
         max = cur;
         maxP = i;
      }
   }
   if(len == 1){printf("P\n"); return 0;}
   if(len == 3){printf("T%d\n",maxP); return 0;}
   printf("S%d\n",maxP);
   return 0;
}

Execute isso como ./agg ID "5 5 5 5".

Eric Tressler
fonte
4

Ninja

Apenas esquiva aleatoriamente tentando evitar ser atingido.

math.randomseed(os.time())
print("D"..tostring(math.random(4)-1))

correr como

lua ninja.lua

Args são desnecessários, mas podem ser adicionados sem problemas.

Kyle Kanos
fonte
2
@KyleKanos Ninja vai desviar de seus próprios tiros?
Skeggse
2
@distilledchaos: ... sim, sim ele vai.
Kyle Kanos
4

Nome : PriorityTargets

Comando Shell : ruby ​​PriorityTargets.rb 5 [game_state]

Língua : Ruby V2.1.2

Descrição : o PriorityTargets tenta encontrar estilos de reprodução comuns. Ele então decide, com base nesses estilos de jogo, quem ele quer atacar e qual arma usar.

Nota : Submissão do First Code Golf! Muito maior do que os outros envios, porque fiquei um pouco louco.

#!/usr/bin/env ruby

class PriorityTargets
  class PlayerAction
    SHOOT = 'S'
    DODGE = 'D'
    PREPARE_GRENADE = 'P'
    THROW_GRENADE = 'T'
    NOTHING = 'N'
    attr_accessor :action, :target

    def initialize(action_string)
        @action = action_string[0, 1]
        @target = self.has_target? ? action_string[1, 1].to_i : false
    end

    def to_s
      string = @action
      string << @target.to_s if self.has_target?
      string
    end

    def has_cooldown?
      [SHOOT].include? @action
    end

    def is_aggressive?
      [SHOOT, PREPARE_GRENADE, THROW_GRENADE].include? @action
    end

    def has_target?
      [SHOOT, DODGE, THROW_GRENADE].include? @action
    end
  end


  class Player
    attr_reader :identifier, :health, :history
    attr_accessor :playstyles

    def initialize(player_identifier, player_string)
      @identifier = player_identifier
      @playstyles = []

      player_info = player_string.split(',')
      @health = player_info.shift.to_i
      @history = parse_history(player_info)
    end


    def has_attacked?(player, round = nil)
      round ||= self.history.length - 1
      player.history[0, round].each do |turn|
        did_attack = true and break if turn.is_aggressive? && turn.has_target? && turn.target == player.identifier
      end
      did_attack ||= false
    end

    def is_holding_grenade?(round = nil)
      round ||= self.history.length
      turn_history = self.history[0, round]
      is_holding = false

      turn_history.each_with_index do |turn, curr_round|
        if turn.action == PlayerAction::PREPARE_GRENADE && curr_round >= round - 3
          is_holding = true if turn_history.drop(curr_round).select{|turn| turn.action == PlayerAction::THROW_GRENADE }.length == 0
        end
      end

      is_holding
    end

    def is_dead?; self.health <= 0; end
    def is_on_cooldown?
      return false if self.history.length == 0
      self.history.last.has_cooldown?
    end

    def turn_at_round(round); self.history[round-1]; end

    private

      def parse_history(history_array)
        parsed = []
        history_array.each {|action_string| parsed << PlayerAction.new(action_string) }
        parsed
      end
  end

  class PlayerList
    include Enumerable

    def initialize(player_list = [], filter_list = false)
      @list = player_list
      @filter = filter_list if filter_list
    end

    #Enumerable Methods
    def each
      list = @list.select{|player| @filter.include?(player.identifier) } if @filter
      list = @list unless @filter
      list.each {|player| yield(player) }
    end

    def <<(player); @list << player; end
    def [](key)
      player = @list.select{|player| @filter.include?(player.identifier) }[key] if @filter
      player = @list[key] unless @filter
      player
    end

    def length
      list = @list.select{|player| @filter.include?(player.identifier) } if @filter
      list = @list unless @filter
      list.length
    end

    def empty?; self.length == 0; end
    def not_empty?; self.length > 0; end

    def create_filtered_list(player_ids)
      new_player_list = PlayerList.new(@list, player_ids)
      new_player_list
    end

    #PlayerList Methods
    def includes_playstyle?(playstyle)
      (self.with_playstyle(playstyle).length > 0)
    end

    def have_executed_action?(action)
      action_found = false
      self.each {|player| action_found = true and break if player.history.select {|turn| turn.action == action}.length > 0 }
      action_found
    end

    def direct_damages(round = nil)
      round ||= self.first.history.length

      damage_list = {}
      @list.each {|player| damage_list[player.identifier] = 0 }

      if round >= 1
        @list.each do |player|
          player.history[0, round].each_with_index do |turn, curr_round|

            if turn.has_target?
              target_player = @list.select{|curr_player| curr_player.identifier == turn.target }.first
              target_turn = target_player.turn_at_round(curr_round)

              damage_list[turn.target] += 8 if turn.action == PlayerAction::THROW_GRENADE

              if turn.action == PlayerAction::SHOOT
                damage_list[turn.target] += 2 unless target_turn.action == PlayerAction::DODGE && target_turn.target == player.identifier
              end
            end
          end
        end
      end

      damage_list.select! {|key| @filter.include? key } if @filter
      damage_list
    end


    def filtered_with_condition(&condition_block)
      player_ids = []
      self.each {|player| player_ids << player.identifier if condition_block.call(player) }
      create_filtered_list(player_ids)
    end

    def on_cooldown; filtered_with_condition {|player| player.is_on_cooldown?} end
    def not_on_cooldown; filtered_with_condition {|player| !player.is_on_cooldown?} end

    def dead; filtered_with_condition {|player| player.is_dead?} end
    def not_dead; filtered_with_condition {|player| !player.is_dead?} end

    def with_playstyle(playstyle); filtered_with_condition {|player| player.playstyles.include?(playstyle)} end
    def not_with_playstyle(playstyle); filtered_with_condition {|player| !player.playstyles.include?(playstyle)} end

    def with_max_health(round = nil)
      round ||= self.first.history.length
      player_damages = direct_damages(round)
      filtered_with_condition {|player| player_damages[player.identifier] == player_damages.values.min }
    end

    def with_identifier(identifier)
      matches = self.with_identifiers([ identifier ])
      return nil if matches.empty?
      matches.first
    end

    def with_identifiers(identifiers)
      create_filtered_list(identifiers)
    end
  end

  class PlayerTypes
    GRENADIER = :GRENADIER
    COWBOY = :COWBOY
    SKIDDISH = :SKIDDISH
    AGGRESSOR = :AGGRESSOR
    DEFENSIVE = :DEFENSIVE
    ANTI_GRENADIER = :ANTI_GRENADIER
    PLAYSTYLE_ORDER = [GRENADIER, COWBOY, SKIDDISH, AGGRESSOR, DEFENSIVE, ANTI_GRENADIER]

    def initialize(player_list)
      @players = player_list
    end

    def analyze_playstyles
      return if @players.first.history.length == 0

      PLAYSTYLE_ORDER.each do |playstyle|
        check_fnc = "is_"+playstyle.to_s+'?'
        @players.each {|player| player.playstyles << playstyle if self.send(check_fnc, player) }
      end
    end

    def is_GRENADIER?(player)
      #Grenade on first turn
      #Used more than one grenade
      #Never used gun, only grenade
      shoot_count = player.history.count {|turn| turn.action == PlayerAction::SHOOT }
      grenade_count = player.history.count {|turn| turn.action == PlayerAction::PREPARE_GRENADE }

      profiled ||= true if player.history.first.action == PlayerAction::PREPARE_GRENADE
      profiled ||= true if grenade_count > 1
      profiled ||= true if shoot_count == 0 && grenade_count > 0
      profiled ||= false
    end

    def is_COWBOY?(player)
      #Never used grenade, only gun
      shoot_count = player.history.count {|turn| turn.action == PlayerAction::SHOOT }
      grenade_count = player.history.count {|turn| turn.action == PlayerAction::PREPARE_GRENADE }

      profiled ||= true if grenade_count == 0 && shoot_count > 0
      profiled ||= false
    end

    def is_SKIDDISH?(player)
      #Dodged more than once
      #Never hurts anybody
      dodge_count = player.history.count {|turn| turn.action == PlayerAction::DODGE }
      attack_count = player.history.count {|turn| turn.is_aggressive? }

      profiled ||= true if dodge_count > 1
      profiled ||= true if attack_count == 0 && player.history.length > 1
      profiled ||= false
    end

    def is_AGGRESSOR?(player)
      #Only shoots person >= most health
      profiled = false
      player.history.each {|turn| profiled = true if turn.is_aggressive? && turn.has_target? }

      player.history.each_with_index do |turn, round|
        if turn.is_aggressive? && turn.has_target?
          profiled = false if [email protected]_max_health(round).include? @players.with_identifier(turn.target)
        end
      end
      profiled
    end

    def is_DEFENSIVE?(player)
      #Only hurts people who hurt them first
      player.history.each {|turn| profiled = true if turn.is_aggressive? && turn.has_target? }

      player.history.each_with_index do |turn, round|
        if turn.is_aggressive? && turn.has_target?
          target_player = @players.with_identifier(turn.target)
          profiled = false unless target_player.has_attacked?(player, round)
        end
      end
      profiled ||= false
    end

    def is_ANTI_GRENADIER?(player)
      #After a Grenadier has been shown, only shoots grenadier
      shots_fired = 0
      shots_fired_while_holding = 0

      player.history.each_with_index do |turn, round|
        if turn.is_aggressive? && turn.has_target?
          target_player = @players.with_identifier(turn.target)
          shots_fired += 1
          shots_fired_while_holding += 1 if target_player.is_holding_grenade?(round)
        end
      end

      (shots_fired > 0 && shots_fired/2.0 <= shots_fired_while_holding)
    end
  end




  def initialize(game_state)
    players_info = game_state.split(' ')
    @player = Player.new(0, players_info.shift)
    @players = PlayerList.new
    @players << @player
    enemy_identifiers = []

    players_info.each_with_index {|info, index| @players << Player.new(index+1, info); enemy_identifiers << index+1; }

    @enemies = @players.with_identifiers(enemy_identifiers  )
  end

  def analyze_playstyles
    types = PlayerTypes.new(@players)
    types.analyze_playstyles
  end

  def find_dodge_target
    armed_aggressors = @enemies.with_playstyle(PlayerTypes::AGGRESSOR).not_on_cooldown().not_dead()

    if armed_aggressors.not_empty?
      return armed_aggressors.with_max_health().first if @players.with_max_health().include?(@player) && @players.with_max_health().length == 1
    end

    return @enemies[Random.rand(3)] if @player.history.length == 0
    nil
  end

  def find_target
    unarmed_aggressors = @enemies.with_playstyle(PlayerTypes::AGGRESSOR).on_cooldown().not_dead()
    anti_grenadiers = @enemies.with_playstyle(PlayerTypes::ANTI_GRENADIER).not_dead()
    grenadiers = @enemies.with_playstyle(PlayerTypes::GRENADIER).not_dead()
    cowboys = @enemies.with_playstyle(PlayerTypes::COWBOY).not_dead()
    skiddish = @enemies.with_playstyle(PlayerTypes::SKIDDISH).not_dead()
    defensive = @enemies.with_playstyle(PlayerTypes::DEFENSIVE).not_dead()

    if unarmed_aggressors.not_empty?
      return unarmed_aggressors.with_max_health().first if @players.with_max_health().include?(@player) && @players.with_max_health().length == 1
    end

    return anti_grenadiers.with_max_health().first if anti_grenadiers.not_empty?
    return grenadiers.with_max_health().first if grenadiers.not_empty?
    return cowboys.with_max_health().first if cowboys.not_empty?
    return skiddish.with_max_health().first if skiddish.not_empty?
    return defensive.with_max_health().first if defensive.not_empty?
    return @enemies.with_max_health().not_dead().first if @enemies.with_max_health().not_dead().length > 0
    nil
  end

  def find_weapon
    return PlayerAction::THROW_GRENADE if @player.is_holding_grenade?

    anti_grenadiers = @enemies.with_playstyle(PlayerTypes::ANTI_GRENADIER).not_dead()

    return PlayerAction::PREPARE_GRENADE if anti_grenadiers.empty? && @enemies.have_executed_action?(PlayerAction::PREPARE_GRENADE)
    PlayerAction::SHOOT
  end

  def make_decision
    dodge_target = self.find_dodge_target
    target = self.find_target
    weapon = self.find_weapon

    decision ||= PlayerAction.new(PlayerAction::NOTHING) if @player.is_on_cooldown? || @enemies.with_max_health().not_dead().length == 0
    decision ||= PlayerAction.new(PlayerAction::DODGE + dodge_target.identifier.to_s) if dodge_target
    decision ||= PlayerAction.new(weapon + target.identifier.to_s)
    STDOUT.write decision.to_s
  end
end

priority_targets = PriorityTargets.new(ARGV[1])
priority_targets.analyze_playstyles
priority_targets.make_decision
fingerco
fonte
11
Gosto da sua abordagem, estou ansioso para ver como será.
overactor
Infelizmente, parece que havia um bug que criava um granadeiro. Ah, bem, vai fazer melhor da próxima vez :)
fingerco
3

Covarde - Perl

Atua de maneira muito covarde. Quando se sente saudável, escolhe um inimigo que não se sente assim e atira nele. Pontos de bônus para os inimigos que estavam atirando no último turno (porque eles sabem que estão fazendo Nothingesse turno e, portanto, são absolutamente indefesos). Quando ele não se sente tão bem, ele corre para se esconder, para matar alguém ocasionalmente.

#!/usr/bin/perl

@allinfo = map { [split/,/] } split / /, $ARGV[1];
@life = map { $_->[0] } @allinfo;
@action = map { @$_>1 ? $_->[-1] : () } @allinfo;

if($life[0] < 3 && rand() < .5 )
{
    printf "D%d", +(sort { ($life[$a]>0)*($action[$a] eq "N") <=> ($life[$b]>0)*($action[$b] eq "N") } 1..3)[2]
}
else
{
    @score = map { $life[$_]>0 ? (5/$life[$_] + 2*($action[$_] =~ /S./)) : 0 } 1..3;
    printf "S%d", +(sort { $score[$a] <=> $score[$b] } 1..3);
}

Código Perl bastante padrão; salve-o em algum arquivo e executeperl file argument argument [...] . Eu verifiquei a sintaxe e estava tudo bem, então espero não ter problemas com isso.

E: eliminou o potencial de divisão por 0 erro.

Ramillies
fonte
3

Bomberman

O bot escrito em R, na linha de comando, deve ser: Rscript Bomberman.R arg0 arg1
percebi que, depois de começar a escrever esse bot, o Geobits já fez um granadeiro, mas acho que o meu é significativamente diferente, pois verifica sua saúde acima de 3 antes de preparar uma granada e o joga no último atirador primeiro e o segundo mais saudável, e se sua saúde estiver abaixo de 3, ele desviará do jogador perigoso (nem morto nem atirador na última rodada) ou atirará em um dos jogadores restantes.

input <- commandArgs(TRUE)
history <- do.call(rbind,strsplit(scan(textConnection(input[2]),"",quiet=TRUE),","))
health <- as.integer(history[,1])
last_shooter <- which(grepl("S",history[-1,ncol(history)]))
last_prepare <- which(history[1,]=="P")
if(!length(last_prepare)) last_prepare <- -1
last_throw <- which(grepl("T",history[1,]))
if(!length(last_throw)) last_throw <- 0
most_healthy <- which.max(health[-1])
dead <- which(health[-1]<=0)
inoffensive <- c(last_shooter,dead)
danger <- which(!(1:3)%in%inoffensive)
alive <- which(!(1:3)%in%dead)
if(health[1]>3 & last_throw > last_prepare) out <- "P"
if(last_throw < last_prepare) out <- ifelse(length(last_shooter),paste("T",last_shooter[1],sep=""),paste("T",most_healthy[1],sep=""))
if(health[1]<=3 & last_throw > last_prepare){
    if(length(danger)){
        out <- paste("D",sample(danger,1),sep="")
    }else{
        out <- paste("S",sample(alive,1),sep="")
    }
}
cat(out)

Editar

Parece haver algum problema de comunicação entre esse bot e o seu controlador, pois todos os logs que eu olhei mostraram que meu bot apenas produzia N. Então, aqui está o mesmo bot, mas reescrito em Python, na esperança de que, se este também tiver um problema de comunicação, alguém o veja.
Para ser chamado com python Bomberman.py arg0 arg1.

import sys,re,random

history = sys.argv[2]
history = [k.split(",") for k in history.split()]
health = [k[0] for k in history]
last_turn = [k[-1] for k in history]
last_shooter = [i for i,x in enumerate(last_turn) if re.search(r'S[0-3]',x)]
last_prepare = [i for i,x in enumerate(history[0]) if x=='P']
if not len(last_prepare):
    last_prepare = [-1]

last_throw = [i for i,x in enumerate(history[0]) if re.search(r'T[0-3]',x)]
if not len(last_throw):
    last_throw = [0]

most_healthy = [i for i,x in enumerate(health) if x==max(health)]
dead = [i for i,x in enumerate(health) if x<=0]
inoffensive = last_shooter+dead
danger = [k for k in range(1,4) if k not in inoffensive]
alive = [k for k in range(1,4) if k not in dead]
if health[0]>3 and last_throw[-1] > last_prepare[-1]:
    out = 'P'

if last_throw[-1] < last_prepare[-1]:
    if len(last_shooter):
        out = 'T'+random.choice(last_shooter)
    else:
        out = 'T'+random.choice(most_healthy)

if health[0]<=3 and last_throw[-1] > last_prepare[-1]:
    if len(danger):
        out = 'D'+random.choice(danger)
    else:
        out = 'S'+random.choice(alive)

print(out)
plannapus
fonte
O nome do bot é relativamente fraca, mas eu corri para fora de idéia, se alguém pode pensar em um nome melhor, por favor comentário :)
plannapus
GymnastBomber !!
Cruncher
3

Neo

Desvie de um jogador vivo que não atirou no último turno. Se todo mundo vivo atirou no último turno, atire em um jogador vivo aleatório. Suicídio quando você vê faróis.

import java.util.Random;
public class Neo {
    public static void main(String[] args) {
        if(args.length < 2)
            return;
        String[] list = args[1].split(" ");
        if(list.length < 4)
            return;
        Random rand = new Random();
        int turn = list[0].split(",").length;
        if(turn == 49){
            System.out.print("S0");
            return;
        }
        int target=0;
        for(int i=1;i<4;i++)
            if(list[i].length()<2 || (list[i].charAt(0)!='-' && list[i].charAt(list[i].length()-2)!='S'))
                target=i;
        if(target>0){
            System.out.print("D"+target);
            return;
        }
        while(target<1){
            int i=rand.nextInt(3)+1;
            if(list[i].charAt(0)!='-')
                target=i;
        }
        System.out.print("S"+target);
    }
}

Não espero muito desse cara contra atiradores de granadas, mas contra atiradores pode funcionar muito bem. Veremos.

Geobits
fonte
Eu usei um pouco do seu código padrão na minha resposta . Espero que esteja tudo bem.
overactor
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1 at java.lang.String.charAt(String.java:658) at Neo.main(Neo.java:17)
precisa saber é o seguinte
@ es1024 Deve ser bom ir agora e não fará nada a cada primeiro turno.
Geobits
2

Século XXI e Meio

Essa entrada do Python se esquiva até que apenas jogadores passivos ou um único jogador agressivo permaneçam e depois começam a atirar. Ela espera que um marciano que esteja passando cuide de granadeiros e caminhoneiros bêbados.

A menos que eu tenha feito algo errado, isso é Python funcional. Certamente não se parece com o tipo de Python que escrevi antes de Haskell e seus amigos me encontrarem, e acho que não mudei nada. Mas se você souber melhor, por favor, me diga.

#!/usr/bin/env python
import sys
import random

## ==== Move Types ================================================== ##
def move_type (move):
    if "" == move:
        return "N"
    return move[0]

def is_passive_move (move):
    if "N" == move:
        return True
    if "D" == move_type (move):
        return True
    return False

def is_aggressive_move (move):
    return not is_passive_move (move)

def passive_moves (moves):
    return [m for m in moves if is_passive_move (m)]

def aggressive_moves (moves):
    return [m for m in moves if is_aggressive_move (m)]
## ================================================== Move Types ==== ##

## ==== Player Model ================================================ ##
class Player:
    def __init__ (self, number, health, moves):
        self.number = number
        self.health = health
        self.moves  = moves

    def last_move (self):
        if 0 == len (self.moves):
            return ""
        return self.moves[-1]

def player_from (number, player_string):
    x = player_string.split (",")
    health = int (x[0].strip ())
    moves = [move.strip () for move in x[1:]]

    return Player (number, health, moves)

def players_from (game_state):
    return [player_from (n, p) for (n, p) in
                                   zip (range(4), game_state.split ())]

def is_alive (player):
    return 0 < player.health

def i_am_dead (me):
    return not is_alive (me)

def can_shoot (player):
    return "S" != move_type (player.last_move ())

def is_passive (player):
    passive_move_count = len (passive_moves (player.moves))
    aggressive_move_count = len (aggressive_moves (player.moves))

    return passive_move_count > (aggressive_move_count + 1)

def players_who_can_breathe (players):
    return [p for p in players if is_alive (p)]

def players_who_can_shoot (players):
    return [p for p in players if can_shoot (p)]

def players_who_stand_around (players):
    return [p for p in players if is_passive (p)]
## ================================================ Player Model ==== ##

## ==== Actions ===================================================== ##
def shoot_randomly_at (possible_targets):
    chosen_target = random.choice (possible_targets)
    return "S{0}".format (chosen_target.number)

def dodge_one_of_the (potential_shooters):
    chosen_shooter = random.choice (potential_shooters)
    return "D{0}".format (chosen_shooter.number)

def do_nothing ():
    return "N"

def pick_move (game_state):

    players = players_from (game_state)
    me = players[0]
    enemies = players[1:]

    if i_am_dead (me):
        return do_nothing ()

    living_enemies = players_who_can_breathe (enemies)
    if 1 == len (living_enemies):
        return shoot_randomly_at (living_enemies)

    passive_enemies = players_who_stand_around (living_enemies)
    if len (living_enemies) == len (passive_enemies):
        return shoot_randomly_at (passive_enemies)

    potential_shooters = players_who_can_shoot (living_enemies)
    if 0 < len (potential_shooters):
        return dodge_one_of_the (potential_shooters)

    return do_nothing ()
## ===================================================== Actions ==== ##

if "__main__" == __name__:

    game_state = sys.argv[2]
    print (pick_move (game_state))

Correr como:

python twenty-fourth-and-a-halfth-century.py 0 "5 5 5 5"
comperendinous
fonte
2

Assustada

Esta submissão tem medo de todos. Mas é especialmente assustador para algumas pessoas. Então, descobre quem é o mais perigoso e atira neles. Se vários inimigos parecerem os mais perigosos, ele atira aleatoriamente.

import sys
import random


def is_alive(player):
    return int(player.split(",")[0]) > 0


# Anyone with a live grenade who is alive is dangerous
def is_dangerous(player):
    return player.count("P") > player.count("T") and \
        int(player.split(",")[0]) > 0


def health(player):
    return int(player.split(",")[0])


# Failing that, healthy people are dangerous
def danger_rating(player):
    return 6 if is_dangerous(player) else health(player)

enemies = sys.argv[2].split()[1:]

highest_danger = max(danger_rating(enemy) for enemy in enemies)
most_dangerous_enemy = random.choice(
    [enemy_num+1 for enemy_num in range(len(enemies))
     if danger_rating(enemies[enemy_num]) == highest_danger])

print("S"+str(most_dangerous_enemy))

Este é python (2 ou 3, o mesmo resultado em qualquer um.) Salve como scared.py, execute compython3 scared.py

isaacg
fonte
2

Bastardo manipulador - Python

Prepara e lança granadas. Se ele acha que não há tempo ou há poucos inimigos, ele atira. Se ele está sozinho, ele tenta enganar o outro cara.

import sys

def health(p):
    return int(p[0])

def is_alive(p):
    return health(p) > 0

def can_act(p):
    return is_alive(p) and p[-1][0] != 'S'

def can_throw(p):
    return is_alive(p) and p[-1][0] == 'P'

def shot_first(p):
    if len(p) == 1:
        return False
    return p[1][0] == 'S'

def act(a):
    print a
    sys.exit(0)

player = sys.argv[2].split()[0].split(',')
enemies = [e.split(',') for e in sys.argv[2].split()[1:]]
healthiest = sorted(enumerate(enemies, 1), key=lambda e:health(e[1]))[-1]
alive = sum(is_alive(e) for e in enemies)

if alive == 1:
    i, e = healthiest
    if health(e) <= 2 and not can_act(e):
        act('S%d' % i)
    if can_throw(player):
        act('T%d' % i)
    if can_throw(e):
        act('S%d' % i)
    if can_act(e) and shot_first(e) and len(player) < 40:
        act('D%d' % i)
    if len(player) > 45:
        act('P')
    act('S%d' % i)

if can_throw(player):
    i, e = healthiest
    act('T%d' % i)

if len(player) > 45:
    act('P')

if health(player) <= 2 or any(can_throw(e) for e in enemies) or alive == 2:
    i, e = healthiest
    act('S%d' % i)

act('P')
fhyqrkka
fonte
2

Osama

Eu venho tentando isso há um dia ou mais, agora é hora de postar e ver como os outros evoluíram nesse meio tempo.

module Main where

import Data.List
import Data.Ord
import System.Environment

words' "" = []
words' s = s' : words' (tail' s'')
  where
    (s', s'') = break (==',') s
    tail' (',':r) = r
    tail' r = r

nRound = length . words'

lastAction = last . words'

health :: String -> Int
health = read . head . words'

alive = (>0) . health

grenadeAge :: String -> Int
grenadeAge p | not (alive p) = 0
             | otherwise = g 0 $ tail $ words' p
  where
    g n (a:b:r) | head a == 'S' = g (if n>0 then n+2 else 0) r
    g 0 ("P":r) = g 1 r
    g n (('T':_):r) | n>0 = g 0 r
    g n (_:r) | n>0 = g (n+1) r
    g n (_:r) = g n r
    g n [] = n

prepared :: String -> Bool
prepared p = alive p && head (lastAction p) /= 'S'

nShotMe = length . filter (=="S0") . words'

getPlayer = (!!)

action players@(me:them) | not (prepared me) = "S2" -- bogus
                         | nRound me >= 49 = "S0"
                         | grenadeAge me >= 1 = 'T':(show $ maximumBy (comparing (nShotMe . getPlayer players)) l)
                         | any prepared them && nRound me > 0 = 'D':(show $ maximumBy (comparing (nShotMe . getPlayer players)) l)
                         | otherwise = 'S':(show $ maximumBy (comparing (health . getPlayer players)) l)
  where l = filter (alive . (getPlayer players)) [1..3]



main = do
  players <- fmap (words . head . tail) getArgs
  putStrLn $ action players

Compile com ghc -O2 osama.hse execute usando ./players/Osama/osama.

TheSpanishInquisition
fonte
2

Sniper - Lua

No primeiro turno, ele atirará em uma pessoa aleatória e, em seguida, atirará em qualquer jogador que possa matar (2 ou 1 ponto de vida). Se nenhum deles funcionar, ele tentará atirar no jogador que atirou por último, caso contrário, atirará em um jogador aleatório. Correr comlua Sniper.lua

turns = arg[2]
health = string.sub(turns, 1, 1)
--make random numbers random
math.randomseed(io.popen("date +%s%N"):read("*all"))
math.random(); math.random(); math.random()
function Split(str, delim, maxNb)
    -- Eliminate bad cases...
    if string.find(str, delim) == nil then
        return { str }
    end
    if maxNb == nil or maxNb < 1 then
        maxNb = 0    -- No limit
    end
    local result = {}
    local pat = "(.-)" .. delim .. "()"
    local nb = 0
    local lastPos
    for part, pos in string.gmatch(str, pat) do
        nb = nb + 1
        result[nb] = part
        lastPos = pos
        if nb == maxNb then break end
    end
    -- Handle the last field
    if nb ~= maxNb then
        result[nb + 1] = string.sub(str, lastPos)
    end
    return result
end
enemies = Split(turns, " ")
--first turn
if #enemies[1] == 1 then
  print(string.format("S%i",math.random(1,3)))
  os.exit()
end
--kills if possible
for enemy=1,3 do
  if (tonumber(string.sub(enemies[enemy + 1],1,1)) or 0) < 3 and string.sub(enemies[enemy + 1],1,1) ~= "-" then
    print(string.format("S%i",enemy))
    os.exit()
  end
end
--shoots the last person that shot at it
for enemy=1,3 do
  if string.sub(enemies[enemy + 1],#enemies[enemy + 1]-1) == "S0" and tonumber(string.sub(enemies[enemy + 1],1,1)) > 0 then
    print(string.format("S%i",enemy))
    os.exit()
  end
end
--otherwise shoot a random alive person
local aliveEnemies = {}
for enemy=1,3 do
  if string.sub(enemies[enemy + 1],1,1) ~= "-" then
    aliveEnemies[#aliveEnemies+1]=enemy
  end
end
print(string.format("S%i",math.random(1,#aliveEnemies)))
waylon531
fonte
Na verdade, ele será executado com um argumento extra primeiro; por exemplo lua Sniper.lua 3 "5,S1 3,D3 5,N 5,P",. Pode ser necessário verificar seu argíndice.
comperendinous
@comperendinous, obrigado, corrigido agora
waylon531
Olá, @ waylon531, pergunta sobre Lua: the randomseed math.randoms "math.randomseed (os.time ()) math.random (); math.random (); math.random ()" não é suficiente para randomizar o roteiro?
AndoDaan
11
No AndoDaan, de acordo com lua-users.org/wiki/MathLibraryTutorial, alguns SOs sempre retornam o mesmo número na primeira vez que math.random () é chamado.
waylon531
lua: ./players/Sniper/Sniper.lua:38: attempt to compare nil with numberstack traceback:./players/Sniper/Sniper.lua:38: in main chunk [C]: in ?
es1024
2

Darwin

A sobrevivência do mais apto significa que os menos saudáveis ​​devem morrer.

Fundamentação

Olhando para o lote de resultados da terça-feira (12), parece haver três grupos distintos: sobreviventes; o efetivamente suicida; e o pior que o inútil. Os sobreviventes compartilham estratégias simples baseadas em tiro. Enquanto alguns outros bots ( Spock , Coward ) terão como alvo o inimigo menos saudável, eles também complicam suas estratégias com outras ações. Este não. Como o Simple Shooter , ele tem uma definição clara do alvo e o mantém implacavelmente. Será interessante ver onde ele se encaixa nos resultados.

#!/usr/bin/env python

import sys
import random

## ==== Player Model ================================================ ##
class Player:
    def __init__ (self, number, health):
        self.number = number
        self.health = health

def player_from (number, player_string):
    x = player_string.split (",")
    health = int (x[0].strip ())

    return Player (number, health)

def players_from (game_state):
    return [player_from (n, p) for (n, p) in
                                   zip (range(4), game_state.split ())]

def is_alive (player):
    return 0 < player.health

def i_am_dead (me):
    return not is_alive (me)

def players_who_can_breathe (players):
    return [p for p in players if is_alive (p)]

def players_by_health (players):
    return sorted (players, key=lambda p: p.health)

def least_healthy_players (players):
    sorted_living_players = \
        players_by_health (players_who_can_breathe (players))
    lowest_living_health = sorted_living_players[0].health
    return [p for p in players if lowest_living_health == p.health]
## ================================================ Player Model ==== ##

## ==== Actions ===================================================== ##
def shoot_randomly_at (possible_targets):
    chosen_target = random.choice (possible_targets)
    return "S{0}".format (chosen_target.number)

def do_nothing ():
    return "N"

def pick_move (game_state):
    players = players_from (game_state)
    me = players[0]
    enemies = players[1:]

    if i_am_dead (me):
        return do_nothing ()

    least_healthy_enemies = least_healthy_players (enemies)
    return shoot_randomly_at (least_healthy_enemies)
## ===================================================== Actions ==== ##

if "__main__" == __name__:

    game_state = sys.argv[2]
    print (pick_move (game_state))

Esta é uma versão simplificada e levemente modificada do meu século XXI e meio anterior e compartilha sua invocação:

python darwin.py 3 "5 5 5 5"
comperendinous
fonte
2

Zaenille - C

Prioridades:

  1. Atire se houver 1 em 1
  2. Atirar granadeiros
  3. Dodge
  4. Nada (apenas para confundir alguns)

Ajuntar com gcc <filename.c> .

Corra com ./a.out <parameters>.

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]){
    char* input = argv[2];
    int enemyCount=1;
    int aliveCount=0;
    int aliveEnemy=0;

    //default
    char action = 'N';
    int target = NULL;

    const char delim[1] = " ";
    char *token;

    //first turn
    if(strcmp(input,"5 5 5 5")==0){
        printf("D1");
        return 0;
    }

    token = strtok(input, delim);
    token = strtok(NULL, delim); //skip to the first enemy

    while(token != NULL){
        //if someone is alive :
        if(strstr(token,"-")==NULL && token[0]!='0'){
            aliveCount++;
            aliveEnemy=enemyCount;
            //if that person did nothing this turn, take it as a tip that he will shoot next turn, and dodge
            if(strstr(token, "N")!=NULL){
                action = 'D';
                target=enemyCount;
            }

            //if that person prepared a grenade, shoot him down
            if(strstr(token, "P")!=NULL){
                action = 'S';
                target=enemyCount;
            }
        }

        token = strtok(NULL, delim);
        enemyCount++;
    }

    //if there is 1 enemy left, shoot him down
    if(aliveCount==1){
        action='S';
        target=aliveEnemy;
    }

    printf(action=='N'?"N":"%c%d",action,target);

    return 0;
}
Mark Gabriel
fonte
11
O primeiro argumento (inteiro) não indica a contagem de rounds, se os exemplos dados na pergunta são algo a ser seguido. Você não iria querer atirar-se no primeiro turno só porque você tinha sido atribuído ao número impasse 82.
comperendinous
Realmente? D: Obrigado @comperendinous. Editará o código.
Mark Gabriel
2

InputAnalyzer

A chave de um jogo como esse é analisar como todos os seus oponentes estão jogando para responder de acordo. Meu bot fará exatamente isso usando algoritmos complicados que resultarão no uso de meus oponentes, para minha vantagem, dando uma vitória decisiva!

Edit: Eu agora

  1. esquivar qualquer jogador que tenha uma granada ao vivo
  2. não vou mais tentar atirar / jogar / me esquivar.

import System.Environment   
import Data.Char (ord)
import Data.List.Split

main = do 
    args <- getArgs
    let secondArg = (last args)
    let opt = (argCount secondArg 0)
    let list = (splitOn " " secondArg)
    let enemysToCheck = [1,2,3]
    let target = (avoidShootingSelf (findTarget (last args) 0 0 0 0))
    putStrLn (decide list enemysToCheck opt target)

argCount :: String -> Int -> Int
argCount (s:str) i
    |(length str) == 0 = i `mod` 4
    | otherwise = (argCount str (i + (ord s)))

--myPseudo takes number 0-3, and a possible target and translates it to a command 
myPseudo :: Int -> Int -> String
myPseudo 0 b = "S" ++ (show b)
myPseudo 1 b = "D" ++ (show b)
myPseudo 2 b = "P"
myPseudo 3 b = "T" ++ (show b)

decide :: [String] -> [Int] -> Int -> Int -> String
decide [] [] a b = (myPseudo a b)
decide (x:xs) [] a b = (myPseudo a b)
decide xs (y:ys) a b
    | (liveGrenade z 0) == True = "D" ++ (show y)
    | otherwise = (decide xs ys a b)
    where z = xs!!y

--checks if a player has a live grenade
liveGrenade :: String -> Int -> Bool
liveGrenade [] a = a > 0
liveGrenade (s:str) a
    | s == 'T' = (liveGrenade str (a - 1))
    | s == 'P' = (liveGrenade str (a + 1))
    | otherwise = (liveGrenade str a)

--findTarget picks a target by doing some irrelevant string processing on the 2nd argument
findTarget :: String -> Int -> Int -> Int -> Int -> Int
findTarget [] a b c d = ((maximum [a,b,c,d]) `mod` 4)
findTarget (s:str) a b c d
    | s == 'S' = (findTarget str (a + 1) b c d)
    | s == 'D' = (findTarget str a (b + 1) c d)
    | s == 'P' = (findTarget str a b (c + 1) d)
    | s == 'T' = (findTarget str a b c (d + 1))
    | s == 'N' = (findTarget str a b c (d + 1))
    | otherwise = (findTarget str a b c d)

--Makes sure I do target myself takes int 0-3
avoidShootingSelf :: Int -> Int
avoidShootingSelf 0 = 1
avoidShootingSelf a = a

Compile o bot com o seguinte comando (Precisa ter o ghc)

ghc --make InputAnalyzer.hs

O comando Shell para executar deve ser o seguinte

./InputAnalyzer

Nota: Eu testei no Windows, por isso, se você tiver algum problema em relação à conformidade / execução, diga-o nos comentários e farei o possível para descobrir o comando correto.

Sahar Rabinoviz
fonte
11
Bem, suponho que essa seja uma maneira de obter um gerador de pseudo-aleatório ponderado em Haskell.
comperendinous
2

Cão chamado Coragem

Primeira coisa - atire nos bandidos à vista. Esquive-se aleatoriamente até que alguém prepare uma granada. Então, quando todos atirarem nele, prepare minha própria granada e jogue-a em alguém. Mas o homem da distração.

Edit: Agora implementado como eu pensei que deveria ser. Antes, a pontuação era: 35,9

Atualizado: às vezes atira em vez de esquivar

couragethedog.py

import sys
from collections import defaultdict as ddict
from random import choice
args = sys.argv
info = " ".join(args[2:]).strip('"').split(" ")
players = ddict(dict)
for i,s in enumerate(info):
    parts = s.split(",")
    players[i]["health"]=int(parts[0])
    players[i]["last"]=parts[-1]
    players[i]["history"]=parts[1:]
    players[i]["turn"]=len(parts)
me=0
others=[1,2,3]
turn=players[me]["turn"]
alive = filter(lambda p:players[p]["health"]>0,others)
def act():
    if turn is 1:
        return "S%d" % choice(alive)
    if "P" == players[me]["history"][-1]:
        targets = set(alive)
        for i in alive:
            if "P" == players[i]["history"][-2]:
                targets.remove(i)
        return "T%d" % choice(list(targets))
    for i in others:
        if players[i]["history"][-1] is "P":
            return "P"
    if choice([True,False,False]):
        return "S%d" % choice(alive)
    return "D%d" % choice(alive)
print act()

Correr como

python couragethedog.py
loa_in_
fonte
2

MAD - Java

O bot da MAD confia no poder da intimidação através da destruição mútua garantida . Sempre que ele não tem uma granada pronta, ele prepara uma. Ele então esquiva possíveis artilheiros até que alguém tente causar dano a ele ou sua granada esteja prestes a explodir. A partir do momento em que é atacado, ele lança granadas para quem tentou causar mais danos a ele neste jogo até agora. Se sua granada está prestes a explodir, ele bombardeia o jogador principal. MAD não é contra atirar em alguém quando não há nada para se esquivar ou atirar diretamente uma granada e sua granada ainda é boa por pelo menos um turno.

    import java.util.ArrayList;
import java.util.Random;

public class MAD 
{
    public static void main(String[] args) 
    {
        if(args.length < 2)
        {
            return; // nothing to do here
        }
        String[] players = args[1].split(" ");
        if(players.length < 4 || !isAlive(players[0]))
        {
            return; // nothing to do here
        }
        Random rand = new Random();

        int grenadeExplodes = grenadeExplodes(players[0]);        
        if(grenadeExplodes==-1)
        {
            System.out.print("P"); // I don't feel safe without a prepared grenade in my hand
            return;
        }

        int highestDamage = -1;
        int playerToShoot = -1;        
        for(int i=1; i<4; i++) // did anyone try to hit me?
        {
            int damage = damageAttempted(players[i], 0);
            if(isAlive(players[i]) && (damage>highestDamage || (damage==highestDamage && rand.nextDouble()>0.5)))
            {
                highestDamage = damage;
                playerToShoot = i;
            }           
        }

        if(highestDamage > 0)
        {
            System.out.print("T" + Integer.toString(playerToShoot)); // don't tell me I didn't warn you
            return;
        }

        int highestHealth = -1;
        int healthiestPlayer = -1;      
        for(int i=1; i<4; i++) // who is doing too well for their own good?
        {
            int health = getHealth(players[i]);
            if(health>highestHealth || (health==highestHealth && rand.nextDouble()>0.5))
            {
                highestHealth = health;
                healthiestPlayer = i;
            }
        }

        if(grenadeExplodes==0)
        {
            System.out.print("T" + Integer.toString(healthiestPlayer).charAt(0)); // get this hot head outta here!!
            return;
        }

        // I've got time to flaunt my grenade around

        ArrayList<Integer> playersToDodge = new ArrayList<Integer>();       
        for(int i=1; i<4; i++) // lets see who could shoot me
        {
            if(canMove(players[i]) && grenadeExplodes(players[i])!=0)
            {
                playersToDodge.add(i);
                if(grenadeExplodes(players[i])==-1) // players who have no grenade are more likely to shoot
                {
                    playersToDodge.add(i);
                }
            }
        }

        if(playersToDodge.size()>0)
        {
            System.out.print("D" + Integer.toString(playersToDodge.get(rand.nextInt(playersToDodge.size() - 1))).charAt(0)); // what do we say to would-be gunners?
            return;
        }

        if(grenadeExplodes!=1)
        {
            System.out.print("S" + Integer.toString(healthiestPlayer).charAt(0)); // seems like I can take a free shot at someone
        }
        else
        {
            System.out.print("N"); // wouldn't want to end up with an exploding grenade in my hand while being unable to throw it.
        }

    }

    public static boolean isAlive(String player) 
    {
        return player.charAt(0)!='-'; 
    }

    public static boolean canMove(String player)
    {
        return isAlive(player) && player.charAt(player.length()-2)!='S';
    }

    public static int grenadeExplodes(String player)
    {
        String[] actions = player.split(",");

        if(actions.length>3 && actions[actions.length - 3].charAt(0)=='P' 
            && actions[actions.length - 2].charAt(0)=='T' 
            && actions[actions.length - 1].charAt(0)=='P')
        {
            return 0;
        } 
        else if(actions.length>2 && actions[actions.length - 2].charAt(0)=='P' 
            && actions[actions.length - 1].charAt(0)=='T')
        {
            return 1;
        } 
        else if(actions.length>1 && actions[actions.length - 1].charAt(0)=='P')
        {
            return 2;
        }
        else
        {
            return -1;
        }
    }

    public static int damageAttempted(String player, int target)
    {
        String[] actions = player.split(",");
        int damage = 0;
        char targetChar = Integer.toString(target).charAt(0);
        for(int i=0; i<actions.length; i++)
        {
            if(actions[i].charAt(0)=='S' && actions[i].charAt(1)==targetChar)
            {
                damage += 2;
            } 
            else if (actions[i].charAt(0)=='T')
            {
                if(actions[i].charAt(1)==targetChar)
                {
                    damage += 8;
                }
                else
                {
                    damage += 3;
                }
            }
        }

        return damage;
    }

    public static int getHealth(String player)
    {
        return Integer.parseInt(player.split(",")[0]);
    }
}

Esse Bot provavelmente terá um desempenho ruim, mas gostei da ideia de qualquer maneira. O MAD provavelmente se sairia melhor em um campo com bots mais inteligentes que registram o comportamento de outros bots e com mais correspondências entre 4 bots.

overactor
fonte
Alguns créditos vão para o Geobits, eu roubei algum código da placa de entrada de Neo.
overactor
Não demorou muito, nenhum crédito necessário :)
Geobits
A chamada java MAD 43 "5 5 5 5"parece não produzir nada.
es1024
2

Sádico

Pitão

Sua prioridade é causar dor e granadas feridas. Ele faz o primeiro turno. Ele gosta de matar quando você não pode atacar. Ele brinca com SSSs (atiradores simples e simples), esquivando-se e puxando para prolongar o domínio. Ele até escolhe atacar quem primeiro não fez nada a ninguém.

Como ele usa granadas, ele (e todos os outros) geralmente não sobreviverão ao segundo ou terceiro turno. Se ele estiver emparelhado com outro granadeiro, todos morrerão. Isso significa que não espero vencer, mas escrevi isso para aprender python (nunca o usei antes e estou tentando fazer uma introdução a várias novas linguagens). Existem vários outros, "puxe estreias", por isso, se você achar que é muito semelhante, me avise. Os outros não parecem estar dispostos a puxar e depois desviar, no entanto.

import sys    

def ident(thatguy):

    return int(thatguy.split(",")[0])

def health(thatguy):
    return int(thatguy.split(",")[1])

def shooter(thatguy):
    if(len(thatguy.split(","))<3):
        return 1==1
    else: return thatguy.split(",")[2][0]=="S"

def mosthealth(group):
    bigbad=group[0]
    for foe in group:
        if (health(foe)>health(bigbad)): bigbad=foe
    return bigbad

def igotanuke(mine):
    return mine.count("P")-mine.count("T")>0

def guytonuke(allguys,fighters):
    backup=allguys[:]
    for Aguy in backup:
        if(health(Aguy)<4):
            allguys.remove(Aguy)
            if (shooter(Aguy)): fighters.remove(Aguy)

    if(len(allguys)==0): return mosthealth(backup)
    if (len(allguys)==len(fighters)):
        return mosthealth(allguys)
    else:
        for fighter in fighters: allguys.remove(fighter)
        return mosthealth(allguys)

raw = sys.argv[2]
player = raw.split(" ")
thisisme=player.pop(0)
turn = len(player[0].split(","))-1

guys=[]
gunners=[]
c=1
for dude in player:
    dude=str(c)+","+dude
    c+=1
    if (health(dude)>0): 
        guys.append(dude)
        if (shooter(dude)):
            gunners.append(dude)

if (turn==0): print "P"
elif(turn==49): print"S0"
elif(igotanuke(thisisme))&( turn % 2 == 1): print "T"+str(ident(guytonuke(guys,gunners)))
elif(len(guys)<2)&(len(gunners)>0) & (turn % 2 == 1): print P
elif(turn % 2 == 0) & (len(gunners)>0): print "D"+str(ident(mosthealth(gunners)))
elif(turn % 2 == 1) & (len(gunners)>0): print "S"+str(ident(mosthealth(gunners)))
else: print "S"+str(ident(mosthealth(guys)))
Kaine
fonte
Eu não acho que isso raw_inputvai funcionar. sys.argv[2]parece ser o consenso para entradas do Python. Você também pode encontrar uso para pop, o que permitiria condensar thisisme=player[0];player.remove(player[0])no mais simples thisisme=player.pop(0).
comperendinous
@comperendinous Eu estava testando o código no Ideone e o sys.argv não funciona (provavelmente devido à importação do sys). É por isso que eu usei raw_input. Existe uma diferença que levaria o último a não funcionar? Nesse caso, provavelmente vou precisar encontrar outro compilador online para python. Obrigado pela sugestão com pop! Não percebi que o comando permitia que o índice fosse especificado. Vou usá-lo para qualquer código python futuro.
kaine
11
raw_inputrecebe STDIN, mas o histórico do jogador é passado para o seu programa como um argumento de linha de comando, e é por isso que você precisa sys.argv. Para fins de teste, você pode configurá-lo manualmente com sys.argv = ["sadist.py", "0", "5 5 5 5"]. Então você deve poder ligar player=sys.argv[2].split(). Se sysrealmente for impossível importar , para testar, você pode até soltar o ponto e chamar a matriz sysargv. Contanto que todo o resto funcione e você retorne à sys.argvsua submissão, tudo ficará bem.
comperendinous
@comperendinous para confirmar, se eu chamar sys.argv, ele retornará como uma matriz o nome do programa em 0, esse número único em 1 e a parte real que eu uso em 2? São todas cordas. Com essa informação, eu devo poder editá-la corretamente. Muito obrigado!
kaine