Four-Man Standoff


54

4-Man Standoff

Descrizione

Ti sei in qualche modo trovato in una situazione di stallo a quattro vie. Una pistola carica riposa nelle tue mani e alcune granate sono agganciate alla cintura.

L'obiettivo è quello di avere più salute alla fine di una situazione di stallo. Una situazione di stallo è finita quando al massimo una persona ha una buona quantità di salute.

Ogni giocatore ha 5salute e muore quando la sua salute scende al di sotto / al di sotto 0. Il turno in cui un giocatore muore è l'ultimo turno in cui il giocatore può subire danni.

Se c'è un giocatore dal vivo alla fine di uno stallo, quel giocatore vince. Altrimenti, vince il giocatore con la salute meno negativa.

Azioni

  • Spara : sparare a qualcuno.

    • 2 danno se spara a un nemico vivo
    • 0 danno se spara a un nemico morto
    • health_at_start_of_turn+2danni se ti spari. (Nota che questo ti lascerà in PIÙ -2salute.)
    • Se un nemico ti spara nello stesso turno in cui ti spari, finirai lo stallo con -4 di salute (subisci comunque danni da altri giocatori nel turno in cui ti uccidi).
    • La tua azione nel turno seguente verrà ignorata (e si presume che sia Nothing).
  • Dodge : prova a schivare il tiro di un singolo avversario.

  • Prepara : sgancia la granata e preparati a lanciarla.

    • Hai solo tre turni per lanciarlo, prima di essere fatto saltare in aria ( 6danno a te stesso, 3danno a tutti i nemici vivi)
    • Morire con una granata non gettata equivale a non lanciare la granata per tre turni.
  • Lancia : lancia la granata verso qualcuno e spera per il meglio.

    • Il bersaglio riceve 8danno se è vivo
    • Tutti gli altri (incluso te stesso) ricevono 3danni se vivi
  • Niente : resta fermo per un turno e guarda morire tutti.

Ingresso

Il tuo programma riceverà le seguenti informazioni:

  • La salute di ogni giocatore
  • Un elenco di azioni intraprese da quel giocatore dall'inizio dello standoff Di seguito è riportato il formato delle informazioni trasmesse per giocatore:

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

Le azioni verranno eseguite nel formato specificato nella sezione Output .

Riceverai 4 di queste stringhe, separate da uno spazio e passate come un singolo argomento. L'ordine di queste stringhe è:

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

Le stringhe vengono passate come secondo argomento. Il primo argomento contiene un numero intero che identifica in modo univoco lo stallo in atto. I contrasti tra lo stesso gruppo di giocatori sono garantiti non simultanei. Tuttavia, si verificheranno più distacchi contemporaneamente.

Per esempio:

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

Attualmente, il giocatore e il secondo avversario hanno 3 punti salute, il primo avversario ha 5 punti salute e il terzo avversario ha -2 punti salute ed è morto.

Al primo turno:

  • Il giocatore 1 ha sparato al nemico 2
  • Il nemico 1 ha preparato una granata
  • Giocatore nemico con 2 colpi
  • Il nemico 3 si è sparato

Al secondo turno:

  • Tutti i giocatori non hanno fatto nulla. (Il giocatore e il nemico 2 non possono fare nulla da quando hanno sparato nel turno precedente. Il nemico 3 è morto: lo farà Nothingper il resto dello stallo.)

Il secondo argomento all'inizio di una situazione di stallo è: 5 5 5 5.

Produzione

Un comando deve essere emesso nel formato sotto elencato. Un output non valido viene interpretato come "Niente". Un comando che richiede un bersaglio dovrebbe essere seguito da un numero intero ( 0-3, con 0rappresentare il giocatore e 1-3rappresentare i nemici 1-3).

  • S[target]: Spara [bersaglio].
  • D[target]: Cerca di schivare [bersaglio].
  • P: Prepara una granata.
  • T[target]: Lancia la granata contro [bersaglio].
  • N: Fare niente.

Un comando che richiede un bersaglio, ma viene alimentato un bersaglio non tra 0e 3o non alimentato un obiettivo interamente sarà assunta al bersaglio 0(lettore).

punteggio

Alla fine di ogni situazione di stallo, i giocatori ricevono un punteggio calcolato con la seguente formula:

35 + health at end of standoff 

Nel caso in cui un giocatore si conclude una situazione di stallo con la salute negativi, essi saranno ricevere un punteggio inferiore a 35 . I seguenti punti vengono inoltre premiati come bonus:

  • Più salute: +4 punti
  • Secondo maggior salute: +2 punti
  • Terza maggior parte della salute: +1 punto.

In caso di pareggio, viene concesso il bonus inferiore (se due persone legano con la maggior parte della salute, entrambi ricevono +2; se ci sono 3 persone con la maggior salute, +1 e se tutti finiscono allo stesso modo, +0).

Il punteggio finale viene determinato calcolando la media di tutti i punteggi individuali.

Regole / Dettagli

  • L'ordine degli eventi all'interno di un turno è il seguente:
    • Tutti i giocatori fanno le loro azioni.
    • I giocatori che hanno 0 o meno punti vita.
    • Le granate non gettate che devono esplodere esploderanno (i giocatori che sono appena morti sono ancora feriti, poiché questo è ancora il turno in cui sono morti).
  • Nessuna collaborazione tra le voci.
  • Tra ogni set di 4 giocatori si verificheranno tre * stand-off. (L'ordine dei giocatori può variare con ogni situazione di stallo).
  • Le voci che consumano quantità eccessive di memoria dello spazio su disco verranno squalificate.
  • La lettura o la modifica di file diversi da quelli immessi squalificherà la voce.
  • Un camion, guidato da un ubriacone, investirà tutti i giocatori viventi dopo il 50thturno, se lo stallo non è ancora terminato alla fine del 50thturno.
    • Questo camion infligge 20 danni a tutti i giocatori dal vivo.
  • I conflitti si verificano rapidamente. I programmi vengono interrotti dopo 1 secondo.
  • Il tuo programma verrà chiamato ad ogni turno, anche dopo la tua morte.
  • Puoi leggere o scrivere file solo nella tua directory (se la tua voce si chiama JohnDoe, puoi salvare i file nella directory player / JohnDoe /); tuttavia, questa NON sarà la directory corrente mentre lo script è in esecuzione.
  • Gli standoff si svolgeranno su una macchina che esegue Arch Linux (versione 2014.08.01).

Il controller è disponibile su GitHub .

Ti preghiamo di includere quanto segue nel tuo post:

  • Un nome per il tuo bot
  • Un comando shell per eseguire il bot (es. java Doe.java) L'input verrà passato attraverso la riga di comando come un singolo argomento ( java Doe.java 5 "-2,S0 -2,S1 -2,S2 5,N")
  • Codice del tuo bot
  • Come compilare il bot (se applicabile)
  • Lingua (e versione se applicabile, specialmente per Python)

* Il controller impiega troppo tempo per sei.

tabellone segnapunti

                      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

Registri: su GitHub


1
Hai esattamente una granata o ne hai molte? Puoi preparare più granate alla volta?
isaacg,

2
@Bob Abbastanza sicuro che EmoWolf sia stato aggiunto alle scappatoie standard che non sono più divertenti . Anche se un ingresso suicida potrebbe non farlo in modo terribile.
es1024

3
Lezione per tutti: non bere e guidare.
Mark Gabriel,

8
@ es1024 Laddove il suicidio è in realtà una strategia praticabile, dovrebbe essere consentita una presentazione di tipo EmoWolf. Soprattutto quando le azioni disponibili includono esplicitamente il suicidio! Non è una "scappatoia" ora, vero? E non è davvero un vantaggio ingiusto, come la maggior parte di quelle scappatoie sono davvero. Ma questa è solo la mia opinione.
Bob

3
Basato sull'esecuzione del controller un paio di volte sembra piuttosto rumoroso. Se questo contest viene mai chiuso, probabilmente dovresti aumentare il numero di run per appianarlo un po '.
Davis Yoshida,

Risposte:


7

Osservatore

Questo ragazzo analizza i suoi nemici. L'obiettivo è sopravvivere fino a quando rimane un solo avversario "aggressivo", e poi ucciderlo in un epico conflitto.

Compila: javac Observer.javaEsegui: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)è questa una condizione necessaria nella funzione "isAggressive"? Un giocatore suicida
morirà

22

Granatiere

Le pistole sono sopravvalutate. Il vero standoff di uno scozzese va così:

  • Preparare
  • Lancia il nemico con la maggior parte della salute
  • Ripeti (se per miracolo sei ancora vivo)

Anche se questo sembra banale, probabilmente non è una strategia terribile . Poiché pistole e bombe entrambi hanno un ciclo di due volta, questo è di gran lunga il più efficiente 1 modo per danni affare.

Certo, se tutti e tre gli avversari mi sparano al primo turno non va bene. Ma neanche molto altro sarebbe.

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

Compilare / eseguire nel modo Java standard:

> javac Grenadier.java
> java Grenadier arg0 arg1

1 Nota inutile


41
hahaha la nota a piè di pagina
haskeller orgoglioso

Penso che lanciare una granata, e quindi sparare sia più efficiente. La possibilità di sopravvivere a 4 turni con questa strategia è insensibilmente bassa. Ma 3 forse (sì, entrambi prendono 2, ma il secondo turno di tiro è dopo l'azione, non prima)
Cruncher,

@Cruncher Probabilmente hai ragione. Eric ha detto la stessa cosa in chat. Gli ho detto che il mio ragazzo non crede nelle pistole ed è troppo testardo per usare quella logica, quindi ha pubblicato quella strategia. Tuttavia, credo ancora che questo sia più efficiente , se parliamo rigorosamente del danno inflitto. Ciò non significa che sia più efficace nel vincere la partita. Anche se muoio al terzo turno, la mia seconda granata si spegne ancora. Quindi, se vivo fino ad allora, sono garantiti 6+ danni a tutti, game over.
Geobits l'

@Geobits ora che ci penso, questo potrebbe essere migliore. La cosa che conta di più è il delta tra te e gli avversari. Quando la granata esplode, ottieni +3 delta con chi l'hai lanciata e +0 con il resto. Una rete di +3. Tiro. Guadagna un delta +2 con chi spari. +0 con il resto. Penso che il problema sia che tu -3 con persone che sono già morte. Dovresti sparare se qualcuno è morto :)
Cruncher,

2
@codebreaker Non l'ho mai giocato. È un riferimento alla vita reale .
Geobits,

16

Asimov's Rule Number 0 Bot - Python

Un robot non può danneggiare l'umanità o, per inazione, permettere all'umanità di arrecare danno.

Abbastanza diretto, attaccherà il primo giocatore che vede in possesso di una granata per proteggere la maggior parte degli umani. Se nessuno è una minaccia per la maggior parte degli umani, non farà nulla.

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

Eseguilo come:

python rule0bot.py

2
Il tuo robot è illogico. Se il giocatore che tiene in mano la granata lancia, l'umanità subisce 8 + 3 + 3 + 3 = 17 danni. Se lo uccidi con il tiro, l'umanità subisce 2 + 6 + 3 + 3 + 3 = 17 danni. In entrambi gli scenari, chiunque faccia esplodere la granata ne prende 8 e tutti gli altri ne prendono 3 (a meno che non siano morti in precedenza). L'umanità nel suo insieme non è influenzata. Mi piace ancora però. +1: D
Geobits l'

4
In realtà, lo scenario migliore per l' umanità è sperare che la granata venga lanciata contro il robot;)
Geobits

1
@Geobits Non cercare di fermare qualcuno che è una minaccia è contro la natura dei robot. Tenterà di impedire a qualcuno che detiene una granata di impedire che la maggioranza (altri due) venga ferita. Hai letto io, robot? Questa logica è supportata da Little Lost Robot e The Evitable Conflict.
William Barbosa,

L'ho letto, ma quello che sto dicendo è che sparare a loro non lo ferma qui. Se muore mentre tiene in mano la granata, esplode comunque. Non solo, ma la quantità totale di danni arrecati all'umanità rimane la stessa. Stai facendo del male diretto a un essere umano senza alcun guadagno per l'umanità.
Geobits l'

2
+1 Non sono d'accordo con il voto di Kyle Kanos e voglio annullarlo. Inoltre, Geobits ha torto nel ritenere che ciò non faccia nulla per aiutare l'umanità. Certo, l'umanità potrebbe non uscire meglio nello scenario peggiore, ma se gli altri due giocatori sparano alla granata con la doccia, allora sono tutti meglio per questo.
FreeAsInBeer l'

14

Han Solo - Python

Han sparò per primo. In questo caso, sparerà per primo selezionando vivo il bersaglio più vicino.

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

Eseguilo come:

python hansolo.py

Nota : questa è la prima cosa che abbia mai scritto in Python, quindi se vedi delle cattive pratiche specifiche di Python, per favore fammi sapere.


1
Lo stile pep8 suggerisce che il tuo metodo dovrebbe essereis_alive
Daenyth,

4
@WilliamBarbosa dai un'occhiata a pep8, è la guida di stile in pitone che tutti usano. legacy.python.org/dev/peps/pep-0008
Daenyth

2
Congratulazioni per essere l'unico bot con una salute media superiore a 0, nel round dell'8 / 11.
Isaacg,

6
IMO, "guide di stile" sono per parrucchieri, non per programmatori.
Kyle Kanos,

2
@KyleKanos È bello avere un po 'di coerenza, però. Voglio dire, se metà degli sviluppatori di un progetto usa un caso di cammello e gli altri metà tipi come questo, il risultato sarà "blergh"
William Barbosa,

12

EmoCowboy

Perché aspettare di morire? Ucciditi adesso. Spero che il resto degli sciocchi esploda fino a molto meno di -2.

Il punteggio sarà normalmente -2. A volte -4 se la gente decide di spararmi fuori dal pipistrello. Raramente più di questo, il che significa che questo dovrebbe battere molte delle attuali osservazioni.

Pitone

print('S0')

python EmoCowboy.py

EDIT: Questo non è uno scherzo, motivo per cui questi contributi emo sono disapprovati. Questa è una strategia legittima. Essere vivi è mortale!


11

Pacifista

È un vero ragazzo bello, appena preso dalla folla sbagliata.

main = putStr "N"

Esegui come runghc pacifist.hs, ma potresti voler compilarlo con -O3 se l'efficienza è un problema.


1
Per favore, rinominalo Luigi e vediamo se vincerà qualcosa!
William Barbosa,

1
@WilliamBarbosa Luigi? Hai detto Luigi ?
killmous

7
Lol come se -O3facesse la differenza.
tomsmeding

@tomsmeding È lento sul runghclato. In realtà è 10 volte più lento sulla mia scatola di Linux.
Ray

5
Ciò implica l'esistenza della violenza, un'implicazione che il nostro pacifista non è disposto a gestire
killmous

9

Monkey - Python (la prima volta in assoluto!)

Le scimmie vedono le scimmie fanno. Ripeterà esattamente l'ultima azione eseguita da un giocatore a caso.

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

Può essere eseguito in questo modo: "python monkey.py args" Non sono richiesti passaggi aggiuntivi.


2
Spero che non ti stessero sparando! Python supporta indici di array negativi, quindi non è necessario calcolare la lunghezza e sottrarne uno; basta usare -1direttamente.
comperendinous

@comperendinous Dimmi che sono S3 nella loro lista. Se eseguo S3, non mi sparerà sciocco. Inoltre, l'indice -1 restituirà l'ultimo elemento? Se è così, fico! Sarò sicuro di aggiungerlo.
Elias Benevedes,

E non dimenticare il primo argomento (intero). Devi argv[2]avere la cronologia dei giocatori.
comperendinous

Spero solo di non essere abbinato a Emo Cowboy.
codebreaker

6

Simple Shooter - Perl (bug risolto)

Questo robot spara all'avversario con più salute. È una strategia molto semplice, ma penso che abbia buone possibilità di fare davvero bene.

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

Ecco come eseguirlo usando alcuni input di esempio:

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

Wow. Semplice e intelligente.
Soham Chowdhury,

6

Spock, in Python 3.x

Questo codice è più che altro un esperimento (quindi prende il nome da Spock perché ... è un vulcaniano e sono abbastanza bravi in ​​questo genere di cose) ma è stato comunque divertente costruirlo. Il ragionamento principale dietro tutto questo codice sono le ipotesi che un buon essere logico, come Spock, farebbe, se date le regole del gioco:


L'obiettivo di questo gioco è di massimizzare il punteggio, che sarebbe fatto da tutti fermi, il che non è possibile, a causa del camion.

  • Una delle direttive che Spock deve seguire è quella di impedire che il camion appaia, assicurandosi che tutti tranne uno sia morto prima che appaia il camion.

Il modo in cui Spock gioca nel resto del gioco può essere riassunto dalla sua famosa citazione: " I bisogni di molti superano quelli di pochi ". In altre parole, Spock deve assicurarsi che venga subito il minimo danno, uccidendo quelli che lo fanno. Come lo fa:

  • Se nessun giocatore ha preparato una granata, scegli come bersaglio il giocatore meno sano che sta ancora giocando.
  • Se ci sono giocatori che hanno preparato granate, da quelli bersaglio il meno sano.

Il ragionamento è che, prendendo di mira i giocatori più deboli, stiamo eliminando le fonti di danno. Il ragionamento alla base delle granate è che stanno sparando a prescindere e fanno meno danni se non vengono lanciati.


E così questo bot funziona. Non ho ampiamente testato errori di input (quindi per favore avvisami se qualcosa va storto) ma sono sicuro di aver risolto la maggior parte dei nodi. Ho basato una piccola parte del codice dal bot HanSolo ma per la maggior parte è un pasticcio di codice. Godere.

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)

Eseguilo come:

python spock.py

12-08-2014 - Bugfix minori relativi al rilevamento di granate
2014-08-14 - Bugfix minori relativi al gioco finale, grazie a isaacg per averlo segnalato prima


Non ti è permesso sparare più di una volta ogni due round. Leggi le specifiche sulle riprese.
isaacg,

@isaacg Grazie per il promemoria (che spiega il comportamento), ma sembra che ci siano alcuni bug latenti. Ad esempio, in questo Spock avrebbe dovuto sparare a InputAnalyser perché aveva una granata viva (anche se Solo avrebbe avuto più 2 punti salute).
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]dovrebbe essere int(player[1][1]).
isaacg,

@isaacg di nuovo, ti ringrazio per l'aiuto. Lo avrei fatto prima, ma sono stato sommerso da roba. Alla fine Spock è stato costruito su un concetto errato su come ciò si sarebbe svolto, da cui il punteggio relativamente basso che ha ottenuto. Ho alcune idee per nuovi robot, ma con così tanti adesso devo assicurarmi che l'idea principale sia originale.
Doktoro Reichard,

5

Gunman politicamente corretto

Molto politicamente corretto, in quanto non discrimina nulla. Quindi non è molto intelligente.

import random

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

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

Non importa davvero quali argomenti gli vengano passati come. python politicallycorrectgunman.py


Non credo che le parentesi quadre debbano far parte dell'output. Forse @ es1024 può confermarlo. E conosci random.choice? È ottimo per questo tipo di selezioni.
comperendinous

non può esserci nulla prima dell'azione e del target nell'output, anche se qualcosa dopo viene ignorato
es1024

Sembra migliore @ es1024?
Annulla il

@ Annulla Sì, funziona perfettamente ora
es1024

7
Non potresti semplicemente usare random.choice(array)?
user2357112

5

Tiratore dritto

È una parte addestrata della cavalleria e parla in molte lingue ma, essendo ammiccato, Straight Shooter può vedere solo un nemico di fronte a lui. Essendo un cavallo, non capisce che devi aspettare tra i colpi.

print('S2')

Perl, Python 2/3, Ruby: questo cavallo è davvero una voce poligota.

Sto vincendo comunque. Non posso perdere. Puoi spararmi ma non puoi uccidermi. Il signor Ed non ha merda addosso!

Per una risposta che abbia un po 'più di pensiero (e qualche paradigma funzionale), vedi il ventiquattresimo e mezzo secolo .


5

Anti-Grenadier

Le granate sono cattive. Molto brutto. Quindi, se qualcuno lo sta preparando, la cosa migliore da fare è sparargli. Altrimenti, andremo semplicemente in giro.

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

Strategie semplici sembrano fare decentemente in questa sfida, quindi eccone un'altra. Spara a un giocatore vivente a caso. Ha la caratteristica aggiuntiva di suicidarsi alla fine per evitare il camion.

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

Esegui così:

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

4

Aggressore

Tira il primo round, lancia l'avversario con il massimo della salute al secondo round, poi spara all'avversario con il più alto livello di salute.

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

Esegui questo come ./agg ID "5 5 5 5".


4

Ninja

Evita casualmente il tentativo di evitare di essere colpito.

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

correre come

lua ninja.lua

Gli argomenti non sono necessari, ma possono essere aggiunti senza problemi.


2
@KyleKanos Ninja eviterà i suoi colpi?
skeggse il

2
@distilledchaos: ... sì, sì, lo farà.
Kyle Kanos,

4

Nome : Target prioritari

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

Lingua : Ruby V2.1.2

Descrizione : PriorityTargets tenta di trovare stili di gioco comuni. Decide quindi, in base a quegli stili di gioco, chi vuole attaccare e quale arma usare.

Nota : prima presentazione Golf Code! Molto più grande degli altri argomenti perché sono diventato un po 'matto.

#!/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
Mi piace il tuo approccio, non vedo l'ora di vedere come andrà.
overactor

Purtroppo, sembra che avesse un bug che ha creato un Granatiere. Ah bene, la prossima volta andrà meglio :)
fingerco,

3

Vigliacco - Perl

Agisce in modo molto codardo. Quando si sente in salute, sceglie un nemico che non lo sente e gli spara. Punti bonus per quei nemici che stavano sparando nell'ultimo turno (perché è noto che stanno facendo Nothingquesto turno e quindi sono assolutamente indifesi). Quando non si sente così bene, corre a cercare riparo per nascondersi, sparando occasionalmente a qualcuno.

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

Codice Perl abbastanza standard; salvalo in qualche file ed eseguilo perl file argument argument [...]. Ho verificato la sintassi ed è stato OK, quindi spero di non avere problemi con questo.

E: eliminato un potenziale di divisione per errore 0.


3

Bomberman

Bot scritto in R, la riga di comando dovrebbe essere: Rscript Bomberman.R arg0 arg1
Mi sono reso conto dopo aver iniziato a scrivere questo bot che Geobits ha già fatto un granatiere ma penso che il mio sia significativamente diverso, in quanto controlla che la sua salute sia superiore a 3 prima di preparare una granata, lo lancia al l'ultimo tiratore per primo, e il secondo più sano, e se la sua salute è inferiore a 3 schiverà il giocatore pericoloso (né morto né sparatutto nell'ultimo round) o sparerà a uno dei giocatori rimanenti.

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)

modificare

Sembra che ci sia qualche problema di comunicazione tra questo bot e il tuo controller poiché tutti i log che ho guardato hanno mostrato che il mio bot era solo in uscita N. Quindi, ecco lo stesso bot ma riscritto in Python, nella speranza che se anche questo ha un problema di comunicazione, qualcuno lo vedrà.
Per essere chiamato 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)

Il nome del bot è relativamente debole, ma sono rimasto senza idea, se qualcuno può pensare a un nome migliore, per favore commenta :)
plannapus

GymnastBomber !!
Cruncher,

3

Neo

Schiva un giocatore vivente che non ha sparato nell'ultimo turno. Se tutti i giocatori hanno sparato all'ultimo turno, sparare a un giocatore vivente a caso. Il suicidio quando vedi i fari.

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

Non mi aspetto molto da questo ragazzo contro i lanciatori di granate, ma contro i tiratori potrebbe funzionare abbastanza bene. Vedremo.


Ho usato un po 'del tuo codice del boilerplate nella mia risposta . Spero vada bene.
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 Dovrebbe andare bene adesso, e non farà nulla ad ogni primo turno.
Geobits il

2

Ventiquattresimo e mezzo secolo

Questa voce di Python schiva e schiva fino a quando rimangono solo giocatori passivi o un singolo giocatore aggressivo, quindi inizia a sparare. Spera che un marziano di passaggio si occupi di granatieri e di camionisti ubriachi.

A meno che non abbia fatto qualcosa di sbagliato, questo è funzionale Python. Certamente non sembra il tipo di Python che ho scritto prima che Haskell e gli amici mi trovassero, e non credo di aver mutato nulla sul posto. Ma se lo sai meglio, per favore dimmelo.

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

Correre come:

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

2

Impaurito

Questa presentazione è spaventata da tutti. Ma è particolarmente spaventato da alcune persone. Quindi capisce chi è il più pericoloso e li spara. Se più nemici sembrano i più pericolosi, spara a uno a caso.

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

Questo è python (2 o 3, lo stesso risultato in entrambi.) Salva con nome scared.py, avvia conpython3 scared.py


2

Manipulative Bastard - Python

Prepara e lancia granate. Se pensa che non ci sia tempo o che ci siano troppo pochi nemici, spara. Se è solo, cerca di superare in astuzia l'altro ragazzo.

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

Ci sto provando da circa un giorno, ora è il momento di pubblicare e vedere come gli altri si sono evoluti nel frattempo.

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

Compilare con ghc -O2 osama.hs, quindi eseguire utilizzando ./players/Osama/osama.


2

Cecchino - Lua

Al primo turno sparerà a una persona a caso, quindi sparerà a tutti i giocatori che può uccidere (2 o 1 salute). Se nessuno di questi funziona tenterà di sparare al giocatore che lo ha sparato per ultimo, altrimenti sparerà a un giocatore a caso. Corri 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)))

In realtà verrà eseguito prima con un argomento aggiuntivo; ad es lua Sniper.lua 3 "5,S1 3,D3 5,N 5,P". Potrebbe essere necessario controllare il tuo argindice.
comperendinous

@comperendinous, grazie, risolto ora
waylon531

Ciao, @ waylon531, domanda su Lua: the randomseed math.randoms "math.randomseed (os.time ()) math.random (); math.random (); math.random ()" non è abbastanza per randomizzare sceneggiatura?
AndoDaan,

1
AndoDaan, secondo lua-users.org/wiki/MathLibraryTutorial alcuni SO restituiscono sempre lo stesso numero la prima volta che viene chiamato math.random ().
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

Sopravvivere al più forte significa che il meno sano deve morire.

Fondamento logico

Guardando la serie di risultati di martedì (12), sembrano esserci tre gruppi distinti: sopravvissuti; l'effettivo suicidio; e il peggio che inutile. I sopravvissuti condividono semplici strategie di tiro. Mentre un paio di altri robot ( Spock , Coward ) prendono di mira il nemico meno sano, complicano anche le loro strategie con altre azioni. Questo no. Come Simple Shooter , ha una chiara definizione del bersaglio e si attacca senza sosta. Sarà interessante vedere dove si inserisce nei risultati.

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

Questa è una versione ridotta e leggermente modificata del mio precedente ventiquattresimo e mezzo secolo e condivide la sua invocazione:

python darwin.py 3 "5 5 5 5"

2

Zaenille - C

Priorità:

  1. Spara se è un 1 su 1 a sinistra
  2. Spara ai granatieri
  3. Schivare
  4. Niente (solo per confondere un po ')

Compila con gcc <filename.c>.

Corri 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
Il primo argomento (intero) non indica il conteggio dei round, se gli esempi forniti nella domanda sono qualcosa da seguire. Non vorrai
spararti

Veramente? D: Grazie @comperendinous. Modifica il codice.
Mark Gabriel,

2

InputAnalyzer

La chiave di un gioco come questo è analizzare come tutti i tuoi avversari stanno giocando per rispondere di conseguenza. Il mio bot farà proprio questo usando algoritmi complicati che risulteranno nell'uso dei miei avversari a mio vantaggio dando una vittoria decisiva!

Modifica: io adesso

  1. schivare qualsiasi giocatore che ha una granata dal vivo
  2. non tenterò più di sparare / lanciare / schivare me stesso.

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

Compilare il bot con il seguente comando (è necessario disporre di ghc)

ghc --make InputAnalyzer.hs

Il comando Shell da eseguire dovrebbe essere il seguente

./InputAnalyzer

Nota: ho testato su Windows, quindi in caso di problemi con la conformità / esecuzione, si prega di dirlo nei commenti e farò del mio meglio per trovare il comando corretto.


1
Bene, suppongo che sia un modo per ottenere un generatore pseudocasuale ponderato in Haskell.
comperendinous

2

Cane di nome Courage

Prima cosa: spara ai cattivi a vista. Quindi schiva a caso fino a quando qualcuno non prepara una granata. Quindi quando tutti gli sparano, prepara la mia granata e lanciala su chiunque. Ma l'uomo della distrazione.

Modifica: ora implementato come pensavo dovesse essere. In precedenza, il punteggio era: 35,9

Aggiornato: a volte spara invece di schivare

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

Correre come

python couragethedog.py

2

MAD - Java

Il robot MAD ha fiducia nel potere dell'intimidazione attraverso la reciproca distruzione assicurata . Ogni volta che non ha una granata pronta, ne prepara una. Quindi schiva possibili artiglieri fino a quando qualcuno tenta di infliggergli danno o la sua granata sta per esplodere. Dal momento in cui viene attaccato, lancia granate contro chiunque abbia provato a infliggergli più danni finora. Se la sua granata sta per esplodere, bombarda il giocatore principale. MAD non è contrario a sparare a qualcuno quando non c'è nulla da schivare o lanciare direttamente una granata e la sua granata è ancora valida per almeno 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]);
    }
}

Probabilmente questo Bot funzionerà male, ma l'idea mi è piaciuta comunque. MAD probabilmente farebbe meglio in un campo con robot più intelligenti che registrano il comportamento di altri robot e con più partite eseguite tra 4 robot.


Un po 'di credito va a Geobits, ho rubato un codice di targa della sua entrata Neo.
overactor

Non hai preso molto, nessun credito necessario :)
Geobits

La chiamata java MAD 43 "5 5 5 5"sembra non produrre nulla.
es1024,

2

Sadico

pitone

La sua priorità è quella di causare dolore e granate ferite. Tira il primo turno. Gli piace uccidere quando non puoi attaccare. Gioca con gli SSS (singoli tiratori semplici) schivando e tirando per prolungare il dominio. Ha anche scelto di attaccare quelli che per primi non hanno fatto niente a nessuno.

Poiché usa granate, lui (e tutti gli altri) non sopravvivranno normalmente al secondo o al terzo round. Se viene accoppiato con un altro granata, tutti moriranno. Questo significa che non mi aspetto di vincere, ma ho scritto questo per imparare Python (non l'ho mai usato prima e sto cercando di ottenere un'introduzione in un sacco di nuove lingue). Ci sono molti altri "pull first", quindi se ritieni che sia troppo semplice fammelo sapere. Gli altri non sembrano disposti a tirare e poi a schivare, comunque.

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

Non penso che raw_inputfunzionerà. sys.argv[2]sembra essere il consenso per le voci di Python. Potresti anche trovare l'uso per pop, che ti permetterebbe di condensare thisisme=player[0];player.remove(player[0])nel più semplice thisisme=player.pop(0).
comperendinous

@comperendinous Stavo testando il codice su Ideone e sys.argv non funziona affatto (probabilmente a causa dell'importazione di sys). Ecco perché ho usato raw_input. C'è una differenza che potrebbe impedire a quest'ultimo di funzionare? In tal caso probabilmente dovrò trovare un altro compilatore online per Python. Grazie per il suggerimento con pop! Non mi ero reso conto che quel comando permettesse di specificare l'indice. Lo userò per qualsiasi futuro codice Python.
Kaine,

1
raw_inputtira da STDIN, ma la cronologia del giocatore viene passata al tuo programma come argomento della riga di comando, motivo per cui ti serve sys.argv. Per motivi di test, puoi semplicemente impostarlo manualmente con sys.argv = ["sadist.py", "0", "5 5 5 5"]. Quindi dovresti essere in grado di chiamare player=sys.argv[2].split(). Se l'importazione sysè davvero impossibile, per i test è possibile persino rilasciare il punto e chiamare l'array sysargv. Fintanto che tutto il resto funziona e torni alla sys.argvtua presentazione, dovrebbe andare bene.
comperendinous

@comperendinous per confermare, se chiamo sys.argv restituirà come array il nome del programma in 0, quel singolo numero in 1 e la parte effettiva che uso in 2? Sono tutte stringhe. Con queste informazioni dovrei essere in grado di modificarlo correttamente. Grazie mille!
Kaine,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.