Affrontement à quatre

54

Confrontation 4 hommes

La description

Vous vous êtes en quelque sorte retrouvé dans une impasse à quatre voies. Un pistolet chargé repose dans vos mains et des grenades sont accrochées à votre ceinture.

L'objectif est d'avoir le plus de santé possible à la fin d'une impasse. Une impasse est terminée quand au plus une personne a une quantité positive de santé.

Chaque joueur a la 5santé et meurt quand sa santé tombe à / en dessous 0. Le tour d'un joueur qui meurt est le dernier tour que ce joueur peut subir.

S'il y a un joueur en direct à la fin d'une impasse, ce joueur gagne. Sinon, le joueur avec la santé la moins négative gagne.

Actions

  • Shoot : Tirez sur quelqu'un.

    • 2 dégâts si vous tirez sur un ennemi vivant
    • 0 dégâts si vous tirez sur un ennemi mort
    • health_at_start_of_turn+2dommage si vous tirez vous-même. (Notez que cela vous laissera avec la plupart des -2soins de santé.)
    • Si un ennemi vous tire dessus au même tour que vous vous tirez vous-même, vous mettez fin à l'impasse avec -4 points de vie (vous subissez quand même des dégâts des autres joueurs le tour où vous vous tuez).
    • Votre action au tour suivant sera ignorée (et supposée l'être Nothing).
  • Esquiver : Essayez d'esquiver le tir d'un seul adversaire.

  • Préparez : Décrochez votre grenade et préparez-vous à la lancer.

    • Vous n'avez que trois tours pour le lancer, avant de vous faire exploser (vous infligez des 6dégâts, 3tous les ennemis vivants sont endommagés)
    • Mourir avec une grenade non percée équivaut à ne pas lancer la grenade pendant trois tours.
  • Lancer : Lancez la grenade vers quelqu'un et espérez que tout ira pour le mieux.

    • La cible subit des 8dégâts si elle est en vie
    • Tous les autres (y compris vous-même) subissent des 3dégâts s'ils sont en vie
  • Rien : restez les bras croisés et regardez tout le monde mourir.

Contribution

Votre programme recevra les informations suivantes:

  • La santé de chaque joueur
  • Liste des actions entreprises par ce joueur depuis le début de la confrontation. Vous trouverez ci-dessous le format des informations transmises par joueur:

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

Les actions seront données dans le format spécifié dans la section Sortie .

Vous recevrez 4 telles chaînes, séparées par un espace et passées sous forme d'argument unique. L'ordre de ces chaînes est:

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

Les chaînes sont passées en tant que deuxième argument. Le premier argument contient un entier qui identifie de manière unique l’impasse en cours d’adoption. Les affrontements entre les mêmes joueurs sont garantis de ne pas être simultanés. Cependant, plusieurs impasses se produiront en même temps.

Par exemple:

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

Actuellement, le joueur et le second adversaire ont 3 points de vie, le premier adversaire a 5 points de vie et le troisième adversaire a -2 points de vie et est mort.

Au premier tour:

  • Joueur 1 tir ennemi 2
  • Enemy 1 a préparé une grenade
  • Enemy 2 tireur
  • Enemy 3 s'est tiré une balle

Au deuxième tour:

  • Tous les joueurs n'ont rien fait. (Le joueur et l'ennemi 2 ne peuvent rien faire puisqu'ils ont tiré au tour précédent. L'ennemi 3 est mort: il le fera Nothingpour le reste de l'impasse.)

Le second argument au début d'un bras de fer est: 5 5 5 5.

Sortie

Une commande doit être sortie dans le format indiqué ci-dessous. Une sortie invalide est interprétée comme 'Nothing'. Une commande nécessitant une cible doit être suivie d'un entier ( 0-3, avec 0représentant le joueur et 1-3représentant les ennemis 1 à 3).

  • S[target]: Tire [cible].
  • D[target]: Essaie d'esquiver [cible].
  • P: Préparez une grenade.
  • T[target]: Lancer la grenade sur [cible].
  • N: Ne fais rien.

Une commande qui a besoin d'une cible, mais est alimentée avec une cible qui n'est pas entre 0et 3ou qui n'est pas alimentée entièrement avec une cible, sera supposée cibler 0(le joueur).

Notation

À la fin de chaque confrontation, les joueurs reçoivent un score calculé selon la formule suivante:

35 + health at end of standoff 

Dans le cas où un joueur se termine un bras de fer avec la santé négative, ils vont recevoir un score inférieur à 35 . Les points suivants sont également récompensés en bonus:

  • Le plus de santé: +4 points
  • Deuxième plus de points de vie: +2 points
  • Troisième plus de santé: +1 point.

En cas d'égalité, le bonus le plus bas est accordé (si deux personnes sont associées avec le plus de points de vie, on leur attribue +2; si 3 personnes ont le plus de santé, +1 et si tout le monde finit à égalité, +0).

Le score final est déterminé en calculant la moyenne de tous les scores individuels.

Règles / Détails

  • L'ordre des événements dans un tour est le suivant:
    • Tous les joueurs font leurs actions.
    • Les joueurs ayant 0 ou moins de santé meurent.
    • Les grenades non tirées qui doivent exploser vont exploser (les joueurs qui viennent de mourir sont toujours blessés, car c'est toujours le tour où ils sont morts).
  • Pas de collaboration entre les entrées.
  • Trois * affrontements auront lieu entre chaque groupe de 4 joueurs. (L'ordre des joueurs peut varier d'une impasse à l'autre).
  • Les entrées consommant une quantité excessive de mémoire d'espace disque seront disqualifiées.
  • Lire ou modifier des fichiers autres que ceux de votre entrée entraînera sa disqualification.
  • Un camion conduit par un ivrogne écrasera tous les joueurs en vie après le 50thtournant, si le bras de fer n’est pas terminé à la fin du 50thtour.
    • Ce camion inflige 20 dégâts à tous les joueurs en direct.
  • Les affrontements arrivent vite. Les programmes sont coupés après 1 seconde.
  • Votre programme sera appelé à chaque tour, même après votre décès.
  • Vous pouvez lire ou écrire des fichiers dans votre répertoire uniquement (si votre entrée s'appelle JohnDoe, vous pouvez enregistrer des fichiers dans le répertoire players / JohnDoe /); cependant, ce ne sera PAS le répertoire en cours pendant l'exécution de votre script.
  • Les entretiens auront lieu sur une machine exécutant Arch Linux (version 2014.08.01).

Le contrôleur est disponible sur GitHub .

Veuillez inclure les éléments suivants dans votre message:

  • Un nom pour votre bot
  • Une commande shell pour exécuter le bot (ex. java Doe.java) L'entrée sera passée à travers la ligne de commande sous forme d'argument unique ( java Doe.java 5 "-2,S0 -2,S1 -2,S2 5,N")
  • Code de votre bot
  • Comment le bot doit être compilé (le cas échéant)
  • Langue (et version si applicable, spécialement pour Python)

* Le contrôleur prend trop de temps pour six.

Tableau de bord

                      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

Journaux: sur GitHub

es1024
la source
1
Avez-vous exactement une grenade ou en avez-vous plusieurs? Peut-on préparer plusieurs grenades à la fois?
isaacg
2
@Bob Je suis sûr que EmoWolf a été ajouté aux échappements standard qui ne sont plus amusants . Bien qu'une entrée suicidaire puisse ne pas vraiment le faire.
es1024
3
Leçon à tout le monde: ne pas boire et conduire.
Mark Gabriel
8
@ es1024 Lorsque le suicide est une stratégie viable, une soumission de type EmoWolf devrait être autorisée. Surtout quand les actions disponibles incluent explicitement le suicide! Pas tellement une "échappatoire" maintenant, n'est-ce pas? Et pas vraiment un avantage injuste, ce que la plupart de ces échappatoires sont réellement. Mais c'est juste mon opinion.
Bob
3
Basé sur l'exécution du contrôleur plusieurs fois, il semble assez bruyant. Si ce concours se termine, vous devriez probablement augmenter le nombre de points pour le lisser un peu.
Davis Yoshida

Réponses:

7

Observateur

Ce mec analyse ses ennemis. Le but est de survivre jusqu'à ce qu'il ne reste qu'un seul adversaire "agressif", puis de le tuer dans un affrontement épique.

Compiler: javac Observer.javaExécuter:java Observer arg0 arg1

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

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

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

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

        calcEnemyInfo(players);

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

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

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

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

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

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

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

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

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

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

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

    private static boolean shotLastTurn(String player, int id) {
        return player.charAt(player.length() - 2) == 'S' && !player.contains("S" + id);
    }
}
CommonGuy
la source
!player.contains("S" + id)est-ce une condition nécessaire dans la fonction "isAgressif"? Un joueur suicidaire sera mort de toute façon
Cruncher
22

Grenadier

Les armes sont surestimées. Le vrai bras de fer d'un écossais est le suivant:

  • Préparer
  • Lancer à l'ennemi avec le plus de santé
  • Répétez (si par miracle vous êtes encore en vie)

Bien que cela semble trivial, ce n'est probablement pas une stratégie terrible . Depuis des fusils et des grenades ont tous deux un cycle de deux tour, c'est de loin le plus efficace 1 moyen de infligent.

Bien sûr, si les trois adversaires me tirent au premier tour, ce n'est pas bon. Mais pas grand-chose d'autre non plus.

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

Compiler / exécuter de la manière standard Java:

> javac Grenadier.java
> java Grenadier arg0 arg1

1 note de bas de page inutile

Géobits
la source
41
hahaha la note de bas de page
fier haskeller
Je pense que lancer une grenade, puis tirer est plus efficace. Cette chance de survivre 4 tours avec cette stratégie est extrêmement basse. Mais 3 peut-être (oui, les deux prennent 2, mais le deuxième tour pour le tir est après l'action, pas avant)
Cruncher
@ Cruncher Vous avez probablement raison. Eric a dit la même chose dans le chat. Je lui ai dit que mon gars ne croyait pas aux armes à feu et qu'il était trop têtu pour utiliser cette logique. Il a donc publié cette stratégie. Cependant, je pense toujours que cela sera plus efficace si nous parlons strictement de dommages causés. Cela ne signifie pas qu'il est plus efficace de gagner le match. Même si je meurs au troisième tour, ma deuxième grenade continue à exploser. Donc, si je vis jusque-là, cela garantira 6+ dommages à tout le monde, game over.
Geobits
@Geobits maintenant que j'y pense, c'est peut-être mieux. Ce qui compte le plus, c'est le delta entre vous et vos adversaires. Lorsque la grenade explose, vous gagnez +3 delta avec qui vous l'avez lancée et +0 avec le reste. Un filet de +3. Tournage. Vous gagne un delta +2 avec qui vous tirez. +0 avec le reste. Je pense que le problème est que vous -3 avec des personnes qui sont déjà mortes. Vous devriez tirer si quelqu'un est mort :)
Cruncher
2
@codebreaker Jamais joué. C'est une référence de la vie réelle .
Geobits
16

Règle d'Asimov numéro 0 Bot - Python

Un robot ne peut pas nuire à l'humanité ou, par son inaction, permettre à l'humanité de nuire.

Assez simple, il attaquera le premier joueur qu'il voit tenir une grenade pour protéger la majorité des humains. Si personne n'est une menace pour la majorité des humains, il ne fera rien.

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

Courez comme ça:

python rule0bot.py
William Barbosa
la source
2
Votre robot est illogique. Si le joueur qui tient la grenade lève, l'humanité subit 8 + 3 + 3 + 3 = 17 dégâts. Si vous le tuez avec le coup, l'humanité subit 2 + 6 + 3 + 3 + 3 = 17 dégâts. Dans les deux scénarios, celui qui fait exploser la grenade en prend 8 et tous les autres, 3 (sauf s'ils étaient morts auparavant). L'humanité dans son ensemble n'est pas affectée. Je l'aime encore malgré çà. +1: D
Geobits
4
En fait, le meilleur scénario pour l' humanité est d'espérer que la grenade soit lancée sur le robot;)
Geobits
1
@ Geobits Ne pas essayer d'arrêter quelqu'un qui est une menace est contre la nature des robots. Cela va essayer d'empêcher quelqu'un de tenir une grenade pour empêcher que la majorité (les deux autres) ne soit blessée. Avez-vous lu moi, Robot? Cette logique est soutenue par Little Lost Robot et The Evitable Conflict.
William Barbosa
Je l'ai lu, mais ce que je dis, c'est que leur tirer dessus ne l'arrête pas ici. S'il meurt en tenant la grenade, elle explose toujours. Non seulement cela, mais le montant total des dommages causés à l'humanité reste le même. Vous faites un mal direct à un humain sans gain pour l'humanité.
Geobits
2
+1 Je ne suis pas d'accord avec le vote de Kyle Kanos et je veux l'annuler. De plus, Geobits a tort de supposer que cela ne fait rien pour aider l'humanité. Bien sûr, l’humanité n’est peut-être pas meilleure dans le pire des cas, mais si les deux autres joueurs tirent la grenade avec une douche, ils en seront tous meilleurs.
FreeAsInBeer
14

Han Solo - Python

Han a tiré le premier. Dans ce cas, il tirera en premier en choisissant la cible vivante la plus proche.

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

Courez comme ça:

python hansolo.py

Remarque : C’est la première chose que j’ai écrite en Python. Si vous rencontrez des pratiques malveillantes spécifiques à Python, faites-le moi savoir.

William Barbosa
la source
1
style pep8 suggère que votre méthode devrait êtreis_alive
Daenyth
4
@WilliamBarbosa jetez un oeil à pep8, c'est le guide de style en python que tout le monde utilise. legacy.python.org/dev/peps/pep-0008
Daenyth
2
Félicitations pour être le seul bot avec une santé moyenne supérieure à 0, dans la ronde 8/11.
isaacg
6
OMI, "guides de style" sont pour les coiffeurs, pas les programmeurs.
Kyle Kanos
2
@KyleKanos C'est bien d'avoir une certaine cohérence, cependant. Je veux dire, si la moitié des développeurs d'un projet utilisent des boîtiers à chameaux et les autres types comme celui-ci, le résultat sera "blergh"
William Barbosa
12

EmoCowboy

Pourquoi attendre pour mourir? Tue-toi maintenant. Espérons que le reste des imbéciles se soufflera beaucoup moins que -2.

Le score sera normalement -2. Parfois -4 si les gens décident de me tirer dessus. Rarement plus que cela, ce qui signifie que cela devrait battre plusieurs des soumissions actuelles.

Python

print('S0')

python EmoCowboy.py

EDIT: Ce n'est pas une blague, c'est généralement pourquoi ces soumissions emo sont mal vues. C'est une stratégie légitime. Être en vie est mortel!

Cruncher
la source
11

Pacifiste

C'est un vrai type de gars, il vient de se retrouver avec la mauvaise foule.

main = putStr "N"

Exécutez en tant que runghc pacifist.hs, mais vous voudrez peut-être le compiler avec -O3 si l'efficacité pose problème.

Killmous
la source
1
S'il vous plaît renommez-le Luigi et voyons s'il va gagner quelque chose!
William Barbosa
1
@ WilliamBarbosa Luigi? Avez-vous dit Luigi ?
killmous
7
Lol comme si -O3fait une différence foutue.
tomsmeding
@ Tomsmeding C'est lent sur le runghccôté. En fait, il est 10 fois plus lent sur ma machine Linux.
Ray
5
Cela implique l'existence de la violence, une implication que notre pacifiste n'est pas prêt à gérer
killmous
9

Singe - Python (Première entrée!)

Ce que le singe voit, le singe fait. Répétera exactement la dernière action prise par un joueur au hasard.

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

Peut être exécuté comme ceci: "python monkey.py args" Aucune étape supplémentaire requise.

Elias Benevedes
la source
2
J'espère qu'ils ne vous ont pas tiré dessus! Python prend en charge les index de tableau négatifs. Vous n'avez donc pas besoin de calculer la longueur ni d'en soustraire un; juste utiliser -1directement.
comperendinous
@comperendinous Dites que je suis S3 dans leur liste. Si j'exécute S3, il ne me tirera pas de bêtises. De plus, l'index -1 renverra le dernier élément? Si oui, cool! Je vais être sûr de l'ajouter.
Elias Benevedes
Et n'oubliez pas le premier argument (entier). Vous devez argv[2]obtenir l'historique des joueurs.
comperendinous
J'espère juste que vous ne serez pas jumelé à Emo Cowboy.
Codebreaker
6

Simple Shooter - Perl (bug corrigé)

Ce bot tire sur l'adversaire avec le plus de santé. C'est une stratégie très simple, mais je pense qu'elle a une chance décente de bien réussir.

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

Voici comment l'exécuter en utilisant un exemple d'entrée:

perl simpleshooter.plx 7 "3,S2,N 5,P,N 3,S0,N -2,S3,N"
PhiNotPi
la source
Sensationnel. Simple et intelligent.
Soham Chowdhury
6

Spock, en Python 3.x

Ce code est plutôt une expérience bien pensée (donc nommé d'après Spock parce que ... c'est un vulcan, et ils sont plutôt doués pour ce genre de choses), mais c'était amusant de le construire quand même. Le raisonnement principal derrière tout ce code est l'hypothèse qu'un bon être logique, comme Spock, ferait, si on lui donnait les règles du jeu:


L'objectif de ce jeu est de maximiser le score, ce qui serait fait par tout le monde debout, ce qui est impossible, à cause du camion.

  • L'une des directives que Spock doit suivre est d'empêcher le camion de comparaître, en s'assurant que tout le monde sauf un est mort avant le camion.

La façon dont Spock joue dans le reste du jeu peut être résumée par sa célèbre citation: " Les besoins de la majorité l'emportent sur ceux de quelques-uns ". En d'autres termes, Spock doit s'assurer que le moins de dégâts possible est subi, en tuant ceux qui le font. Comment il le fait:

  • Si aucun joueur n'a préparé une grenade, ciblez le joueur le moins en santé qui joue encore.
  • S'il y a des joueurs qui ont préparé des grenades, parmi ceux qui sont le moins en santé.

Le raisonnement est que, en ciblant les joueurs les plus faibles, nous mettons fin aux sources de dommages. Le raisonnement derrière les grenades est qu'elles partent quand même et qu'elles causent moins de dégâts si elles ne sont pas lancées.


Et si ce bot fonctionne. Je n'ai pas fait de tests approfondis sur les échecs d'entrée (merci de m'avertir si quelque chose ne va pas), mais je suis convaincu que j'ai résolu la plupart des problèmes. J'ai basé une petite partie du code du bot HanSolo, mais la plupart du temps, c'est un fouillis de code enchevêtré. Prendre plaisir.

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)

Courez comme ça:

python spock.py

2014-08-12 -
Correction de bug mineure concernant la détection de grenade 2014-08-14 - Correction de bug mineure concernant la phase finale, merci à isaacg de l'avoir signalé avant

Doktoro Reichard
la source
Vous n'êtes pas autorisé à tirer plus d'une fois tous les deux tours. Lisez les spécifications sur le tournage.
isaacg
@isaacg Merci pour le rappel (qui explique le comportement), mais il semble y avoir des bogues cachés. Par exemple, dans cette situation, Spock aurait dû tirer sur InputAnalyser car il avait une grenade réelle (même si Solo aurait plus de 2 points de vie).
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]devrait être int(player[1][1]).
isaacg
@isaacg encore une fois, je vous remercie pour l'aide. J'aurais fait ça plus tôt mais j'ai été submergé de trucs. Spock a finalement été construit sur un concept erroné sur la façon dont cela se déroulerait, d’où le score relativement bas qu’il a obtenu. J'ai quelques idées pour créer de nouveaux robots, mais avec tant d'autres, je dois maintenant m'assurer que l'idée principale est originale.
Doktoro Reichard
5

Gunman politiquement correct

Très politiquement correct, car cela ne discrimine rien. Donc ce n'est pas très intelligent.

import random

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

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

Peu importe quels arguments lui sont transmis comment. python politicallycorrectgunman.py

annuler
la source
Je ne pense pas que les crochets soient censés faire partie de la sortie. Peut-être que @ es1024 peut le confirmer. Et connaissez-vous random.choice? C'est génial pour ce genre de sélections.
comperendinous
il ne peut y avoir rien avant l'action et la cible dans la sortie, bien que tout ce qui suit soit ignoré
es1024
Est-ce que ça a l'air mieux @ es1024?
Annuler
@Undo Oui, fonctionne parfaitement maintenant
es1024
7
Ne pourriez-vous pas simplement utiliser random.choice(array)?
user2357112
5

Bon tireur

Il fait partie de la cavalerie et parle plusieurs langues mais, étant aveuglé, Straight Shooter ne peut voir que l’ennemi en face de lui. Étant un cheval, il ne comprend pas que vous devez attendre entre les tirs.

print('S2')

Perl, Python 2/3, Ruby: ce cheval est vraiment une entrée polygot.

Je gagne quand même. Je ne peux pas perdre. Tu peux me tirer dessus mais tu ne peux pas me tuer. Monsieur Ed n'a pas de merde sur moi!

Pour une réponse qui comporte un peu plus de réflexion (et un paradigme fonctionnel), voir Vingt-quatrième et demi-siècle .

compertendinous
la source
5

Anti-grenadier

Les grenades sont mauvaises. Très mauvais. Donc, si quelqu'un en prépare un, la meilleure chose à faire est de leur tirer dessus. Sinon, nous allons simplement sortir.

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

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

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

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

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

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

Ricochet - Perl

Les stratégies simples semblent bien réussir dans ce défi, alors en voici un autre. Il tire un joueur vivant aléatoire. Il a la particularité supplémentaire de se suicider à la fin pour éviter le 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";

Courez comme si:

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

Agresseur

Tire au premier tour, au adversaire au plus haut niveau de santé au deuxième tour, tire ensuite à l'adversaire au plus haut niveau de santé.

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

Exécutez ceci comme ./agg ID "5 5 5 5".

Eric Tressler
la source
4

Ninja

Esquive au hasard en essayant d'éviter de se faire toucher.

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

courir comme

lua ninja.lua

Les args sont inutiles, mais peuvent être ajoutés sans problème.

Kyle Kanos
la source
2
@KyleKanos Ninja évitera-t-il ses propres attaques?
Skeggse
2
@distilledchaos: ... oui, oui il le fera.
Kyle Kanos
4

Nom : PriorityTargets

Commande de shell : ruby ​​PriorityTargets.rb 5 [état_de_jeu]

Langue : Ruby V2.1.2

Description : PriorityTargets tente de trouver des styles de lecture courants. Il décide ensuite, en fonction de ces styles de jeu, qui il veut attaquer et quelle arme utiliser.

Remarque : Première soumission de Code Code! Beaucoup plus grand que les autres soumissions parce que je suis devenu un peu fou.

#!/usr/bin/env ruby

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

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

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

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

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

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


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

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

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


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

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

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

      is_holding
    end

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

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

    private

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

  class PlayerList
    include Enumerable

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

    def with_identifiers(identifiers)
      create_filtered_list(identifiers)
    end
  end

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

    def initialize(player_list)
      @players = player_list
    end

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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




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

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

    @enemies = @players.with_identifiers(enemy_identifiers  )
  end

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

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

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

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

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

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

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

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

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

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

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

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

priority_targets = PriorityTargets.new(ARGV[1])
priority_targets.analyze_playstyles
priority_targets.make_decision
fingerco
la source
1
J'aime votre approche, j'ai hâte de voir comment cela se passera.
Overactor
Malheureusement, il semble qu’il y ait eu un virus qui a créé un Grenadier. Ah bien, ferons mieux la prochaine fois :)
fingerco
3

Coward - Perl

Fait très lâche. Lorsqu'il se sent en bonne santé, il choisit un ennemi qui ne le ressent pas et lui tire dessus. Points bonus pour les ennemis qui tiraient le dernier tour (car ils sont connus pour faire Nothingce tour et donc être absolument sans défense). Quand il ne se sent pas très bien, il court se mettre à l'abri pour sauver sa peau, tirant parfois sur quelqu'un.

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

Joli code Perl standard; enregistrez-le dans un fichier, puis exécutez-le perl file argument argument [...]. J'ai vérifié la syntaxe et tout s'est bien passé. J'espère donc que cela ne posera aucun problème.

E: élimine un potentiel de division par 0 erreur.

Ramillies
la source
3

Bomberman

Bot écrit en R, ligne de commande doit être: Rscript Bomberman.R arg0 arg1
je pris conscience après avoir commencé à écrire ce bot qui Geobits déjà fait un grenadier mais je pense que la mienne est sensiblement différente, en ce sens qu'elle vérifie sa santé est supérieure à 3 avant de préparer une grenade, le jette à la le dernier tireur en premier, et le second le plus sain, et si sa santé est inférieure à 3, il esquivera le joueur dangereux (ni mort ni tireur au dernier tour) ou ne tirera qu’un des joueurs restants.

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)

Modifier

Il semble y avoir un problème de communication entre ce bot et votre contrôleur car tous les journaux que j’ai regardés ont montré que mon bot ne sortait que N. Donc, voici le même bot mais réécrit en Python, dans l’espoir que si celui-ci rencontre également un problème de communication, quelqu'un le verra.
Être appelé avec 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)
planificateur
la source
Le nom du bot est relativement faible, mais je suis à court d'idée. Si quelqu'un peut penser à un meilleur nom, veuillez commenter :)
plannapus
GymnastBomber !!
Cruncher
3

Néo

Esquivez un joueur vivant qui n'a pas tiré le dernier tour. Si tout le monde en vie tire au dernier tour, tirez sur un joueur vivant au hasard. Suicide quand vous voyez des phares.

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

Je ne m'attends pas à grand chose de ce type contre les piqueurs de grenades, mais contre les tireurs, ça pourrait bien marcher. On verra.

Géobits
la source
J'ai utilisé une partie de votre code standard dans ma réponse . J'espère que ça va.
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 Devrait être bon à partir maintenant, et ne fera rien à chaque premier tour.
Geobits
2

Vingt-quatrième et un siècle

Cette entrée Python esquive et esquive jusqu’à ce qu’il ne reste que des joueurs passifs ou un seul joueur agressif, puis commence à tirer. Il espère qu'un martien passager s'occupe des grenadiers et des chauffeurs de camions ivres.

Sauf si j'ai fait quelque chose de mal, c'est Python fonctionnel. Cela ne ressemble certainement pas au genre de Python que j'ai écrit avant que Haskell et ses amis ne me trouvent, et je ne pense pas avoir rien muté sur place. Mais si vous savez mieux, dites-le-moi s'il vous plaît.

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

Courir comme:

python twenty-fourth-and-a-halfth-century.py 0 "5 5 5 5"
compertendinous
la source
2

Effrayé

Cette soumission a peur de tout le monde. Mais certaines personnes ont particulièrement peur. Donc, il détermine qui est le plus dangereux, et leur tire dessus. Si plusieurs ennemis paraissent les plus dangereux, il tire au hasard.

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

Ceci est python (2 ou 3, même résultat dans les deux cas.) Enregistrer sous scared.py, exécuter avecpython3 scared.py

isaacg
la source
2

Bâtard manipulateur - Python

Prépare et jette des grenades. S'il pense que le temps presse ou qu'il y a trop peu d'ennemis, il tire. S'il est seul, il tente de déjouer l'autre gars.

import sys

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

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

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

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

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

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

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

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

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

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

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

act('P')
fhyqrkka
la source
2

Oussama

J'essaie cela depuis un jour ou deux, maintenant il est temps de poster et de voir comment les autres ont évolué entre-temps.

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

Compiler avec ghc -O2 osama.hs, puis exécuter en utilisant ./players/Osama/osama.

TheEspagnolInquisition
la source
2

Sniper - Lua

Au premier tour, il tirera sur une personne au hasard, puis sur tous les joueurs qu'il peut tuer (2 ou 1 PV). Si aucun de ceux-ci ne fonctionne, il essaiera de tirer sur le joueur qui l'a tiré en dernier, sinon il tirera sur un joueur aléatoire. Courir aveclua Sniper.lua

turns = arg[2]
health = string.sub(turns, 1, 1)
--make random numbers random
math.randomseed(io.popen("date +%s%N"):read("*all"))
math.random(); math.random(); math.random()
function Split(str, delim, maxNb)
    -- Eliminate bad cases...
    if string.find(str, delim) == nil then
        return { str }
    end
    if maxNb == nil or maxNb < 1 then
        maxNb = 0    -- No limit
    end
    local result = {}
    local pat = "(.-)" .. delim .. "()"
    local nb = 0
    local lastPos
    for part, pos in string.gmatch(str, pat) do
        nb = nb + 1
        result[nb] = part
        lastPos = pos
        if nb == maxNb then break end
    end
    -- Handle the last field
    if nb ~= maxNb then
        result[nb + 1] = string.sub(str, lastPos)
    end
    return result
end
enemies = Split(turns, " ")
--first turn
if #enemies[1] == 1 then
  print(string.format("S%i",math.random(1,3)))
  os.exit()
end
--kills if possible
for enemy=1,3 do
  if (tonumber(string.sub(enemies[enemy + 1],1,1)) or 0) < 3 and string.sub(enemies[enemy + 1],1,1) ~= "-" then
    print(string.format("S%i",enemy))
    os.exit()
  end
end
--shoots the last person that shot at it
for enemy=1,3 do
  if string.sub(enemies[enemy + 1],#enemies[enemy + 1]-1) == "S0" and tonumber(string.sub(enemies[enemy + 1],1,1)) > 0 then
    print(string.format("S%i",enemy))
    os.exit()
  end
end
--otherwise shoot a random alive person
local aliveEnemies = {}
for enemy=1,3 do
  if string.sub(enemies[enemy + 1],1,1) ~= "-" then
    aliveEnemies[#aliveEnemies+1]=enemy
  end
end
print(string.format("S%i",math.random(1,#aliveEnemies)))
waylon531
la source
En fait, il s'agira d'abord d'un argument supplémentaire. par exemple lua Sniper.lua 3 "5,S1 3,D3 5,N 5,P". Vous devrez peut-être vérifier votre argindex.
comperendinous
@comperendinous, merci, corrigé maintenant
waylon531
Bonjour, @ waylon531, question sur Lua: math.randoms, une graine aléatoire "math.randomseed (os.time ()) math.random (); math.random (); math.random ()" ne suffit pas à randomiser le scénario?
AndoDaan
1
AndoDaan, selon lua-users.org/wiki/MathLibraryTutorial, certains systèmes d’exploitation renvoient toujours le même nombre lors du premier appel à math.random ().
waylon531
lua: ./players/Sniper/Sniper.lua:38: attempt to compare nil with numberpile ./players/Sniper/Sniper.lua:38: in main chunk [C]: in ?
traceback
2

Darwin

La survie du plus apte signifie que le moins sain doit mourir.

Raisonnement

En regardant le lot de résultats du mardi 12, il semble y avoir trois groupes distincts: les survivants; le effectivement suicidaire; et le pire qu'inutile. Les survivants partagent des stratégies simples basées sur le tir. Alors que quelques autres robots ( Spock , Coward ) cibleront l'ennemi le moins en santé, ils compliquent également leurs stratégies avec d'autres actions. Celui-ci ne le fait pas. Comme Simple Shooter , il a une définition claire de la cible et le respecte sans relâche. Il sera intéressant de voir où cela se situe dans les résultats.

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

Ceci est une version allégée, légèrement modifiée de mon précédent vingt-quatrième et demi-siècle , et partage son invocation:

python darwin.py 3 "5 5 5 5"
compertendinous
la source
2

Zaenille - C

Les priorités:

  1. Tirez si c'est un 1 sur 1 à gauche
  2. Tirez des grenadiers
  3. Esquive
  4. Rien (juste pour en confondre)

Compiler avec gcc <filename.c>.

Courez avec ./a.out <parameters>.

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

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

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

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

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

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

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

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

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

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

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

    return 0;
}
Mark Gabriel
la source
1
Le premier argument (entier) n'indique pas le nombre d'arrondis, si les exemples donnés dans la question sont tout ce qu'il y a à dire. Vous ne voudriez pas vous tirer une balle au premier tour juste parce que vous aviez été assigné à l’attaquant numéro 82.
comperendinous
Vraiment? D: Merci @comperendinous. Va éditer le code.
Mark Gabriel
2

InputAnalyzer

La clé d'un tel jeu consiste à analyser comment tous vos adversaires jouent pour réagir en conséquence. Mon bot fera justement cela en utilisant des algorithmes compliqués qui vont conduire à utiliser mes adversaires tourne à mon avantage en donnant une victoire décisive!

Edit: je maintenant

  1. esquiver tout joueur qui a une grenade en direct
  2. n'essaierai plus de me projeter / lancer / esquiver.

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

Compilez le bot avec la commande suivante (besoin d'avoir ghc)

ghc --make InputAnalyzer.hs

La commande shell à exécuter devrait être la suivante

./InputAnalyzer

Remarque: j'ai testé sur Windows, donc si vous avez un problème de conformité / exécution, merci de le commenter et je ferai de mon mieux pour connaître la commande correcte.

Sahar Rabinoviz
la source
1
Eh bien, je suppose que c'est une façon d'obtenir un générateur pseudo-aléatoire pondéré en Haskell.
comperendinous
2

Chien nommé Courage

Première chose - tirez les méchants à vue. Puis esquivez au hasard jusqu'à ce que quelqu'un prépare une grenade. Puis, quand tout le monde lui tire dessus, préparez ma propre grenade et lancez-la sur n'importe qui. Mais l'homme de distraction.

Edit: Maintenant implémenté comme je le pensais. Avant, le score était de: 35,9

Mise à jour: tire parfois au lieu d'esquiver

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

Courir comme

python couragethedog.py
loa_in_
la source
2

MAD - Java

MAD bot fait confiance au pouvoir de l'intimidation par la destruction mutuelle assurée . Chaque fois qu'il n'a pas de grenade prête, il en prépare une. Il évite ensuite les mitrailleurs potentiels jusqu'à ce que quelqu'un essaye de lui causer des dégâts ou que sa grenade soit sur le point d'exploser. Dès le moment où il est attaqué, il lance des grenades sur celui qui a essayé de lui infliger plus de dégâts ce match. Si sa grenade est sur le point d'exploser, il bombarde le principal joueur. MAD n'est pas contre de tirer sur quelqu'un quand il n'y a rien à esquiver ni à lancer une grenade et que sa grenade est encore bonne pour au moins un tour.

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

Ce Bot aura probablement de mauvaises performances, mais j'ai quand même bien aimé l'idée. MAD ferait probablement mieux dans un domaine avec des robots plus intelligents qui enregistrent le comportement des autres robots et avec plus de matchs entre 4 robots.

suracteur
la source
Certains crédits doivent aller à Geobits, j'ai volé un code de plaque de chaudière de son entrée Neo.
overactor
Vous n'avez pas pris beaucoup, pas de crédit nécessaire :)
Geobits
L'appel java MAD 43 "5 5 5 5"semble ne rien produire.
es1024
2

Sadique

python

Sa priorité est de causer de la douleur et des blessures aux grenades. Il tire le premier tour. Il aime tuer quand on ne peut pas attaquer. Il joue avec les SSS (tireurs simples simples) en esquivant et en tirant pour prolonger la domination. Il a même choisi d'attaquer les premiers qui n'ont rien fait à personne.

Comme il utilise des grenades, il (et tous les autres) ne survivra généralement pas au deuxième ou au troisième round. S'il est jumelé avec un autre grenade, tout le monde mourra. Cela signifie que je ne m'attends pas à gagner mais que j'ai écrit ceci pour apprendre le python (je ne l'avais jamais utilisé auparavant et j'essaie de me familiariser avec de nouvelles langues). Il existe plusieurs autres "premiers tirages", donc si vous pensez que c'est trop similaire, faites-le-moi savoir. Les autres ne semblent cependant pas disposés à tirer et à esquiver.

import sys    

def ident(thatguy):

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

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

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

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

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

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

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

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

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

if (turn==0): print "P"
elif(turn==49): print"S0"
elif(igotanuke(thisisme))&( turn % 2 == 1): print "T"+str(ident(guytonuke(guys,gunners)))
elif(len(guys)<2)&(len(gunners)>0) & (turn % 2 == 1): print P
elif(turn % 2 == 0) & (len(gunners)>0): print "D"+str(ident(mosthealth(gunners)))
elif(turn % 2 == 1) & (len(gunners)>0): print "S"+str(ident(mosthealth(gunners)))
else: print "S"+str(ident(mosthealth(guys)))
Kaine
la source
Je ne pense pas que ça raw_inputva marcher. sys.argv[2]semble être le consensus pour les entrées Python. Vous pourriez également trouver une utilisation pour pop, ce qui vous permettrait de condenser thisisme=player[0];player.remove(player[0])dans le plus simple thisisme=player.pop(0).
comperendinous
@comperendinous J'essayais le code chez Ideone et sys.argv ne fonctionnait pas du tout (probablement à cause de l'importation de sys). C'est pourquoi j'ai utilisé raw_input. Y a-t-il une différence qui ferait que ces derniers ne fonctionnent pas? Si c'est le cas, il faudra probablement que je trouve un autre compilateur en ligne pour python. Merci pour la suggestion avec pop! Je n'avais pas réalisé que cette commande permettait de spécifier l'index. Je vais l'utiliser pour tout code python futur.
Kaine
1
raw_inputtire de STDIN, mais l'historique du joueur est passé à votre programme sous forme d'argument de ligne de commande, c'est pourquoi vous en avez besoin sys.argv. À des fins de test, vous pouvez simplement le définir manuellement avec sys.argv = ["sadist.py", "0", "5 5 5 5"]. Ensuite, vous devriez pouvoir appeler player=sys.argv[2].split(). Si l'importation sysest vraiment impossible, vous pouvez même laisser tomber le point et appeler le tableau à des fins de test sysargv. Tant que tout le reste fonctionne et que vous revenez sys.argvdans votre soumission, ça devrait aller.
comperendinous
@comperendinous pour confirmer, si j'appelle sys.argv, il renverra sous forme de tableau le nom du programme en 0, ce numéro unique en 1 et la partie réelle que j'utilise en 2? Ils sont tous des chaînes. Avec cette information, je devrais pouvoir l'éditer correctement. Merci beaucoup!
Kaine