Contexte
Le jeu de Morra est un jeu simple. Dans la version "originale", plusieurs joueurs lancent simultanément un numéro 0-5 avec leurs mains tout en devinant la somme totale des mains de chacun. La version que j'utiliserai ici a été modifiée pour augmenter le potentiel de stratégie non triviale, et elle est décrite ci-dessous:
- Il y a deux joueurs.
- Comme dans les ciseaux à papier, les joueurs se déplacent simultanément.
- Chaque tour, chaque joueur choisit un nombre 0-5 et devine également le choix de son adversaire 0-5. Cela signifie que deux nombres sont sortis à chaque tour. Pour clarifier, la sortie des deux nombres doit être comprise entre 0 et 5 inclus.
- Si vous devinez correctement le choix de votre adversaire mais que votre adversaire n'a pas deviné correctement, vous gagnez un certain nombre de points égal à la somme des deux nombres joués. Par exemple, si les nombres joués étaient 3 et 5, une estimation correcte vaut 8 points.
- Si les deux joueurs ou aucun des deux ne devine correctement, aucun point n'est attribué.
- La personne avec le plus de points après 1000 tours remporte la partie.
Le tournois
Le tournoi se déroulera dans un style de tournoi à la ronde et se déroulera en créant chaque paire de concurrents possible. Pour chaque victoire, le candidat gagne 2 points de victoire. Chaque égalité donne 1 point de victoire. Aucun point de victoire n'est gagné pour une perte.
Intuitivement, le vainqueur du tournoi sera le concurrent avec le plus de points de victoire contre les autres.
Comment entrer
Il y aura deux méthodes pour soumettre des robots pour participer. La première méthode, et de loin préférée, consiste à implémenter une interface Java fournie par le contrôleur. La deuxième méthode consiste à écrire un programme indépendant.
Voyons d'abord la méthode Java. L'interface vous devrez implémenter est Player
et il définit deux méthodes: public String getName()
identifie votre bot et public int[] getMove(String[] args)
prend args
comme un tableau de six cordes, mychoices myguesses myscore opponentchoices opponentguesses opponentscore
. Un exemple est le suivant:
042 045 0 324 432 6
Cela signifie que j'ai choisi 0 au premier tour et j'ai deviné que mon adversaire allait lancer un 0. Mon adversaire a lancé un 3 et a deviné que je lancerais un 4. Au troisième tour, mon adversaire a fait la bonne supposition que je lancerais un 2, ce qui signifie qu'il gagne 2 + 4 = 6 points.
Votre méthode renverra un tableau de deux entiers, qui sont respectivement votre choix et votre supposition. Un exemple est {4,2}
pour un choix de 4 et une estimation de 2.
Voici un exemple de bot Java complet écrit comme méthode. Si vous le souhaitez, votre soumission doit uniquement inclure ce qui se passe dans la getMove
méthode.
import java.util.Random;
/**
* A simple example Morra bot to get you started.
*/
public class ExampleBot implements Player
{
public String getName()
{
return "ExampleBot";
}
public int[] getMove(String [] args)
{
//easiest way I know to break down to create a move history
//(just contains their throw history)
char[] theirThrowsC = args[3].toCharArray();
int[] theirThrows = new int[theirThrowsC.length];
for(int i = 0; i < theirThrowsC.length; i++)
{
theirThrows[i] = Integer.parseInt(Character.toString(theirThrowsC[i]));
}
//get my score
int myScore = Integer.parseInt(args[2]);
Random r = new Random();
int guess = r.nextInt(6);
if(theirThrows.length > 0)
{
guess = theirThrows[theirThrows.length-1];
}
//throws a random number, guesses what they threw last
return new int[] {r.nextInt(6),guess};
}
public static int otherMethod(int example) //you can write additional static methods
{
return 0;
}
}
En tant que programme indépendant
Je suis actuellement limité dans ma prise en charge de langues supplémentaires. Outre Java, je peux accepter des programmes écrits en Python 3.4, Perl 5 ou Ruby 2.1.5. S'il y a une langue que plusieurs personnes semblent vouloir, je ferai de mon mieux pour l'ajouter.
L'entrée de votre programme sera des arguments sur la ligne de commande. Cela pourrait ressembler à ceci:
perl awesomebot.plx 042 045 0 324 432 6
La sortie de votre programme doit être votre choix suivi de votre supposition, chacun suivi d'un espace.
Veuillez inclure dans votre réponse la commande exacte nécessaire pour l'exécuter. Gardez à l'esprit que j'utilise Windows 8.1.
Règles supplémentaires
Enregistrement de l'état et des délais d'attente
Votre programme sera autorisé à créer un fichier texte dans le répertoire local, où vous pourrez stocker des informations. Ces informations seront conservées tout au long du tournoi mais supprimées par la suite. Donnez au fichier un nom que je peux identifier.
Il y a un délai de 500 millisecondes pour que votre code réponde. Le fait de ne pas répondre dans le délai imparti (ou de donner un coup invalide) entraînera la perte de ce match particulier. Les soumissions Java ont actuellement un délai d'attente passif (que je peux mettre à niveau vers actif), tandis que les soumissions non Java ont un délai d'attente où leur processus se termine après 500 millisecondes.
Plus de règles de soumission
- Vous êtes autorisé à soumettre plusieurs soumissions, tant qu'elles respectent les règles et ne marquent pas l'équipe.
- Chaque entrée doit être unique. Vous ne pouvez pas faire une copie exacte de la logique d'un autre bot dans une langue différente.
- Les bots ne peuvent pas interagir les uns avec les autres (pour former une équipe de toute sorte).
- Vous ne pouvez pas utiliser la logique des autres robots à l'intérieur de votre robot pour, par exemple, identifier votre concurrent et prédire ses actions. Vous pouvez, bien sûr, essayer de déterminer la stratégie de votre adversaire.
- N'essayez pas de jouer avec le contrôleur, les autres concurrents ou mon ordinateur. Ne vous connectez pas à des sources d'informations externes.
Le controlle
La version actuelle du contrôleur se trouve ici . Il est écrit en Java 8. Le fichier "Tournoi" est le contrôleur principal, qui contient également la liste des concurrents (si vous souhaitez héberger vos propres compétitions).
Classement
Je n'ai pas vraiment pu mettre à jour le classement très souvent. Je suis plutôt occupé ce week-end. Par "plutôt occupé", je veux dire pas d'accès à un ordinateur de 6h30 à 21h30. Voici les scores après 5 runs. Le bot "Echo" a continué à perdre pour une raison quelconque (peut-être ma faute, je n'ai pas encore enquêté).
170 - Quinn and Valor
158 - Historian
142 - DeltaMax
140 - MorraCowbell
132 - Extrapolator
115 - Rainbolt
102 - Popularity
100 - Interpolator
83 - CounterBot
80 - Basilisk
76 - Erratica
65 - Trendy
63 - Scholar
62 - RandomGuesser
60 - KingFisher
59 - NullifierBot
55 - EvolvedBot
48 - Confused
Crédit
Un grand merci à Rainbolt et Peter Taylor pour leur aide avec le contrôleur.
la source
Réponses:
Morra Cowbell
Pour tous ceux qui recherchent une signification au nom de ce bot, le nom Morra me fait penser à Space Italian , alors j'ai pensé que j'avais besoin d'un nom qui jouait dessus. Parmi les autres candidats, Morra vous a trompé et Morra pour moi .
Il s'agit d'une classe complète implémentant l'
Player
interface. Explication ci-dessous.Explication
J'ai commencé par analyser les jeux avec moins de doigts. La plus simple et non triviale permet les appels de
0
ou1
et a la table de gains suivante (les valeurs sont les gains pour le joueur de ligne):La
(0,0)
stratégie est dominée par(0,1)
, nous pouvons donc réduire le tableau àMaintenant, la
(1,0)
stratégie est dominée par(0,1)
, afin que nous puissions réduire davantage le tableau àEt maintenant
(1,1)
est dominé par(0,1)
, donc nous nous retrouvons avecPar conséquent, toujours jouer
(0,1)
est un équilibre de Nash. Mais ce qui est curieux, c'est que ce n'est pas le seul. Il s'agit d'un jeu symétrique à somme nulle, donc le gain attendu est de 0, et toute stratégie mixte combinant(0,1)
et(1,0)
où(0,1)
est choisie au moins 50% du temps réalise ce gain. Nous avons donc un espace unidimensionnel d'équilibres de Nash.Il semble que ce soit le cas, même si je ne l'ai pas prouvé, que
n
-finger Morra a unn
polytope dimensionnel d'équilibres de Nash qui sont des stratégies mixtes entre lesn+1
(pick, guess)
paires pour lesquellespick + guess = n
.Les nombres magiques dans le code ci-dessus codent les 32 sommets du polytope à 5 dimensions des équilibres de Nash. Je les ai trouvés en créant une instance de programmation linéaire qui représentait le polytope et en utilisant ensuite des fonctions objectives aléatoires. La raison pour encoder les 32 plutôt que d'en choisir un est simple: le gain attendu est 0, donc je dois faire mieux que prévu pour gagner. Je suppose essentiellement que l'autre joueur utilise une stratégie mixte et estime la distribution en fonction de son historique de choix. Ensuite, je sélectionne le sommet du polytope qui maximise mon gain attendu par rapport à cette distribution estimée.
QuinnAndValor démontre la vulnérabilité de l'hypothèse que l'autre joueur utilise une stratégie mixte. En détectant un joueur qui utilise les stratégies des équilibres de Nash, il est capable de basculer dans un mode de marche aléatoire où, jouant une stratégie de non-équilibre, il est susceptible de perdre en moyenne, mais il n'a besoin que de prendre l'avantage une fois puis il peut revenir à jouer des paires pour lesquelles
pick + guess = n
. Ainsi, les équilibres de Nash pour un seul jeu ne se généralisent pas de manière triviale aux équilibres de Nash pour le jeu répété, ce qui permet des stratégies plus complexes.la source
Quinn et Valor (mis à jour)
Quinn et Valor sont une équipe de rangers d'élite. Avec l'arbalète et la griffe, ils déchirent chaque adversaire ose les défier.
Ils gagnent presque toujours contre toutes les solutions Java sur ma machine.
Modifier:
J'avoue que Quinn et Valor n'ont pas réussi à se battre en historien, mais j'ai toujours bonne foi en eux pour remporter le tournoi.
Mon principe est, pour toute solution avec
choice + guess == 5
, de jouer aussi avec leschoice + guess == 5
bénéficiaires en gardant votre avantage.Mise à jour:
Eh bien ... tout est devenu compliqué.
la source
Savant
Le chercheur essaie d'apprendre des mouvements de son adversaire, choisissant celui que son adversaire a le moins deviné et devinant celui que son adversaire a le plus utilisé. Mais la théorie n'est pas tout, donc Scholar ne fait pas très bien ...
la source
DeltaMax
(Mis à jour pour ne pas utiliser de fichiers et ajouté une nouvelle section. Également modifié pour ne plus se coincer dans la première section.)
Consiste en quelques stratégies qui commencent simples puis deviennent plus complexes - si vous en supprimez une, cela vous fait passer à la section suivante.
{0, 5}
régulièrement(choice, guess)
paire qui aurait la meilleure attente, pondérée de sorte que les rondes récentes soient plus importantesPour savoir quelle stratégie a finalement été utilisée, décommentez
ligne.
Toutes mes excuses pour l'horrible Java, j'ai passé mon après-midi à reconstituer des morceaux et à réapprendre le langage :)
la source
private int strat;
est assez bon.Historien
(Mise à jour: même logique, code plus court et 100 fois plus rapide, mais vous ne pouvez utiliser qu'un seul bot historien lors d'un tournoi.)
Utilise une pondération aléatoire pour choisir une paire de lancer-deviner basée sur l'efficacité de n'utiliser que cette paire contre l'historique précédent de l'adversaire. Les poids sont les carrés des scores réalisables.
Beats
Quinn and Valor
(pas plus) et perd àMorra Cowbell
. Dans le tournoi, la plupart des botsHistorian
arrivent en deuxième positionQuinn and Valor
.la source
Morra Cowbell
. Modifié le message. Vous pouvez cependant supprimer les commentaires s'ils deviennent obsolètes.Extrapolateur (v1.1)
Extrapolation extrême à partir de l'un des équilibres de Nash d'un jeu plus simple.
Je soutiens le format de réponse concise! (En style python.)
Semble égaler avec la vache magique (Morra Cowbell) et bat les autres entrées que j'ai vérifiées.
la source
Branché
Trendy jette un œil aux mouvements passés de l'adversaire, en les pondérant par la récence. Devine le plus lourd, et en choisit un légèrement décalé. Le voici, dans toute sa splendeur:
La seule chose avec laquelle je peux le comparer maintenant est Cowbell. Il perd par une petite marge la plupart du temps, mais ressort souvent assez souvent à mon goût. Nous verrons comment cela se passe avec plus de concurrents.
la source
Devineur aléatoire
C'est vraiment simple. Il lance effectivement un d6 et ajoute un autre rouleau au rouleau précédent pour sa conjecture. Il ne gagnera pas, mais il fournira une belle référence.
la source
Confus, Python 3
Une entrée inutilement compliquée. Même moi, je ne sais pas ce que ça fait.
Bien que cet algorithme avancé semble moins performant qu'aléatoire dans ce tournoi, et utilise une mémoire et une durée d'exécution importantes, il a des résultats étonnants pour certaines valeurs de 5 ;-)
la source
Rainbolt
Prend la différence entre les deux derniers chiffres que notre adversaire a deviné, ajoute cela à la dernière supposition de notre adversaire, trouve le module et évite de choisir ce numéro à tout prix. Par exemple, si vous devinez {5,4,3} (en diminuant d'une unité), nous éviterions à tout prix d'en choisir 2.
Prend la différence entre les deux derniers nombres choisis par notre adversaire, ajoute cela au dernier choix de notre adversaire et devine ce nombre. Par exemple, si vous devinez {1,4,5,2} (augmentant par trois), nous devinerions 5.
Evite les rouleaux inutiles ou très proches.
la source
getMove()
méthode statique. Vous ne pouvez pas implémenter une méthode non statique comme celle-ci (du moins pas en Java 8).Bot évolué
J'ai fait évoluer ce bot pour qu'il soit le meilleur bot aléatoire.
la source
Popularité, Python 3
Calculez la supposition en fonction des nombres populaires utilisés dans le passé par l'adversaire. Les chiffres utilisés récemment ont plus de poids. Le choix du nombre est souvent le même que la supposition.
la source
Interpolateur
(Passé à Java car Python posait des problèmes)
Utilise une interpolation polynomiale sur les 10 derniers choix de l'adversaire pour déterminer le numéro suivant de l'adversaire, puis fait de même pour ses propres choix et évite de choisir ce numéro. De plus, Interpolator a un léger biais contre le choix de 0 ou 5, et son choix est parfois affecté par sa supposition:
la source
CounterBot
Ne contrecarre personne mais compte plutôt de 0 à 5 dans un cercle (
0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4 ...
)la source
Basilic, Python
Selon la légende, le basilic est le roi des serpents. ( source ) J'ai pensé que c'était un nom approprié pour un bot qui joue "The Noble Game Of Kings" et est écrit en python. = D Ce bot fait peur au cœur des autres bots et provoque la mort d'un seul coup d'œil.
Cela fonctionne sur une stratégie assez simple. Je ne m'attends pas à ce qu'il gagne, mais c'était amusant d'écrire. C'est également mon premier défi KoTH, donc je suis ravi de voir à quel point il fonctionne.
Comment il choisit son prochain coup.
Le Basilic effectue toujours le coup que son adversaire a deviné le moins de fois. En cas d'égalité, il choisira le plus petit nombre. (pour minimiser le nombre de points de l'adversaire.)
Comment il choisit sa prochaine supposition.
Le basilic choisira la réponse la plus probable à sa supposition précédente. Par exemple, si la dernière fois, il a deviné un 3, il reviendra à travers toutes les fois précédentes où il a deviné un 3, puis retourne le coup de l'adversaire le plus courant qui vient après une supposition de 3. En cas d'égalité , il choisira le plus grand nombre (pour maximiser le nombre de points qu'il pourrait faire.)
Sur une note technique, cela fonctionnera-t-il correctement? Est-ce que print () est suffisant, ou devrais-je utiliser quelque chose comme sys.stdout.write () comme les autres Pythonistas l'ont fait?
la source
Idem
Cela devient l'adversaire, mais derrière par une supposition / choix.
la source
NullifierBot, Java
Lance toujours 0 pour minimiser les gains de l'adversaire. Si l'adversaire devine jamais mon numéro, il ne gagne que ce qu'il a lancé.
Devine toujours 5 pour maximiser mes gains. Comme je ne peux obtenir aucun point de mon lancer, je veux en obtenir autant de l'adversaire. Je pourrais deviner au hasard, mais où est le plaisir là-dedans?
la source
Erratica, Java
Pas génial, mais il a été initialement conçu pour être principalement aléatoire, jusqu'à ce que la valeur du compromis me soit apparue. Gère de façon constante contre Counter Bot> _ <
la source
Echo, Ruby
Joue le dernier jeu joué par l'adversaire, sur la théorie que n'importe qui peut faire un bot qu'il ne peut pas prédire. Devine en fonction de la valeur attendue à l'aide d'un échantillon de cent mouvements.
la source
echo.rb:3:in
<main> ': méthode non définiesize' for nil:NilClass (NoMethodError)
. Cela ne semble se produire qu'au premier tour, quand il n'y a pas d'historique de mouvement.if (mychoices.size > 990 && myscore == '0') nextchoice = rand(1..5)
pièce?KING FISHER
Ce mec est composé d'alghorithmes de mauvaise estimation qui utilisent principalement des tableaux pondérés.
la source
Euh euh. Je sais ce que tu penses. "Est-ce qu'il va en choisir cinq ou autre chose?" Eh bien, pour vous dire la vérité dans toute cette excitation, je ne suis pas sûr moi-même, mais étant une méthode .44, la méthode la plus puissante au monde et qui surchargerait votre pile tout de suite, vous devez vous poser une question : "Est-ce que je me sens chanceux?"
Eh bien, punk?
la source