The Ultimate Samurai Showdown


37

Wskazówka: Ta wyzwanie zakończyła. Oznacza to, że zielony znacznik wyboru, który został przyznany C5H8NNaO4 za ich wejście Obserwator nie zostanie przeniesiony do żadnej nowej odpowiedzi.

Nadal możesz przesyłać nowe zgłoszenia, ale mogą występować opóźnienia w nowych turniejach, ponieważ nie sprawdzam już aktywnie nowych zgłoszeń.

Wprowadzenie

W tym wyzwaniu grasz w grę zręcznościową zatytułowaną The Ultimate Samurai Showdown Ultimate Edition Special Version 2.0 X Alpha Omega Turbo (lub po prostu Ultimate Samurai Showdown ). Twoi przeciwnicy? Nikt inny niż inni członkowie Programming Puzzles & Code Golf!

Jak można się spodziewać po zręcznościowej grze PPCG, nie grasz bezpośrednio w Ultimate Samurai Showdown , ale raczej piszesz program, który zagra dla Ciebie. Ten program będzie walczył z programami przesłanymi przez innych użytkowników w pojedynkach jeden na jednego. Najbardziej wykwalifikowany program zostanie ukoronowany Ostatecznym Samurajem PPCG i otrzyma zielony tyk legendy.

Opis gry

W tej części opisano mechanikę gry.

Warunek zwycięstwa

Mecz składa się z dwóch samurajów , które są skierowane przeciwko sobie nawzajem. Każdy samuraj rozpoczyna każdy mecz 20 punktami wytrzymałości i 1 honorem . Samuraj wygrywa, jeśli jego przeciwnik nie żyje i nadal żyje. Istnieją dwie metody śmierci samuraja:

  1. Jeśli punkty wytrzymałości samuraja spadną do 0, umrze.
  2. Jeśli samuraj przyniesie swój honor poniżej 0, zostanie on powalony przez bogów za nieuczciwe działanie w pojedynku.

Powalenie przez bogów ma wyższy priorytet niż zmniejszenie punktów życia do 0, więc w sytuacji, gdy jeden samuraj ma 0 punktów zdrowia, a drugi za -1 honoru, samuraj z 0 punktami zdrowia wygra. W sytuacji, gdy obaj samurajowie mają honor -1, obaj zostają powaleni przez bogów, a gra kończy się remisem.

Mecz składa się z maksymalnie 500 tur . Jeśli wszystkie 500 tur minie, a mecz nie zostanie rozstrzygnięty (żaden samuraj nie umarł), bogowie się nudzą i powalają obu samurajów, co powoduje remis.

działania

W każdej turze samuraj musi wykonać dokładnie jedną z następujących czynności:

W

Samurajowie będą czekać i nie wykonywać żadnych działań. To sprawia, że ​​wygląda fajnie, ale nie pomaga mu pokonać przeciwnika. Jest to również akcja domyślna.

B

Samurajowie pokłonią się przeciwnikowi w sposób honorowy. To podoba się bogom, dzięki czemu samurajowie zdobędą 1 Honor. Honor jest niezbędny do sukcesu twojego samuraja, ponieważ Honor jest zasadniczo „zasobem” w tej grze - wszystkie ruchy oprócz Bi Wmogą zmniejszyć Honor. Ponadto, jeśli samuraj zyska 7 Honoru lub więcej, przyznany mu zostanie Miecz Bogów . Konsekwencje tego są opisane poniżej.
Jednak ukłon w stronę przeciwnika pozostawia cię otwartym, jeśli przeciwnik zdecyduje się cię uderzyć mieczem, więc bądź ostrożny, kiedy wybierzesz ukłon.

G

Samurajowie wejdą do pozycji obronnej i będą strzegli się wszelkich uderzeń mieczem. Ten ruch z powodzeniem zablokuje wszystkie ciosy mieczem, nawet te wykonane Mieczem Bogów .
Jednak bogowie patrzą na zbyt defensywnego samuraja, więc ten ruch pochłonie 1 Honor, jeśli akcja samuraja w bezpośrednio poprzedzającej turze również się strzegła. W przeciwnym razie nie konsumuje Honoru.

I

Samuraj spróbuje uderzyć przeciwnika szybkim wyciągnięciem miecza z pochwy. Jeśli samuraj ma 7 Honoru lub więcej, użyje Miecza Bogów zamiast swojego zwykłego miecza. Ten ruch pochłania 1 Honor.
Szybki remis to szybkie uderzenie, które pokona wolniejsze ataki z góry, jednak przegra z parami. Jeśli uderzenie zakończy się powodzeniem, zadaje 1 obrażenie lub 2 obrażenia Mieczem Bogów .

P

Samuraj spróbuje sparować każdy nadchodzący atak, a następnie rozpocznie własny atak. Jeśli samuraj ma 7 Honoru lub więcej, użyje Miecza Bogów zamiast swojego zwykłego miecza. Ten ruch pochłania 1 Honor.
Parowanie jest dobrym manewrem przeciwko szybkim atakom, ale zostanie obezwładnione przez wolniejsze ataki z góry. Jeśli uderzenie zakończy się powodzeniem, zadaje 1 obrażenie lub 2 obrażenia Mieczem Bogów .

O

Samuraj będzie próbował uderzyć przeciwnika wolniejszym atakiem z góry. Jeśli samuraj ma 7 Honoru lub więcej, użyje Miecza Bogów zamiast swojego zwykłego miecza. Ten ruch pochłania 1 honor.
Uderzenie ogólne może obezwładnić parowania, ale przegra z szybkimi uderzeniami. Jeśli uderzenie zakończy się powodzeniem, zadaje 1 obrażenie lub 2 obrażenia Mieczem Bogów .

Miecz Bogów

Samuraj z Honorem, który wynosi 7 lub więcej, zyskuje możliwość użycia Miecza Bogów . Jeśli jego Honor spadnie poniżej 7, umiejętność użycia Miecza Bogów zostanie mu odebrana. Sword of the Gods zajmuje 2 obrażenia zamiast 1.

Sword of the Gods nie pozwala pokonać strajk strajk miecz, że nie będzie zwyczajnie pokonać. Na przykład, sparowanie Miecza Bogów nadal przegrywa ze zwykłym uderzeniem z góry, a szybki los Miecza Bogów nie obezwładni zwykłego szybkiego ciosu . Rzeczywiście, tak zwany Miecz Bogów nie jest tak potężny - być może jest to kosmiczny żart grany przez bogów ...

Tabela interakcji

Poniższy fragment stosu zawiera tabelę, w której wyraźnie wymieniono wszystkie możliwe wyniki różnych kombinacji działań, które może podjąć dwóch samurajów. Aby go wyświetlić, kliknij „Pokaż fragment kodu”, a następnie „Uruchom fragment kodu”.

Komunikacja programowa

Aby ułatwić przeprowadzenie turnieju, napisano program kontrolny, który ma pełnić rolę „bogów” - przechowuje zapisy honoru i zdrowia oraz odpowiednio uderza w samuraja. W tej sekcji opisano, w jaki sposób twój program będzie komunikował się z programem kontrolera.

Opis wejścia

Program kontrolny wywoła twój program z linii poleceń w następujący sposób:

<command> <history> <enemy_history> <your_health> <enemy_health> <your_honour> <enemy_honour>

gdzie:

  • <command>to polecenie wymagane do uruchomienia programu. Na przykład, jeśli twój program znajduje się w pliku super_sentai.pl, prawdopodobnie jest to polecenie perl super_sentai.pl.

  • <history>to historia twoich ruchów. Na przykład WWBPoznaczałoby to, że czekałeś dwa razy, ukłoniłeś się raz i sparowałeś raz.

  • <enemy_history>to historia ruchów wykonanych przez twojego wroga. Na przykład BBBIoznaczałoby to , że twój wróg ukłonił się trzy razy i wykonał jeden szybki remis.

  • <your_health> jest twoje obecne zdrowie.

  • <enemy_health> to aktualne zdrowie wroga.
  • <your_honour> jest waszym obecnym honorem.
  • <enemy_honour> to obecny honor wroga.

W pierwszej turze znaki historyi enemy_historybędą puste, więc program zostanie wywołany z czterema ostatnimi argumentami:

<command> <your_health> <enemy_health> <your_honour> <enemy_honour>

Przygotuj się na to!

Bystrzy czytelnicy mogą zauważyć, że cztery argumenty zapewniające honor i zdrowie obu samurajów są w pewnym stopniu zbędne; ponieważ jest to doskonała gra informacyjna, honor i zdrowie samurajów można określić tylko na podstawie historii.

Wartości te podano dla wygody, abyś nie musiał analizować argumentów historii. To powinno się przydać przy wdrażaniu prostych strategii, takich jak nie atakowanie, gdy twój Honor wynosi 0.

Opis wyjścia

Aby wybrać akcję, Twój program powinien jedno wyjście W, B, G, I, P, lub Ostandardowe wyjście, w zależności od tego, co akcja chcesz zrobić. Jeśli twój program nie wypisze niczego w ciągu 1000ms, zostanie zakończony, a twój program będzie traktowany tak, jakby został wypisany W.

Jeśli twój program wypisuje więcej niż jedną literę, brana będzie pod uwagę tylko pierwsza litera - więc wypisywanie Parrybędzie takie samo jak wypisywanie P.

Jeśli wynik pierwszej litery programu nie jest żadną z opcji wymienionych powyżej, domyślnie będzie to W.

Format zgłoszenia

Prześlij program jako odpowiedź na ten post. Możesz przesłać wiele programów. Jeśli przesyłasz wiele prostych programów, zalecamy przesłanie ich jako pojedynczej odpowiedzi; jeśli przesyłasz wiele złożonych programów, zalecamy przesłanie ich jako osobnych odpowiedzi. Po pomyślnym dodaniu twojego programu / programów do turnieju, dokonam zatwierdzenia do repozytorium git z twoim zgłoszeniem (link poniżej).

Jeśli napotkam problemy, które uniemożliwiają dodanie twojego programu do turnieju, zostawię komentarz na temat twojego zgłoszenia wskazujący problem.

W zgłoszeniu należy uwzględnić następujące informacje:

  1. Czytelna dla człowieka nazwa twojego programu, do użycia w tablicach wyników. Spacje są tutaj dozwolone; przecinki i znaki Unicode nie są.
  2. Język, w którym napisany jest Twój program. Unikaj pisania w dziwnych, trudno dostępnych językach, takich jak TinyMUSH.
  3. Krótkie streszczenie twojego programu. Może to być opis działania programu lub po prostu tekst smaku na temat programu (jeśli chcesz być całkowicie tajny), a może jedno i drugie.
  4. Polecenia wymagane do uruchomienia programu. Na przykład, jeśli piszesz swoje zgłoszenie w Javie o nazwie example.java, dostarczasz instrukcji kompilacji, javac example.javaa następnie instrukcji uruchamiania java example.
  5. Kod źródłowy programu.

Aby pomóc w przesłaniu, udostępniam szablon zgłoszenia, który można znaleźć tutaj . Szablon sprawia, że ​​przesyłanie wygląda ładniej. Gorąco zachęcam do korzystania z niego.

Podaję również dwa przykładowe wpisy. Mimo że przykładowe zgłoszenia będą brały udział w rundzie robin, ich głównym celem jest wyjaśnienie formatów przesyłania i wprowadzania / wysyłania do turnieju, a nie poważna rywalizacja o tytuł Ultimate Samurai.

Struktura turnieju

W tej części opisano, w jaki sposób odbędzie się turniej między uczestnikami.

Program kontroli

Program sterujący jest napisany w Pythonie 2 i można go znaleźć w repozytorium Ultimate Samurai Showdown Github . Jeśli chcesz go uruchomić samodzielnie, instrukcje, jak go uruchomić, znajdują się w pliku README.md w łączu. Jednak tylko turnieje rozgrywane na moim komputerze będą oficjalne, aby uniknąć różnic sprzętowych wpływających na wyniki turniejów.

Program sterujący zostanie uruchomiony na komputerze przenośnym z systemem Arch Linux. Ma procesor Intel Core i7 i 8 GB pamięci RAM. Spróbuję uruchomić wszystkie wpisy na moim komputerze, ale byłbym bardzo wdzięczny, jeśli unikniesz języków, do których nie można uzyskać swobodnego dostępu (ponieważ nie wiąże się to z żadnymi kosztami pieniężnymi).

System oceniania

System punktacji to okrągły robin. Każdy program rozegra osiem meczów z każdym innym programem. Wygrana daje programowi 1 punkt, strata bez punktów, a remis 0,5 punktu. Program z najwyższym wynikiem wygrywa. Jeśli dojdzie do remisu, pojedynkuję dwa najlepsze programy ze sobą, aby ustalić zwycięzcę.

Liczba odtworzeń każdego programu może zostać zmniejszona z 8, jeśli liczba uczestników jest bardzo duża. Dodam tutaj notatkę, jeśli to nastąpi.

Będę uruchamiał okrągły robin wiele razy, gdy publikowane są nowe zgłoszenia, ale liczy się tylko najnowszy okrągły robin.

Dyskwalifikacje

Możliwe jest, że Twój program zostanie zdyskwalifikowany z turnieju. Dyskwalifikacja może nastąpić, jeżeli:

  • Twój program nie kompiluje się ani nie uruchamia;
  • Twój program jest strategicznym duplikatem innego programu (tzn. Implementuje dokładnie taką samą strategię jak inny program);
  • Twój program próbuje sabotować inne programy, modyfikując kod kontrolera, kod innego programu itp .;
  • Twój program próbuje wykorzystać błąd w kodzie kontrolera. Zamiast wykorzystywać błędy, powinieneś otworzyć problem w repozytorium git, skomentować go lub pingować na czacie.

Wcześniejsze wyniki

Szczegółowe wyniki wszystkich turniejów są dostępne na stronie wiki .

Ostatni turniej został ukończony w dniu 17.07.2015, 07:20. Oto podsumowanie wyników:

The Observer: 209.0
Coward: 203.0
Monk: 173.0
Elephant Warrior: 157.0
Iniqy: 157.0
Agent 38: 144.0
Ninja: 138.0
Meiyo Senshi: 138.0
Kakashi: 136.0
Yoshimitsu: 131.0
Hermurai: 121.0
Warrior Princess: 120.0
Gargoyle: 119.5
The Honourable: 119.0
Hebi: 118.5
Predictor: 116.0
Whack-a-mole: 107.0
The Fool: 106.0
The Prophet: 105.0
Copy-san: 97.0
YAGMCSE: 80.0
The Waiter: 66.0
Swordsman: 43.0
Spork Holder: 32.5
Blessed Samurai: 27.5
Attacker: 27.0
The Terminator: 17.0
Master Yi: 16.0

1
Kelner ma się zaskakująco dobrze. Musi się zbierać wygrane przeciwko Spork Holder, gdy skończy się honor.
StephenTG

To fajne wyzwanie. Wyraźnie w to dużo myślisz i pracujesz i myślę, że zdecydowanie się opłaciło. Świetna robota. :)
Alex A.

1
@ C5H8NNaO4 Tak, sprawdzę dostępność botów, zanim rozpocznę następny turniej.
absynt

1
Uwaga: Mój laptop niedawno się zepsuł. Dlatego nie mam obecnie sposobu na przeprowadzenie turnieju w najbliższej przyszłości. Wystąpią opóźnienia w uruchomieniu następnego turnieju, gdy próbuję znaleźć komputer, którego mogę użyć.
absynt

1
@Levi Tak! Producent przysłał mi zamiennik, który dotarł dzisiaj. W tej chwili trwa turniej.
absynt

Odpowiedzi:


8

The Monk (Java)

Mnich ceni honor i chwali błogosławieństwa bogów. Będąc wyćwiczonym w cierpliwości, spokojnie wysyła swoje modlitwy do nieba, dopóki nie poczuje się uprzywilejowany przez Boga.

Ciesząc się życiem, stara się go chronić. Kiedy traci zdrowie w określonym tempie, broni się najlepiej, jak potrafi.

W nadziei na wsparcie swoich bogów losowo wysyła wytrysk [1] do nieba, w przeciwnym razie walczy najlepiej, jak potrafi.

Jeśli jego przeciwnik jest zmęczony walką, kończy go, wykorzystując swój pozostały honor, aby zapewnić mu szybką i bezbolesną śmierć.

Kompiluj / Uruchom

javac Monk.java
java Monk

public class Monk {
    public static void main(String[] args){
        char  r = 'B';
        double  s = Math.random ();
        int n = Math.max (args [0].length ()- 8, 1);
        int p = args.length > 4 ? Integer.parseInt (args [4]):0;
        int l = Integer.parseInt (args [3]);
        int m = Integer.parseInt (args [2]);
        double d = 1 + (20 - m) / n;
        double e = 1 + (20 - l) / n;

        if (((p>8&&s<.7)||l<11||m<2)&&p>0) {
                r=(s<(.14)||d>=2||e/d<.618)?'G':"OPI".charAt((int)(Math.random()*3));
        }

        System.out.print (r);
    }
}

The Ninja (Java)

Ninja jest szybki i atakuje jeszcze szybciej. Atakuje natychmiast po przyjacielskim oficjalnym powitaniu, dodatkowo myląc wroga, kłaniając się przed i po każdym ataku.

Po otrzymaniu błogosławieństwa ninja podtrzymuje to zachowanie, czekając, aż przeciwnik wykona swój pierwszy ruch (ruchy). Korzystając z okazji, wyzwala serię wybuchów, pobłogosławionych przez boginię ninja, dopóki nie będzie zbyt zmęczony walką. Wykorzystując swój pozostały honor, ukrywa się pod liśćmi poniżej, chroniąc się przed następnym atakiem. Wyskakuje i atakuje swojego przeciwnika od tyłu, znów będąc tak szybko schowanym.

Jeśli otrzyma śmiertelną ranę, idzie na całość, aby zabrać ze sobą życie swojego przeciwnika - oczywiście zachowując odrobinę honoru.

javac Ninja.java
java Ninja

public class Ninja {
    public static void main(String[] args){
        char  r = 'B';
        int n = args [0].length ();
        int p = args.length > 4 ? Integer.parseInt (args [4]):0;
        int m = Integer.parseInt (args [2]);
        int a = n % 3;
        if (p>7) {
           if (m>17) {
                r = "BBI".charAt (a);
           } else if (m>13) {
                r = "BII".charAt (a); 
           } else {
               r  = "GIG".charAt (a);
           }

        } else if (p>0) {
           if (m > 10) {
                    r = "BBI".charAt (a);
           } else {
                r="IGI".charAt (n%2);
           }
        }
        System.out.print (r);
    }
}

Kakashi, The Copycat Ninja (Java)

Kakashi kopiuje ruchy przeciwnika, losowo wybierając pomiędzy dwoma ostatnimi ruchami wykonanymi przez przeciwnika. Jeśli przeciwnik czeka, kłania się - zachowuje również swój honor.

javac Kakashi.java
java Kakashi

public class Kakashi {
    public static void main(String[] args){
        char  r;
        String h = args [1];
        if (h=="W" || Integer.parseInt ( args.length > 4?args [4]:"0") < 1){
                 r = 'B';
        } else if (Math.random ()<.1) {
            r = 'I';
        } else {
            r  = h.charAt ((int) (h.length()==1?0: h.length()-Math.random ()*2));
        }

        System.out.print (r);
    }
}


Chciałbym, aby Kakashi mógł zostać pobłogosławiony przez sharingan. Myślałem o przeczytaniu cast.txt. Symuluj każdą rundę jego historii przeciwko każdemu przeciwnikowi. Spróbuj dowiedzieć się, z którym przeciwnikiem walczy, porównując historię symulowanych wrogów z historią prawdziwych wrogów. Następnie wykorzystaj te informacje, aby przewidzieć następny ruch, który wykona przeciwnik, i wybierz najlepsze przeciwdziałanie ze wstępnie zdefiniowanej listy. Ale wydaje mi się, że może to trochę potrwać, ponieważ mam w tej chwili bardzo wolny Internet i brak znajomości języka Java

The Observer, (node.js)

Obserwator kłania się, zanim spróbuje przewidzieć następny ruch przeciwnika na podstawie ostatnich 5 ruchów, wybierając najlepszy odpowiednik dla przewidywanego ruchu.

Edycja: Podziękowania dla @apsillers za udostępnienie pliku node.js!

node observer.js

var argv = process.argv;
var history = argv.length>6?argv[2]:"";
var enemyHistory = argv.length>6?argv[3]:"";
var offset = 8 - argv.length;
var my = { health:+argv[4-offset], honor:+argv[6-offset], history:history };
var enemy = { health:+argv[5-offset], honor:+argv[7-offset], history:enemyHistory };
my.godSword = my.honor >= 7;
enemy.godSword = enemy.honor >= 7;
function decide() {
    process.stdout.write(arguments[Math.floor(arguments.length*Math.random())]);
    process.exit();
}

var m = {
    m:{},
    l:function (a,b) {
        if (!this.m[a]) {
           this.m [a] = [];
        }
        this.m[a].push (b);
    },
    p:function (a) {
       for (var k=0;k<a.length;k++)
       for (var j=1;j<a.length;j++)
       for (var i=-1+k; i<a.length-j; i++)this.l (a.slice (i,i+j),a[i+j]);
    },
    a:function (a) {
      if (!this.m[a])return;
      return this.m[a][0|Math.random () * this.m[a].length-1]
    }
}
var g={
   B:"IPO",
   G:"B",
   I:"PG",
   O:"IG",
   P:"OG",
   W:"I"
}
var c,i=0;
m.p(enemy.history);
while (!c && i++<enemy.history.length) {
   c=m.a (enemy.history.slice (i));
}
decide.apply  (0,my.honor < 7?["B"]:g[c].split (''))

Edycja: Miałem poważną wadę u obserwatora, właściwie nie wiem, co myślałem wczoraj wieczorem. Wygląda na to, że spojrzał tylko na dwa ostatnie ruchy wroga. Zaskakująco dobrze mu się to udało.

Jego pamięć jest teraz przeszukiwana przez najdłuższą (końcową) część historii wrogów, którą już widział. Zawiera tablicę ze wszystkimi ruchami, które nastąpiły po historii ruchów. Jeden jest wybierany losowo. Więc jeśli jeden ruch następował częściej, jest również bardziej prawdopodobne, że zostanie wybrany. Coś w rodzaju łańcuchów Markowa.

Obserwator, również teraz strzeże.


[1]: TIL: wytrysk ma znaczenie religijne


Jesteś teraz # 1 i # 3! Ładne boty! :)
apsillers

Gratulujemy wygranej z The Observer. Zielony tyk jest teraz twój: D
absynt

7

Meiyo Senshi (Java)

Pochodzący z obszaru Haijima niewiele wiadomo o Meiyo. Zwykle nie biorą udziału w grach sportowych, ale wysłali wojownika, aby ocenili swoich rywali.

Są to jednak honorowe grono, więc możesz mieć pewność, że w krótkim czasie ujawni swoją obecność bogom. Gdy zobaczy wystarczająco dużo swojego wroga, aby się zgłosić, użyje otrzymanych błogosławieństw, aby powalić przeciwnika.

Aby skompilować uruchomienie, jest to standardowy sposób Java:

> javac MeiyoSenshi.java
> java MeiyoSenshi
public class MeiyoSenshi {
    public static void main(String[] args){
        System.out.print(
                Integer.valueOf(args[args.length<5?0:2])>12 ||
                Integer.valueOf(args[args.length<5?2:4])<1  ?
                "B":
                "IPO".charAt((int)(Math.random()*3))
        );
    }
}

7

Uchwyt Spork (Rubinowy)

Spork Holder kłania się w pierwszej turze, a potem losowo zachowuje się. Jest to jeden z dwóch przykładowych wpisów.

Dowództwo: ruby spork-holder.rb

if ARGV.length == 4
    print "B"
else
    print ["W", "B", "G", "I", "P", "O"].sample
end

The Waiter (bash)

Kelner czeka tylko na każdym kroku. Jest to jeden z dwóch przykładowych wpisów.

Dowództwo: echo W

Nie jest wymagany kod źródłowy.


7

Tchórz (Node.js)

Jestem tchórzem / Cudem śmiem oddychać
Obezwładniony / Przez najdelikatniejszy letni powiew

  • Sprawdza, czy BXBXBX/ BBBwzory cię kłaniają (lub uderzają) podczas kłaniania się.
  • Sprawdza, czy GXGXGXwzory się kłaniają, gdy się strzeżesz.
  • Jeśli jego losowy wynik odwagi przekroczy próg strachu w tej rundzie, spróbuje trafić.
    • Posiadanie Miecza Bogów czyni go odważniejszym.
    • Przeciwnik z Mieczem Bogów czyni go bardziej przerażającym.
    • Przeciwnik, który prowadzi co najmniej 5 Zdrowia lub więcej, również go trochę przeraża.
  • W przeciwnym razie na zmianę chroni i kłania się.

Jeśli chcesz napisać zgłoszenie Node.js , skorzystaj z mojego kodu typu „kocioł”; wszystko, włącznie z decidefunkcją, jest w pełni ogólne i bezpłatne.


node coward.js

var argv = process.argv;
var history = argv.length>6?argv[2]:"";
var enemyHistory = argv.length>6?argv[3]:"";
var offset = 8 - argv.length;
var my = { health:+argv[4-offset], honor:+argv[6-offset], history:history };
var enemy = { health:+argv[5-offset], honor:+argv[7-offset], history:enemyHistory };
my.godSword = my.honor >= 7;
enemy.godSword = enemy.honor >= 7;
function decide() {
    process.stdout.write(arguments[Math.floor(arguments.length*Math.random())]);
    process.exit();
}

var enemyGuards = !!enemy.history.match(/G.G.G.$/);
var enemyBows = !!enemy.history.match(/(B.B.B.$)|(BBB$)/);

// open with a bow
if(!my.history) { decide("B"); }

// enemy will likely bow? Hit them with your super sword! (or bow)
if((!enemy.honor || enemyBows)) {
    if(my.godSword) { decide("P","I","O"); }
    else { decide("B"); }
}

// no point in hitting them if they're going to guard
if(enemyGuards) { decide("B"); }

// calculate bravery level
var braveryLevel = 0.3;
braveryLevel += (my.godSword * 0.2) - (enemy.godSword * 0.2);
braveryLevel -= (enemy.health - my.health > 5) * 0.1;

// if we're feeling brave, hit them
if(Math.random() < braveryLevel && my.honor) { decide("P","I","O"); }

// if we didn't just guard, and we're not feeling brave, cower in fear
if(!my.history.match(/G$/)) {
    decide("G");
}

// if we did just guard, and we're feeling cowardly,
//   if we don't have sword of the gods, bow
//   otherwise, do anything except guard
if(!my.godSword) {
    decide("B");
} else {
    decide("B","P","I","O");
}

1
To trudny bot. Niesamowity bojler; Użyję go od razu. Dzięki za udostępnienie :)
C5H8NNaO4

6

Whack-a-mole (R)

Uderza, gdy wróg może się ukłonić, w przeciwnym razie strażnicy.

args <- commandArgs(TRUE)
L <- length(args)
my_health <- as.integer(args[L-3])
enemy_health <- as.integer(args[L-2])
my_honour <- as.integer(args[L-1])
enemy_honour <- as.integer(args[L])
if(L>4){enemy_history <- args[L-4]}else{enemy_history <- ""}
if(my_honour<1){
    out <- "B"
}else if (enemy_honour<=1 | grepl("BB$",enemy_history)){
    out <- sample(c("I","O"),1)
}else{
    out <- "G"
}
cat(out)

Uruchom za pomocą Rscript Whack-a-mole.R.


1
Dobra robota i uwielbiam to imię.
Alex A.

3

Elephant Warrior (Java)

Elephant Warrior pochodzi ze starszego, bardziej naturalnego czasu. Wiele widział i pamięta wszystko. Podczas gdy on przygląda się swojemu przeciwnikowi, kibicuje bogom, a potem, gdy bierze je do serca, rozbiera ich na części.

Kompiluj: javac ElephantWarrior.java
polecenie:java ElephantWarrior

import java.util.LinkedList;

//Elephants never forget
class ElephantWarrior
{


  static LinkedList<Choice> analysis = new LinkedList<Choice>();

  public static void main(String[] args){
      if(args.length < 6){ respond("B");}   
      String myhis = args[0];
      String enHis = args[1];
      int health = Integer.parseInt(args[2]);
      int enHealth = Integer.parseInt(args[3]);
      int honour = Integer.parseInt(args[4]);
      int enHonour = Integer.parseInt(args[5]);

        //Bow a few times until I know how he operates
        if(enHis.length() <= 5){
            respond("B");
        }

        //Special cases
        //If I'm at 0 honor, better bow
        else if(honour <= 0){
            respond("B");

        }
        else{
          analyze(enHis);

          //Narrow it down to applicable choices
          char hisLast = enHis.toCharArray()[enHis.toCharArray().length - 1];
          LinkedList<Choice> hisOptions = new LinkedList<Choice>();
          for(Choice c: analysis){
              if(c.pattern.toCharArray()[0] == hisLast){
                  hisOptions.add(c);
              }
          }

           //Default to assuming they bow
          char hisNext = 'B';
          int mostLikely = 0;

          //What will they do next?
          for(Choice c : hisOptions){
              if(c != null && c.probability > mostLikely){
                  //System.out.println("Option = " + c.pattern);
                  //System.out.println("Prob = " + c.probability);
                  mostLikely = c.probability;
                  hisNext = c.pattern.toCharArray()[1]; }
          }

          //Now go through potential case
          switch(hisNext){
              case 'W':
                  respond("I");
                  break;
              case 'B': 
                  respond("O");
                  break;
              case 'G':
                  respond("B");
                  break;
              case 'I':
                  if(enHonour  > 0){
                      respond("P");
                  }
                  else{
                      respond("B");
                  }
                  break;
              case 'P':
                  respond("O");
                  break;
              case 'O':
                  respond("I");
                  break;
              default:
                  respond("G");
          }
        }
    }





      static void analyze(String his){

        //Keep track of his previous moves
        char[] shortString = his.substring(1,his.length() - 1).toCharArray();
        char[] longString = his.toCharArray();
        for( int i = 0; i < shortString.length; i++) {
          String pattern = "" + longString[i] + shortString[i];
          boolean exists = false;
          for(Choice c : analysis){
              if(c.pattern.equals(pattern)){
                  exists = true;
                  c.probability++;
              }
          }
          if(!exists){
              analysis.add(new Choice(pattern, 1));
          }
        }
      }

      private static void respond(String s){
            System.out.println(s);
            System.exit(0);
        }

    }

class Choice{
        String pattern;
        int probability;

       Choice(String p, int i){
            pattern = p;
            probability = i;
       }
}

2
Nie testowałem tego, ale wygląda na to, że przekroczy pierwszą granicę, gdy są tylko cztery args.
Geobits

Racja, nie zdawałem sobie sprawy, że w ogóle nie zostaną uwzględnione. Chyba oczywiście nie można przekazać pustego sznurka, dzięki!
Cain

@katya Zostało już naprawione, btw, powinno zostać uwzględnione w turnieju.
Cain

3

Wojownicza księżniczka (Julia)

To pierwsze wyzwanie King of the Hill, w którym brałem udział. Zobaczmy, jak to się potoczy.

Wojownicza księżniczka traktuje priorytetowo atak i honor, aw razie potrzeby ucieka się do samozachowania. Jest raczej chętna i nigdy nie czeka. Starając się zachować zwinność, nie używa również ataku z góry.


Zapisz jako warrior-princess.jli uruchom z wiersza poleceń tak:

julia warrior-princess.jl <arguments>

Jeśli nie masz Julii, możesz pobrać ją tutaj . Aby uniknąć problemów, zalecana jest najnowsza stabilna wersja (tj. Nie wersja rozwojowa).


type Samurai
    history::String
    health::Int
    honor::Int
end

A = length(ARGS) < 5 ? ["", "", ARGS] : ARGS

me = Samurai(A[1], int(A[3]), int(A[5]))
opponent = Samurai(A[2], int(A[4]), int(A[6]))


if length(me.history) == 0

    # Always begin the match with an honorable bow
    action = "B"

elseif (!ismatch(r"[OIP]", opponent.history) && me.history[end] != 'G') ||
       (me.health < 2 && me.honor > 0)

    # Guard if the enemy has not yet attacked and I did not previously
    # guard, or if my health is low and my honor is sufficient
    action = "G"

elseif me.honor < 2

    # Bow if I'm low on honor
    action = "B"

elseif opponent.honor >= 7 && opponent.history[end]['B', 'W']

    # Assume the enemy will attack with the Sword of the Gods if they
    # most recently bowed or waited
    action = "I"

else
    action = "P"
end

println(action)

1
Twój pierwszy wpis KotH i pierwszy wpis Julii KotH, jeśli się nie mylę: gratulacje!
plannapus

@plannapus Thanks! : D Może zrobię z tego nawyk.
Alex A.

3

Gargulec (Java)

Próbuje użyć ruchu obronnego, nie zużywając honoru.

Ponieważ jest to wpis Java:

> javac Gargoyle.java
> java Gargoyle
public class Gargoyle { 
    public static void main(String args[]) {
        if (args.length < 5 || Integer.valueOf(args[4]) > 0) {
            System.out.println("IPO".charAt((int)(Math.random()*3)));
        } else if (args[0].charAt(args[0].length()-1) != 'G') {
            System.out.println('G');
        } else {
            System.out.println('B');
        }
    }
}

3

Swordsman (C / Java)

Szermierz kłania się w pierwszej turze i za każdym razem, gdy kończy mu się honor. Następnie sprawdza, czy przeciwnik nie ukłonił się, nie bronił lub nie czekał w poprzedniej turze. Jeśli przeciwnik tego nie zrobił, istnieje duże prawdopodobieństwo, że zrobi jedno z nich w bieżącej turze, a szermierz losowo zaatakuje przeciwnika. Jeśli to nie prawda, broni się, jeśli nie bronił poprzedniej tury. Jeśli tak, kłania się, by zdobyć honor.

Wersja C:

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

void print_and_exit(char* str)
{
    puts(str);
    exit(0);
}

int main(int argc, char** argv){

    srand(time(NULL));
    char* attack_moves[]={"I", "P", "O"};
    int random_num = rand() % 3;

    if(argc == 5 || atoi(argv[5]) == 0)
        print_and_exit("B");
    else if(argv[2][strlen(argv[2])-1] != 'B' && argv[2][strlen(argv[2])-1] != 'G' && argv[2][strlen(argv[2])-1] != 'W')
        print_and_exit(attack_moves[random_num]);
    else if(argv[1][strlen(argv[1])-1] != 'G')
        print_and_exit("G");

     print_and_exit("B");
}

Zainstaluj GCC (kompilator) i zapisz kod w pliku o nazwie „ Swordsman.c ” do kompilacji:

gcc Swordsman.c -o Swordsman

Zostanie utworzony plik wykonywalny o nazwie „ Swordsman ”. Uruchom za pomocą

Swordsman

Wersja Java:

public class Swordsman {

    public static void print_and_exit(String str)
    {
        System.out.println(str);
        System.exit(0);
    }
    public static void main(String[] argv) {

        String attack_moves[]={"I", "P", "O"};
        int random_num = (int)(Math.random()*3);

        if(argv.length == 4 || Integer.valueOf(argv[5]) == 0)
            print_and_exit("B");
        else if(argv[2].charAt(argv[2].length()-1) != 'B' && argv[2].charAt(argv[2].length()-1) != 'G' && argv[2].charAt(argv[2].length()-1) != 'W')
            print_and_exit(attack_moves[random_num]);
        else if(argv[1].charAt(argv[1].length()-1) != 'G')
            print_and_exit("G");

         print_and_exit("B");
    }

}

Zainstaluj javac (kompilator) i zapisz kod w pliku o nazwie „ Swordsman.java ” do kompilacji:

javac Swordsman.java

Plik klasy o nazwie „ Swordsman.class ” zostanie utworzony. Uruchom za pomocą

java Swordsman



Attacker (Java)

Atakujący nie dba o nic poza tym, że chce zabić swojego przeciwnika. Losowo uderza jeden z ruchów ataku, a jeśli ma niski honor, kłania się.

public class Attacker {

    static int position = -1;

    public static void print_and_exit(String str)
    {
        System.out.println(str);
        System.exit(0);
    }
    public static void main(String[] argv) {

        String attack_moves[]={"I", "P", "O"};
        position = (position + 1) % 3;

        if(argv.length != 5 && Integer.valueOf(argv[5]) == 0)
            print_and_exit("B");
        else 
            print_and_exit(attack_moves[position]);
    }

}

Zainstaluj javac (kompilator) i zapisz kod w pliku o nazwie „ Attacker.java ” do kompilacji:

javac Attacker.java

Plik klasy o nazwie „ Attacker.class ” zostanie utworzony. Uruchom za pomocą

java Attacker


Predyktor (C / Java)

Predyktor przewiduje ruchy wrogów. W pierwszej turze używa losowego ruchu. Kłania się, jeśli jego honor jest niski, uderza, jeśli honor wroga jest niski lub ukłonił się w poprzedniej turze. Jeśli predyktor nie strzegł poprzedniej tury, chroni w obecnej turze. W przeciwnym razie wykonuje ten sam ruch, co wróg wykonał w poprzedniej turze, pod warunkiem, że nie 'W'w takim przypadku Predictor się kłania.

Wersja C:

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

void print_and_exit(char* str)
{
    puts(str);
    exit(0);
}

int main(int argc, char** argv){

    srand(time(NULL));
    int random = rand() % 5;
    char* moves[] = {"B", "G", "I", "P", "O"};

    if(argc == 5)
        print_and_exit(moves[random]);

    if(atoi(argv[5]) <= 0)
        print_and_exit(moves[0]);
    if(atoi(argv[6]) <= 0)
        print_and_exit(moves[4]);
    if(argv[2][strlen(argv[2])-1] == 'G')
        print_and_exit(moves[4]);
    if(argv[1][strlen(argv[1])-1] != 'G')
        print_and_exit(moves[1]);

    if(argv[2][strlen(argv[2])-1] != 'W'){
        char buf[2]={0};
        *buf = argv[2][strlen(argv[2])-1];
        print_and_exit(buf);
    }

    print_and_exit(moves[0]);

}

Zainstaluj GCC (kompilator) i zapisz kod w pliku o nazwie „ Predictor.c ” do kompilacji:

gcc Predictor.c -o Predictor

Zostanie utworzony plik wykonywalny o nazwie „ Predictor ”. Uruchom za pomocą

Predictor

Wersja Java:

public class Predicator{

    public static void print_and_exit(String str)
    {
        System.out.println(str);
        System.exit(0);
    }

    public static void main(String[] argv){

        int random = (int)(Math.random() * 5);
        String moves[] = {"B", "G", "I", "P", "O"};

        if(argv.length == 4)
            print_and_exit(moves[random]);
        else if(Integer.valueOf(argv[5]) <= 0)
            print_and_exit(moves[0]);
        else if(Integer.valueOf(argv[6]) <= 0)
            print_and_exit(moves[4]);
        else if(argv[2].charAt((argv[2].length())-1) == 'G')
            print_and_exit(moves[4]);
        else if(argv[1].charAt((argv[1].length())-1) != 'G')
            print_and_exit(moves[1]);
        else if(argv[2].charAt((argv[1].length())-1) != 'W'){
                    print_and_exit(""+argv[2].charAt((argv[2].length())-1));
        }
        else
            print_and_exit(moves[0]);
    }
}

Zainstaluj javac (kompilator) i zapisz kod w pliku o nazwie „ Predicator.java ” do kompilacji:

javac Predicator.java

Plik klasy o nazwie „ Predicator.class ” zostanie utworzony. Uruchom za pomocą

java Predicator


Nie jestem pewien, jak skuteczne będą te boty, ponieważ nie mam interpretera python2, aby je przetestować.


1
Nie testowałem tego (Attacker), ale wygląda na to, że przekroczy pierwszą granicę, gdy są tylko cztery argumenty.
Geobits

Atakujący wydaje się dawać ArrayIndexOutOfBoundsExceptionw pierwszej turze, co powoduje, że musi czekać w pierwszej turze. Poza tym działa.
absynt

@Katya and Geobits, Naprawiono. Dzięki za wykrycie tego.
Spikatrix

Po uruchomieniu predyktora dostaję segmentation fault (core dumped)po 24 rundzie
C5H8NNaO4

@ C5H8NNaO4 Naprawiono problem. Zaktualizowany kod dla wszystkich trzech botów. Powinien teraz działać dobrze. Dzięki za wskazanie tego! :-D
Spikatrix

2

Master Yi (Python)

Mistrz zabójców zyskuje dużą przychylność we wczesnej fazie gry, budując ją, aż stanie się niepokonany. Próbuje zaatakować, gdy najmniej tego oczekują.

import sys, random

class MasterYi(object):
    def __init__(self):
        self.attack = lambda: random.choice(['I','P','O'])
        self.bow   = "B"
        self.guard = "G"
        self.wait  = "W"
        if len(sys.argv)>6:
            self.hist = sys.argv[1]; self.ohist = sys.argv[2]
            self.hp   = sys.argv[3]; self.ohp   = sys.argv[4]
            self.hon  = sys.argv[5]; self.ohon  = sys.argv[6]
        else:
            self.hist = [];          self.ohist = []
            self.hp   = sys.argv[1]; self.ohp   = sys.argv[2]
            self.hon  = sys.argv[3]; self.ohon  = sys.argv[4]
        self.last  = self.hist  and self.hist[-1]  or "W"
        self.olast = self.ohist and self.ohist[-1] or "W"
        self.oGuarder = len(self.ohist)>4 and self.ohist[-4]==self.ohist[-2]=="G"

    def move(self):
        if self.hon < 1: return self.bow
        if self.olast == "G": return self.attack
        if self.hon > 6:
            if self.oGuarder: return self.bow
            if self.ohon > 6: return self.guard
            if self.ohon < 7: return self.attack
            return self.attack
        if self.ohon > 6: return self.guard
        return self.bow

Yi = MasterYi()
print(Yi.move())

Aby uruchomić: Zapisz jako MasterYi.py

python MasterYi.py <args>

2

Copy-san (C)

Kopiuje każdy ruch przeciwnika. Jestem pewien, że na pewno przegra. Skompilować:gcc copy-san.c

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

int main(int argc, char *argv[]) {
    if (argc == 5) {
        putchar('B');
    } else {
        char *enemy_hist = argv[2];
        size_t len = strlen(enemy_hist);
        putchar(enemy_hist[len - 1]);
    }
    putchar('\n');
    return 0;
}

2

Hebrajski (Java)

Hebi podążają Drogą Węża.

Wąż nie potrzebuje błogosławieństwa bogów.

Wąż ślizga się; jak fale na plaży, to, co nadchodzi, cofa się w taki sposób, w jaki przyszło.

Wąż nigdy nie czeka.

Wąż nie ma poczucia trafności, w przeciwnym razie zostałby napisany w Pythonie.

Instrukcje biegowe:

> javac hebi.java
> java hebi

Kod treści:

public class hebi{

    public static void main(String args[]){

        if( (args.length < 5) || (args[0].length() % 18 == 0) ) System.out.println( "IPO".charAt((int)(Math.random()*3)) );
        else{

            int hist_size = args[0].length();

            if      (hist_size % 3 == 1) System.out.println("G");
            else if (hist_size % 3 == 2) System.out.println("B");
            else{

                if     (hist_size % 18 ==  9) System.out.println(args[0].charAt(hist_size -  3));
                else if(hist_size % 18 == 12) System.out.println(args[0].charAt(hist_size -  9));
                else if(hist_size % 18 == 15) System.out.println(args[0].charAt(hist_size - 15));
                else{

                    char move_head = args[0].charAt( (hist_size / 18) * 18 );
                    char move_mid;
                    if( hist_size % 18 == 3 ){
                        if     ( move_head == 'I' ) move_mid = "PO".charAt((int)(Math.random()*2));
                        else if( move_head == 'O' ) move_mid = "IP".charAt((int)(Math.random()*2));
                        else                        move_mid = "OI".charAt((int)(Math.random()*2));
                        System.out.println(move_mid);
                    }
                    else{
                        move_mid = args[0].charAt( ((hist_size / 18) * 18) + 3 );
                        char move_tail;

                        if( move_head == 'I' ){
                            if( move_mid == 'P' ) move_tail = 'O';
                            else                  move_tail = 'P';
                        }else if( move_head == 'P' ){
                            if( move_mid == 'O' ) move_tail = 'I';
                            else                  move_tail = 'O';
                        }else{
                            if( move_mid == 'I' ) move_tail = 'P';
                            else                  move_tail = 'I';
                        }

                        System.out.println( move_tail );

                    }

                }

            }

        }

    }

}

2

The Honorable (Java)

Honorowe wartości honorują przede wszystkim. To znaczy, jego honor ponad wszystkich innych. Jeśli wrogi samuraj ma większy lub równy honor, kłania się. Nikt nie będzie bardziej honorowy niż on. W przeciwnym razie wykonuje losowy ruch. Nigdy nie strzeże dwa razy z rzędu - byłoby to hańbą!

kompilować:

> javac TheHonourable.java
> java TheHonourable

Źródło:

public class TheHonourable {
    public static void main(String[] args) {
        char move;

        if (args.length < 5) {
            move = 'B';
        } else if (Integer.valueOf(args[5]) >= Integer.valueOf(args[4])){
            move = 'B';
        } else {
            move =  (args[0].endsWith("G")) ?
                    "IPO".charAt((int)(Math.random()*3)) :
                    "GIPO".charAt((int)(Math.random()*4));
        }

        System.out.print(move);
    }
}

1

Błogosławiony samuraj (Python)

Ten samuraj stara się jak najdłużej zachować przychylność bogów. Pędzi, by zdobyć święty miecz, a następnie naprzemiennie strzeże i atakuje jednym z ciosów, w razie potrzeby uzupełniając honor. Jeśli wygląda na to, że on lub jego przeciwnik może wkrótce upaść, rzuca się na śmierć. Z łatwością spadnie na przeciwnika, który może śledzić jego wzór, ale jego strategia polegająca na atakowaniu zawsze z dwoma obrażeniami powinna być całkiem skuteczna.

import sys
import random
class BlessedSamurai(object):
    def __init__(self):
        if len(sys.argv) < 7:
            print("B")
        else:
            self.attack = ['O', 'I', 'P']
            self.hp = sys.argv[3]
            self.ohp = sys.argv[4]
            self.hon = sys.argv[5]
            self.last = sys.argv[1][-1]
            print(self.move())

    def move(self):
        #check if I have low health or should rush the kill
        if (self.hp < 5 or self.ohp < 5) and self.hon > 0:
            return(random.choice(self.attack))
        # charge honour to get SOTG
        elif self.hon < 7:
            return 'B'
        #Alternate guarding and attacking
        else:
            if self.last == 'G':
                return(random.choice(self.attack))
            return 'G'
Sam = BlessedSamurai()

Aby uruchomić:
Zapisz jako BlessedSamurai.py

python BlessedSamurai.py <args>

4
Twój program musi wydrukować swój ruch.
mbomb007

3
Nie testowałem tego, ale wygląda na to, że przy pierwszym zakręcie wypadnie poza granice, gdzie są tylko cztery argumenty.
Geobits

Użyłem formatu podobnego do tego, co on zrobił. @Stranjyr, spójrz na to, co zrobiłem dla uzyskania argumentów.
mbomb007

Dzięki wam wszystkim! Nie mam teraz dostępu do interpretera Pythona, ale myślę, że naprawiłem problemy. Jakoś kompletnie tęskniłem za tym, że pierwszy zestaw instrukcji nie miałby historii.
Stranjyr

Cześć, miałeś mały błąd w swoim programie „globalna nazwa„ last ”nie jest zdefiniowana”. Ponieważ jest to mały błąd, który zmieniłem lastna, self.lastktóry wydaje się naprawiać problem.
absynt

1

Hermurai (C ++)

Podziwia swojego przeciwnika i jest trochę paranoikiem. Chce wiedzieć, czy potrafi robić to, co potrafią inni samurajowie, ponieważ wciąż nie może uwierzyć, że jest samurajem. Jego nigdy nie znikający sen stał się rzeczywistością, zanim się o tym dowiedział. Co może kosztować jego głowę ...

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

using namespace std;

char getLastAttack(string enemy_history)
{
    size_t found = enemy_history.find_last_of("IPO");
    if(found == string::npos)
    {
        return 'I';
    }

    return enemy_history[found];
}

int main(int argc, const char * argv[])
{
    if(argc != 7){
        printf("B");
        return 0;
    }

    string enemy_history(argv[2]);

    int ho;
    string honour(argv[5]);
    stringstream(honour) >> ho;

    if(ho > 20){
        char atk = getLastAttack(enemy_history);
        printf("%c", atk);
        return 0;
    }

    char lastMove = enemy_history[enemy_history.length()-1];
    if(lastMove == 'W' || lastMove == 'G')
        lastMove = 'B';
    printf("%c", lastMove);
    return 0;
}

Iniqy (C ++)

Uderza tak mocno, jak to możliwe. Przechodzi w tryb nie do powstrzymania, gdy jest w niebezpieczeństwie.

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

using namespace std;

char getLastAttack(string enemy_history)
{
    size_t found = enemy_history.find_last_of("IPO");
    if(found == string::npos)
    {
        return 'I';
    }

    return enemy_history[found];
}

int main(int argc, const char * argv[])
{
    if(argc != 7){
        printf("B");
        return 0;
    }

    string history(argv[1]);
    string enemy_history(argv[2]);
    string health(argv[3]);
    string enemy_health(argv[4]);
    string honour(argv[5]);
    string enemy_honour(argv[6]);

    int he, enemy_he, ho, enemy_ho;
    stringstream(health) >> he;
    stringstream(enemy_health) >> enemy_he;
    stringstream(honour) >> ho;
    stringstream(enemy_honour) >> enemy_ho;

    if(ho > 6 || ((he < 6 || enemy_he < 6) && ho > 0))
    {
        char atk = getLastAttack(enemy_history);
        printf("%c", atk);
        return 0;
    }


    printf("B");
    return 0;
}

Oba są napisane w C ++. Kompilować:

g++ iniqy.cpp -o iniqy

Aby uruchomić w systemie Linux: ./iniqy

Aby uruchomić w systemie Windows: iniqy.exe


1

Terminator (rubin)

Terminator nie zwraca uwagi na własne zdrowie. Terminator nie ma pojęcia honoru. Terminator jest wysyłany z przyszłości i po prostu zdecydowany zakończyć wroga. Robi to, obserwując ruchy przeciwników i nic więcej. Próbkuje ruchy i oblicza odpowiednią odpowiedź w tak zawiły sposób, że żadna współczesna technologia nie jest w stanie przewidzieć działań Terminatora. W rzeczywistości dla każdego, kto mieszka w 2015 roku, Terminator może wydawać się nieco przypadkowy ...

responses = {
  ?W => %w(B I),
  ?B => %w(I O),
  ?G => %w(B B),
  ?I => %w(G P),
  ?P => %w(B O),
  ?O => %w(G I)
}

if ARGV.size > 4
  pool = ARGV[1].chars.map{ |c| responses[c] }.flatten
  puts pool.sample
else
  puts %w(O I P B).sample
end

1

Agent 38 [1] (C)

Jako produkt rozległej manipulacji genetycznej, Agent 38 ma sylwetkę i ostrość psychiczną super [2] samurajów i zdecydowanie przewyższa wszystkich swoich bezradnych [potrzebnych cytatów] wadliwych [potrzebnych cytatów] konkurentów.


//Agent 38
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#ifdef _WIN32
#include <Windows.h>
unsigned int tick_count(){
    return GetTickCount();
}
#else
#include <sys/time.h>
unsigned int tick_count(){
    struct timeval t;
    gettimeofday(&t, NULL);
    return 1000 * t.tv_sec + t.tv_usec / 1000;
}
#endif

float program[5][4][4][4][4]={
    {{{{-1.192779,0.693321,-1.472931,-0.054087},{0.958562,0.557915,0.883166,-0.631304},{-0.333221,1.410731,0.496346,0.087134},{0.459846,0.629780,-0.479042,-0.025909}},{{0.547976,1.059051,-0.748062,-0.675350},{-0.607591,-0.152156,-0.400350,-0.685337},{1.686450,0.628706,0.312865,0.324119},{1.652558,0.403733,-0.456481,-0.081492}},{{0.371629,-0.036948,-0.982682,0.065115},{1.360809,0.681294,0.505074,0.782737},{-0.545192,0.954937,-0.727853,0.273542},{-0.575777,1.615253,-0.064885,-0.516893}},{{0.577015,-0.112664,0.456595,-0.007560},{-0.660930,-0.738453,0.668093,1.716388},{1.972322,0.108558,0.535114,-0.337916},{0.640208,-0.019680,-0.769389,0.873087}}},{{{-0.021140,-0.095956,-0.098309,-0.280295},{-0.926284,1.724028,0.278855,0.678060},{0.153006,-1.860947,-0.577699,-1.931683},{-0.187152,0.529719,-1.164157,0.125499}},{{0.582208,-0.835029,-0.329857,0.088176},{-0.030797,0.389396,0.584636,-0.025866},{-0.736538,1.624658,0.690493,0.387515},{0.973253,-0.530825,1.934379,-0.872921}},{{0.812884,0.138399,-1.452478,-1.504340},{-0.119595,0.986078,-0.993806,1.102894},{0.848321,-0.268764,0.876110,0.782469},{0.948619,-0.557342,0.749764,-0.712915}},{{-1.195538,0.783784,-1.973428,-0.873207},{0.085426,-0.241360,-0.534561,-0.372105},{0.029696,-0.906821,0.932227,-0.834607},{0.764903,-0.276117,-1.346102,-0.093012}}},{{{0.168113,0.855724,1.817381,-0.547482},{0.468312,0.923739,-0.723461,0.798782},{-0.875978,-0.942505,-0.684104,-0.046389},{0.893797,-0.071382,0.283264,0.811233}},{{0.391760,0.309392,-0.045396,-0.977564},{0.085694,0.257926,-0.775461,0.060361},{0.486737,-0.175236,0.806258,-0.196521},{0.691731,-0.070052,0.636548,0.464838}},{{0.532747,-1.436236,-0.900262,-0.697533},{0.566295,0.650852,0.871414,-0.566183},{-0.075736,-0.886402,0.245348,-0.438080},{-0.811976,0.022233,-0.685647,0.323351}},{{-1.864578,1.141054,1.636157,-0.455965},{0.592333,0.890900,-0.259255,0.702826},{0.404528,0.905776,0.917764,0.051214},{0.761990,0.766907,-0.595618,-0.558207}}},{{{0.209262,-1.126957,-0.517694,-0.875215},{0.264791,0.338225,0.551586,0.505277},{0.183185,0.782227,0.888956,0.687343},{0.271838,0.125254,1.071891,-0.849511}},{{0.261293,-0.445399,0.170976,-0.401571},{0.801811,0.045041,-0.990778,-0.013705},{-0.343000,-0.913162,0.840992,0.551525},{-0.526818,-0.231089,0.085968,0.861459}},{{0.540677,-0.844281,-0.888770,0.438555},{0.802355,-0.825937,0.472974,-0.719263},{-0.648519,1.281454,0.470129,-0.538160},{-0.851015,0.985721,-0.993719,0.558735}},{{1.164560,-0.302101,0.953803,0.277318},{0.886169,0.623929,1.274299,-0.559466},{-0.948670,0.807814,-1.586962,-0.502652},{-0.069760,1.387864,-0.423140,0.285045}}}},
    {{{{0.747424,-0.044005,0.402212,-0.027484},{0.785297,0.169685,0.734339,-0.984272},{-0.656865,-1.397558,0.935961,-0.490159},{-0.099856,-0.293917,0.129296,-0.920536}},{{0.546529,-0.488280,-0.516120,-1.112775},{0.155881,-0.103160,0.187689,0.485805},{0.918357,0.829929,0.619437,0.877277},{0.389621,0.360045,0.434281,0.456462}},{{-0.803458,-0.525248,-0.467349,0.714159},{-0.648302,-0.005998,-0.812863,0.205664},{0.591453,0.653762,-0.227193,-0.946375},{0.080461,0.311794,0.802115,-1.115836}},{{-0.495051,-0.869153,-0.179932,0.925227},{-1.950445,1.908723,-0.378323,-0.472620},{-0.688403,-1.470251,1.991375,-1.698926},{-0.955808,-0.260230,0.319449,-1.368107}}},{{{-0.029073,-0.622921,-1.095426,-0.764465},{-0.362713,-0.123863,0.234856,-0.772613},{0.697097,0.103340,0.831709,0.529785},{0.103735,-0.526333,-0.084778,0.696831}},{{-0.670775,0.289993,-0.082204,-1.489529},{0.336070,0.322759,0.613241,0.743160},{0.298744,-1.193191,0.848769,-0.736213},{0.472611,-0.830342,0.437290,-0.467557}},{{-0.529196,-0.245683,0.809606,-0.956047},{-1.725613,0.187572,0.528054,-0.996271},{-0.330207,0.206237,0.218373,0.187079},{0.243388,0.625787,-0.388859,0.439888}},{{-0.802928,-0.811282,0.788538,0.948829},{0.966371,1.316717,0.004928,0.832735},{-0.226313,0.364653,0.724902,-0.579910},{-0.544782,-0.143865,0.069256,-0.020610}}},{{{-0.393249,0.671239,-0.481891,0.861149},{-0.662027,-0.693554,-0.564079,-0.477654},{0.070920,-0.052125,-0.059709,0.473953},{-0.280146,-0.418355,0.703337,0.981932}},{{-0.676855,0.102765,-0.832902,-0.590961},{1.717802,0.516057,-0.625379,-0.743204},{-0.170791,-0.813844,-0.269250,0.707447},{0.057623,0.472053,-0.211435,0.147894}},{{-0.298217,0.577550,1.845773,0.876933},{0.617987,0.502801,0.951405,0.122180},{0.924724,-0.166798,0.632685,-0.466165},{-0.834315,-0.864180,-0.274019,0.568493}},{{0.669850,-0.961671,0.790462,0.738113},{-0.534215,-0.556158,0.653896,0.031419},{0.065819,0.220394,0.153365,-0.373006},{0.886610,-0.742343,1.282099,0.198137}}},{{{0.092579,-0.026559,-1.121547,0.143613},{-0.289030,0.265226,-0.350741,-0.897469},{-0.918046,0.038521,-1.515900,0.488701},{-0.759326,-1.782885,-1.787784,0.249131}},{{-0.849816,-0.857074,-0.843467,-0.153686},{0.998653,0.356216,0.926775,0.300663},{-0.749890,-0.003425,-0.607109,0.317334},{-0.561644,0.446478,-0.898901,0.711265}},{{0.232020,-0.445016,0.618918,0.162098},{0.381030,-0.036170,0.084177,0.766972},{0.493139,0.189652,-0.511946,-0.273525},{0.863772,-0.586968,0.829531,-0.075552}},{{0.191787,-0.627198,0.975013,-0.448483},{-0.197885,0.151927,-0.558646,-1.308541},{-0.582967,1.207841,0.746132,0.245631},{0.314827,-0.702463,-0.301494,0.787569}}}},
    {{{{0.670028,-1.825749,-0.739187,0.482428},{0.175521,-0.020120,-0.154805,0.187004},{0.971728,-0.160181,-0.164031,-0.868147},{-0.954732,-0.175713,0.791116,0.294173}},{{-0.958337,-0.843157,-0.472882,0.273517},{-0.999058,0.824762,-0.223130,-0.150628},{0.393747,-0.301297,0.095572,-0.798950},{-0.119787,0.746673,0.955094,0.259353}},{{0.951590,0.225539,0.503282,0.668746},{-0.384898,-0.979592,-0.005485,-0.191883},{-0.692369,-0.642401,-0.825598,0.171933},{-0.321919,-0.498635,0.449704,0.780842}},{{-0.387902,0.522435,0.565608,0.166193},{-0.799671,-0.295871,-0.702573,-0.151006},{0.040550,-0.468503,0.651076,0.636352},{-0.839299,-0.090651,0.428761,0.187043}}},{{{-0.369823,0.377011,0.422936,0.284752},{-0.181514,-0.701449,0.748768,0.540533},{0.734381,0.149410,-0.867043,-0.397142},{-0.770904,-0.581897,-1.578306,-0.402638}},{{0.859015,-0.540358,0.202715,-0.975354},{-0.773629,-0.382342,-0.022498,-0.129286},{-0.901210,-0.641866,1.219216,0.731525},{0.740457,0.858546,-0.408661,-0.364897}},{{-0.830865,-1.370657,-1.226303,-0.392147},{-0.810554,-0.975232,-0.717845,-0.825379},{-0.150096,-0.664533,0.347084,0.243443},{-0.447383,0.842164,1.491342,0.380295}},{{-0.383958,0.811219,0.160459,0.841601},{1.631515,0.371637,0.110000,0.467783},{-0.689356,-0.004289,-0.081057,-0.317243},{0.092451,-0.181268,-0.575747,-0.580061}}},{{{0.908549,-0.013975,-0.880165,-0.938937},{-0.225713,0.449478,0.372569,-0.229889},{0.255711,-0.264752,0.307982,0.260505},{0.314966,-0.540905,0.743032,-0.078475}},{{-0.307472,-1.268296,0.020383,1.798401},{-0.150954,0.909716,-0.407903,0.379046},{0.621853,-0.003629,-0.582697,0.614618},{-0.122843,-0.627133,-0.217968,0.608322}},{{0.071923,0.807315,0.538905,-0.630660},{0.495641,0.240202,-0.920822,-0.258533},{-1.760363,-0.448525,-0.351553,-0.551666},{0.152720,0.900531,0.061966,-0.544377}},{{0.648923,0.450945,-1.530020,1.570190},{0.536210,0.078454,0.577168,0.464872},{-0.888258,-0.950748,0.781474,0.958593},{0.463631,0.319614,-0.248374,-0.413144}}},{{{0.293463,0.236284,1.721511,0.107408},{-0.790508,-0.072027,-0.559467,-0.955839},{-0.777662,-0.169876,0.896220,0.776105},{0.003944,-0.745496,-0.236446,-0.824604}},{{-1.770746,-0.051266,-0.174258,0.003074},{-0.339553,-0.868807,-0.032754,-0.494847},{-0.896712,0.957339,-0.003444,-1.582125},{-0.699883,0.626691,0.799635,-0.542343}},{{-0.635123,-0.755960,0.576373,-0.899530},{-0.393745,0.718900,0.312400,0.511415},{-0.647565,0.368431,0.214726,0.892693},{-0.511960,-0.513262,0.885908,-0.536478}},{{-0.590074,0.623328,0.268674,-0.401391},{0.308868,-0.869862,0.233132,0.243337},{-0.242908,-0.557192,-0.728454,0.867029},{0.156435,-0.805308,-0.815392,-1.437798}}}},
    {{{{0.613484,1.454566,-0.363858,0.634053},{0.535096,-0.641079,-0.607553,0.852559},{0.959100,-0.398621,0.375819,0.385756},{-0.601982,0.494128,0.809699,0.608804}},{{-1.390871,-0.943062,1.556671,0.966501},{-0.013242,0.152716,-0.089592,0.230793},{0.933785,0.119358,0.057387,0.502033},{-0.332925,0.537509,-0.081436,-0.701995}},{{-0.435117,0.996885,0.646630,-0.092342},{0.004343,-0.737514,-0.716187,-0.946819},{0.814258,-0.766971,-0.488162,-0.531619},{-0.923069,0.683915,-0.023809,-1.242992}},{{-0.909155,-0.166488,-0.159273,-0.908121},{-0.783871,-0.522598,0.691845,-0.164065},{1.255966,0.051373,-0.566025,0.820081},{0.186583,0.266032,-0.793747,-0.510092}}},{{{0.890639,0.970042,-0.507885,-0.029557},{-0.771142,-0.875802,0.400070,-1.264247},{-0.881146,0.570950,-0.051624,0.347612},{0.312110,-0.374885,0.600112,0.388460}},{{-0.417107,-0.309284,-0.128477,0.689671},{-0.695866,1.254585,-0.381883,-0.313415},{0.433565,0.919626,0.159180,-0.657310},{-1.396139,0.346053,0.108768,0.061238}},{{-0.776695,0.084491,0.045357,0.312823},{-0.379268,1.217006,-0.014838,-1.032272},{-1.251344,-0.366283,-0.124786,0.729754},{0.979936,0.669519,-0.900018,-0.596954}},{{-0.998834,0.593942,0.375639,-0.627459},{0.297281,0.400240,0.839707,0.960262},{-0.872143,0.574040,-0.559580,-1.965570},{-0.559218,-0.778780,-0.955526,-0.253380}}},{{{-1.919625,-1.911049,0.025035,0.754917},{-0.110993,0.535933,-0.572788,-0.856476},{-0.810836,-0.496261,1.128368,1.758826},{-0.564368,-1.849772,-0.251560,0.635528}},{{0.768196,-0.934122,0.207228,0.884610},{-0.356145,0.265792,-0.835582,0.377675},{-0.410745,0.613212,0.245560,-0.873826},{1.725191,-0.263344,-0.077167,-0.976379}},{{-0.736299,-0.109476,0.044512,-0.004005},{0.692230,0.316670,0.267247,-1.076821},{-0.903184,0.189762,-0.674111,0.219113},{0.639162,1.347521,0.428823,-0.765664}},{{-0.509165,0.458806,-0.851011,0.455027},{-0.218564,-0.063492,0.889320,-0.762062},{0.145950,0.985037,-0.489372,-0.879851},{0.352346,-0.127275,0.896496,-0.596037}}},{{{0.402678,1.479855,0.089187,0.967153},{-0.431225,0.402980,0.883584,-0.900324},{0.262233,-0.647278,0.637005,0.142678},{-0.003253,-0.671924,0.969458,-0.316752}},{{0.345185,-0.477503,-0.326822,-0.106251},{0.239521,1.617125,0.632651,0.969976},{-1.015183,-0.676629,0.955842,0.134925},{-0.319063,-0.493157,-0.488088,0.713008}},{{-0.468621,1.301292,-1.826501,1.138666},{0.170247,-0.661171,0.895204,-0.400700},{-0.077645,-0.978179,-0.245724,0.245282},{-0.258300,0.287261,-0.006274,0.549716}},{{-0.932247,-0.274950,0.920451,0.016237},{0.888865,-0.845248,1.661716,-0.108960},{0.712357,0.586609,-0.867356,0.355058},{-0.540912,0.892622,0.302627,0.247194}}}},
    {{{{0.817578,0.719047,0.438903,0.637398},{0.750466,-0.911799,-0.609606,0.358541},{-1.782979,-0.851717,-0.802122,0.735913},{0.490604,-0.417822,-0.332074,0.836756}},{{-0.650232,-0.442026,0.874916,0.705671},{0.217602,-0.755841,0.573944,0.279365},{-0.713729,0.358880,-0.308992,0.778297},{0.832099,-0.916695,-0.887834,1.041483}},{{1.019467,1.099488,-0.130674,-0.241995},{0.792572,0.756977,0.518186,0.070411},{-0.815779,-0.790757,-1.027439,-0.163698},{0.721461,-0.403364,0.656609,-0.367364}},{{-0.279333,-0.742041,0.515832,-0.408114},{0.834577,0.736056,0.900594,0.276357},{0.726000,0.464991,-0.569281,0.098139},{-0.582324,0.875666,-0.681556,-0.903009}}},{{{1.300969,-0.798351,0.107230,1.611284},{0.239211,0.418231,-0.795764,-0.398818},{-0.939666,1.768175,-0.297023,-0.064087},{-0.239119,-0.365132,0.864138,0.595560}},{{1.898313,-0.343816,1.066256,0.876655},{-0.053636,0.544756,-0.937927,0.189233},{0.445371,-0.656790,-0.675091,0.753163},{-0.293330,-0.002717,0.341173,0.095493}},{{0.951658,0.513912,-0.678347,-0.981140},{-0.020791,0.571138,-0.890648,0.881789},{-1.783345,0.909598,-0.393155,0.240630},{-0.057908,-0.237435,-0.124993,-0.754091}},{{-0.014153,0.127172,0.097134,0.538952},{0.167943,0.786395,0.946153,-0.762513},{-0.562758,0.675657,-0.226395,0.979761},{0.850214,0.818309,0.397074,-0.372059}}},{{{0.803316,-0.659538,-1.987864,-0.186366},{-0.259213,0.315848,-0.427898,0.326521},{-0.168181,-0.620898,0.562309,0.722064},{-1.949690,0.307720,-0.147760,0.603492}},{{0.898339,0.986228,0.724530,0.105193},{0.066046,0.037689,-0.553543,0.597864},{0.296553,0.165199,0.500125,-0.395978},{0.790120,-1.873361,0.354841,-0.187812}},{{-0.559746,0.357012,0.373903,-0.113564},{-0.671918,-0.919720,0.258328,-0.283453},{0.008365,0.597272,0.355827,0.391287},{0.355297,-0.631888,0.221383,1.448221}},{{0.259199,-0.491776,0.721151,0.391427},{0.494000,0.652814,-0.153306,-0.615687},{0.142167,-0.601161,0.281702,0.563390},{0.904019,1.284241,0.901663,0.244620}}},{{{-0.664638,-0.564596,0.839897,0.153358},{-0.506883,0.822337,-0.974957,-0.098112},{-0.962870,-0.274566,0.418039,-0.020525},{-0.965969,0.954587,-0.250493,-0.031592}},{{-0.966475,0.455338,0.868491,0.723032},{-0.002141,0.021922,-0.131429,-0.601106},{-1.240003,1.483318,1.612920,-0.653210},{-0.505979,0.005588,-0.087506,-0.705789}},{{-0.203137,0.765652,-0.132974,-0.900534},{0.731132,0.133467,-1.086363,0.600763},{1.795911,-0.411613,-1.990494,0.405937},{0.729332,-0.119175,-0.979213,0.362346}},{{-0.049014,0.228577,-1.728796,-0.898348},{-0.540969,1.245881,-0.820859,0.285859},{0.430751,-0.373652,0.034535,0.434466},{0.365354,0.243261,0.910114,1.497873}}}}
};
float eval_polynomial(float variables[4],int program_index,int variable_index,int indices[4]){
    if(variable_index==4)return program[program_index][indices[0]][indices[1]][indices[2]][indices[3]];
    float result=0,base=1;
    for(int power=0;power<4;++power){
        indices[variable_index]=power;
        result+=base*eval_polynomial(variables,program_index,variable_index+1,indices);
        base*=variables[variable_index];
    }
    return result;
}
int main(int argc,char *argv[]){
    srand(tick_count());
    rand();
    float variables[4],probability[5],total=0;
    int i,indices[4],temp;
    for(i=0;i<4;++i){
        sscanf(argv[i-4+argc],"%d",&temp);
        variables[i]=temp;
    }
    temp=variables[1];
    variables[1]=variables[2];
    variables[2]=temp;
    if(variables[1]==0){ //bow if our honour is 0
        putchar('B');
        return 0;
    }

    variables[0]/=20;variables[2]/=20;
    variables[1]=1/(variables[1]+1);variables[3]=1/(variables[3]+1);
    for(i=0;i<5;++i){
        probability[i]=eval_polynomial(variables,i,0,indices);
        if(probability[i]<0)probability[i]=0;
        total+=probability[i];
        probability[i]=total;
    }
    total*=(float)rand()/RAND_MAX;
    for(i=0;i<5;++i)if(total<probability[i]){
        putchar("BGIPO"[i]);
        return 0;
    }
    putchar('B');
    return 0;
}

[1] Zupełnie nieistotna liczba [2] Gwarantowana prawda przez 1% czasu


YAGMCSE

Metody Monte Carlo wydają się prezentować przyzwoitą zabawę, więc oto jeszcze jedno ogólne wejście do symulacji Monte Carlo!

W przeciwieństwie do większości innych zgłoszeń w tym konkursie, ten wpis wykorzystuje dużą liczbę symulacji gier losowych, a zatem wymaga użycia flagi -O3 dla optymalnej wydajności.

Skompiluj program za pomocą polecenia: gcc monte.c -o monte -O3 -std = c99

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

#ifdef _WIN32
#include <Windows.h>
unsigned int tick_count(){
    return GetTickCount();
}
#else
#include <sys/time.h>
unsigned int tick_count(){
    struct timeval t;
    gettimeofday(&t, NULL);
    return 1000 * t.tv_sec + t.tv_usec / 1000;
}
#endif

const int turn_limit=500;
enum Move{
    WAIT,BOW,GUARD,QUICK,PARRY,OVERHEAD
};
struct Player{
    int health,honour;
    enum Move lastMove;
};
typedef struct Player Player;
//<command> <history> <enemy_history> <your_health> <enemy_health> <your_honour> <enemy_honour>
//<command> <your_health> <enemy_health> <your_honour> <enemy_honour>
int damage_table[6][6][2]={
    {{0,0},{0,0},{0,0},{1,0},{1,0},{1,0}}, //P1 is waiting
    {{0,0},{0,0},{0,0},{1,0},{1,0},{1,0}}, //P1 is bowing
    {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, //P1 is guarding
    {{0,1},{0,1},{0,0},{0,0},{1,0},{0,1}}, //P1 is using quick draw
    {{0,1},{0,1},{0,0},{0,1},{0,0},{1,0}}, //P1 is parrying
    {{0,1},{0,1},{0,0},{1,0},{0,1},{0,0}} //P1 is using overhead attack
};
enum Move decode_move(char x){
    switch(x){
        case 'W': return WAIT; break;
        case 'B': return BOW; break;
        case 'G': return GUARD; break;
        case 'I': return QUICK; break;
        case 'P': return PARRY; break;
        case 'O': return OVERHEAD; break;
    }
    return WAIT;
}
struct SimulationStat{
    enum Move first_me_move;
    int win,draw,lose,compound;
};
int stat_compare(const void*a,const void*b){
    return ((struct SimulationStat*)b)->compound-((struct SimulationStat*)a)->compound;
}
struct SimulationStat monte_carlo(int num_iters,enum Move first_me_move,Player original_me,Player original_opponent){
    struct SimulationStat simulation_result={first_me_move,0,0,0};

    for(int iter=0;iter<num_iters;++iter){
    Player me=original_me,opponent=original_opponent;
        int turn,game_result;
        for(turn=0;turn<turn_limit;++turn){
            enum Move me_move,opponent_move=rand()%(OVERHEAD-BOW+1)+BOW;
            if(turn==0)me_move=first_me_move;
            else me_move=rand()%(OVERHEAD-BOW+1)+BOW;

            //update honour for guarding
            if(me.lastMove==GUARD&&me_move==GUARD)--me.honour;
            if(opponent.lastMove==GUARD&&opponent_move==GUARD)--opponent.honour;

            int me_attacking=me_move==QUICK||me_move==PARRY||me_move==OVERHEAD,opponent_attacking=opponent_move==QUICK||opponent_move==PARRY||opponent_move==OVERHEAD;

            //update health of players
            me.health-=damage_table[me_move][opponent_move][0]*(1+(opponent.honour>=7));
            opponent.health-=damage_table[me_move][opponent_move][1]*(1+(me.honour>=7));

            //update honour for attacking (Sword of the Gods is revoked after the player attacks with an original honour value of 7)
            if(me_attacking)--me.honour;
            if(opponent_attacking)--opponent.honour;

            //printf("%d %d\n",me.health,me.honour);
            //printf("%d %d\n",opponent.health,opponent.honour);

            //check if any of the terminating conditions are met
            //c. both players fall off the graces of the gods (me.honour<0&&opponent.honour<0)
            if(me.honour<0&&opponent.honour<0){
                game_result=0; //draw
                break;
            }
            //a. player 1 falls off the graces of the gods (me.honour<0)
            else if(me.honour<0){
                game_result=-1; //loss
                break;
            }
            //b. player 2 falls off the graces of the gods (opponent.honour<0)
            else if(opponent.honour<0){
                game_result=1; //win
                break;
            }
            //d. both players are dead (me.health<0&&opponent.health<0)
            else if(me.health<0&&opponent.health<0){
                game_result=0; //draw
                break;
            }
            //e. player 1 is dead (me.health<0)
            else if(me.health<0){
                game_result=-1; //loss
                break;
            }
            //f. player 2 is dead (opponent.health<0)
            else if(opponent.health<0){
                game_result=1; //win
                break;
            }
        }
        //both players get struck down by the guards for being boring
        if(turn==turn_limit)game_result=0; //draw

        if(game_result==1)++simulation_result.win;
        else if(game_result==0)++simulation_result.draw;
        else ++simulation_result.lose;
    }
    return simulation_result;
}
int main(int argc,char*argv[]){
    //const int num_iters=200000,num_shortlist_iters=1000000;
    const int num_iters=20000,num_shortlist_iters=55000;

    srand(tick_count());
    Player me,opponent;
    if(argc==5){
        sscanf(argv[1],"%d",&me.health);
        sscanf(argv[2],"%d",&opponent.health);
        sscanf(argv[3],"%d",&me.honour);
        sscanf(argv[4],"%d",&opponent.honour);
        me.lastMove=WAIT;
        opponent.lastMove=WAIT;
    }else{
        sscanf(argv[3],"%d",&me.health);
        sscanf(argv[4],"%d",&opponent.health);
        sscanf(argv[5],"%d",&me.honour);
        sscanf(argv[6],"%d",&opponent.honour);
        me.lastMove=decode_move(argv[1][strlen(argv[1])-1]);
        opponent.lastMove=decode_move(argv[2][strlen(argv[2])-1]);
    }

    struct SimulationStat results[6];
    results[0].first_me_move=WAIT;
    results[0].win=0;
    results[0].draw=0;
    results[0].lose=num_iters;
    results[0].compound=-num_iters*2-1000; //waiting is worse than any other action

    for(enum Move first_me_move=BOW;first_me_move<=OVERHEAD;++first_me_move){
        results[first_me_move]=monte_carlo(num_iters,first_me_move,me,opponent);
        struct SimulationStat *cur=&results[first_me_move];
        cur->compound=cur->win*4+cur->draw*1-cur->lose*2;
    }
    qsort(results,OVERHEAD-WAIT+1,sizeof(*results),stat_compare);

    for(int i=0;i<OVERHEAD-BOW+1;++i){
        struct SimulationStat *cur=&results[i];
//        fprintf(stderr,"%c: %f%% win, %f%% draw, %f%% lose => %d\n","WBGIPO"[cur->first_me_move],(double)cur->win/num_iters*100.,(double)cur->draw/num_iters*100.,(double)cur->lose/num_iters*100.,cur->compound);
    }

    for(int i=0;i<2;++i){
        results[i]=monte_carlo(num_shortlist_iters,results[i].first_me_move,me,opponent);
        struct SimulationStat *cur=&results[i];
        cur->compound=cur->win*2+cur->draw*1;
    }
    qsort(results,2,sizeof(*results),stat_compare); 

    for(int i=0;i<2;++i){
        struct SimulationStat *cur=&results[i];
//        fprintf(stderr,"%c: %f%% win, %f%% draw, %f%% lose => %d\n","WBGIPO"[cur->first_me_move],(double)cur->win/num_shortlist_iters*100.,(double)cur->draw/num_shortlist_iters*100.,(double)cur->lose/num_shortlist_iters*100.,cur->compound);
    }
    putchar("WBGIPO"[results[0].first_me_move]);
    return 0;
}

1
Wydaje się, że kłania się z jakiegokolwiek powodu. Możesz rzucić okiem
C5H8NNaO4

@ C5H8NNaO4 Dziękujemy za powiadomienie mnie o tym poważnym błędzie. Moja edycja powinna naprawić błąd.
Potatomato

Wydaje się, że YAGMCSE wykonuje tylko jedno GBWWWWW...lubBWWWW
C5H8NNaO4

@ C5H8NNaO4 To dziwne. Nie jestem w stanie powielić wyników, o których wspomniałeś. Czy przeciwnik YAGMCSE wiecznie kłaniał się / strzegł / czekał?
Potatomato

Tak, kłaniał się przez pierwsze 7 rund. Oto pastebin
C5H8NNaO4

1

Po mojej nieudanej próbie wejścia do Target Dummy, przedstawiam wam mojego następnego bota ...

ScroogeBot - Python 2

Ten bot pokłoni się, jeśli będzie miał jeden honor. W przeciwnym razie rzuci monetą.

Jeśli wyląduje na głowach, wykona losowy atak. Jeśli wyląduje na ogonie, będzie się kłaniał lub strzec.

Dowództwo: python scroogebot.py

import random, sys
# If he has more than one honor...
if int(sys.argv[5]) > 1:
    #Flip a coin.
    coin = random.choice(['heads','tails'])
    #If the coin lands on heads...
    if coin == 'heads':
        #Attack!
        print random.choice(['I','O','P'])
    #If the coin lands on tails...
    else:
        #Don't attack!
        print random.choice(['G','B'])
#If he has 1 honor...
else:
    #Bow!
    print "B"

Tak, nowy wpis! Szybka heads-up - może minąć trochę czasu, zanim będę mógł rozpocząć nowy turniej, ponieważ wczoraj zmieniłem system operacyjny. Powinienem jednak przygotować nowy turniej z twoimi wynikami do końca tygodnia.
absynt

0

Yoshimitsu (JS)

Próbuje się nie strzec przez sprawdzenie ostatnich dwóch ruchów, otrzyma odwagę z wyższym honorem. na podstawie wykonanych apsillerów szablonu

var attacks = ['I','P','O'];
var pasive = ['B','W'];
var argv = process.argv;
var playerHistory = argv.length>6?argv[2].split(''):[];
var enemyHistory = argv.length>6?argv[3].split(''):[];
var offset = 8 - argv.length;
var my = { health:+argv[4-offset], honor:+argv[6-offset], history:playerHistory };
var enemy = { health:+argv[5-offset], honor:+argv[7-offset], history:enemyHistory };
my.godSword = my.honor >= 7;
enemy.godSword = enemy.honor >= 7;

enemy.lastMove = enemyHistory.pop();
enemy.secondToLast = enemyHistory.pop();

enemy.didAttack = !!attacks.indexOf(enemy.lastMove);

my.lastMove = playerHistory.pop();

function decide() {
    process.stdout.write(arguments[Math.floor(arguments.length*Math.random())]);
    process.exit();
}

chooseAnAttack = function(){ decide.apply(this,attacks); };

if( ( pasive.indexOf( enemy.lastMove ) && my.honor < 15 ) || (my.honor < 7 && enemy.health > 10) || my.honor === 1 ){
    if( Math.random * 15 < my.honor ){
        chooseAnAttack();
    } else {
        decide('B');
    }
} else if( enemy.honor < 2 ){
    chooseAnAttack();
} else if( enemy.didAttack ){

    if( attacks.indexOf( enemy.secondToLast ) ){
        decide('G');
    } else if( pasive.indexOf( enemy.secondToLast ) ){
        chooseAnAttack();
    } else if( enemy.secondToLast == 'G' ){
        decide('B');
    }

} else if( enemy.lastMove = 'G' ) {
    chooseAnAttack();
} else if( enemy.lastMove === 'W' ){
    if( attacks.indexOf( enemy.secondToLast ) ){
        decide('G');
    } else if( pasive.indexOf( enemy.secondToLast ) ){
        chooseAnAttack();
    } else if( enemy.secondToLast == 'G' ){
        decide('B');
    }
}

0

Głupiec (C)

Błazen sugeruje raczej błędną strategię, nigdy nie powtarzając dwukrotnie tego samego ruchu, chyba że zostanie zmuszony przez brak honoru. Jego ruchy są w dużej mierze oparte na przypadkowości, co utrudnia przewidywanie jego działań. Jego dobre samopoczucie jest ostatnią rzeczą w jego umyśle, ponieważ jego myśli skupiają się wyłącznie na rozlewu krwi i ostatecznym zwycięstwie

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

const char commands[] =
{
    'W', 'B', 'G', 'I', 'P', 'O'
};

char select_candidate(const char c[])
{
    unsigned i = 0;
    int n_candidates = 0;
    char candidates[sizeof(commands)];

    for (; i < sizeof(commands); i++)
        if (c[i])
            candidates[n_candidates++] = c[i];

    /* There are no candidates for actions, so the fool blindly attacks his opponent, hoping for the best */
    return n_candidates == 0 ? 'I' : candidates[rand() % n_candidates];
}

int main(int argc, char *argv[])
{
    unsigned i = 0;
    int honour;
    char candidates[sizeof(commands)];
    char last_action;

    srand(time(NULL));

    memcpy(candidates, commands, sizeof(commands));

    /* It's the first round, the fool selects a random action except for waiting */
    if (argc != 7)
    {
        candidates[0] = 0;
        putchar(select_candidate(candidates));
        return 0;
    }

    last_action = argv[1][strlen(argv[1]) - 1];
    honour = atoi(argv[5]);

    if (honour == 0)
    {
        /* The fool realises he will meet his doom if he performs any of the following moves */
        /* and removes them from his list of possible actions */
        candidates[3] = 0;
        candidates[4] = 0;
        candidates[5] = 0;

        /* Only omit the blocking action if the last action was blocking */
        if (last_action == 'G')
            candidates[2] = 0;
    } else if (honour >= 7) {

        /* If the fool has the opportunity to abuse power, he will */
        candidates[0] = 0;
        candidates[1] = 0;
    }

    /* However unintellegent, the fool decides never to repeat the same move twice */
    for (; i < sizeof(commands); i++)
    {
        if (candidates[i] == last_action)
        candidates[i] = 0;
    }

    /* The fool randomly selects a possible action and hopes for the best */
    putchar(select_candidate(candidates));

    return 0;
}


Prorok (C)

Prorok wykorzystuje wiedzę o 2 poprzednich ruchach przeciwnika, aby przewidzieć następny ruch i zapewnia szybki i śmiertelny kontratak. Poza tym zajmuje się astrologią i tym podobne.

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

int main(int argc, char* argv[])
{
    char* hist;
    char* enemy_hist;
    int hist_len;
    int enemy_hist_len;
    int health;
    int enemy_health;
    int honour;
    int enemy_honour;

    if (argc != 7)
    {
        /* Always start with guarding */
        putchar('G');
        return 0;
    }

    srand(time(NULL));

    /* Grab the command-line values */
    hist         = argv[1];
    enemy_hist   = argv[2];
    health       = atoi(argv[3]);
    enemy_health = atoi(argv[4]);
    honour       = atoi(argv[5]);
    enemy_honour = atoi(argv[6]);

    hist_len = strlen(hist);
    enemy_hist_len = strlen(enemy_hist);

    /* Looks like the enemy is starving for honour. */
    /* This means that they have to bow, so attack them,  */
    /* But only if we have the honour to do so. */
    if (enemy_honour == 0 && honour > 0)
    {
        putchar('O');
        return 0;
    } else if (honour == 0) {
        /* We have to bow */
        putchar('B');
        return 0;
    } else if (honour <= 3) {
        /* We have low honour, attack if the enemy has no honour, otherwise bow to restore some of our honour */
        putchar(enemy_honour == 0 ? ((rand() % 2) ? 'I' : 'O') : 'B');
        return 0;
    }

    switch (enemy_hist[enemy_hist_len - 1])
    {
        /* The enemy has previously performed a passive action, so they will likely attack this round */
        case 'W':
        case 'B':
        case 'G':
            putchar(hist[hist_len - 1] == 'G' ? 'P' : 'G'); /* Protect ourselves, using `guard` if we did not use it last turn */
            return 0;

        default:
            if (enemy_hist_len >= 2)
            {
                switch (enemy_hist[enemy_hist_len - 2])
                {
                    case 'I':
                    case 'P':
                    case 'O':
                        /* The enemy has attacked for the last 2 turns, they will likely rest now */
                        putchar((rand() % 2) ? 'I' : 'O');
                        return 0;

                    default:
                        /* Low health, block an incoming attack */
                        if (health <= 5)
                        {
                            putchar(hist[hist_len - 1] == 'G' ? 'P' : 'G');
                            return 0;
                        } else {
                            /* Choose randomly to bow or attack */
                            int decision = rand() % 3;
                            putchar(decision == 2 ? 'B' : decision == 1 ? 'I' : 'O');
                            return 0;
                        }
                }
            } else {
                /* Attack! */
                putchar((rand() % 2) ? 'I' : 'O');
                return 0;
            }
    }

    /* If somehow we get to this point, parry */
    putchar('P');
    return 0;
}


Kompilacja

Oba programy są napisane w C i można je skompilować z gcc:

gcc fool.c -o fool
gcc prophet.c -o prophet


Bieganie

*nic

./fool <args>
./prophet <args>

Windows

fool.exe <args>
prophet.exe <args>
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.