La confrontation ultime des samouraïs

37

Avis: Ce défi du est terminé. Cela signifie que la coche verte, qui a été attribuée à C5H8NNaO4 pour son entrée The Observer ne sera pas déplacé vers une nouvelle réponse.

Vous pouvez toujours soumettre de nouvelles entrées, mais il peut y avoir des retards dans le déroulement des nouveaux tournois car je ne vérifie plus activement les nouvelles entrées.

introduction

Dans ce défi, vous jouez à un jeu d'arcade intitulé The Ultimate Samurai Showdown, édition spéciale Ultimate Edition 2.0 X Alpha Omega Turbo (ou simplement Ultimate Samurai Showdown en abrégé). Vos adversaires? Nul autre que les autres membres de Programming Puzzles & Code Golf!

Comme vous pouvez vous attendre d'un jeu d'arcade PPCG, vous ne jouez pas directement dans Ultimate Samurai Showdown , mais écrivez plutôt un programme qui jouera le jeu pour vous. Ce programme luttera contre les programmes soumis par d’autres utilisateurs lors de duels individuels. Le programme le plus qualifié sera couronné Ultimate Samurai de PPCG et obtiendra le titre de légende vert.

Description du jeu

Cette section décrit les mécanismes derrière le jeu.

Condition de victoire

Un match consiste en deux samouraïs qui se font face. Chaque samouraï commence chaque match avec 20 points de vie et 1 honneur . Un samouraï gagne si son adversaire est mort et qu'il est toujours en vie. Il existe deux méthodes par lesquelles un samouraï peut mourir:

  1. Si les points de vie d'un samouraï sont ramenés à 0, il mourra.
  2. Si un samouraï ramène son propre honneur en dessous de 0, il sera frappé par les dieux pour avoir agi de manière déshonorante dans un duel.

Être frappé par les dieux a la priorité sur la réduction du nombre de points de vie à 0. Ainsi, dans une situation où un samouraï est à 0 point de santé et l'autre à -1 honneur, le samouraï avec 0 point de santé l'emportera. Dans une situation où les deux samouraïs sont à -1 honneur, ils sont tous deux frappés par les dieux et le jeu est un match nul.

Un match comprend jusqu'à 500 tours . Si tous les 500 tours sont passés et que le match n’a pas été décidé (aucun samouraï n’est mort), les dieux s’ennuient et abattent les deux samouraïs, ce qui entraîne un match nul.

actes

À chaque tour, le samouraï doit effectuer exactement l'une des actions suivantes:

W

Le samouraï doit attendre et ne rien faire. Cela le rend cool mais ne l'aide pas à vaincre son adversaire. C'est aussi l'action par défaut.

B

Le samouraï doit s'incliner devant son adversaire de manière honorable. Cela plaît aux dieux et ainsi les samouraïs gagneront 1 honneur. L’honneur est essentiel au succès de votre samouraï, car l’honneur est essentiellement la "ressource" de ce jeu - tous les mouvements sont différents Bet Wpeuvent diminuer l’honneur. De plus, si un samouraï gagne 7 points d’honneur ou plus, il se voit accorder l’utilisation de l’ Épée des Dieux . Les implications de ceci sont décrites ci-dessous.
Cependant, s'incliner devant votre adversaire vous laisse ouvert si votre adversaire décide de vous frapper avec son épée. Soyez donc prudent lorsque vous choisissez de vous incliner.

G

Le samouraï doit entrer en position défensive et se prémunir contre les coups d’épée. Ce mouvement bloquera avec succès toutes les frappes à l'épée, même celles effectuées avec l' épée des dieux .
Cependant, les dieux froncent les sourcils sur un samouraï trop défensif. Ce mouvement consomme 1 Honneur si l'action du samouraï au tour précédent était également en garde. Il ne consomme pas l'honneur autrement.

I

Le samouraï doit tenter de frapper son adversaire avec un tirage rapide de son épée de son fourreau. Si le samouraï a 7 honneur ou plus, il utilisera l' épée des dieux à la place de son épée habituelle. Ce mouvement consomme 1 Honneur.
Le tirage rapide est une frappe rapide qui battra des attaques plus lentes au-dessus de la tête, mais perdra contre des parades. Si la frappe se connecte avec succès, elle infligera 1 dommage, ou 2 dégâts avec l' épée des dieux .

P

Le samouraï doit tenter de parer toute attaque imminente, puis lance sa propre attaque. Si le samouraï a 7 honneur ou plus, il utilisera l' épée des dieux à la place de son épée habituelle. Ce mouvement consomme 1 Honneur.
La parade est une bonne manœuvre contre les frappes rapides, mais elle sera dominée par des attaques aériennes plus lentes. Si la frappe se connecte avec succès, elle infligera 1 dommage, ou 2 dégâts avec l' épée des dieux .

O

Le samouraï doit tenter de frapper son adversaire avec une attaque aérienne plus lente. Si le samouraï a 7 points d'honneur ou plus, il utilisera l' épée des dieux à la place de son épée habituelle. Ce mouvement consomme 1 honneur.
La frappe aérienne peut maîtriser les parades, mais elle perdra face aux frappes rapides. Si la frappe se connecte avec succès, elle infligera 1 dommage, ou 2 dégâts avec l' épée des dieux .

Épée des dieux

Un samouraï avec honneur de 7 ans ou plus gagne la capacité d'utiliser l' épée des dieux . Si son honneur est réduit à moins de 7, sa capacité à utiliser l' épée des dieux lui sera révoquée. L' épée des dieux inflige 2 dégâts au lieu de 1.

L' épée des dieux ne permet pas à une frappe de vaincre une frappe d'épée qui ne serait normalement pas vaincue. Par exemple, une parade de Sword of the Gods perdra toujours face à une frappe aérienne ordinaire, et un tirage rapide de Sword of the Gods ne l'emportera pas sur un tirage rapide ordinaire. En fait, la soi-disant épée des dieux n’est en réalité pas très puissante - c’est peut-être une blague cosmique jouée par les dieux ...

Table d'interaction

Le fragment de pile ci-dessous contient un tableau qui répertorie explicitement tous les résultats possibles des différentes combinaisons d’actions que les deux samouraïs peuvent effectuer. Pour l'afficher, cliquez sur "Afficher l'extrait de code", puis sur "Exécuter l'extrait de code".

Programme de communication

Pour faciliter le déroulement du tournoi, un programme de contrôleurs a été écrit pour jouer le rôle de "dieux" - il garde des records d’honneur et de santé et frappe les samouraïs en conséquence. Cette section décrit comment votre programme communiquera avec le programme du contrôleur.

Description de l'entrée

Le programme du contrôleur appellera votre programme à partir de la ligne de commande, comme suit:

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

où:

  • <command>est la commande requise pour exécuter votre programme. Par exemple, si votre programme est dans un fichier super_sentai.pl, la commande est probablement perl super_sentai.pl.

  • <history>est une histoire de mouvements que vous avez faits. Par exemple, WWBPcela signifierait que vous avez attendu deux fois, que vous vous êtes incliné une fois et que vous avez été paré une fois.

  • <enemy_history>est une histoire de mouvements effectués par votre ennemi. Par exemple, BBBIcela signifierait que votre ennemi s'est incliné trois fois et a effectué un tirage rapide.

  • <your_health> est votre santé actuelle.

  • <enemy_health> est la santé actuelle de l'ennemi.
  • <your_honour> est votre honneur actuel.
  • <enemy_honour> est l'honneur actuel de l'ennemi.

Pour le premier tour, le historyet enemy_historysera vide, votre programme sera donc appelé avec les quatre derniers arguments comme ceci:

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

S'il vous plaît soyez prêt pour cela!

Les lecteurs avisés remarqueront peut-être que les quatre arguments fournissant l’honneur et la santé des deux samouraïs sont, dans une certaine mesure, superflus; S'agissant d'un jeu d'informations parfait, l'honneur et la santé des samouraïs peuvent être déterminés à l'aide des historiques uniquement.

Ces valeurs sont fournies à des fins pratiques afin que vous n'ayez pas à analyser les arguments de l'historique. Cela devrait s'avérer utile pour mettre en œuvre des stratégies simples, telles que ne pas attaquer lorsque votre honneur est égal à 0.

Description de la sortie

Pour choisir une action, votre programme devrait afficher l' un des W, B, G, I, Pou Oà la sortie standard, en fonction de l' action que vous voulez faire. Si votre programme ne génère rien dans un délai de 1000 ms, il sera terminé et votre programme sera traité comme s'il était sorti W.

Si votre programme génère plus d'une lettre, seule la première lettre sera prise en compte. La sortie Parrysera donc identique à la sortie P.

Si le résultat de la première lettre de votre programme ne correspond à aucune des options répertoriées ci-dessus, sa valeur par défaut est W.

Format de soumission

Soumettez un programme en réponse à cet article. Vous pouvez soumettre plusieurs programmes. Si vous soumettez plusieurs programmes simples, je vous recommande de les soumettre en tant que réponse unique; Si vous soumettez plusieurs programmes complexes, je vous recommande de les soumettre séparément. Une fois que j'ai ajouté avec succès votre / vos programme (s) au tournoi, je ferai un engagement dans le référentiel git avec votre inscription (lien ci-dessous).

Si je rencontre des problèmes qui empêchent l'ajout de votre programme au tournoi, je laisserai un commentaire sur votre inscription pour indiquer le problème.

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

  1. Nom lisible par l’homme de votre programme, à utiliser dans les tableaux de bord. Les espaces sont autorisés ici; les virgules et les caractères Unicode ne le sont pas.
  2. La langue dans laquelle votre programme est écrit. Veuillez éviter d’écrire dans des langues étranges et difficiles d’accès telles que TinyMUSH.
  3. Un bref synopsis de votre programme. Il peut s’agir d’une description du fonctionnement du programme, ou simplement d’un texte de synthèse sur votre programme (si vous souhaitez rester secret), ou peut-être des deux.
  4. La commande / s requise pour exécuter votre programme. Par exemple, si vous écrivez votre soumission en Java appelée example.java, vous devez fournir des instructions de compilation javac example.javapuis des instructions d'exécution java example.
  5. Le code source du programme.

Pour aider à la soumission, je fournis un modèle de soumission qui peut être trouvé ici . Le modèle rend les soumissions plus jolies. J'encourage fortement à l'utiliser.

Je fournis également deux exemples d'entrées. Bien que les exemples d’exemples participeront au round robin, leur objectif principal est de clarifier les formats de soumission et d’entrée / sortie du tournoi, plutôt que d’être de sérieux prétendants au titre d’Ultimate Samurai.

Structure du tournoi

Cette section décrit le déroulement du tournoi entre les participants.

Programme de contrôle

Le programme de contrôle est écrit en Python 2 et se trouve dans le référentiel Ultimate Samurai Showdown Github . Si vous souhaitez l'exécuter vous-même, des instructions sur son exécution sont incluses dans le fichier README.md dans le lien. Cependant, seuls les tournois organisés sur mon ordinateur seront officiels pour éviter les différences matérielles affectant les résultats du tournoi.

Le programme de contrôle sera exécuté sur un ordinateur portable sous Arch Linux. Il dispose d'un processeur Intel Core i7 et de 8 Go de RAM. Je vais essayer de faire en sorte que toutes les entrées soient exécutées sur mon ordinateur, mais je vous en serais très reconnaissant si vous évitiez des langues inaccessibles (sans aucun coût monétaire).

Système de notation

Le système de notation est un round robin. Chaque programme jouera huit matches contre tous les autres programmes. Une victoire donne au programme 1 point, une perte sans points et un match nul 0,5 point. Le programme avec le score le plus élevé gagne la partie. S'il y a un match nul, je combinerai les deux meilleurs programmes pour déterminer le vainqueur.

Le nombre de répétitions de chaque programme peut être réduit de 8 si le nombre de participants est extrêmement élevé. Je vais ajouter une note ici si cela se produit.

J'organiserai le tournoi à la ronde à plusieurs reprises au fur et à mesure que de nouvelles soumissions seront publiées, mais seul le plus récent tournoi à la ronde comptera.

Disqualifications

Il est possible que votre programme soit disqualifié du tournoi. L’exclusion peut survenir si:

  • Votre programme ne compile ni ne court;
  • Votre programme est un duplicata stratégique d’un autre programme (c’est-à-dire qu’il met en œuvre exactement la même stratégie qu’un autre programme);
  • Votre programme tente de saboter d'autres programmes en modifiant le code du contrôleur, le code d'un autre programme, etc.
  • Votre programme tente d'exploiter un bogue dans le code du contrôleur. Au lieu d’exploiter des bogues, vous devriez plutôt ouvrir un problème dans le référentiel git, faire un commentaire ici ou cingler.

Résultats passés

Les résultats détaillés de tous les tournois sont disponibles sur la page wiki .

Le plus récent tournoi a été clôturé le 2015-07-17 07:20. Voici un résumé des résultats:

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
Absinthe
la source
1
Le serveur va étonnamment bien. Doit remporter des victoires contre Spork Holder quand il manque d'honneur.
StephenTG
C'est un défi intéressant. De toute évidence, vous y avez longuement réfléchi et travaillé et je pense que cela a porté ses fruits. Excellent travail. :)
Alex A.
1
@ C5H8NNaO4 Oui, je vérifierai les mises à jour des robots avant de lancer le prochain tournoi.
absinthe
1
Remarque: mon ordinateur portable est tombé en panne récemment. Ainsi, je n’ai actuellement aucun moyen d’organiser le tournoi dans un avenir proche. Il y aura des retards dans l'organisation du prochain tournoi car j'essaie de trouver un ordinateur que je peux utiliser.
absinthe le
1
@ Levi Oui! Le fabricant m'a envoyé un remplacement qui est arrivé aujourd'hui. Il y a un tournoi en cours au moment où nous parlons.
absinthe

Réponses:

8

Le moine (Java)

Les valeurs du moine honorent et louent les bénédictions des dieux. Entraîné à la patience, il envoie ses prières au ciel avec calme jusqu'à ce qu'il se sente favorisé par Dieu.

Profitant de sa vie, il tente de la protéger. Lorsqu'il perd la santé au-dessus d'un certain taux, il se défend du mieux qu'il peut.

Espérant avoir le soutien de ses dieux, il envoie au hasard des éjaculations [1] au ciel, sinon il se bat du mieux qu'il peut.

Si son adversaire est usé de la bataille, il le termine en utilisant son dernier honneur pour lui accorder une mort rapide et sans douleur.

Compiler / Exécuter

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

Le Ninja (Java)

Le Ninja est rapide et attaque encore plus vite. Il attaque tout de suite après un salut formel et amical, déroutant davantage son ennemi en s'inclinant avant et après chaque attaque.

Après avoir été béni, le ninja maintient ce comportement, attendant que son adversaire fasse son (ses) premier (s) mouvement (s). Profitant de cette opportunité, il déchaîne une série d'explosions bénies par la déesse ninja jusqu'à ce qu'il soit trop épuisé par la bataille. Utilisant son dernier honneur, il se cache sous les feuilles, se protégeant de la prochaine attaque. Il saute et attaque son ennemi par derrière, se cachant aussi vite que possible.

S'il reçoit une blessure mortelle, il met tout en œuvre pour emmener avec lui la vie de son adversaire - bien sûr, en gardant un minimum d'honneur.

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, le copycat ninja (Java)

Kakashi copie ses mouvements adverses en choisissant au hasard entre les deux derniers mouvements effectués par l'adversaire. Si l'adversaire attend, il s'incline. Il conserve également son honneur.

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


Je souhaite que Kakashi soit béni avec le sharingan .. J'ai pensé à lire le casting.txt. Simulez chaque tour de son histoire contre chaque adversaire. Essayez de savoir contre quel adversaire il se bat en comparant l’histoire simulée de l’ennemi à l’histoire réelle. Ensuite, utilisez ces informations pour prédire le prochain coup que l’adversaire ferait et choisir le meilleur contre-mouvement à partir d’une liste prédéfinie. Mais je pense que cela pourrait prendre un peu, car je suis très lent sur Internet et qu’il n’ya aucune connaissance de Java

L'observateur, (node.js)

L'observateur s'incline avant d'essayer de prédire le prochain mouvement de l'adversaire parmi ses 5 derniers mouvements, en choisissant le meilleur pendant du mouvement prédit.

Edit: Merci à @apsillers pour le partage du node.js boilerplate !.

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

Edit: j’avais un défaut majeur chez l’observateur, je ne sais pas ce que je pensais hier soir. Il semble qu'il n'ait regardé que les deux derniers mouvements de l'ennemi. Il a fait étonnamment bien comme ça.

Sa mémoire est maintenant interrogée pour la partie la plus longue de l'histoire de l'ennemi qu'il a déjà vue. Cela contient un tableau avec tous les mouvements qui ont suivi l'historique des mouvements. L'un est sélectionné au hasard. Donc, si un mouvement suivait plus souvent, il est également plus probable qu'il soit choisi. Un peu comme les chaînes de markov.

The Observer, maintenant également gardien.


[1]: TIL: l'éjaculation a un sens religieux

C5H8NNaO4
la source
Vous êtes n ° 1 et n ° 3 en ce moment! Nice bots! :)
apsillers
Félicitations pour gagner avec The Observer. La coche verte est maintenant à vous: D
absinthe
7

Meiyo Senshi (Java)

Originaire de la région de Haijima, on ne sait pas grand-chose du Meiyo. Ils ne participent normalement pas à des jeux de sport, mais ont envoyé un guerrier à celui-ci afin d'évaluer leurs rivaux.

Cependant, ils forment un groupe honorable. Vous pouvez donc être assurés qu'il fera bientôt connaître sa présence aux dieux. Une fois qu'il aura vu assez de son ennemi pour le signaler, il utilisera les bénédictions reçues pour abattre son adversaire.

Pour compiler, c'est la méthode Java standard:

> 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))
        );
    }
}
Géobits
la source
7

Porte-Spork (Rubis)

Spork Holder s'incline au premier tour, puis agit de manière aléatoire après. C'est l'un des deux exemples d'entrées.

Commander: ruby spork-holder.rb

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

Le serveur (bash)

Le serveur attend seulement à chaque tour. C'est l'un des deux exemples d'entrées.

Commander: echo W

Il n'y a pas de code source requis.

Absinthe
la source
7

Coward (Node.js)

Je suis un lâche / C'est un miracle que je ne peut plus respirer
Destructeur / Par la brise d'été douce

  • Vérifie BXBXBX/ les BBBmodèles pour s'incliner (ou te frapper) lorsque tu te prosternes.
  • Vérifie les GXGXGXmodèles à s'incliner lorsque vous gardez.
  • Si son jet de bravoure aléatoire dépasse son seuil de peur pour ce tour, il tentera un coup.
    • Avoir une épée des dieux le rend plus courageux.
    • Un adversaire avec une épée des dieux le rend plus craintif.
    • Un adversaire qui mène avec au moins 5 PV ou plus le rend également un peu effrayé.
  • Sinon, il garde à tour de rôle et s'incline.

Si vous souhaitez rédiger une soumission Node.js , n'hésitez pas à utiliser mon code standard. tout, y compris la decidefonction, est entièrement général et gratuit.


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");
}
apsillers
la source
1
C'est un bot difficile. Superbe passe-partout; Je vais l'utiliser tout de suite. Merci de partager :)
C5H8NNaO4
6

Whack-a-mole (R)

Frappe quand l'ennemi est susceptible de s'incliner, sinon gardes.

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)

Courir en utilisant Rscript Whack-a-mole.R.

planificateur
la source
1
Beau travail, plus j'aime le nom.
Alex A.
3

Guerrier Éléphant (Java)

Le guerrier d'éléphant vient d'un temps plus ancien et plus naturel. Il a beaucoup vu et se souvient de tout. Il recherche les faveurs des dieux pendant qu'il examine son adversaire, puis, une fois qu'il les prend dans son cœur, il les sépare.

Compiler: javac ElephantWarrior.java
Commande: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;
       }
}
Caïn
la source
2
Je n’ai pas testé cela, mais il semble qu’il sortira du terrain au premier tour où il n’y en aura que quatre args.
Geobits
Oui, je ne savais pas que ceux-là ne seraient pas inclus du tout. Je suppose que de toute évidence une chaîne vide ne peut pas être passée, merci!
Caïn
@katya C'est corrigé maintenant, d'ailleurs, devrait être inclus dans le tournoi.
Cain
3

Princesse guerrière (Julia)

C'est le premier défi du roi de la colline auquel je participe. Voyons comment cela se passe.

La princesse guerrière donne la priorité à l'attaque et à l'honneur, et recourt à l'auto-préservation en cas de besoin. Elle est plutôt impatiente et n'attend jamais. Dans un effort pour rester agile, elle n’utilise pas non plus d’attaque aérienne.


Enregistrez sous warrior-princess.jlet exécutez à partir de la ligne de commande comme suit:

julia warrior-princess.jl <arguments>

Si vous n'avez pas Julia, vous pouvez le télécharger ici . Pour éviter les problèmes, la dernière version stable est recommandée (c’est-à-dire pas la version de développement).


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)
Alex A.
la source
1
Votre première entrée KotH et la première entrée Julia KotH de ma vie si je ne me trompe pas: félicitations!
Plannapus
@ plannapus Merci! : D Je vais peut-être en prendre l'habitude.
Alex A.
3

Gargouille (Java)

Essaie d'utiliser le mouvement défensif sans consommer l'honneur.

Comme c'est une entrée 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');
        }
    }
}
CommonGuy
la source
3

Épéiste (C / Java)

Swordsman s'incline au premier tour et chaque fois qu'il manque d'honneur. Il vérifie ensuite si l'adversaire ne s'est pas incliné, ne s'est pas défendu ou n'a pas attendu au tour précédent. Si l’adversaire ne l’avait pas fait, il ya une forte probabilité qu’il en fasse une dans le tour en cours et que l’épéiste frappe ainsi au hasard sur l’adversaire. Si ce n'est pas vrai, il défend s'il n'a pas défendu le tour précédent. S'il l'a eu, il s'incline pour gagner l'honneur.

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

Installez GCC (compilateur) et enregistrez le code dans un fichier nommé " Swordsman.c " pour compiler:

gcc Swordsman.c -o Swordsman

Un exécutable nommé " Swordsman " sera créé. Courir en utilisant

Swordsman

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

}

Installez javac (compilateur) et enregistrez le code dans un fichier nommé " Swordsman.java " pour compiler:

javac Swordsman.java

Un fichier de classe nommé " Swordsman.class " sera créé. Courir en utilisant

java Swordsman



Attaquant (Java)

L'attaquant ne se soucie de rien sauf qu'il veut la mort de son adversaire. Il frappe au hasard un des mouvements d'attaque et, s'il a peu d'honneur, s'incline.

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

}

Installez javac (compilateur) et enregistrez le code dans un fichier nommé " Attacker.java " pour compiler:

javac Attacker.java

Un fichier de classe nommé " Attacker.class " sera créé. Courir en utilisant

java Attacker


Prédicteur (C / Java)

Predictor prédit les mouvements de l'ennemi. Au premier tour, il utilise un coup aléatoire. S'incline si son honneur est bas, frappe si l'honneur de l'ennemi est bas ou s'il s'est incliné au tour précédent. Si le prédicteur n'a pas gardé le tour précédent, les gardes du tour actuel. Sinon, fait le même mouvement que l'ennemi lors du tour précédent, à condition que ce ne soit pas le 'W'cas, Predictor s'incline.

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

}

Installez GCC (compilateur) et enregistrez le code dans un fichier nommé " Predictor.c " pour la compilation:

gcc Predictor.c -o Predictor

Un exécutable nommé " Predictor " sera créé. Courir en utilisant

Predictor

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

Installez javac (compilateur) et enregistrez le code dans un fichier nommé " Predicator.java " pour compiler:

javac Predicator.java

Un fichier de classe nommé " Predicator.class " sera créé. Courir en utilisant

java Predicator


Pas sûr de l'efficacité de ces robots car je n'ai pas l'interpréteur python2 pour le tester.

Spikatrix
la source
1
Je n'ai pas testé cela (attaquant), mais il semble que le premier tour sera hors limites lors du premier tour où il n'y a que quatre arguments.
Geobits
L'attaquant semble donner un coup ArrayIndexOutOfBoundsExceptionau premier tour, l'obligeant à attendre le premier tour. En dehors de cela, il fonctionne.
absinthe
@ Katya et Geobits, corrigés. Merci de l'avoir repéré.
Spikatrix
Lorsque j'exécute le prédicteur, je reçois un segmentation fault (core dumped)après la ronde 24
C5H8NNaO4 le
@ C5H8NNaO4 Résolution du problème. Code mis à jour pour les trois robots. Devrait bien fonctionner maintenant. Merci de l'avoir signalé! :-D
Spikatrix
2

Maître Yi (Python)

Le maître assassin gagne beaucoup de faveur au début du jeu, le construisant jusqu'à ce qu'il soit invincible. Essaie d'attaquer quand ils s'y attendent le moins.

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

Pour exécuter: Enregistrer sous MasterYi.py

python MasterYi.py <args>
mbomb007
la source
2

Copy-san (C)

Copie chaque mouvement de son adversaire. Je suis sûr qu'il est assuré de perdre. Compiler: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;
}
Functino
la source
2

Hebi (Java)

Hebi suit la voie du serpent.

Le serpent n'a pas besoin de la bénédiction des dieux.

Le serpent glisse ses grèves; comme des vagues sur la plage, ce qui arrive recule comme il était venu.

Le serpent n'attend jamais.

Le serpent n'a aucun sens d'aptitude, sinon il aurait été écrit en Python.

Instructions d'exécution:

> javac hebi.java
> java hebi

Corps du code:

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

                    }

                }

            }

        }

    }

}
Docteur Heckle
la source
2

L'honorable (Java)

Les valeurs honorables honorent avant tout. C'est-à-dire que son honneur est supérieur à celui des autres. Si le samouraï ennemi a un honneur plus grand ou égal, il s'incline. Personne ne sera plus honorable que lui. Sinon, il fait un mouvement aléatoire. Il ne garde jamais deux fois d'affilée - ce serait déshonorant!

compiler:

> javac TheHonourable.java
> java TheHonourable

La source:

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);
    }
}
Neal
la source
1

Bienheureux Samurai (Python)

Ce samouraï essaie de garder la faveur des dieux aussi longtemps que possible. Il se précipite pour obtenir l'épée sacrée, puis alterne entre Garder et Attaquer avec l'une des frappes, reconstituant l'honneur en cas de besoin. S'il semble que son adversaire ou lui-même risque de tomber, il se précipite pour tuer. Il tombera facilement devant un adversaire capable de suivre son schéma, mais sa stratégie consistant à toujours attaquer à deux dégâts devrait être assez efficace.

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

Pour exécuter:
Enregistrer sous BlessedSamurai.py

python BlessedSamurai.py <args>
Stranjyr
la source
4
Votre programme doit imprimer son déplacement.
mbomb007
3
Je n'ai pas testé cela, mais il semble que cela va sortir des limites du premier tour où il n'y a que quatre arguments.
Geobits
J'ai utilisé un format similaire à ce qu'il a fait. @ Stranjyr, regardez ce que j'ai fait pour obtenir les arguments.
mbomb007
Merci à vous deux! Je n'ai pas accès à un interpréteur Python pour le moment, mais je pense avoir résolu le problème. D'une manière ou d'une autre, j'ai complètement manqué que la première série d'instructions n'aurait pas d'histoire.
Stranjyr
Bonjour, vous aviez un petit bug dans votre programme "le nom global 'dernier' n'est pas défini". Comme il est un petit bug que j'ai changé lastà ce self.lastqui semble résoudre le problème.
absinthe
1

Hermurai (C ++)

Admire son adversaire et est un peu paranoïaque. Il veut savoir s’il peut faire ce que les autres samouraïs peuvent faire, car il ne peut toujours pas se croire samurai. Son rêve ne s'est jamais estompé est devenu réalité avant qu'il ne le sache. Ce qui pourrait lui coûter la tête ...

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

Frappe aussi fort que possible. Passe en mode d'attaque imparable lorsqu'il est en danger.

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

Les deux sont écrits en C ++. Compiler:

g++ iniqy.cpp -o iniqy

Pour fonctionner sous Linux: ./iniqy

Pour fonctionner sous Windows: iniqy.exe

Herjan
la source
1

Le terminateur (rubis)

Le Terminator ne fait pas attention à sa propre santé. Le Terminator n'a aucune notion d'honneur. Le Terminator est envoyé du futur et simplement déterminé à mettre fin à son adversaire. Il le fait en regardant ses adversaires bouger, et rien d’autre. Il échantillonne les déplacements et calcule la réponse appropriée de manière si complexe qu'aucune technologie actuelle ne peut prédire les actions du Terminator. En fait, pour ceux qui vivent en 2015, le Terminator peut sembler quelque peu aléatoire ...

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
Daniero
la source
1

Agent 38 [1] (C)

En tant que produit de la manipulation génétique importante, l' agent 38 a le physique et l' acuité mentale d'un super [2] -samurai, et est nettement supérieure à tous ses sans ressource [citation nécessaire] viciée [citation nécessaire] concurrents.


//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] Nombre complètement non pertinent. [2] Garanti d'être vrai 1% du temps.


YAGMCSE

Les méthodes de Monte Carlo semblent présenter un jeu décent, alors voici encore une autre entrée générique pour la simulation de Monte Carlo!

Contrairement à la plupart des autres participations de ce concours, cette inscription utilise un grand nombre de simulations de jeux aléatoires et nécessite donc l'utilisation de l'indicateur -O3 pour des performances optimales.

Compilez le programme avec la commande suivante: 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;
}
Pomme de terre
la source
1
Il semble seulement s'incliner pour une raison quelconque. Vous voudrez peut-être y jeter un coup d'œil
C5H8NNaO4 Le
@ C5H8NNaO4 Merci de m'avoir signalé ce grave bug. Mon édition devrait corriger le bogue.
Pomme de terre
YAGMCSE semble ne faire que l'un GBWWWWW...ou l' autreBWWWW
C5H8NNaO4
@ C5H8NNaO4 C'est étrange. Je ne suis pas en mesure de reproduire les résultats que vous avez mentionnés. Est-ce que l'adversaire de YAGMCSE se prosternait / gardait / attendait?
Pomme de terre aux pommes
Oui, il courbait les 7 premiers tours. Voici un pastebin
C5H8NNaO4
1

Après ma tentative infructueuse d'entrer dans Target Dummy, je vous présente mon prochain bot ...

ScroogeBot - Python 2

Ce bot s'inclinera s'il n'a qu'un seul honneur. Sinon, il lancera une pièce de monnaie.

S'il tombe sur la tête, il effectuera une attaque au hasard. S'il tombe sur la queue, il s'incline ou se protège.

Commander: 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"
DJgamer98
la source
Yay, une nouvelle entrée! Un bref avertissement: il me faudra peut-être un peu de temps avant de pouvoir organiser un nouveau tournoi, car j'ai reconfiguré mon système d'exploitation hier. Je devrais cependant avoir un nouveau tournoi avec vos résultats d’ici la fin de la semaine.
absinthe
0

Yoshimitsu (JS)

Essaie de ne pas se protéger en vérifiant les deux derniers mouvements, obtiendra le courage avec un plus grand honneur. basé sur le modèle apsillers fait

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');
    }
}
Gilsham
la source
0

Le fou (C)

Le Fou implore une stratégie plutôt erratique, ne répétant jamais deux fois le même mouvement à moins d'y être contraint par manque d'honneur. Ses mouvements sont largement basés sur le hasard, ce qui rend difficile de prédire ses actions. Son bien-être est la dernière chose à laquelle il pense, car ses pensées ne sont orientées que sur l'effusion de sang et la victoire ultime.

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


Le prophète (c)

Le Prophète utilise la connaissance des 2 précédents mouvements de son adversaire afin de prédire son prochain mouvement et fournit une contre-attaque rapide et mortelle. En outre, il fait de l'astrologie et d'autres choses.

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


Compilation

Les deux programmes sont écrits en C et peuvent être compilés avec gcc:

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


Fonctionnement

*rien

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

les fenêtres

fool.exe <args>
prophet.exe <args>
Levi
la source