Concours ouvert en permanence - Mis à jour le 10 août 2017
Même si le 5 juin 2017, j'ai déclaré un gagnant (qui restera la meilleure réponse), je vais lancer de nouveaux bots et mettre à jour les résultats.
Résultats du 5 juin
Félicitations user1502040
Puisqu'il n'y a pas d'égalité, je montre seulement le% de matchs gagnés.
Statistician2
- 95,7%
Fitter
- 89,1%
Nash
- 83,9%
Weigher
- 79,9%
ExpectedBayes
- 76,4%
AntiRepeater
- 72,1%
Yggdrasil
- 65,0%
AntiGreedy
- 64,1%
Reactor
- 59,9%
NotHungry
- 57,3%
NashBot
- 55,1%
Blodsocer
- 48,6%
BestOfBothWorlds
- 48,4%
GoodWinning
- 43,9%
Rockstar
- 40,5%
ArtsyChild
- 40,4%
Assassin
- 38,1 %
WeightedRandom
- 37,7%
Ensemble
- 37,4%
UseOpponents
- 36,4%
GreedyPsychologist
- 36,3%
TheMessenger
- 33,9%
Copycat
- 31,4%
Greedy
- 28,3%
SomewhatHungry
- 27,6%
AntiAntiGreedy
- 21,0%
Cycler
- 20,3%
Swap
- 19,8%
RandomBot
- 16,2%
J'ai créé une feuille Google avec la grille de résultats de chaque association: https://docs.google.com/spreadsheets/d/1KrMvcvWMkK-h1Ee50w0gWLh_L6rCFOgLhTN_QlEXHyk/edit?usp=sharing
Grâce au dilemme de Petri, je me suis retrouvé capable de gérer ce roi de la colline.
Le jeu
Le jeu est un simple "Rock-Paper-Scissors" avec une touche: les points gagnés à chaque victoire augmentent pendant le match (votre R, P ou S est chargé).
- Le papier gagne le rock
- Ciseaux remporte Paper
- Rock gagne des ciseaux
Le gagnant obtient autant de points que sa charge sur son jeu.
Le perdant augmente de 1 la charge de son jeu.
En cas d'égalité, chaque joueur augmente la charge de son jeu de 0,5.
Après 100 parties, celui qui a le plus de points est le gagnant.
par exemple: P1 a des charges [10,11,12] (roche, papier, ciseaux) et P2 [7,8,9]. P1 joue R, P2 joue P. P2 gagne et obtient 8 points. Les charges P1 deviennent [11,11,12], les charges P2 restent les mêmes.
Spécifications du défi
Votre programme doit être écrit en Python (désolé, je ne sais pas comment le gérer autrement). Vous devez créer une fonction qui prend chacune de ces variables comme argument à chaque exécution:
my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history
points
- Points actuels (le vôtre et votre opp)
loaded
- Tableau avec charges (dans l'ordre RPS) (le vôtre et votre opp)
history
- Chaîne avec tous les jeux, le dernier personnage est le dernier jeu (le vôtre et votre opp)
Vous devez revenir "R"
, "P"
ou "S"
. Si vous retourniez quelque chose de différent, ce serait une perte automatique du match.
Règles
Vous ne pouvez pas modifier les fonctions intégrées.
Essai
Je garderai un Git mis à jour avec le code et tous les bots compiting: https://github.com/Masclins/LoadedRPS
Juger
Le vainqueur sera déterminé en sélectionnant la personne avec le plus de matchs gagnants après 1000 tournois complets. Les égalités seront brisées par des matchs à égalité. 1000 matchs sont joués plutôt qu'un, car je m'attends à beaucoup d'aléatoire, et de cette façon l'aléatoire serait moins pertinent.
Vous pouvez soumettre jusqu'à 5 bots.
Le concours se termine le 4 juillet (ce sera le dernier jour où j'accepterai une réponse), et le 5 juillet je posterai les stadings finaux (je pourrais essayer de poster un avancemnt avant).
Comme il s'agit de mon premier KOTH, je suis 100% ouvert à tout changement pour l'amélioration, comme le nombre de matchs joués contre chaque bot.
Modifié à 1000 correspondances, car je vois qu'il y a vraiment du hasard.
la source
runcode
etbots
)?Réponses:
Statisticien(ne joue plus)Bascule entre quelques stratégies simples basées sur les performances passées attendues
Statisticien 2
Nash
Calcule un équilibre de Nash approximatif par descente de gradient.
la source
Peseur
J'ai perdu la trace du raisonnement lors de l'expérimentation du code, mais l'idée de base est d'estimer la probabilité de mouvement de l'adversaire par les 3 derniers mouvements en utilisant des poids et de les multiplier par un autre poids qui dépend des charges. Je pensais que je pouvais
my_loaded
également l' utiliser , mais je ne pouvais pas décider comment, alors laissez-le de côté.Satan
Sera probablement disqualifié, car c'est une sorte de tricherie et il fait des hypothèses sur la fonction de test (il doit avoir la fonction de l'adversaire dans une variable sur son cadre de pile), mais il ne casse techniquement aucune règle actuelle - il ne le fait pas redéfinir ou réécrire quoi que ce soit. Il utilise simplement la magie noire pour exécuter la fonction adverse pour voir quel tour ils ont fait / vont faire. Il ne peut pas gérer le hasard, mais les robots déterministes n'ont aucune chance de vaincre Satan.
la source
my_loaded
vous pouvez ajouter un poids qui évalue le coup qui serait perdu par rapport à votre dernier coup. C'est comme supposer que votre adversaire fera quelque chose de similaire à ce que vous avez fait, et donc le punir pour supposer que vous continuerez à jouer de la même manière. Quelque chose comme:for i, m in enumerate(reversed(my_history[-3:])): sc[(idx[m]+1)%3] += (K / (1 + i))
Installateur
Ce robot améliore le modèle et le fusionne avec l'économiste (le modèle et l'économiste ne participeront plus)
L'amélioration de Pattern est que le Bot recherche maintenant deux types de patterns: l'adversaire réagissant à son dernier jeu et l'adversaire réagissant à mon dernier jeu. Évalue ensuite les deux prédictions pour utiliser celle qui correspond le mieux.
De ce modèle, le Bot a maintenant la probabilité de R, P et S. En tenant compte de cela et de la valeur attendue de chaque jeu (comme l'a fait Economist), le Bot joue celui qui donne le plus de valeur.
Voici les deux anciens codes
Motif(ne joue plus)Le Pattern essaie de trouver des modèles sur son adversaire. Il ressemble à ce que l'adversaire avait joué après le dernier jeu qu'il a fait (donnant plus de poids à ces derniers jeux). Grâce à cela, il devine ce que l'adversaire va jouer et joue le contre-match.
Economiste(ne joue plus)The Economist fait ce qui suit: Devine la probabilité de chaque jeu de l'adversaire en regardant ce qu'il avait joué les 9 derniers tours. À partir de là, calcule le bénéfice attendu de chaque jeu et va avec celui qui a la meilleure valeur attendue.
la source
Yggdrasil
Ceci est nommé "Yggdrasil" car il regarde vers l'avant dans l'arbre du jeu. Ce bot n'effectue aucune prédiction sur l'adversaire, il tente simplement de maintenir un avantage statistique s'il lui est attribué (en équilibrant les bénéfices actuels et futurs). Il calcule une stratégie mixte approximativement idéale et renvoie un mouvement sélectionné au hasard avec ces poids. Si ce bot était parfait (ce qui n'est pas le cas, car la fonction de valorisation de l'État est assez mauvaise et ne semble pas très loin), il serait impossible de battre ce bot plus de 50% du temps. Je ne sais pas dans quelle mesure ce bot fera l'affaire.
la source
Anti-répéteur
Picks papier au premier tour, après quoi il retourne tout ce qui bat ce que l'adversaire a fait le plus, ramasser du papier en cas d'égalité.
Imitateur
Copie simplement le dernier coup de l'adversaire.
Anti-Anti-Greedy
Prend tout ce qui perd au choix le plus lourd de l'adversaire.
Un peu faim
la source
Le Messager
Rock star
Assassin
Explication
Maintenant, vous pensez peut-être que ces robots sont totalement stupides.
pas entièrement vrai, ceux-ci sont en fait basés sur l'idée, d'amasser un énorme bonus, et l'ennemi de faire un faux pas et de se faire surprendre.
maintenant, ces robots jouent de manière très similaire aux gourmands, cependant, ils sont plus simples, et ne choisissent pas au hasard jusqu'à ce qu'ils obtiennent une charge sur une arme, ils s'en tiennent à leur arme de choix.
Autre chose à noter: celles-ci battront chacune gourmande environ la moitié du temps, tirant un tiers du temps, et perdant un sixième du temps. quand ils gagnent, ils ont tendance à gagner beaucoup. Pourquoi est-ce?
Gourmand, jusqu'à ce qu'il perde un tour, choisira une arme au hasard. cela signifie que lorsqu'il ne gagne pas un tour, il choisira à nouveau une arme au hasard, qui pourrait être gagnante à nouveau. si le cupide tire ou perd, il reste avec cette arme. si le cupide gagne au moins un round, puis choisit la même arme que le bot, le cupide gagne. si le gourmand choisit l'arme perdante à un moment donné, notre bot gagne, car la charge sur notre arme aurait été plus élevée que le score du gourmand.
En supposant que les gourmands ne choisissent pas toujours l'arme gagnante par grande chance, cela signifie que les chances sont les suivantes:
1/3: {1/2 victoire (1/6 au total). 1/2 défaite (1/6 au total). }
1/3 nul
1/3 victoire
donc: 1/3 chance de tirer, 1/6 chance de perdre, 1/2 chance de gagner.
cela montre probablement que vous devez faire plusieurs jeux de plusieurs tours
ce sont principalement pour lancer le défi
la source
Réacteur
Fait le jeu qui aurait gagné le tour précédent.
la source
opp_history[len(opp_history)-1]
paropp_history[-1]
.Enfant Artsy
Ce bot agit comme un enfant qui joue aux arts et métiers, commencera avec du papier et utilisera du papier ou des ciseaux au hasard, mais n'utilisera pas de ciseaux après la roche ou des ciseaux car il doit utiliser les ciseaux sur du papier. Jettera un rocher à quiconque lui lancera un rocher.
la source
Voici les trois robots que j'ai construits pour les tests:
RandomBot
Glouton
Choisit simplement son option la plus chargée.
Antigreedy
Suppose que l'adversaire jouera gourmand et joue l'alternative gagnante.
la source
Pas faim
C'est littéralement l'inverse de Greedy, il choisit l'option de points les plus bas disponible.
la source
Utiliser le favori de l'adversaire
Pour le premier tour, choisit un objet au hasard. Pour chaque autre tour, utilise le choix le plus courant de l'adversaire. S'il y a égalité, il s'agit par défaut du premier choix le plus courant.
// J'ai volé du code d' ici
Gagner, c'est bien
Renvoie le choix du gagnant du tour précédent. Si le tour précédent était une égalité, vérifie récursivement le tour précédent. S'il ne s'agissait que d'égalité, ou s'il s'agit du premier tour, renvoie un choix aléatoire.
la source
Le meilleur des deux mondes
Ce bot combine essentiellement Anti-Greedy et Greedy (d'où son nom).
la source
find
est pour les chaînes.my_loaded
etopp_loaded
sont les deux listes.index
devrait être bon pour ce que vous voulez.NashBot
Choisit au hasard entre les trois options de manière à ce que l'adversaire n'ait statistiquement aucune préférence entre les mouvements en ce qui concerne le score; en d'autres termes, Greedy et Not Hungry devraient avoir le même score moyen attendu.
la source
Baies attendues
Modifier: classement mis à jour
Il s'agit du nouveau meilleur classement après l'inclusion d'Expectedbayes:
Explications
(NB: soumission post 05/06/2017)
Ce bot essaie de maximiser la valeur attendue de son prochain mouvement en:
Les probabilités sont mises à jour tous les dix coups. Le nombre de mouvements passés utilisés pour calculer les probabilités a été fixé à 10 pour chaque bot (soit 20 fonctionnalités au total). Cela surestime probablement les données, mais je n'ai pas essayé de vérifier davantage.
Il s'appuie sur la bibliothèque scikit pour calculer les probabilités de déplacement de l'adversaire (je le dis au cas où j'aurais mal lu les règles et que ce n'était en fait pas autorisé).
Il gagne facilement contre des bots qui font toujours le même choix. Étonnamment, il est assez efficace contre le bot aléatoire avec un taux de victoire de 93% (je pense que cela est dû au fait qu'il limite le nombre de points que son adversaire peut obtenir tout en maximisant son propre nombre de points possibles pour chaque tour).
J'ai fait un essai rapide avec 100 tours et seulement un nombre limité de bots, et c'est ce que j'ai obtenu de result_stand:
Ce qui n'est pas si mal!
la source
Cycleur
0
la source
Ensemble
Plusieurs algorithmes concurrents votent sur la meilleure solution.
Échanger
Fait un coup au hasard, mais sans répéter le dernier coup qu'il a fait.
la source
blodsocer
épicerie
Je lui ai donné un correctif, donc ça devrait probablement fonctionner maintenant j'espère
J'ai gâché quelque chose à nouveau, j'ai donc supprimé et restauré. Je fais beaucoup de dégâts.
la source
if opp_history[1] == "S": return "R" elif opp_history[1] == "R": return "R" else: return "P"
quelle sorte d'épicerie est-ce?elif min(opp_history.count(i) for i in "RPS")/max(opp_history.count(i) for i in "RPS") >0.8 and len(my_history)>30:
"RPS"[my_loaded.index(max(my_loaded))+len(my_history)%2]
mais il semble hors de portée (tout comme les autres lignes).Aléatoire pondéré
Comme RandomBot, mais il n'en prend que 2 à lancer chaque fois qu'il est invoqué. Battra parfois Rockstar ou Assassin, mais augmentera les scores de l'autre (par exemple, s'il bat Rockstar, il donne un coup de pouce à Assassin).
la source
Psychologue gourmand
Nommé cela parce qu'il est par défaut gourmand, mais s'il ne peut pas décider, il contrecarre tout ce que l'adversaire ferait s'il utilisait la stratégie gourmande. S'il ne peut toujours pas décider, il se déroule au hasard.
la source