Résultat final
La compétition est finie. Félicitations à hard_coded
!
Quelques faits intéressants:
Dans 31600 enchères sur 40920 (77,2%), le vainqueur du premier tour a remporté le plus de tours de cette enchère.
Si des exemples de bots sont inclus dans la compétition, les neuf premières places ne changeront pas sauf cela
AverageMine
etheurist
échangeront leurs positions.Top 10 des résultats d'une vente aux enchères:
[2, 2, 3, 3] 16637
[0, 3, 3, 4] 7186
[1, 3, 3, 3] 6217
[1, 2, 3, 4] 4561
[0, 1, 4, 5] 1148
[0, 2, 4, 4] 1111
[2, 2, 2, 4] 765
[0, 2, 3, 5] 593
[1, 1, 4, 4] 471
[0, 0, 5, 5] 462
Comte Tie (nombre de ventes aux enchères que le i-ème tour avait pas de gagnant):
[719, 126, 25, 36, 15, 58, 10, 7, 19, 38]
.Offre publique moyen gagnant du i-ème tour:
[449.4, 855.6, 1100.8, 1166.8, 1290.6, 1386.3, 1500.2, 1526.5, 1639.3, 3227.1]
.
Tableau d'affichage
Bot count: 33
hard_coded Score: 16141 Total: 20075170
eenie_meanie_more Score: 15633 Total: 18513346
minus_one Score: 15288 Total: 19862540
AverageMine Score: 15287 Total: 19389331
heurist Score: 15270 Total: 19442892
blacklist_mod Score: 15199 Total: 19572326
Swapper Score: 15155 Total: 19730832
Almost_All_In Score: 15001 Total: 19731428
HighHorse Score: 14976 Total: 19740760
bid_higher Score: 14950 Total: 18545549
Graylist Score: 14936 Total: 17823051
above_average Score: 14936 Total: 19712477
below_average Score: 14813 Total: 19819816
Wingman_1 Score: 14456 Total: 18480040
wingman_2 Score: 14047 Total: 18482699
simple_bot Score: 13855 Total: 20935527
I_Dont_Even Score: 13505 Total: 20062500
AntiMaxer Score: 13260 Total: 16528523
Showoff Score: 13208 Total: 20941233
average_joe Score: 13066 Total: 18712157
BeatTheWinner Score: 12991 Total: 15859037
escalating Score: 12914 Total: 18832696
one_upper Score: 12618 Total: 18613875
half_in Score: 12605 Total: 19592760
distributer Score: 12581 Total: 18680641
copycat_or_sad Score: 11573 Total: 19026290
slow_starter Score: 11132 Total: 20458100
meanie Score: 10559 Total: 12185779
FiveFiveFive Score: 7110 Total: 24144915
patient_bot Score: 7088 Total: 22967773
forgetful_bot Score: 2943 Total: 1471500
bob_hater Score: 650 Total: 1300
one_dollar_bob Score: 401 Total: 401
Dans ce jeu, nous simulerons une vente aux enchères scellée.
Chaque enchère est un jeu à 4 joueurs, composé de 10 tours. Au départ, les joueurs n'ont pas d'argent. Au début de chaque tour, chaque joueur recevra 500 $, puis fera ses propres enchères. L'enchère peut être un entier non négatif inférieur ou égal au montant dont ils disposent. Habituellement, celui qui offre le plus haut remporte la manche. Cependant, pour rendre les choses plus intéressantes, si plusieurs joueurs offrent le même prix, leur enchère ne sera pas prise en compte (donc ne peut pas gagner le tour). Par exemple, si quatre joueurs enchérissent 400 400 300 200, celui enchérit 300 victoires; s'ils enchérissent 400 400 300 300, personne ne gagne. Le gagnant doit payer ce qu'il a offert.
Puisqu'il s'agit d'une enchère «à enchères scellées», le seul joueur qui connaîtra les enchères est le gagnant et combien il a payé au début du prochain tour (afin que le joueur puisse savoir combien chacun a).
Notation
Une enchère aura lieu pour chaque combinaison possible de 4 joueurs. Autrement dit, s'il y a N bots au total, il y aura une enchère N C 4 . Le bot qui remportera le plus de tours sera le vainqueur final. En cas d'égalité, le bot qui a payé le moins au total gagnera. S'il y a toujours une égalité, de la même manière que l'enchère, ces égalités seront supprimées.
Codage
Vous devez implémenter une classe Python 3 avec une fonction membre play_round
(et __init__
ou d'autres si vous en avez besoin). play_round
devrait prendre 3 arguments (y compris l'auto). Les deuxième et troisième arguments seront, dans l'ordre: l'identifiant du vainqueur du tour précédent, suivi du montant qu'ils ont payé. Si personne ne gagne ou que c'est le premier tour, ils seront tous les deux -1. Votre identifiant sera toujours 0 et les identifiants 1 à 3 seront les autres joueurs dans un ordre uniquement déterminé par la position sur ce post.
Règles supplémentaires
1. Déterministe:
le comportement de votre fonction ne devrait dépendre que des arguments d'entrée dans une enchère. Autrement dit, vous ne pouvez pas accéder aux fichiers, à l'heure, aux variables globales ou à tout ce qui stockera des états entre différentes enchères ou bots . Si vous souhaitez utiliser un générateur pseudo-aléatoire, il est préférable de l'écrire par vous-même (pour éviter d'affecter les programmes des autres comme random
dans la bibliothèque Python), et assurez-vous de le réinitialiser avec une graine fixe dans __init__
ou au premier tour.
2. Trois bots par personne: vous êtes autorisé à soumettre au plus 3 bots, vous pouvez donc développer une stratégie pour faire coopérer vos bots d'une manière ou d'une autre.
3. Pas trop lent: étant donné qu'il y aura de nombreuses enchères, assurez-vous que vos robots ne fonctionneront pas trop lentement. Vos robots devraient pouvoir terminer au moins 1 000 enchères en une seconde.
Manette
Voici le contrôleur que j'utilise. Tous les bots seront importés et ajoutés bot_list
dans l'ordre de cette publication.
# from some_bots import some_bots
bot_list = [
#one_bot, another_bot,
]
import hashlib
def decide_order(ls):
hash = int(hashlib.sha1(str(ls).encode()).hexdigest(), 16) % 24
nls = []
for i in range(4, 0, -1):
nls.append(ls[hash % i])
del ls[hash % i]
hash //= i
return nls
N = len(bot_list)
score = [0] * N
total = [0] * N
def auction(ls):
global score, total
pl = decide_order(sorted(ls))
bots = [bot_list[i]() for i in pl]
dollar = [0] * 4
prev_win, prev_bid = -1, -1
for rounds in range(10):
bids = []
for i in range(4): dollar[i] += 500
for i in range(4):
tmp_win = prev_win
if prev_win == i: tmp_win = 0
elif prev_win != -1 and prev_win < i: tmp_win += 1
bid = int(bots[i].play_round(tmp_win, prev_bid))
if bid < 0 or bid > dollar[i]: raise ValueError(pl[i])
bids.append((bid, i))
bids.sort(reverse = True)
winner = 0
if bids[0][0] == bids[1][0]:
if bids[2][0] == bids[3][0]: winner = -1
elif bids[1][0] == bids[2][0]: winner = 3
else: winner = 2
if winner == -1:
prev_win, prev_bid = -1, -1
else:
prev_bid, prev_win = bids[winner]
score[pl[prev_win]] += 1
total[pl[prev_win]] += prev_bid
dollar[prev_win] -= prev_bid
for a in range(N - 3):
for b in range(a + 1, N - 2):
for c in range(b + 1, N - 1):
for d in range(c + 1, N): auction([a, b, c, d])
res = sorted(map(list, zip(score, total, bot_list)), key = lambda k: (-k[0], k[1]))
class TIE_REMOVED: pass
for i in range(N - 1):
if (res[i][0], res[i][1]) == (res[i + 1][0], res[i + 1][1]):
res[i][2] = res[i + 1][2] = TIE_REMOVED
for sc, t, tp in res:
print('%-20s Score: %-6d Total: %d' % (tp.__name__, sc, t))
Exemples
Si vous avez besoin d'un générateur pseudo-aléatoire, en voici un simple.
class myrand:
def __init__(self, seed): self.val = seed
def randint(self, a, b):
self.val = (self.val * 6364136223846793005 + 1) % (1 << 64)
return (self.val >> 32) % (b - a + 1) + a
class zero_bot:
def play_round(self, i_dont, care): return 0
class all_in_bot:
def __init__(self): self.dollar = 0
def play_round(self, winner, win_amount):
self.dollar += 500
if winner == 0: self.dollar -= win_amount
return self.dollar
class random_bot:
def __init__(self):
self.dollar = 0
self.random = myrand(1)
def play_round(self, winner, win_amount):
self.dollar += 500
if winner == 0: self.dollar -= win_amount
return self.random.randint(0, self.dollar)
class average_bot:
def __init__(self):
self.dollar = 0
self.round = 11
def play_round(self, winner, win_amount):
self.dollar += 500
self.round -= 1
if winner == 0: self.dollar -= win_amount
return self.dollar / self.round
class fortytwo_bot:
def play_round(self, i_dont, care): return 42
Résultat
all_in_bot Score: 20 Total: 15500
random_bot Score: 15 Total: 14264
average_bot Score: 15 Total: 20000
TIE_REMOVED Score: 0 Total: 0
TIE_REMOVED Score: 0 Total: 0
Le gagnant est all_in_bot
. Notez que zero_bot
et fortytwo_bot
ont le même score et le même total, ils sont donc supprimés.
Ces bots ne seront pas inclus dans la compétition. Vous pouvez les utiliser si vous pensez qu'ils sont géniaux.
La compétition finale aura lieu le 23/11/2017 à 14h00 (UTC) . Vous pouvez apporter des modifications à vos robots avant cela.
la source
Réponses:
codé en dur
Ce bot est le résultat d'un entraînement génétique contre beaucoup d'autres robots pseudo-aléatoires (et certains des robots dans d'autres réponses). J'ai passé un peu de temps à affiner à la fin, mais sa structure est en fait très simple.
Les décisions sont basées uniquement sur un ensemble fixe de paramètres et non sur les résultats des cycles précédents.
La clé semble être le premier tour: vous devez faire tapis, enchérir 500 est la solution sûre. Trop de bots essaient de déjouer le coup initial en enchérissant 499 ou 498. Gagner le premier tour vous donne un gros avantage pour le reste de l'enchère. Vous n'avez que 500 dollars de retard et vous avez le temps de récupérer.
Une valeur sûre au deuxième tour est un peu plus de 990, mais même enchérir 0 donne un bon résultat. Enchérir trop haut et gagner pourrait être pire que de perdre ce tour.
Au troisième tour, la plupart des bots cessent de grimper: 50% d'entre eux ont maintenant moins de 1500 dollars, il n'est donc pas nécessaire de gaspiller de l'argent sur ce tour, 1170 est un bon compromis. Même chose au quatrième tour. Si vous avez perdu les trois premiers, vous pouvez gagner celui-ci très bon marché et avoir encore assez d'argent pour le prochain.
Après cela, l'argent moyen requis pour gagner un tour est de 1500 dollars (ce qui est la conclusion logique: tout le monde gagne maintenant un tour sur quatre, enchérir moins pour gagner plus tard ne fait que gaspiller de l'argent, la situation s'est stabilisée et c'est juste un tour- robin à partir de maintenant).
Le dernier tour doit être all-in, et les autres paramètres sont affinés pour gagner le dernier tour en misant le plus bas possible jusque-là.
Beaucoup de bots essaient de gagner le neuvième tour en enchérissant plus de 2000 dollars, alors j'ai pris cela en compte et j'ai essayé de les surenchérir (je ne peux pas gagner les deux derniers tours de toute façon, et le dernier sera plus difficile).
la source
Au dessus de la moyenne
Des enchères supérieures au montant moyen des autres joueurs. Offre tout au dernier tour.
la source
Je ne fais même pas
Ne participe qu'aux tours impairs et au dernier tour.
la source
Le bot oublieux ne sait pas combien d'argent il a, alors il met juste l'argent qui lui a été donné pour ce tour. S'il découvre qu'il a de l'argent à la fin, il le donne simplement à un organisme de bienfaisance.
la source
One Upper
Je ne sais pas grand chose sur Python, donc je pourrais faire une sorte d'erreur
offre 1 de plus que l'enchère gagnante précédente, ou fait tapis lors du dernier tour.
Je pourrai à l'avenir décider d'une stratégie différente pour quand
win_amount
est -1la source
Patient Bot
N'offre rien pour les cinq premiers tours, puis offre ~ 1000 dollars pour les quatre tours suivants, et finalement offre tout ce qu'il a au dernier tour.
la source
Copycat Or Sad
Troisième et dernier bot.
Ce bot offrira exactement le même montant que le gagnant précédent (y compris lui-même). Cependant, s'il n'a pas assez d'argent pour le faire, ce sera triste et il offrira un maigre billet de 1 dollar avec sa larme dessus. Dans le tour final, il fera tapis.
Je ne programme jamais en Python, donc si vous voyez des erreurs faites le moi savoir ..
la source
-1
sur la première vente aux enchères.Essai
J'ai édité un test précédent mis en place par Steadybox en ajoutant les dernières soumissions.
Je le poste ici, donc il y a un endroit où le lien peut être mis à jour avec des versions plus récentes, ce message est un wiki communautaire alors n'hésitez pas à le mettre à jour si vous postez une nouvelle soumission, modifiez une ancienne ou voyez simplement quelque chose nouveau d'une autre soumission!
Voici le lien vers le test! (TIO)
la source
Demi dedans
Ce bot offre toujours la moitié de ce qu'il lui reste, sauf au dernier tour où il fera tapis.
Je ne programme jamais en Python, donc si vous voyez des erreurs faites le moi savoir ..
la source
Graylist
Inspiré par la soumission de la liste noire par l'histocrate , ce bot garde en mémoire tous les paris gagnants précédents des autres joueurs, à la fois le rapport d'argent qu'ils ont parié par rapport à leur argent total et la différence entre leur montant de pari et le montant total. Afin d'éviter de perdre à égalité (ce qui est apparemment un facteur important dans cette compétition), il évite alors de parier n'importe quel nombre qui pourrait donner les mêmes résultats compte tenu des fonds actuels de ses adversaires.
EDIT: comme la valeur de départ de l'enchère utilise désormais le minimum entre: son argent actuel, 1 de plus que l'argent de l'adversaire le plus riche, X de plus que le dernier pari gagnant, ou Y de plus que l'argent moyen de ses adversaires. X et Y sont des constantes qui seront probablement modifiées avant la fin de la compétition.
la source
AverageMine
Ce joueur calcule le pourcentage (enchère / argent total) pour le vainqueur de chaque tour et offre son (argent total * pourcentage de gain moyen + 85) à moins qu'il ait plus d'argent que tous les autres joueurs, puis il offre 1 de plus que le plus haut concurrent . Commence par une enchère de 99,0% du montant de départ.
la source
Eenie Meanie Plus
Ce joueur est identique à Meanie, à l'exception d'une variable. Cette version enchérit de manière plus agressive et fait que certains joueurs dépensent plus que la moyenne ne le pense.
la source
Distributeur
Lorsque ce bot perd un tour, il répartit l'excédent d'argent entre tous les tours suivants. Il met 499 $ au premier tour en pensant que les autres seront à égalité avec 500 $ et seront éliminés.
la source
rounds
au lieu deself.rounds
provoquera des erreurs. Même chose avecmoney
.Meanie
Ce joueur prend l'argent total qui entrera en jeu pour obtenir l'enchère moyenne sur le nombre de joueurs et les tours restants. Si cet objectif est supérieur à ce que tous les autres joueurs détiennent actuellement, il réduit son enchère au solde de son plus grand concurrent plus un. Si le joueur ne peut pas se permettre sa cible, il est all-in.
la source
Battre le gagnant
Enchérissez 1 de plus que le joueur avec le plus de victoires jusqu'à présent
la source
m,w
dans le bon ordre?Moins un
la source
Enchérissez plus
Python toujours en apprentissage; enchérir un peu plus que le dernier gagnant.
la source
inc = 100
àinc = 101
.FiveFiveFive
Saute le premier tour et offre 555 $ pour les tours restants. Au dernier tour, tous les tapis seront allés à moins que 2 autres bots aient le même montant (et seront probablement à égalité).
la source
Presque tout en
Offre toujours un peu moins que ce qu'elle a.
la source
Escalade rapide
Offre des fractions croissantes de son argent à chaque tour (veuillez me faire savoir s'il y a des erreurs, un certain temps depuis que j'ai utilisé Python)
la source
Sous la moyenne
Similaire à la moyenne, mais va un peu plus bas
la source
HighHorse
Ce joueur offre tout son argent moins le numéro du tour en cours, sauf au dernier tour, où il fait tapis.
la source
Swapper
Alterne entre une enchère sous son maximum et une mise à tapis.
J'ai pensé que je devais trouver quelque chose qui pourrait battre le moins_one de Steadybox. :)
la source
Liste noire modulaire
Parie le montant le plus élevé possible qui n'est pas congru modulo 500 à tous les nombres qu'il a vu auparavant.
Modifié pour ne pas appliquer la liste noire lorsqu'il peut obtenir une victoire garantie.
la source
blacklist_mod
est cinquième au classement , alors qu'ilblacklist
est à la deuxième place. Si l'ancienne version deblacklist
est utilisée à la place,blacklist
tombe à la sixième place, maisblacklist_mod
prend la tête !blacklist
complet semble donnerblacklist_mod
une avance encore plus solide , mais ce n'est pas concluant.Heurist
L' Heurist traite ce jeu comme une probabilité répétable, il sait donc où tracer la ligne.
Il est également avare, il offre donc le strict minimum requis pour une victoire quand il le peut.
Avertissement:
max_bid
est sujet à changementla source
bob_hater
Ce bot n'aime pas Bob et va donc toujours miser 2 $ pour gagner contre Bob.
la source
Frimer
C'est ce gars qui montre sa capacité mathématique dans des situations qui ne nécessitent vraiment rien de si compliqué. Jusqu'au dernier round (dans lequel il fait tapis), il utilise un modèle logistique pour déterminer son offre, plus si ses ennemis ont une plus grande partie de leur argent restant.
La courbe logistique utilisée est f (x) = 1 / (1 + e -8 (x-0,5) ), où x est le rapport de l'argent ennemi actuel à l'argent ennemi potentiel total du round. Plus les autres en ont, plus il enchérit. Cela a l' avantage possible d'enchérir près de 500 $, mais pas tout à fait, au premier tour.
la source
AntiMaxer
Faites correspondre le montant le plus élevé que nous pouvons nous permettre avec l'argent de tous les joueurs. Cela fera en sorte que tous les bots tentent de faire tapis sur ce round.
la source
Bot simple
Presque la même chose que Patient Bot, mais pas en tant que patient. Obtient un score bien meilleur que lui, cependant.
la source
Wingman 2
Si un ailier est bon, deux doivent être meilleurs?
la source