Créez un bot pour choisir le plus petit numéro unique.
(Basé sur une expérience de psychologie dont j'ai entendu parler il y a de nombreuses années mais que je n'ai pas pu retrouver.)
Règles
- Chaque jeu sera composé de 10 bots sélectionnés au hasard jouant 1000 tours.
- Chaque tour, tous les bots sélectionnent un entier de 1 à 10 (inclus). Tous les bots qui choisissent la même valeur seront exclus et le bot restant avec la plus petite valeur recevra un point.
- Dans le cas où aucun bot ne choisit une valeur unique, aucun point ne sera attribué.
- À la fin de 1000 tours, le bot avec le plus de points (ou tous les bots à égalité avec le plus de points) remporte la partie.
- Le tournoi durera 200 * (nombre de joueurs) matchs.
- Le bot avec le pourcentage de victoire le plus élevé remporte le tournoi.
Caractéristiques
Les bots doivent être des classes Python 3 et doivent implémenter deux méthodes: select
et update
.
Les bots seront construits avec un index.
select
ne reçoit aucun argument et renvoie le choix du bot pour le tour en cours.
update
est passé une liste des choix effectués par chaque bot au tour précédent.
Exemple
class Lowball(object):
def __init__(self, index):
# Initial setup happens here.
self.index = index
def select(self):
# Decision-making happens here.
return 1
def update(self, choices):
# Learning about opponents happens here.
# Note that choices[self.index] will be this bot's choice.
pass
Manette
import numpy as np
from bots import allBotConstructors
allIndices = range(len(allBotConstructors))
games = {i: 0 for i in allIndices}
wins = {i: 0 for i in allIndices}
for _ in range(200 * len(allBotConstructors)):
# Choose players.
playerIndices = np.random.choice(allIndices, 10, replace=False)
players = [allBotConstructors[j](i) for i, j in enumerate(playerIndices)]
scores = [0] * 10
for _ in range(1000):
# Let everyone choose a value.
choices = [bot.select() for bot in players]
for bot in players:
bot.update(choices[:])
# Find who picked the best.
unique = [x for x in choices if choices.count(x) == 1]
if unique:
scores[choices.index(min(unique))] += 1
# Update stats.
for i in playerIndices:
games[i] += 1
bestScore = max(scores)
for i, s in enumerate(scores):
if s == bestScore:
wins[playerIndices[i]] += 1
winRates = {i: wins[i] / games[i] for i in allIndices}
for i in sorted(winRates, key=lambda i: winRates[i], reverse=True):
print('{:>40}: {:.4f} ({}/{})'.format(allBotConstructors[i], winRates[i], wins[i], games[i]))
Information additionnelle
- Aucun bot ne jouera dans un match contre lui-même.
- Dans le cas peu probable où un bot est inclus dans moins de 100 matchs, le tournoi sera relancé.
- Les bots peuvent stocker l'état entre les tours, mais pas entre les jeux.
- L'accès au contrôleur ou à d'autres robots n'est pas autorisé.
- Le nombre de parties et le nombre de tours par partie sont susceptibles d'augmenter si les résultats sont trop variables.
- Tous les bots qui soulèvent des erreurs ou donnent des réponses invalides (non-ints, valeurs en dehors de [1, 10], etc.) seront disqualifiés et le tournoi sera relancé sans eux.
- Il n'y a pas de limite de temps pour les tours, mais je peux en appliquer un si les bots prennent trop de temps pour réfléchir.
- Il n'y a pas de limite au nombre de soumissions par utilisateur.
La date limite pour les soumissions est 23:59:59 UTC le vendredi 28 septembre.Le tournoi est maintenant fermé pour les soumissions.
Résultats
BayesBot: 0.3998 (796/1991)
WhoopDiScoopDiPoop: 0.3913 (752/1922)
PoopDiScoopty: 0.3216 (649/2018)
Water: 0.3213 (660/2054)
Lowball: 0.2743 (564/2056)
Saboteur: 0.2730 (553/2026)
OneUpper: 0.2640 (532/2015)
StupidGreedyOne: 0.2610 (516/1977)
SecondSaboteur: 0.2492 (492/1974)
T42T: 0.2407 (488/2027)
T4T: 0.2368 (476/2010)
OpportunityBot: 0.2322 (454/1955)
TheGeneral: 0.1932 (374/1936)
FindRepeats: 0.1433 (280/1954)
MinWin: 0.1398 (283/2025)
LazyStalker: 0.1130 (226/2000)
FollowBot: 0.1112 (229/2060)
Assassin: 0.1096 (219/1999)
MostlyAverage: 0.0958 (194/2024)
UnchosenBot: 0.0890 (174/1955)
Raccoon: 0.0868 (175/2015)
Equalizer: 0.0831 (166/1997)
AvoidConstantBots: 0.0798 (158/1980)
WeightedPreviousUnchosen: 0.0599 (122/2038)
BitterBot: 0.0581 (116/1996)
Profiteur: 0.0564 (114/2023)
HistoryBot: 0.0425 (84/1978)
ThreeFourSix: 0.0328 (65/1984)
Stalker: 0.0306 (61/1994)
Psychadelic: 0.0278 (54/1943)
Unpopulist: 0.0186 (37/1994)
PoissonsBot: 0.0177 (35/1978)
RaccoonTriangle: 0.0168 (33/1964)
LowHalfRNG: 0.0134 (27/2022)
VictoryPM1: 0.0109 (22/2016)
TimeWeighted: 0.0079 (16/2021)
TotallyLost: 0.0077 (15/1945)
OneTrackMind: 0.0065 (13/1985)
LuckySeven: 0.0053 (11/2063)
FinalCountdown: 0.0045 (9/2000)
Triangle: 0.0039 (8/2052)
LeastFrequent: 0.0019 (4/2067)
Fountain: 0.0015 (3/1951)
PlayerCycle: 0.0015 (3/1995)
Cycler: 0.0010 (2/1986)
SecureRNG: 0.0010 (2/2032)
SneakyNiner: 0.0005 (1/2030)
I_Like_Nines: 0.0000 (0/1973)