Separación de cuatro hombres


54

Separación de 4 hombres

Descripción

De alguna manera te has encontrado en un enfrentamiento de cuatro vías. Un arma cargada descansa en tus manos, y algunas granadas están enganchadas en tu cinturón.

El objetivo es tener la mayor salud al final de un enfrentamiento. Un enfrentamiento termina cuando, como máximo, una persona tiene una cantidad positiva de salud.

Cada jugador tiene 5salud y muere cuando su salud cae a / debajo 0. El turno que muere un jugador es el último turno en el que ese jugador puede recibir daño.

Si hay un jugador en vivo al final de un enfrentamiento, ese jugador gana. De lo contrario, el jugador con la salud menos negativa gana.

Comportamiento

  • Dispara : dispara a alguien.

    • 2 daño si disparas a un enemigo vivo
    • 0 daño si dispara a un enemigo muerto
    • health_at_start_of_turn+2daño si te disparas a ti mismo. (Tenga en cuenta que esto lo dejará con MÁS -2salud).
    • Si un enemigo te dispara en el mismo turno en el que te disparas a ti mismo, terminarás el enfrentamiento con -4 puntos de vida (igual recibirás daño de otros jugadores el turno en que te mates).
    • Su acción el siguiente turno será ignorada (y se supondrá que es Nothing).
  • Esquiva : intenta esquivar el tiro de un solo oponente.

  • Prepárese : desenganche su granada y prepárese para lanzarla.

    • Solo tienes tres turnos para lanzarlo, antes de explotar ( 6daño a ti mismo, 3daño a todos los enemigos vivos)
    • Morir con una granada no lanzada es equivalente a no arrojar la granada durante tres turnos.
  • Lanzar : Lanza la granada hacia alguien y espera lo mejor.

    • El objetivo recibe 8daño si está vivo
    • Todos los demás (incluido usted) reciben 3daño si están vivos
  • Nada : quédese de brazos cruzados y mire a todos morir.

Entrada

Su programa recibirá la siguiente información:

  • La salud de cada jugador.
  • Una lista de las acciones tomadas por ese jugador desde el inicio del enfrentamiento A continuación se muestra el formato de la información que se pasa por jugador:

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

Las acciones se darán en el formato especificado en la sección Salida .

Recibirá 4 cadenas de este tipo, separadas por un espacio, y pasadas como un solo argumento. El orden de estas cadenas es:

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

Las cadenas se pasan como el segundo argumento. El primer argumento contiene un número entero que identifica de forma exclusiva el enfrentamiento que se está promulgando. Se garantiza que los enfrentamientos entre el mismo conjunto de jugadores no serán simultáneos. Sin embargo, se producirán múltiples enfrentamientos al mismo tiempo.

Por ejemplo:

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

Actualmente, el jugador y el segundo oponente tienen 3 puntos de vida, el primer oponente tiene 5 puntos de vida y el tercer oponente tiene -2 puntos de vida y está muerto.

En el primer turno:

  • El jugador 1 disparó al enemigo 2
  • El enemigo 1 preparó una granada
  • Enemigo 2 jugador de tiro
  • El enemigo 3 se disparó

En el segundo turno:

  • Todos los jugadores no hicieron nada. (El jugador y el enemigo 2 no pueden hacer nada ya que dispararon en el turno anterior. El enemigo 3 está muerto: lo hará Nothingpor el resto del enfrentamiento).

El segundo argumento en el inicio de un enfrentamiento es: 5 5 5 5.

Salida

Se debe emitir un comando en el siguiente formato. Una salida no válida se interpreta como 'Nada'. Un comando que requiere un objetivo debe ser seguido por un número entero ( 0-3, con 0lo que representa el jugador, y 1-3que representa enemigos 1-3).

  • S[target]: Dispara [objetivo].
  • D[target]: Intenta esquivar [objetivo].
  • P: Prepara una granada.
  • T[target]: Lanza la granada a [objetivo].
  • N: Hacer nada.

Un comando que necesita un objetivo, pero se alimenta un objetivo no entre 0y 3o no alimenta un objetivo totalmente será asumido a objetivo 0(el jugador).

Puntuación

Al final de cada enfrentamiento, los jugadores reciben una puntuación calculada por la siguiente fórmula:

35 + health at end of standoff 

En el caso de que un jugador pone fin a un enfrentamiento con la salud negativos, que se recibirá una puntuación por debajo de 35 . Los siguientes puntos también son recompensados ​​como un bono:

  • Mayor salud: +4 puntos
  • Segundo más saludable: +2 puntos
  • Tercero más salud: +1 punto.

En caso de empate, se otorga la bonificación más baja (si dos personas empatan con la mayor cantidad de salud, a ambas se les otorga +2; si hay 3 personas con la mayor cantidad de salud, +1, y si todos terminan igual, +0).

El puntaje final se determina calculando la media de todos los puntajes individuales.

Reglas / Detalles

  • El orden de los eventos dentro de un turno es el siguiente:
    • Todos los jugadores hacen sus acciones.
    • Los jugadores que tienen 0 o menos de vida mueren.
    • Las granadas no lanzadas que necesitan explotar explotarán (los jugadores que acaban de morir siguen heridos, ya que este es el turno en que murieron).
  • No hay colaboración entre las entradas.
  • Se producirán tres * enfrentamientos entre cada conjunto de 4 jugadores. (El orden de los jugadores puede variar con cada enfrentamiento).
  • Las entradas que consuman cantidades excesivas de memoria de espacio en disco serán descalificadas.
  • Leer o modificar archivos que no sean los de su entrada descalificará su entrada.
  • Un camión, conducido por un borracho, atropellará a todos los jugadores vivos después del 50thturno, si el enfrentamiento aún no ha terminado al final del 50thturno.
    • Este camión causa 20 daños a todos los jugadores vivos.
  • Los enfrentamientos suceden rápidamente. Los programas se cortan después de 1 segundo.
  • Su programa se llamará cada turno, incluso después de que haya muerto.
  • Puede leer o escribir archivos en su directorio solamente (si su entrada se llama JohnDoe, puede guardar archivos en el directorio players / JohnDoe /); sin embargo, este NO será el directorio actual mientras se ejecuta su secuencia de comandos.
  • Los enfrentamientos tendrán lugar en una máquina que ejecute Arch Linux (Versión 2014.08.01).

El controlador está disponible en GitHub .

Incluya lo siguiente en su publicación:

  • Un nombre para tu bot
  • Un comando de shell para ejecutar el bot (ej. java Doe.java) La entrada se pasará a través de la línea de comando como un solo argumento ( java Doe.java 5 "-2,S0 -2,S1 -2,S2 5,N")
  • Código de tu bot
  • Cómo debe compilarse el bot (si corresponde)
  • Idioma (y versión si corresponde, especialmente para python)

* El controlador tarda demasiado para seis.

Marcador

                      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

Registros: en GitHub


1
¿Tienes exactamente una granada o tienes muchas? ¿Puedes preparar varias granadas a la vez?
isaacg

2
@Bob Estoy bastante seguro de que EmoWolf se agregó a las lagunas estándar que ya no son divertidas . Aunque una entrada suicida podría no ser tan terrible.
es1024

3
Lección para todos: no beber y conducir.
Mark Gabriel

8
@ es1024 Cuando el suicidio es en realidad una estrategia viable, se debe permitir una presentación de tipo EmoWolf. ¡Especialmente cuando las acciones disponibles incluyen explícitamente suicidio! No es tanto un "vacío legal" ahora, ¿verdad? Y no es realmente una ventaja injusta, que en realidad son la mayoría de esas lagunas. Pero esa es solo mi opinión.
Bob

3
Según el funcionamiento del controlador un par de veces, parece bastante ruidoso. Si este concurso alguna vez se cierra, probablemente deberías aumentar el número de carreras para suavizarlo un poco.
Davis Yoshida el

Respuestas:


7

Observador

Este chico analiza a sus enemigos. El objetivo es sobrevivir hasta que solo quede un oponente "agresivo", y luego matarlo en un enfrentamiento épico.

Compilar: javac Observer.javaEjecutar: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);
    }
}

!player.contains("S" + id)¿Es esta una condición necesaria en la función "isAggressive"? Un jugador suicida estará muerto de todos modos
Cruncher

22

Granadero

Las armas están sobrevaloradas. Un verdadero enfrentamiento escocés es así:

  • Preparar
  • Lanza al enemigo con más salud
  • Repite (si por algún milagro sigues vivo)

Si bien esto parece trivial, probablemente no sea una estrategia terrible . Dado que las armas y las granadas tienen un ciclo de dos turnos, esta es, de lejos, la forma más eficiente de hacer daño.

Por supuesto, si los tres oponentes me disparan en la primera ronda, no es bueno. Pero tampoco mucho más sería.

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

Compilar / ejecutar en la forma estándar de Java:

> javac Grenadier.java
> java Grenadier arg0 arg1

1 nota al pie sin sentido


41
jajaja la nota al pie
orgulloso Haskeller

Creo que lanzar una granada y luego disparar es más eficiente. La posibilidad de que sobrevivas 4 turnos con esta estrategia es muy baja. Pero 3 quizás (sí, ambos toman 2, pero el segundo turno para disparar es después de la acción, no antes)
Cruncher

@Cruncher Probablemente tengas razón. Eric dijo lo mismo en el chat. Le dije que mi hombre no cree en las armas y que es demasiado terco para usar esa lógica, así que publicó esa estrategia. Sin embargo, todavía creo que esto es más eficiente , si estamos hablando estrictamente del daño infligido. Eso no significa que sea más efectivo para ganar el juego. Incluso si muero en el tercer turno, mi segunda granada sigue sonando. Entonces, si vivo hasta entonces, eso garantiza más de 6 daños para todos, se acabó el juego.
Geobits

@Geobits ahora que lo pienso, esto puede ser mejor. Lo que más importa es el delta entre usted y sus oponentes. Cuando explota la granada, ganas +3 delta con quién la lanzaste, y +0 con el resto. Una red de +3. Disparo. Te gana un +2 delta con quien disparas. +0 con el resto. Creo que el problema es que tú -3 con personas que ya están muertas. Deberías disparar si alguien está muerto :)
Cruncher

2
@codebreaker Nunca lo jugué. Es una referencia de la vida real .
Geobits

16

Regla de Asimov Número 0 Bot - Python

Un robot no puede dañar a la humanidad o, por inacción, permitir que la humanidad sufra daños.

Bastante sencillo, atacará al primer jugador que vea sosteniendo una granada para proteger a la mayoría de los humanos. Si nadie es una amenaza para la mayoría de los humanos, no hará 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

Ejecútalo como:

python rule0bot.py

2
Tu robot es ilógico. Si el jugador que sostiene la granada lanza, la humanidad recibe 8 + 3 + 3 + 3 = 17 de daño. Si lo matas con el disparo, la humanidad recibe 2 + 6 + 3 + 3 + 3 = 17 de daño. En ambos escenarios, el que tenga la granada explotada toma 8 y todos los demás toman 3 (a menos que hayan muerto previamente). La humanidad en su conjunto no se ve afectada. Sin embargo, todavía me gusta. +1: D
Geobits

44
En realidad, el mejor escenario para la humanidad es esperar que la granada sea arrojada al robot;)
Geobits

1
@Geobits No tratar de detener a alguien que es una amenaza es contra la naturaleza de los robots. Intentará detener a alguien que sostiene una granada para evitar que la mayoría (otras dos) resulten heridas. ¿Has leído yo, robot? Esta lógica está respaldada por Little Lost Robot y The Evitable Conflict.
William Barbosa

Lo he leído, pero lo que digo es que dispararles no lo detiene aquí. Si muere mientras sostiene la granada, aún explota. No solo eso, sino que la cantidad total de daño hecho a la humanidad sigue siendo la misma. Estás haciendo daño directo a un humano sin ganancia para la humanidad.
Geobits

2
+1 No estoy de acuerdo con el voto de Kyle Kanos y quiero anularlo. Además, Geobits se equivoca al suponer que esto no ayuda a la humanidad. Claro, es posible que la humanidad no salga mejor en el peor de los casos, pero si los otros dos jugadores le disparan a la ducha con granada, entonces todos están mejor para eso.
FreeAsInBeer

14

Han Solo - Python

Han disparó primero. En este caso, disparará primero eligiendo vivo el objetivo más cercano.

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

Ejecútalo como:

python hansolo.py

Nota : Esto es lo primero que escribí en Python, por lo que si ve alguna mala práctica específica de Python, hágamelo saber.


1
estilo pep8 sugiere que su método debería seris_alive
Daenyth

44
@WilliamBarbosa echa un vistazo a pep8, es la guía de estilo de python que todos usan. legacy.python.org/dev/peps/pep-0008
Daenyth

2
Felicitaciones por ser el único bot con una salud promedio mayor a 0, en la ronda del 8/11.
isaacg

66
En mi opinión, las "guías de estilo" son para peluqueros, no para programadores.
Kyle Kanos

2
@KyleKanos Sin embargo, es bueno tener algo de consistencia. Quiero decir, si la mitad de los desarrolladores de un proyecto usan un caso de camello y la otra mitad como este, el resultado será "blergh"
William Barbosa

12

EmoCowboy

¿Por qué esperar para morir? Solo mátate ahora mismo. Con suerte, el resto de los tontos se volarán entre sí hasta mucho menos que -2.

La puntuación normalmente será -2. A veces -4 si la gente decide dispararme de la nada. Raramente más que eso, lo que significa que esto debería superar varias de las presentaciones actuales.

Pitón

print('S0')

python EmoCowboy.py

EDITAR: Esto no es una broma, que generalmente es la razón por la cual estas presentaciones emo están mal vistas. Esta es una estrategia legítima. Estar vivo es mortal!


11

Pacifista

Es un tipo genial, acaba de quedar atrapado con la multitud equivocada.

main = putStr "N"

Ejecutar como runghc pacifist.hs, pero es posible que desee compilarlo con -O3 si la eficiencia es un problema.


1
¡Cambie el nombre de Luigi y veamos si gana algo!
William Barbosa

1
@WilliamBarbosa Luigi? ¿Dijiste Luigi ?
killmous

77
Jajaja como si -O3marcara la diferencia.
tomsmeding

@tomsmeding Es lento a un runghclado. En realidad, es 10 veces más lento en mi caja de Linux.
Ray

55
Eso implica la existencia de violencia, una implicación que nuestro pacifista no está preparado para manejar
killmous

9

Monkey - Python (¡Primera entrada!)

Mono mira mono hace. Repetirá exactamente la última acción realizada por un jugador aleatorio.

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

Se puede ejecutar así: "python monkey.py args" No se requieren pasos adicionales.


2
¡Espero que no te estuvieran disparando! Python admite índices de matriz negativos, por lo que no necesita calcular la longitud y restar uno; solo usa -1directamente.
comperendinous

@comperendinous Di que soy S3 en su lista. Si ejecuto S3, no me disparará tonto. Además, ¿el índice -1 devolverá el último elemento? Si es así, genial! Me aseguraré de agregarlo.
Elias Benevedes

Y no olvide el primer argumento (entero). Necesitas argv[2]obtener el historial de los jugadores.
comperendinous

Solo espero que no te emparejen con Emo Cowboy.
Codebreaker

6

Simple Shooter - Perl (error corregido)

Este bot dispara al oponente con más salud. Es una estrategia muy simple, pero creo que tiene una buena posibilidad de hacerlo bien.

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

Así es como ejecutarlo usando alguna entrada de ejemplo:

perl simpleshooter.plx 7 "3,S2,N 5,P,N 3,S0,N -2,S3,N"

Guau. Simple e inteligente
Soham Chowdhury

6

Spock, en Python 3.x

Este código es más bien un experimento (por lo que lleva el nombre de Spock porque ... es vulcano, y son bastante buenos en este tipo de cosas), pero de todos modos fue divertido construirlo. El principal razonamiento detrás de todo este código son los supuestos que un ser lógico y bueno, como Spock, haría si se le dieran las reglas del juego:


El objetivo de este juego es maximizar el puntaje, que sería hecho por todos simplemente parados, lo que no es posible debido al camión.

  • Una de las directivas que Spock tiene que seguir es evitar que aparezca el camión, asegurándose de que todos menos uno estén muertos antes de que aparezca el camión.

La forma en que Spock juega en el resto del juego se puede resumir en su famosa cita: " Las necesidades de muchos superan las necesidades de unos pocos ". En otras palabras, Spock tiene que asegurarse de que se sufra la menor cantidad de daño, matando a los que lo hacen. Cómo lo hace

  • Si ningún jugador ha preparado una granada, apunta al jugador menos saludable que todavía esté jugando.
  • Si hay jugadores que prepararon granadas, de esos objetivos son los menos saludables.

El razonamiento es que, al apuntar a los jugadores más débiles, estamos terminando las fuentes de daño. El razonamiento detrás de las granadas es que se disparan independientemente y hacen menos daño si no se lanzan.


Y entonces este bot funciona. No he realizado pruebas exhaustivas para detectar fallas de entrada (así que, por favor, avíseme si algo sale mal), pero estoy seguro de que resolví la mayoría de los problemas. Basé una pequeña parte del código del robot HanSolo, pero en su mayor parte es un lío enredado. Disfrutar.

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)

Ejecútalo como:

python spock.py

2014-08-12 - Corrección de errores menores con respecto a la detección de granadas
14-08-2014 - Corrección de errores menores con respecto al final del juego, gracias a isaacg por señalarlo antes


No tienes permitido disparar más de una vez cada dos rondas. Lea las especificaciones sobre el disparo.
isaacg

@isaacg Gracias por el recordatorio (que explica el comportamiento), pero parece haber algunos errores latentes. Por ejemplo, en este Spock debería haber disparado InputAnalyser porque tenía una granada viva (incluso si Solo tendría más 2 puntos 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()
es1024

player[1][1]debería ser int(player[1][1]).
isaacg

@isaacg nuevamente, gracias por la ayuda. Habría hecho esto antes, pero me he visto inundado de cosas. Spock finalmente se basó en un concepto equivocado sobre cómo se desarrollaría esto, de ahí el puntaje relativamente más bajo que obtuvo. Tengo algunas ideas para nuevos bots, pero con tantas ahora tengo que asegurarme de que la idea principal sea original.
Doktoro Reichard

5

Pistolero políticamente correcto

Muy políticamente correcto, ya que no discrimina nada. Por lo tanto, no es muy inteligente.

import random

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

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

Realmente ... no importa qué argumentos se le pasen y cómo. python politicallycorrectgunman.py


No creo que se suponga que los corchetes forman parte de la salida. Quizás @ es1024 pueda confirmar eso. ¿Y sabes acerca de random.choice? Es genial para este tipo de selecciones.
comperendinous

no puede haber nada antes de la acción y el objetivo en la salida, aunque se ignora cualquier cosa después
es1024

¿Se ve mejor @ es1024?
Deshacer el

@ Deshacer Sí, funciona perfectamente ahora
es1024

77
¿No podrías usarlo random.choice(array)?
user2357112

5

Tirador recto

Es una parte entrenada de la caballería y habla en muchos idiomas, pero, al ser parpadeado, Straight Shooter solo puede ver al enemigo frente a él. Siendo un caballo, no entiende que hay que esperar entre disparos.

print('S2')

Perl, Python 2/3, Ruby: este caballo realmente es una entrada poligonal.

Estoy ganando de todos modos. No puedo perder Puedes dispararme pero no puedes matarme. ¡El señor Ed no me tiene mierda!

Para una respuesta que tiene un poco más de pensamiento (y algún paradigma funcional) puesto en él, vea Siglo XXI y Medio .


5

Anti-granadero

Las granadas son malas. Muy mal. Entonces, si alguien está preparando uno, lo mejor es dispararles. De lo contrario, pasaremos el rato.

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

4

Ricochet - Perl

Las estrategias simples parecen funcionar decentemente en este desafío, así que aquí hay otra. Dispara a un jugador vivo al azar. Tiene la característica adicional de suicidarse al final para evitar el camión.

@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";

Corre así:

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

4

Agresor

Tira de la ronda uno, lanza al oponente con la salud más alta en la ronda 2, luego dispara al oponente con la salud más alta.

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

Ejecute esto como ./agg ID "5 5 5 5".


4

Ninja

Simplemente esquiva al azar tratando de evitar ser golpeado.

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

correr como

lua ninja.lua

Los argumentos son innecesarios, pero se pueden agregar sin problemas.


2
@KyleKanos ¿Ninja esquivará sus propios disparos?
skeggse

2
@distilledchaos: ... sí, sí lo hará.
Kyle Kanos

4

Nombre : objetivos prioritarios

Comando de shell : ruby ​​PriorityTargets.rb 5 [game_state]

Lenguaje : Ruby V2.1.2

Descripción : PriorityTargets intenta encontrar estilos de juego comunes. Luego decide, basándose en esos estilos de juego, a quién quiere atacar y qué arma usar.

Nota : ¡Primera presentación de Code Golf! Mucho más grande que las otras presentaciones porque me volví un poco loco.

#!/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 !@players.with_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

1
Me gusta su enfoque, espero ver cómo le irá.
overactor

Lamentablemente, parece que tenía un error que creó un granadero. Ah bueno, lo haré mejor la próxima vez :)
fingerco

3

Cobarde - Perl

Actúa muy cobarde. Cuando se siente sano, elige un enemigo que no lo siente y le dispara. Puntos de bonificación para aquellos enemigos que estaban disparando el último turno (porque se sabe que están haciendo Nothingeste turno y, por lo tanto, están absolutamente indefensos). Cuando no se siente tan bien, corre a esconderse para salvar su escondite, disparando ocasionalmente a alguien.

#!/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 bastante estándar de Perl; guárdelo en algún archivo y luego ejecútelo perl file argument argument [...]. He comprobado la sintaxis y estaba bien, así que espero que no haya problemas con esto.

E: eliminado un potencial de división por 0 error.


3

Bomberman

El bot escrito en R, la línea de comando debería ser: Rscript Bomberman.R arg0 arg1
me di cuenta después de comenzar a escribir este bot que Geobits ya hizo un granadero, pero creo que el mío es significativamente diferente, ya que comprueba que su salud está por encima de 3 antes de preparar una granada, lo tira el último tirador primero, y el segundo más saludable, y si su salud es inferior a 3, esquivará al jugador peligroso (ni muerto ni tirador en la última ronda) o disparará a uno de los jugadores 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 haber algún problema de comunicación entre este bot y su controlador ya que todos los registros que busqué mostraron que mi bot solo salía N. Entonces, aquí está el mismo bot pero reescrito en Python, con la esperanza de que si este también tiene un problema de comunicación, alguien lo verá.
Para ser llamado con 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)

El nombre del bot es relativamente débil, pero se me acabó la idea, si alguien puede pensar en un nombre mejor, por favor comente :)
plannapus

GymnastBomber !!
Cruncher

3

Neo

Esquiva a un jugador vivo que no disparó el último turno. Si todos los vivos dispararon el último turno, dispara a un jugador vivo al azar. Suicidio cuando ves faros.

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

No espero mucho de este tipo contra las granadas, pero contra los tiradores podría funcionar bastante bien. Ya veremos.


Usé parte de tu código repetitivo en mi respuesta . Espero que esté bien.
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)
es1024

@ es1024 Debería ser bueno para ir ahora, y no hará nada en cada primer turno.
Geobits

2

Siglo veinticuatro y medio

Esta entrada de Python se agacha y esquiva hasta que solo quedan jugadores pasivos o un solo jugador agresivo, luego comienza a disparar. Espera que un marciano que pasa se haga cargo de granaderos y conductores de camiones borrachos.

A menos que haya hecho algo mal, este es Python funcional. Ciertamente no se parece al tipo de Python que escribí antes de que Haskell y sus amigos me encontraran, y no creo que haya mutado nada en el lugar. Pero si sabes más, por favor dímelo.

#!/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"

2

Asustado

Esta presentación tiene miedo de todos. Pero está especialmente asustado de algunas personas. Entonces descubre quién es el más peligroso y les dispara. Si varios enemigos parecen los más peligrosos, dispara a uno aleatorio.

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

Esto es python (2 o 3, el mismo resultado en cualquiera de los dos). Guardar como scared.py, ejecutar conpython3 scared.py


2

Bastardo manipulador - Python

Prepara y lanza granadas. Si piensa que no hay tiempo o que hay muy pocos enemigos, dispara. Si está solo, intenta burlar al otro tipo.

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

2

Osama

He estado intentando esto durante un día más o menos, ahora es tiempo de publicar y ver cómo los demás han evolucionado mientras tanto.

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

Compilar con ghc -O2 osama.hs, luego ejecutar usando ./players/Osama/osama.


2

Francotirador - Lua

En el primer turno disparará a una persona al azar, luego disparará a cualquier jugador que pueda matar (2 o 1 de salud). Si ninguno de los dos funciona, intentará disparar al jugador que lo disparó por última vez, de lo contrario disparará a un jugador aleatorio. Corre conlua 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)))

En realidad, primero se ejecutará con un argumento adicional; por ejemplo, lua Sniper.lua 3 "5,S1 3,D3 5,N 5,P". Es posible que deba verificar su argíndice.
comperendinous

@comperendinous, gracias, arreglado ahora
waylon531

Hola, @ waylon531, pregunta sobre Lua: la semilla aleatoria math.randoms "math.randomseed (os.time ()) math.random (); math.random (); math.random ()" no es suficiente para aleatorizar ¿guión?
AndoDaan

1
AndoDaan, de acuerdo con lua-users.org/wiki/MathLibraryTutorial, algunos sistemas operativos siempre devuelven el mismo número la primera vez que se llama a math.random ().
waylon531

lua: ./players/Sniper/Sniper.lua:38: attempt to compare nil with number./players/Sniper/Sniper.lua:38: in main chunk [C]: in ?
seguimiento de

2

Darwin

La supervivencia del más apto significa que el menos sano debe morir.

Razón fundamental o base lógica

Mirando el lote de resultados del martes (12), parece haber tres grupos distintos: sobrevivientes; el efectivamente suicida; y lo peor que inútil. Los sobrevivientes comparten estrategias simples basadas en disparos. Mientras que un par de otros bots ( Spock , Coward ) apuntarán al enemigo menos saludable, también complican sus estrategias con otras acciones. Este no lo hace. Al igual que Simple Shooter , tiene una definición clara del objetivo y se mantiene implacable. Será interesante ver dónde encaja en los 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 es una versión simplificada y ligeramente modificada de mi anterior siglo veinticuatro y medio y comparte su invocación:

python darwin.py 3 "5 5 5 5"

2

Zaenille - C

Prioridades:

  1. Dispara si queda un 1 contra 1
  2. Disparar granaderos
  3. Esquivar
  4. Nada (solo para confundir a algunos)

Compilar con gcc <filename.c>.

Corre con ./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;
}

1
El primer argumento (entero) no indica el recuento redondo, si los ejemplos dados en la pregunta tienen algo que ver. Usted no quiere disparar a sí mismo en la primera vuelta sólo porque se habían asignado al número enfrentamiento 82.
comperendinous

De Verdad? D: Gracias @comperendinous. Editará el código.
Mark Gabriel

2

Analizador de entrada

La clave de un juego como este es analizar cómo están jugando todos tus oponentes para responder en consecuencia. ¡Mi bot hará exactamente eso usando algoritmos complicados que resultarán en el uso de mis oponentes para mi ventaja dando una victoria decisiva!

Editar: ahora

  1. esquiva a cualquier jugador que tenga una granada viva
  2. ya no intentaré empujarme, arrojarme o esquivarme.

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

Compila el bot con el siguiente comando (Necesito tener ghc)

ghc --make InputAnalyzer.hs

El comando de shell para ejecutar debe ser el siguiente

./InputAnalyzer

Nota: Probé en Windows, así que si tiene algún problema con respecto a la compilación / ejecución, dígalo en un comentario y haré todo lo posible para encontrar el comando correcto.


1
Bueno, supongo que esa es una forma de obtener un generador pseudoaleatorio ponderado en Haskell.
comperendinous

2

Perro llamado Coraje

Lo primero: dispara a los malos a la vista. Luego esquiva al azar hasta que alguien prepare una granada. Luego, cuando todos le disparen, prepare mi propia granada y se la arroje a cualquiera. Pero el hombre distracción.

Editar: ahora implementado como pensé que debería ser. Antes, el puntaje era: 35,9

Actualizado: a veces dispara en lugar 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

2

MAD - Java

El robot MAD confía en el poder de la intimidación a través de la destrucción mutua asegurada . Cuando no tiene una granada lista, prepara una. Luego esquiva a los posibles artilleros hasta que alguien intenta infligirle daño o su granada está a punto de explotar. Desde el momento en que es atacado, arroja granadas a quien haya tratado de hacerle más daño este partido hasta ahora. Si su granada está a punto de explotar, bombardea al jugador principal. MAD no está en contra de dispararle a alguien cuando no hay nada que esquivar o directamente arrojar una granada y su granada sigue siendo buena durante al menos un 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]);
    }
}

Este Bot probablemente funcionará mal, pero me gustó la idea de todos modos. MAD probablemente lo haría mejor en un campo con bots más inteligentes que registran el comportamiento de otros bots y con más coincidencias ejecutadas entre 4 bots.


Algún crédito debería ir a Geobits, robé un código de placa de caldera de su entrada Neo.
overactor

No tomó mucho, no se necesita crédito :)
Geobits

Las llamadas java MAD 43 "5 5 5 5"parecen no generar nada.
es1024

2

Sádico

pitón

Su prioridad es causar dolor y lastimar granadas. Él tira el primer turno. Le gusta matar cuando no puedes atacar. Él juega con SSS (tiradores simples) esquivando y tirando para prolongar la dominación. Incluso elige atacar a los primeros que no han hecho nada a nadie.

Debido a que usa granadas, él (y todos los demás) generalmente no sobrevivirán a la segunda o tercera ronda. Si está emparejado con otra granada, todos morirán. Esto significa que no espero ganar, pero escribí esto para aprender Python (nunca lo usé antes y estoy tratando de obtener una introducción a un montón de nuevos idiomas). Hay varios otros "pull firsts", así que si crees que es demasiado simular, házmelo saber. Sin embargo, los otros no parecen estar dispuestos a tirar y luego esquivar.

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

No creo que eso raw_inputvaya a funcionar. sys.argv[2]Parece ser el consenso para las entradas de Python. También puede encontrar el uso de pop, que le permitiría condensarse thisisme=player[0];player.remove(player[0])en el más simple thisisme=player.pop(0).
comperendinous

@comperendinous Estaba probando el código en Ideone y sys.argv no funciona en absoluto (probablemente debido a la importación de sys). Es por eso que usé raw_input. ¿Hay alguna diferencia que haga que este último no funcione? Si es así, probablemente necesite encontrar otro compilador en línea para Python. Gracias por la sugerencia con pop! No me di cuenta de que ese comando permite que se especifique el índice. Lo usaré para cualquier código futuro de Python.
kaine

1
raw_inputse retira de STDIN, pero el historial del jugador se pasa a su programa como un argumento de línea de comandos, por lo que necesita sys.argv. En aras de las pruebas, puede configurarlo manualmente con sys.argv = ["sadist.py", "0", "5 5 5 5"]. Entonces deberías poder llamar player=sys.argv[2].split(). Si la importación syses realmente imposible, para las pruebas, incluso podría soltar el punto y llamar a la matriz sysargv. Mientras todo lo demás funcione y vuelvas a sys.argvtu presentación, debería estar bien.
comperendinous

@comperendinous para confirmar, si llamo a sys.argv, ¿devolverá como una matriz el nombre del programa en 0, ese número único en 1 y la parte real que uso en 2? Todos son cuerdas. Con esa información debería poder editarla correctamente. ¡Muchas gracias!
kaine
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.