Pilote d'essai • Discussion sur le défi • Soumettre un aventurier
Plusieurs aventuriers rivaux attaquent les ruines pour trouver des trésors, mais ils ne peuvent en transporter que beaucoup à la fois et ont leurs limites d'endurance. Ils veulent obtenir le trésor le plus précieux et sortir avant de devenir trop fatigués pour continuer. Ils essaient de devenir aussi riches que possible de leurs manigances de pillage.
Gameplay
Chaque aventurier commence dans la première salle du donjon avec 1000 points d'endurance et 50 kg d'espace dans son sac à dos.
Le jeu fonctionne au tour par tour, tous les joueurs résolvant leurs tours simultanément. À chaque tour, vous pouvez effectuer l'une des actions suivantes:
- Passez à la pièce suivante.
- Passez à la pièce précédente.
- Offrez de l'endurance pour prendre un trésor.
- Lâchez un trésor.
Se déplacer entre les pièces nécessite 10 points d'endurance, plus 1 pour chaque 5 kg actuellement dans votre sac à dos, arrondi. Par exemple, un aventurier portant 3 kg de trésors a besoin de 11 points d'endurance pour se déplacer et un porteur de 47 kg a besoin de 20 points d'endurance pour se déplacer.
Lâcher un trésor nécessite 1 endurance quel que soit le trésor lâché.
À la sortie des ruines, le joueur ne prendra plus de tours.
Si un joueur ne peut effectuer aucune de ces actions (en raison du manque d'endurance ou de l'absence de trésors), son aventurier meurt d'épuisement, déversant son trésor détenu dans la pièce actuellement occupée. De même, si un joueur tente de faire une action invalide, son aventurier sera tué par un piège à la place, entraînant le même déversement de trésors.
Enchère
L'enchère minimum pour un trésor est de 1 endurance par 1 kg que le trésor pèse. Vous pouvez également offrir des points d'endurance supplémentaires pour être plus susceptible d'obtenir le trésor. L'endurance qui a été mise est consommée quel que soit le résultat.
Dans le cas où plusieurs joueurs ont misé pour prendre le même trésor, le joueur qui a misé le plus haut obtient le trésor. Si plusieurs joueurs ont fait l'enchère la plus élevée, aucun d'eux ne recevra le trésor.
Condition de victoire
Le joueur avec la plus grande valeur totale de trésors est le gagnant. Dans le cas peu probable d'une égalité, les égalités vont au plus petit poids total, puis au plus petit nombre de trésors, puis à la valeur du trésor le plus précieux, au deuxième plus précieux, au troisième ... jusqu'à ce que l'égalité soit brisée. Dans le cas presque impossible où il y a encore égalité à ce stade, le pilote d'essai dit "vissez" et le vainqueur est ainsi déterminé arbitrairement.
Dans le cadre du tournoi, les joueurs seront classés avec la première place recevant 10 points, la deuxième place avec 9 points, la troisième place avec 8 points, etc ..., avec les joueurs morts et les aventuriers sans trésors marquant 0 point.
À propos des ruines
- Chaque pièce contient initialement entre ettrésors. (Oùest le numéro de la chambre)
- Il y a arbitrairement de nombreuses pièces, limitées uniquement par l'endurance des aventuriers et leur volonté d'explorer.
- Chaque trésor aura une valeur monétaire (en $) et un poids (en kg).
- Les trésors ont tendance à être plus précieux et abondants lorsque vous vous enfoncez plus profondément dans les ruines.
- Les formules spécifiques pour générer des trésors sont les suivantes: (en utilisant la notation pour les lancers de dés)
- Le poids est généré en premier en utilisant la formule (minimum 1)
- La valeur du trésor est alors générée via (où est le numéro de la pièce et est le poids)
Informations visibles pour les joueurs
À chaque tour, les joueurs obtiennent les informations suivantes:
- Le numéro de la pièce dans laquelle ils se trouvent actuellement. Il est indexé sur 1, donc conceptuellement, la sortie est à la "pièce 0"
- Une liste des trésors actuellement dans la salle
- Une liste d'autres joueurs qui sont également actuellement dans la salle.
- Votre inventaire actuel de trésors
- Votre niveau d'endurance actuel
Codage
Le pilote de test peut être trouvé ici .
Vous devez implémenter une sous-classe de cette Adventurer
classe:
class Adventurer:
def __init__(self, name, random):
self.name = name
self.random = random
def get_action(self, state):
raise NotImplementedError()
def enter_ruins(self):
pass
Il vous suffit de remplacer la get_action
méthode. enter_ruins
est exécuté avant le début d'un jeu et est votre chance de préparer tout ce que vous souhaitez préparer pour le jeu. Vous n'avez pas besoin de passer outre __init__
et vous ne devriez vraiment pas . En cas de __init__
plantage, vous serez disqualifié.
get_action
reçoit un seul argument qui est un namedtuple
avec les champs suivants (dans cet ordre, si vous préférez la déstructuration):
room
: le numéro de la pièce dans laquelle vous vous trouvez actuellementtreasures
: la liste des trésors de la salleplayers
: la liste des autres joueurs dans la salle. Vous n'obtenez que le nom du joueur de cette façon, donc vous ne savez pas quel bot les contrôle ou leur inventaire / endurance.inventory
: la liste des trésors dans votre sac à dosstamina
: votre niveau d'endurance actuel
Cet objet fournit en outre deux propriétés utilitaires:
carry_weight
: le poids total de tous les trésors que vous porteztotal_value
: la valeur totale de tous les trésors que vous portez
Les listes treasures
et inventory
contiennent des namedtuple
s avec ces attributs:
name
: le nom du trésor (à des fins esthétiques)value
: la valeur monétaire du trésor en $.weight
: le poids du trésor en kg
get_action
doit renvoyer l'une des valeurs / modèles suivants:
'next'
ou'previous'
pour passer aux salles suivantes / précédentes'take', <treasure index>, <bid>
(oui, en tant que tuple, bien que n'importe quelle séquence fonctionne également techniquement) pour miser sur le trésor à l'index donné dans la liste des trésors de la salle. Les deux arguments doivent être des entiers. Les flotteurs seront arrondis.'drop', <inventory index>
pour laisser tomber le trésor transporté trouvé à l'indice donné. L'index doit (naturellement) être un entier.
Autres restrictions
- Vous ne pouvez utiliser l'instance aléatoire qui vous a été fournie lors de l'initialisation pour pseudo-aléatoire.
- Tout ce qui pourrait introduire un non-déterminisme comportemental n'est pas autorisé. L'intention ici est de faire en sorte que les bots se comportent de manière identique lorsqu'ils reçoivent la même graine pour aider à tester de nouveaux bots (et potentiellement des bogues dans le pilote de test). Seul le rayonnement cosmique devrait provoquer une déviation / non-déterminisme.
- Gardez à l'esprit que les codes de hachage sont aléatoires en Python 3, donc l'utilisation
hash
pour toute prise de décision n'est pas autorisée.dict
les s sont corrects même lors de l'utilisation de l'ordre d'itération pour les décisions car l'ordre est garanti cohérent depuis Python 3.6.
- Vous ne pouvez pas contourner le pilote de test à l'aide de
ctypes
hacks ou deinspect
stack vaudou (ou toute autre méthode). Il y a des choses effrayantes que vous pouvez faire avec ces modules. S'il vous plait, ne le faites pas.- Chaque bot est raisonnablement bien mis en bac à sable via des copies défensives et l'immuabilité naturelle de
namedtuple
s, mais il y a des failles / exploits non détectables. - D'autres fonctionnalités de
inspect
etctypes
peuvent être utilisées tant qu'aucune n'est utilisée pour contourner la fonctionnalité du contrôleur. - Toute méthode pour récupérer des instances des autres robots dans votre jeu actuel n'est pas autorisée.
- Chaque bot est raisonnablement bien mis en bac à sable via des copies défensives et l'immuabilité naturelle de
- Les bots doivent fonctionner en solo et ne peuvent en aucun cas se coordonner avec d'autres bots à quelque fin que ce soit. Cela comprend la création de deux bots avec des objectifs différents tels que l'un se sacrifie pour le succès de l'autre. Une fois qu'il y a plus de 10 concurrents, vous ne serez pas réellement assuré d'avoir les deux bots dans le même jeu et les noms des aventuriers ne donnent aucune indication sur la classe de bot, donc ces types de stratégies sont de toute façon limités.
- Il n'y a actuellement aucune restriction stricte sur le temps d'exécution, mais je me réserve le droit de le limiter à l'avenir si les tournois commencent trop longtemps. Soyez raisonnable et essayez de garder le traitement des virages sous 100 ms , car je ne prévois pas avoir besoin de le limiter en dessous de ce seuil. (Les tournois se dérouleront dans environ 2 heures si tous les robots prennent environ 100 ms par tour.)
- Votre classe de bot doit être nommée de manière unique parmi toutes les soumissions.
- Vous ne vous souvenez peut-être de rien entre les jeux. (Cependant, vous pouvez vous souvenir des choses entre les tours )
- Ne modifiez pas sys.modules. Tout ce qui est en dehors des variables d'instance doit être traité comme une constante.
- Vous ne pouvez pas modifier le code d'un bot par programme, y compris le vôtre.
- Cela comprend la suppression et la restauration de votre code. C'est pour simplifier le débogage et les tournois.
- Tout code provoquant le plantage du contrôleur sera immédiatement disqualifié. Bien que la plupart des exceptions soient interceptées, certaines peuvent passer à travers et les erreurs de segmentation sont inaccessibles. (Oui, vous pouvez vous séparer en Python grâce à
ctypes
)
Soumissions
Afin de faciliter le grattage des réponses, indiquez le nom de votre bot en haut de la réponse par un #Header1
et assurez-vous que votre réponse comprend au moins un bloc de code (seul le premier de votre réponse sera utilisé). Vous n'avez pas besoin d'inclure d'importations ou de docstrings, car ils seront ajoutés automatiquement par le grattoir.
Je serai plus enclin à voter pour des réponses avec des explications détaillées et compréhensibles. D'autres se comporteront probablement de la même manière.
En gros, votre réponse doit être formatée comme ceci:
# Name of Bot
Optional blurb
#imports go here
class BotName(Adventurer):
#implementation
Explanation of bot algorithm, credits, etc...
(rendu comme)
Nom du Bot
Texte de présentation en option
#imports go here class BotName(Adventurer): #implementation
Explication de l'algorithme du bot, des crédits, etc ...
Exécution locale du pilote de test
Vous aurez besoin de Python 3.7+ et je vous recommande également d'installer tabulate
via pip. Le grattage de cette page pour les soumissions nécessite en outre lxml
et requests
. Vous devez également utiliser un terminal prenant en charge les sorties de couleur ANSI pour de meilleurs résultats. Des informations sur la façon de configurer cela dans Windows 10 peuvent être trouvées ici .
Ajoutez votre bot à un fichier dans un sous-répertoire du même répertoire que ruins.py
( ruins_bots
par défaut) et assurez-vous de l'ajouter from __main__ import Adventurer
en haut du module. Ceci est ajouté aux modules lorsque le scraper télécharge votre soumission, et bien qu'il soit définitivement hacky, c'est le moyen le plus simple de vous assurer que votre bot a correctement accès Adventurer
.
Tous les bots de ce répertoire seront chargés dynamiquement lors de l'exécution, donc aucune autre modification n'est nécessaire.
Tournoi
Le vainqueur final sera déterminé dans une série de jeux avec jusqu'à 10 bots dans chaque jeu. S'il y a plus de 10 soumissions au total, les 10 meilleurs bots seront déterminés en les partitionnant systématiquement en groupes de 10 jusqu'à ce que chaque bot ait joué (exactement) 20 parties. Les 10 meilleurs bots seront sélectionnés dans ce groupe avec des scores réinitialisés et joueront des jeux jusqu'à ce que le bot de première place ait atteint une avance de 50 points sur le bot de deuxième place ou jusqu'à ce que 500 jeux aient été joués.
Jusqu'à ce qu'il y ait au moins 10 soumissions, les emplacements vides seront remplis de "ivrognes" qui errent au hasard à travers les ruines et prennent (et parfois déposent) des trésors aléatoires jusqu'à ce qu'ils soient à court d'endurance et doivent se précipiter vers la sortie.
Les tournois seront renouvelés chaque semaine s'il y a de nouvelles soumissions. Il s'agit d'un défi ouvert KOTH sans date de fin définie.
Classement
À partir du 4 mai 2019 à 16 h 25 MDT: (2019-05-04 4:25 -6: 00)
Seed: K48XMESC
Bot Class | Score | Mean Score
--------------+---------+--------------
BountyHunter | 898 | 7.301
Scoundrel | 847 | 6.886
Accountant | 773 | 6.285
Ponderer | 730 | 5.935
Artyventurer | 707 | 5.748
PlanAhead | 698 | 5.675
Sprinter | 683 | 5.553
Accomodator | 661 | 5.374
Memorizer | 459 | 3.732
Backwards | 296 | 2.407
Mise à jour - 15 avril: quelques mises à jour / clarifications de règles
Mise à jour - 17 avril: interdiction de quelques cas marginaux notables d'actions néfastes telles que la modification du code d'autres bots.
Mise à jour - 4 mai: prime accordée à Sleafar pour avoir absolument détruit Backwards. Toutes nos félicitations!
pip
installé et activé PATH
(ce qui est par défaut pour les installations plus récentes AFAIK), vous pouvez exécuter pip install modulename
à partir de Windows dans l'invite de commande. Pour d'autres circonstances (que je ne connais pas), allez dans pip , recherchez le module nécessaire et choisissez une option.