Vier-Mann-Standoff

54

4-Mann-Abstandshalter

Beschreibung

Sie sind irgendwie in eine Vier-Wege-Situation geraten. Eine geladene Waffe liegt in Ihren Händen und einige Granaten sind am Gürtel eingehakt.

Das Ziel ist es, am Ende einer Pattsituation die meiste Gesundheit zu haben. Eine Pattsituation ist beendet, wenn höchstens eine Person einen positiven Gesundheitszustand aufweist.

Jeder Spieler hat 5Gesundheit und stirbt, wenn seine Gesundheit auf / unter sinkt 0. Der Zug, an dem ein Spieler stirbt, ist der letzte Zug, an dem der Spieler Schaden erleiden kann.

Wenn sich am Ende eines Abstands ein Live-Spieler befindet, gewinnt dieser Spieler. Andernfalls gewinnt der Spieler mit der geringsten negativen Gesundheit.

Aktionen

  • Schießen : Schießen Sie auf jemanden.

    • 2 Schaden, wenn ein lebender Feind erschossen wird
    • 0 Schaden, wenn ein toter Feind erschossen wird
    • health_at_start_of_turn+2Schaden, wenn Sie sich selbst erschießen. (Beachten Sie, dass dies Sie mit am meisten -2Gesundheit verlassen wird.)
    • Wenn ein Feind in der gleichen Runde, in der Sie selbst geschossen haben, auf Sie schießt, haben Sie -4 Lebenspunkte.
    • Deine Aktion in der folgenden Runde wird ignoriert (und als solche angenommen Nothing).
  • Ausweichen : Versuchen Sie, dem Schuss eines einzelnen Gegners auszuweichen.

  • Vorbereiten : Hängen Sie Ihre Granate aus und bereiten Sie das Werfen vor.

    • Du hast nur drei Runden Zeit, um es zu werfen, bevor du in die Luft gejagt wirst ( 6Schaden an dir selbst, 3Schaden an allen lebenden Feinden)
    • Das Sterben mit einer nicht geworfenen Granate bedeutet, die Granate drei Runden lang nicht zu werfen.
  • Werfen : Spann die Granate auf jemanden und hoffe auf das Beste.

    • Das Ziel erhält 8Schaden, wenn es lebt
    • Jeder andere (auch Sie selbst) 3erleidet Schaden, wenn er lebt
  • Nichts : Warte eine Weile und beobachte, wie alle sterben.

Eingang

Ihrem Programm werden folgende Informationen übermittelt:

  • Die Gesundheit jedes Spielers
  • Eine Liste der Aktionen, die dieser Spieler seit Beginn des Standoffs ausgeführt hat. Nachfolgend finden Sie das Format für die pro Spieler übergebenen Informationen:

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

Aktionen werden in dem Format angegeben, das im Abschnitt Ausgabe angegeben ist.

Sie erhalten 4 solche Zeichenfolgen, die durch ein Leerzeichen getrennt und als einzelnes Argument übergeben werden. Die Reihenfolge dieser Zeichenfolgen lautet:

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

Die Zeichenfolgen werden als zweites Argument übergeben. Das erste Argument enthält eine Ganzzahl, die den aktivierten Abstand eindeutig identifiziert. Es ist garantiert, dass die Abstände zwischen derselben Gruppe von Spielern nicht gleichzeitig sind. Jedoch mehrere Abstandshalter werden zur gleichen Zeit auftreten.

Zum Beispiel:

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

Derzeit haben der Spieler und der zweite Gegner 3 Gesundheitspunkte, der erste Gegner hat 5 Gesundheitspunkte und der dritte Gegner hat -2 Gesundheitspunkte und ist tot.

In der ersten Runde:

  • Spieler 1 hat Feind 2 erschossen
  • Feind 1 bereitete eine Granate vor
  • Gegnerischer 2-Schuss-Spieler
  • Feind 3 erschoss sich

In der zweiten Runde:

  • Alle Spieler haben nichts getan. (Spieler und Feind 2 können nichts tun, da sie in der vorherigen Runde geschossen haben. Feind 3 ist tot: Er wird Nothingfür den Rest der Distanz sorgen.)

Das zweite Argument zu Beginn einer Pattsituation ist: 5 5 5 5.

Ausgabe

Ein Befehl sollte im unten aufgeführten Format ausgegeben werden. Eine ungültige Ausgabe wird als 'Nothing' interpretiert. Einem Befehl, der ein Ziel erfordert, sollte eine Ganzzahl folgen ( 0-3mit der 0Darstellung des Spielers und der 1-3Darstellung der Feinde 1-3).

  • S[target]: Schießt [Ziel].
  • D[target]: Versucht, [Ziel] auszuweichen.
  • P: Bereite eine Granate vor.
  • T[target]: Wirf die Granate auf [Ziel].
  • N: Nichts tun.

Ein Befehl, der ein Ziel benötigt, dem jedoch ein Ziel zugeführt wird, das nicht zwischen dem Ziel 0und / 3oder einem Ziel liegt, wird als Ziel angenommen 0(der Spieler).

Wertung

Am Ende jeder Auseinandersetzung erhalten die Spieler eine Punktzahl, die nach der folgenden Formel berechnet wird:

35 + health at end of standoff 

Im Fall , dass ein Spieler eine Pattsituation mit negativen gesundheitlichen endet, sie wird eine Punktzahl erhält unter 35 . Die folgenden Punkte werden ebenfalls als Bonus belohnt:

  • Meiste Gesundheit: +4 Punkte
  • Zweithäufigste Gesundheit: +2 Punkte
  • Drittgrößte Gesundheit: +1 Punkt.

Im Falle eines Gleichstands wird der niedrigere Bonus gewährt (bei einem Gleichstand mit zwei Personen mit der höchsten Gesundheit erhalten beide +2; bei drei Personen mit der höchsten Gesundheit +1 und wenn alle gleichermaßen enden, +0).

Die endgültige Punktzahl wird durch Berechnung des Mittelwerts aller Einzelpunktzahlen ermittelt.

Regeln / Details

  • Die Reihenfolge der Ereignisse innerhalb einer Runde ist wie folgt:
    • Alle Spieler machen ihre Aktionen.
    • Spieler mit 0 oder weniger Lebenspunkten sterben.
    • Nicht geworfene Granaten, die explodieren müssen, werden explodieren (Spieler, die gerade gestorben sind, sind immer noch verletzt, da sie noch an der Reihe sind, zu sterben).
  • Keine Zusammenarbeit zwischen Einträgen.
  • Drei * Abstände treten zwischen jedem Satz von 4 Spielern auf. (Die Reihenfolge der Spieler kann mit jedem Standoff variieren.)
  • Einträge, die übermäßig viel Speicherplatz beanspruchen, werden disqualifiziert.
  • Das Lesen oder Ändern von Dateien, die nicht zu Ihren Einträgen gehören, disqualifiziert Ihren Eintrag.
  • Ein von einem Betrunkenen gefahrener LKW überfährt nach dem 50thZug alle lebenden Spieler , wenn die Pattsituation am Ende des 50thZuges noch nicht vorbei ist .
    • Dieser LKW fügt allen lebenden Spielern 20 Schadenspunkte zu.
  • Standoffs passieren schnell. Programme werden nach 1 Sekunde abgebrochen.
  • Ihr Programm wird in jeder Runde aufgerufen, auch nachdem Sie gestorben sind.
  • Sie können nur Dateien in Ihr Verzeichnis lesen oder schreiben (wenn Ihr Eintrag den Namen JohnDoe trägt, können Sie Dateien im Verzeichnis player / JohnDoe / speichern). Dies ist jedoch NICHT das aktuelle Verzeichnis, während Ihr Skript ausgeführt wird.
  • Die Abstände finden auf einem Computer statt, auf dem Arch Linux ausgeführt wird (Release 2014.08.01).

Der Controller ist auf GitHub verfügbar .

Bitte fügen Sie Ihrem Beitrag Folgendes bei:

  • Ein Name für Ihren Bot
  • Ein Shell-Befehl zum Ausführen des Bots (z. java Doe.javaB.). Die Eingabe wird als einzelnes Argument ( java Doe.java 5 "-2,S0 -2,S1 -2,S2 5,N") über die Befehlszeile übergeben.
  • Code Ihres Bots
  • Wie der Bot kompiliert werden soll (falls zutreffend)
  • Sprache (und ggf. Version, insbesondere für Python)

* Controller dauert viel zu lange für sechs.

Anzeigetafel

                      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

Protokolle: auf GitHub

es1024
quelle
1
Haben Sie genau eine Granate oder haben Sie viele? Können mehrere Granaten gleichzeitig vorbereitet werden?
Isaacg
2
@Bob Ich bin mir ziemlich sicher, dass EmoWolf zu Standard- Lücken hinzugefügt wurde, die nicht mehr lustig sind . Obwohl eine Selbstmordattacke möglicherweise nicht so schrecklich ist.
es1024
3
Lektion für alle: Nicht trinken und fahren.
Mark Gabriel
8
@ es1024 Wenn Selbstmord tatsächlich eine praktikable Strategie ist, sollte eine EmoWolf-Vorlage wirklich zulässig sein. Besonders wenn die verfügbaren Aktionen explizit Selbstmord beinhalten! Nicht so sehr eine "Lücke", oder? Und nicht wirklich ein unfairer Vorteil, was die meisten dieser Schlupflöcher wirklich sind. Aber das ist nur meine Meinung.
Bob
3
Wenn man bedenkt, dass der Controller ein paar Mal läuft, scheint er ziemlich laut zu sein. Wenn dieser Wettbewerb jemals beendet wird, sollten Sie wahrscheinlich die Anzahl der Läufe erhöhen, um ihn ein wenig zu glätten.
Davis Yoshida

Antworten:

7

Beobachter

Dieser Typ analysiert seine Feinde. Das Ziel ist es, zu überleben, bis nur noch ein "aggressiver" Gegner übrig ist, und diesen dann in einem epischen Gefecht zu töten.

Kompilieren: javac Observer.javaAusführen: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
quelle
!player.contains("S" + id)Ist dies eine notwendige Bedingung in der Funktion "isAggressive"? Ein selbstmörderischer Spieler wird sowieso tot sein
Cruncher
22

Grenadier

Waffen sind überbewertet. Ein echter Schottenstreit sieht so aus:

  • Bereiten
  • Wirf den Gegner mit der meisten Gesundheit
  • Wiederholen (falls du noch lebst)

Während dies trivial erscheint, ist es wahrscheinlich keine schreckliche Strategie. Da Gewehren und Granaten haben beide eine zwei wiederum Zyklus ist dies bei weitem die effizientere 1 Art und Weise Schaden zuzufügen.

Natürlich ist es nicht gut, wenn alle drei Gegner in der ersten Runde auf mich schießen. Aber sonst wäre es auch nicht viel.

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

Kompilieren Sie / führen Sie in der Standard-Java-Weise aus:

> javac Grenadier.java
> java Grenadier arg0 arg1

1 Sinnlose Fußnote

Geobits
quelle
41
hahaha die
fußnote
Ich denke, eine Granate zu werfen und dann zu schießen ist effizienter. Die Chance, dass Sie mit dieser Strategie 4 Runden überleben, ist betäubend gering. Aber 3 vielleicht (ja, beide nehmen 2, aber die zweite Runde für das Schießen ist nach der Aktion, nicht vor)
Cruncher
@Cruncher Du hast wahrscheinlich recht. Eric sagte dasselbe im Chat. Ich sagte ihm, dass mein Typ nicht an Waffen glaubt und zu stur ist, um diese Logik anzuwenden. Er hat diese Strategie veröffentlicht. Ich glaube jedoch immer noch, dass dies effizienter ist , wenn es sich ausschließlich um Schaden handelt. Das heißt nicht, dass es effektiver ist , das Spiel zu gewinnen. Selbst wenn ich in der dritten Runde sterbe, geht meine zweite Granate immer noch aus. Wenn ich also bis dahin lebe, ist das ein garantierter Schaden von 6+ für alle, das Spiel ist vorbei.
Geobits
@Geobits jetzt, wo ich darüber nachdenke, kann das besser sein. Am wichtigsten ist das Delta zwischen Ihnen und den Gegnern. Wenn die Granate explodiert, erhalten Sie +3 Delta bei dem, auf den Sie sie geworfen haben, und +0 bei dem Rest. Ein Netz von +3. Schießen. Gewinnt dir ein +2 Delta mit wem du schießt. +0 mit dem Rest. Ich denke, das Problem ist, dass Sie -3 mit Menschen, die bereits tot sind. Sie sollten schießen, wenn jemand tot ist :)
Cruncher
2
@codebreaker Habe es noch nie gespielt. Es ist eine Referenz aus dem wirklichen Leben .
Geobits
16

Asimovs Regel Nummer 0 Bot - Python

Ein Roboter darf die Menschheit nicht verletzen oder durch Untätigkeit zulassen, dass die Menschheit Schaden nimmt.

Er greift den ersten Spieler an, den er mit einer Granate sieht, um die Mehrheit der Menschen zu schützen. Wenn niemand die Mehrheit der Menschen bedroht, wird er nichts tun.

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

Führen Sie es wie folgt aus:

python rule0bot.py
William Barbosa
quelle
2
Ihr Roboter ist unlogisch. Wenn der Spieler mit der Granate wirft, erleidet die Menschheit 8 + 3 + 3 + 3 = 17 Schaden. Wenn du ihn mit dem Schuss tötest, erleidet die Menschheit 2 + 6 + 3 + 3 + 3 = 17 Schaden. In beiden Szenarien erhält derjenige, auf den die Granate gesprengt wurde, 8 und alle anderen 3 (sofern sie nicht zuvor tot waren). Die gesamte Menschheit ist nicht betroffen. Ich mag es aber immer noch. +1: D
Geobits
4
Eigentlich ist das beste Szenario für die Menschheit zu hoffen, dass die Granate auf den Roboter geworfen wird;)
Geobits
1
@Geobits Jemanden, der eine Bedrohung darstellt, nicht aufzuhalten, ist gegen die Natur von Robotern. Es wird versucht, jemanden zu stoppen, der eine Granate in der Hand hält, um zu verhindern, dass die Mehrheit (die anderen beiden) verletzt wird. Hast du gelesen, Robot? Diese Logik wird von Little Lost Robot und The Evitable Conflict unterstützt.
William Barbosa
Ich habe es gelesen, aber was ich sage ist, dass es hier nicht aufhört, sie zu erschießen . Wenn er stirbt, während er die Granate in der Hand hält, explodiert sie immer noch. Darüber hinaus bleibt der Gesamtschaden für die Menschheit derselbe. Du tust einem Menschen direkten Schaden, ohne dass die Menschheit davon profitiert.
Geobits
2
+1 Ich bin mit Kyle Kanos 'Stimme nicht einverstanden und möchte sie für nichtig erklären. Geobits geht zu Unrecht davon aus, dass dies der Menschheit nichts nützt. Sicher, die Menschheit kann im schlimmsten Fall nicht besser abschneiden, aber wenn die anderen beiden Spieler auf die Granatendusche schießen, sind sie alle besser dafür.
FreeAsInBeer
14

Han Solo - Python

Han schoss zuerst. In diesem Fall schießt er zuerst, indem er das nächste lebendige Ziel auswählt.

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

Führen Sie es wie folgt aus:

python hansolo.py

Hinweis : Dies ist das erste, was ich jemals in Python geschrieben habe. Wenn Sie also Python-spezifische schlechte Praktiken bemerken, lassen Sie es mich bitte wissen.

William Barbosa
quelle
1
Pep8-Stil schlägt vor, dass Ihre Methode sein sollteis_alive
Daenyth
4
@ WilliamBarbosa werfen Sie einen Blick auf pep8, es ist der Python-Style-Guide, den jeder benutzt. legacy.python.org/dev/peps/pep-0008
Daenyth
2
Herzlichen Glückwunsch, dass Sie in der 8/11-Runde der einzige Bot mit einer durchschnittlichen Gesundheit von mehr als 0 sind.
isaacg
6
IMO, "Styleguides", richten sich an Friseure, nicht an Programmierer.
Kyle Kanos
2
@KyleKanos Es ist jedoch schön, eine gewisse Konsistenz zu haben. Ich meine, wenn die Hälfte der Entwickler eines Projekts Camel Case und die andere Hälfte solche Typen verwendet, wird das Ergebnis "blergh" sein
William Barbosa
12

EmoCowboy

Warum warten, um zu sterben? Töte dich jetzt einfach. Hoffentlich sprengen sich die anderen Dummköpfe gegenseitig bis auf weit unter -2.

Punktzahl wird normalerweise -2 sein. Manchmal -4, wenn Leute beschließen, mich vom Hieb zu schießen. Selten mehr als das, was bedeutet, dass dies einige der aktuellen Einreichungen schlagen sollte.

Python

print('S0')

python EmoCowboy.py

EDIT: Dies ist kein Scherz, weshalb diese Emo-Einreichungen im Allgemeinen verpönt sind. Dies ist eine legitime Strategie. Am Leben zu sein ist tödlich!

Cruncher
quelle
11

Pazifist

Er ist ein echter Swell-Typ, hat sich gerade mit der falschen Menge angefreundet.

main = putStr "N"

Ausführen als runghc pacifist.hs, aber Sie können es mit -O3 kompilieren, wenn Effizienz ein Problem ist.

tödlich
quelle
1
Bitte benenne es in Luigi um und lass uns sehen, ob er irgendetwas gewinnt!
William Barbosa
1
@WilliamBarbosa Luigi? Hast du Luigi gesagt ?
Killmous
7
Lol, als ob -O3es einen verdammten Unterschied macht.
Tomsmeding
@tomsmeding Es ist langsam auf der runghcSeite. Eigentlich ist es auf meiner Linux-Box 10-mal langsamer.
Ray
5
Dies
9

Monkey - Python (Erster Eintrag!)

Affe sehen, Affe tun. Wiederholt genau die letzte Aktion eines zufälligen Spielers.

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

Kann folgendermaßen ausgeführt werden: "python monkey.py args" Keine zusätzlichen Schritte erforderlich.

Elias Benevedes
quelle
2
Ich hoffe, sie haben nicht auf dich geschossen! Python unterstützt negative Array-Indizes, sodass Sie die Länge nicht berechnen und eine davon subtrahieren müssen. Verwenden Sie einfach -1direkt.
Super
@comperendinous Sag, ich bin S3 in ihrer Liste. Wenn ich S3 ausführe, erschießt es mich nicht dumm. Außerdem gibt der Index -1 das letzte Element zurück. Wenn ja, cool! Ich werde es auf jeden Fall hinzufügen.
Elias Benevedes
Und vergessen Sie nicht das erste (ganzzahlige) Argument. Sie müssen argv[2]die Spielerhistorie erhalten.
Super
Hoffe nur, dass du dich nicht mit Emo Cowboy messen kannst.
Codebreaker
6

Simple Shooter - Perl (Fehler behoben)

Dieser Bot schießt auf den Gegner mit der größten Gesundheit. Es ist eine sehr einfache Strategie, aber ich denke, sie hat eine gute Chance, tatsächlich gut abzuschneiden.

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

So führen Sie es mit einer Beispieleingabe aus:

perl simpleshooter.plx 7 "3,S2,N 5,P,N 3,S0,N -2,S3,N"
PhiNotPi
quelle
Beeindruckend. Einfach und schlau.
Soham Chowdhury
6

Spock, in Python 3.x

Dieser Code ist eher ein Versuch (daher nach Spock benannt, weil ... er ein Vulkanier ist und sie in solchen Dingen ziemlich gut sind), aber es hat Spaß gemacht, ihn trotzdem zu erstellen. Die Hauptgründe für all diesen Code sind Annahmen, die ein gutes, logisches Wesen wie Spock machen würde, wenn die Spielregeln gegeben wären:


Das Ziel dieses Spiels ist es, die Punktzahl zu maximieren , was jeder tun würde, der nur stillsteht, was aufgrund des Trucks nicht möglich ist.

  • Eine der Anweisungen, die Spock befolgen muss, besteht darin, das Erscheinen des Lastwagens zu verhindern und sicherzustellen, dass alle außer einem tot sind, bevor der Lastwagen erscheint.

Die Art und Weise, wie Spock im Rest des Spiels spielt, kann durch sein berühmtes Zitat zusammengefasst werden: " Die Bedürfnisse der Vielen überwiegen die Bedürfnisse der Wenigen ". Mit anderen Worten, Spock muss sicherstellen, dass der geringste Schaden entsteht, indem er diejenigen tötet, die ihn verursachen. Wie er es macht:

  • Wenn kein Spieler eine Granate vorbereitet hat, wähle den am wenigsten gesunden Spieler, der noch spielt.
  • Wenn es Spieler gibt, die Granaten vorbereitet haben, zielen diese auf die am wenigsten gesunden ab.

Der Grund dafür ist, dass wir durch das Zielen auf die schwächsten Spieler Schadensquellen ausschalten. Der Grund für die Granaten ist, dass sie unabhängig davon losgehen und weniger Schaden anrichten, wenn sie nicht geworfen werden.


Und so funktioniert dieser Bot. Ich habe nicht ausgiebig auf Eingabefehler getestet (also warnen Sie mich, wenn etwas schief geht), aber ich bin zuversichtlich, dass ich die meisten Probleme behoben habe. Ich habe einen kleinen Teil des Codes aus dem HanSolo-Bot verwendet, aber zum größten Teil handelt es sich um ein Wirrwarr von Code. Genießen.

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)

Führen Sie es wie folgt aus:

python spock.py

2014-08-12 - Kleinere Fehlerbehebung in Bezug auf die Granatenerkennung
2014-08-14 - Kleinere Fehlerbehebung in Bezug auf das Endspiel, dank isaacg für den vorherigen Hinweis

Doktoro Reichard
quelle
Du darfst nicht mehr als einmal alle zwei Runden schießen. Lesen Sie die Angaben zum Schießen.
Isaacg
@isaacg Danke für die Erinnerung (die das Verhalten erklärt), aber es scheint einige latente Fehler zu geben. Zum Beispiel hätte Spock InputAnalyser erschießen sollen, weil er eine lebende Granate hatte (auch wenn Solo mehr als 2 Lebenspunkte hätte).
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]sollte sein int(player[1][1]).
Isaacg
@isaacg nochmal, ich danke dir für die hilfe. Ich hätte das früher getan, aber ich bin mit Sachen überflutet worden. Spock baute letztendlich auf einem fehlgeleiteten Konzept auf, wie sich dies entwickeln würde, daher die relativ niedrige Punktzahl, die er erhalten hat. Ich habe einige Ideen für neue Bots, aber bei so vielen muss ich jetzt sicherstellen, dass die Hauptidee original ist.
Doktoro Reichard
5

Politisch korrekter Schütze

Sehr politisch korrekt, da es nichts diskriminiert. Daher ist es nicht sehr schlau.

import random

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

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

Es ist eigentlich egal, welche Argumente wie an sie weitergegeben werden. python politicallycorrectgunman.py

Rückgängig machen
quelle
Ich glaube nicht, dass die eckigen Klammern Teil der Ausgabe sein sollen. Vielleicht kann @ es1024 das bestätigen. Und kennst du random.choice? Es ist toll für diese Art von Auswahl.
Super
Es kann nichts vor der Aktion und dem Ziel in der Ausgabe geben, obwohl alles danach ignoriert wird
es1024
Sieht das bei es1024 besser aus?
Machen Sie den
@Undo Ja, funktioniert jetzt perfekt
es1024
7
Könntest du nicht einfach benutzen random.choice(array)?
user2357112
5

Straight Shooter

Er ist ein ausgebildeter Teil der Kavallerie und spricht in vielen Sprachen, aber wenn Straight Shooter blinzelt, kann er nur den einen Feind vor sich sehen. Als Pferd versteht er nicht, dass man zwischen den Schüssen warten muss.

print('S2')

Perl, Python 2/3, Ruby: Dieses Pferd ist wirklich ein Polygot-Eintrag.

Ich gewinne trotzdem. Ich kann nicht verlieren Du kannst mich erschießen, aber du kannst mich nicht töten. Mister Ed hat nichts mit mir zu tun!

Für eine Antwort, die ein wenig mehr Gedanken (und ein funktionelles Paradigma) enthält, siehe Vierundzwanzigstes und ein halbes Jahrhundert .

hervorragend
quelle
5

Anti-Grenadier

Granaten sind schlecht. Sehr schlecht. Wenn also jemand eine vorbereitet, ist es am besten, sie zu erschießen. Ansonsten bleiben wir einfach.

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

Ricochet - Perl

Einfache Strategien scheinen in dieser Herausforderung angemessen zu sein, hier ist eine andere. Es schießt einen zufälligen lebenden Spieler. Es hat die zusätzliche Eigenschaft, am Ende Selbstmord zu begehen, um dem Lastwagen auszuweichen.

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

Laufen Sie wie folgt:

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

Aggressor

Zieht in Runde 1, wirft in Runde 2 auf den Gegner mit der höchsten Gesundheit und schießt danach auf den Gegner mit der höchsten Gesundheit.

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

Führen Sie dies wie ./agg ID "5 5 5 5" aus.

Eric Tressler
quelle
4

Ninja

Weicht einfach willkürlich aus, um nicht getroffen zu werden.

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

Rennen wie

lua ninja.lua

Argumente sind nicht erforderlich, können jedoch ohne Probleme hinzugefügt werden.

Kyle Kanos
quelle
2
@KyleKanos Weicht Ninja seinen eigenen Aufnahmen aus?
Skeggse
2
@ destilledchaos: ... ja, ja wird er.
Kyle Kanos
4

Name : PriorityTargets

Shell-Befehl : ruby ​​PriorityTargets.rb 5 [game_state]

Sprache : Ruby V2.1.2

Beschreibung : PriorityTargets versucht, gängige Spielstile zu finden. Anhand dieser Spielstile entscheidet es dann, wen es angreifen möchte und welche Waffe es verwenden soll.

Hinweis : Erster Code Golf Beitrag! Viel größer als die anderen Einsendungen, weil ich ein bisschen verrückt geworden bin.

#!/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
quelle
1
Ich mag Ihre Herangehensweise, ich freue mich darauf zu sehen, wie es geht.
Overactor
Leider scheint es einen Fehler zu geben, der einen Grenadier hervorgebracht hat. Ah gut, wird es beim nächsten Mal besser machen :)
fingerco
3

Feigling - Perl

Benimmt sich sehr feige. Wenn er sich gesund fühlt, wählt er einen Feind, der sich nicht so fühlt und erschießt ihn. Bonuspunkte für die Feinde, die in der letzten Runde geschossen haben (weil bekannt ist, dass sie in Nothingdieser Runde geschossen haben und daher absolut wehrlos sind). Wenn er sich nicht so gut fühlt, rennt er in Deckung, um sein Versteck zu retten, und erschießt gelegentlich jemanden.

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

Ziemlich normaler Perl-Code; Speichern Sie es in einer Datei und führen Sie es dann aus perl file argument argument [...]. Ich habe die Syntax überprüft und es war in Ordnung, daher hoffe ich auf keine Probleme damit.

E: Potentielle Division durch 0 Fehler beseitigt.

Ramillies
quelle
3

Bomberman

Bot in R geschrieben, Kommandozeile sollte lauten: Rscript Bomberman.R arg0 arg1
Nachdem ich angefangen hatte, diesen Bot zu schreiben, wurde mir klar, dass Geobits bereits einen Grenadier hergestellt hat, aber ich denke, meiner unterscheidet sich erheblich darin, dass er prüft, ob sein Gesundheitszustand über 3 liegt, bevor er eine Granate vorbereitet Der letzte Schütze zuerst und der gesündeste zweite, und wenn sein Gesundheitszustand unter 3 liegt, weicht er dem gefährlichen Spieler aus (weder der Tote noch der Schütze in der letzten Runde) oder schießt auf einen der verbleibenden Spieler.

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)

Bearbeiten

Es scheint ein Kommunikationsproblem zwischen diesem Bot und Ihrem Controller zu geben, da alle von mir untersuchten Protokolle zeigten, dass mein Bot nur ausgegeben hat N. Also, hier ist derselbe Bot, der aber in Python umgeschrieben wurde, in der Hoffnung, dass es jemand sieht, wenn dieser auch Kommunikationsprobleme hat.
Mit angerufen werden python Bomberman.py arg0 arg1.

import sys,re,random

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

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

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

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

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

print(out)
Plannapus
quelle
Der Name des Bots ist relativ schwach, aber ich habe keine Ahnung mehr, wenn jemand einen besseren Namen finden kann, bitte kommentieren :)
Plannapus
GymnastBomber !!
Cruncher
3

Neo

Weiche einem lebenden Spieler aus, der in der letzten Runde nicht geschossen hat. Wenn alle Lebenden in der letzten Runde geschossen haben, schieße einen zufälligen lebenden Spieler. Selbstmord, wenn man Scheinwerfer sieht.

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

Ich erwarte nicht viel von diesem Kerl gegen Granatenficker, aber gegen Schützen könnte es ziemlich gut funktionieren. Wir werden sehen.

Geobits
quelle
Ich habe in meiner Antwort einen Teil Ihres Kesselschild-Codes verwendet . Ich hoffe das ist okay.
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 Sollte jetzt gut sein und wird nicht bei jeder ersten Abbiegung nichts tun.
Geobits
2

Vierundzwanzigstes und ein halbes Jahrhundert

Dieser Python-Eintrag duckt sich und weicht aus, bis nur noch passive Spieler oder ein einzelner aggressiver Spieler übrig sind, und beginnt dann zu schießen. Er hofft, dass ein vorübergehender Marsianer sich um Grenadiere und betrunkene Lastwagenfahrer kümmert.

Sofern ich nichts falsch gemacht habe, ist dies funktionales Python. Es sieht bestimmt nicht so aus wie die Art von Python, die ich geschrieben habe, bevor Haskell und Freunde mich gefunden haben, und ich glaube nicht, dass ich irgendetwas an Ort und Stelle mutiert habe. Aber wenn Sie es besser wissen, sagen Sie es mir bitte.

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

Rennen wie:

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

erschrocken

Diese Einreichung hat Angst vor allen. Aber es ist besonders ängstlich von einigen Menschen. So findet es heraus, wer am gefährlichsten ist, und erschießt sie. Wenn mehrere Gegner am gefährlichsten aussehen, schießt sie nach dem Zufallsprinzip.

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

Dies ist Python (2 oder 3, dasselbe Ergebnis in beiden.) Speichern unter scared.py, Ausführen mitpython3 scared.py

isaacg
quelle
2

Manipulativer Bastard - Python

Bereitet Granaten vor und wirft sie. Wenn er denkt, es gibt keine Zeit oder es gibt zu wenige Feinde, schießt er. Wenn er alleine ist, versucht er den anderen auszutricksen.

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

Osama

Ich habe es ungefähr einen Tag lang versucht, jetzt ist es Zeit zu posten und zu sehen, wie sich die anderen in der Zwischenzeit entwickelt haben.

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

Kompilieren Sie mit ghc -O2 osama.hsund führen Sie dann mit ./players/Osama/osama.

TheSpanishInquisition
quelle
2

Scharfschütze - Lua

In der ersten Runde schießt es auf eine zufällige Person und dann auf alle Spieler, die es töten kann (2 oder 1 Gesundheit). Wenn keine dieser Aktionen ausgeführt wird, wird versucht, den Spieler zu erschießen, der zuletzt geschossen hat, andernfalls wird ein zufälliger Spieler erschossen. Laufen Sie mitlua 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
quelle
Es wird tatsächlich zuerst mit einem zusätzlichen Argument ausgeführt. zB lua Sniper.lua 3 "5,S1 3,D3 5,N 5,P". Möglicherweise müssen Sie Ihren argIndex überprüfen .
Super
@comperendinous, danke, jetzt behoben
waylon531
Hallo, @ waylon531, Frage zu Lua: der Zufallsgenerator math.randoms "math.randomseed (os.time ()) math.random (); math.random (); math.random ()" reicht nicht aus, um die zufällige Reihenfolge zu bestimmen Skript?
AndoDaan
1
AndoDaan, laut lua-users.org/wiki/MathLibraryTutorial, geben einige Betriebssysteme beim ersten Aufruf von math.random () immer dieselbe Zahl zurück.
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

Überleben der Stärksten bedeutet, dass die am wenigsten Gesunden sterben müssen.

Begründung

Wenn man sich die Ergebnisse vom Dienstag (12.) ansieht, scheint es drei verschiedene Gruppierungen zu geben: Überlebende; die effektiv Selbstmord; und das schlimmer als nutzlos. Die Überlebenden teilen einfache Schießstrategien. Während ein paar andere Bots ( Spock , Feigling ) den am wenigsten gesunden Feind anvisieren, komplizieren sie ihre Strategien auch mit anderen Aktionen. Dieser tut es nicht. Wie Simple Shooter hat es eine klare Definition des Ziels und bleibt unerbittlich dabei. Es wird interessant sein zu sehen, wo es in die Ergebnisse passt.

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

Dies ist eine abgespeckte, leicht modifizierte Version meiner früheren Vierundzwanzigste und Halfth Jahrhundert , und teilt ihren Aufruf:

python darwin.py 3 "5 5 5 5"
hervorragend
quelle
2

Zaenille - C

Prioritäten:

  1. Schieße, wenn es 1 zu 1 ist
  2. Grenadiere schießen
  3. Ausweichen
  4. Nichts (nur um einige zu verwirren)

Kompilieren mit gcc <filename.c>.

Laufen Sie mit ./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
quelle
1
Das erste (ganzzahlige) Argument gibt nicht die Anzahl der Runden an, wenn die in der Frage angegebenen Beispiele zutreffen. Sie würde nicht wollen , sich auf der ersten Runde schießen , nur weil Sie 82 zu Patt - Nummer zugewiesen worden war
comperendinous
"Ja wirklich?" D: Danke @comperendinous. Wird den Code bearbeiten.
Mark Gabriel
2

InputAnalyzer

Der Schlüssel zu einem solchen Spiel ist, zu analysieren, wie alle Ihre Gegner spielen, um entsprechend zu reagieren. Mein Bot wird genau das mit komplizierten Algorithmen tun, die dazu führen, dass sich meine Gegner zu meinem Vorteil wenden und einen entscheidenden Sieg erringen!

Edit: Ich jetzt

  1. Weiche jedem Spieler mit einer lebenden Granate aus
  2. Ich werde nicht länger versuchen, mich selbst zu zeigen, zu werfen oder auszuweichen.

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

Kompiliere den Bot mit dem folgenden Befehl (Need to have ghc)

ghc --make InputAnalyzer.hs

Der auszuführende Shell-Befehl sollte der folgende sein

./InputAnalyzer

Hinweis: Ich habe auf Windows getestet. Wenn Sie Probleme mit der Ausführung haben, geben Sie dies bitte in den Kommentaren an und ich werde mein Bestes tun, um den richtigen Befehl zu finden.

Sahar Rabinoviz
quelle
1
Nun, ich nehme an, das ist eine Möglichkeit, einen gewichteten Pseudozufallsgenerator in Haskell zu bekommen.
Comperendinous
2

Hund namens Courage

Schießen Sie als erstes auf die Bösen. Weiche dann nach dem Zufallsprinzip aus, bis jemand eine Granate vorbereitet. Wenn dann alle auf ihn schießen, bereite meine eigene Granate vor und wirf sie auf irgendjemanden. Aber der Ablenkungsmann.

Edit: Jetzt implementiert, wie ich es mir vorgestellt habe. Vorher war die Kerbe: 35.9

Aktualisiert: Schießt manchmal, anstatt auszuweichen

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

Rennen wie

python couragethedog.py
loa_in_
quelle
2

MAD - Java

Der MAD-Bot vertraut auf die Macht der Einschüchterung durch gegenseitige sichere Zerstörung . Wenn er keine Granate parat hat, bereitet er sie vor. Dann weicht er möglichen Schützen aus, bis entweder jemand versucht, ihm Schaden zuzufügen, oder seine Granate explodiert. Von dem Moment an, in dem er angegriffen wird, wirft er Granaten auf denjenigen, der versucht hat , ihm in diesem Match mehr Schaden zuzufügen. Wenn seine Granate explodieren soll, bombardiert er den führenden Spieler. MAD ist nicht dagegen, auf jemanden zu schießen, wenn es nichts gibt, woran man ausweichen oder direkt eine Granate angreifen könnte, und seine Granate ist immer noch für mindestens eine Runde gut.

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

Dieser Bot wird wahrscheinlich schlecht abschneiden, aber mir hat die Idee trotzdem gefallen. MAD wäre wahrscheinlich besser in einem Feld mit intelligenteren Bots, die das Verhalten anderer Bots protokollieren, und mit mehr Übereinstimmungen zwischen vier Bots.

Überakteur
quelle
Einige Kredite sollten an Geobits gehen, ich habe einen Kesselschildcode von seinem Neo-Eintrag gestohlen.
Overactor
Sie haben nicht viel genommen, kein Guthaben erforderlich :)
Geobits
Anrufe java MAD 43 "5 5 5 5"scheinen nichts auszugeben.
es1024
2

Sadist

Python

Seine Priorität ist es, Schmerzen zu verursachen und Granaten zu verletzen. Er zieht die erste Kurve. Er tötet gern, wenn man nicht angreifen kann. Er spielt mit SSSs (Single Simple Shooter), indem er ausweicht und zieht, um die Dominanz zu verlängern. Er greift sogar diejenigen an, die noch niemandem etwas angetan haben.

Da er Granaten einsetzt, überlebt er (und alle anderen) die zweite oder dritte Runde in der Regel nicht. Wenn er mit einem anderen Granatwerfer gepaart ist, werden alle sterben. Das heißt, ich erwarte nicht, dass ich gewinnen werde, aber ich habe dies geschrieben, um Python zu lernen (ich habe es noch nie benutzt und versuche, eine Einführung in eine Reihe neuer Sprachen zu bekommen). Es gibt mehrere andere "Pull Firsts". Wenn Sie der Meinung sind, dass es zu ähnlich ist, lassen Sie es mich wissen. Die anderen scheinen jedoch nicht bereit zu sein, zu ziehen und dann auszuweichen.

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
quelle
Ich denke nicht, dass raw_inputdas funktionieren wird. sys.argv[2]scheint der Konsens für Python-Einträge zu sein. Möglicherweise finden Sie auch eine Verwendung für pop, mit der Sie sich auf thisisme=player[0];player.remove(player[0])das Einfachere konzentrieren können thisisme=player.pop(0).
Super
@comperendinous Ich habe den Code bei Ideone getestet und sys.argv funktioniert überhaupt nicht (wahrscheinlich aufgrund des Imports von sys). Deshalb habe ich raw_input verwendet. Gibt es einen Unterschied, der dazu führen würde, dass Letzterer nicht funktioniert? In diesem Fall muss ich wahrscheinlich einen anderen Online-Compiler für Python finden. Danke für den Vorschlag mit Pop! Mit diesem Befehl konnte der Index nicht angegeben werden. Ich werde es für jeden zukünftigen Python-Code verwenden.
Kaine
1
raw_inputzieht aus STDIN, aber der Player-Verlauf wird als Befehlszeilenargument an Ihr Programm übergeben, weshalb Sie benötigen sys.argv. Zum Testen können Sie es einfach manuell mit einstellen sys.argv = ["sadist.py", "0", "5 5 5 5"]. Dann sollten Sie anrufen können player=sys.argv[2].split(). Wenn der Import syswirklich unmöglich ist, können Sie zum Testen sogar den Punkt fallen lassen und das Array aufrufen sysargv. Solange alles andere funktioniert und Sie zu sys.argvIhrer Einreichung zurückkehren, sollte es in Ordnung sein.
comperendinous
@comperendinous zu bestätigen, wenn ich sys.argv aufrufe, wird es als Array den Namen des Programms in 0, die einzelne Zahl in 1 und den tatsächlichen Teil, den ich in 2 benutze, zurückgeben? Sie sind alle Saiten. Mit diesen Informationen sollte ich es richtig bearbeiten können. Vielen Dank!
Kaine