Dans ce défi, vous devez concevoir une espèce d'organisme unicellulaire capable de lutter jusqu'à la mort dans le domaine des boîtes de Pétri. L’arène est représentée par une grille rectangulaire, où chaque cellule occupe un espace:
.....x....
...x...o..
...x.c..o.
.......o..
Les attributs
Chaque cellule a trois attributs. Lorsque vous spécifiez votre espèce de cellule au début du jeu, vous attribuez 12 points à ces attributs.
- Points de vie (HP): Si le HP d'une cellule tombe à zéro, il meurt. Les nouvelles cellules ont plein HP.
- Quand une cellule meurt, elle laisse derrière elle un cadavre qui peut être consommé par d’autres cellules pour l’énergie.
- Une cellule ne peut pas récupérer les HP perdus, mais elle peut créer une nouvelle cellule avec HP complet en se divisant.
- Energie : la plupart des actions qu'une cellule peut entreprendre nécessitent de l'énergie. En se reposant activement, une cellule peut récupérer l'énergie perdue jusqu'au maximum de son espèce.
- Une espèce cellulaire de moins de 5 énergies est susceptible d'échouer car elle ne peut pas se diviser pour créer de nouvelles cellules.
- Une cellule ne peut pas récupérer d'énergie au-delà de la valeur maximale de son espèce.
- Une cellule nouvellement créée a une valeur d'énergie initiale copiée à partir de son parent (et une valeur maximale dictée par ses spécifications d'espèce).
- Acidité : si une cellule choisit d'exploser, son niveau d'acidité est utilisé pour calculer les dommages subis par les cellules adjacentes.
actes
Chaque tour, chaque cellule peut effectuer une action:
Déplacement: la cellule se déplace d’un espace dans n’importe quelle direction (N / S / E / W / NE / NO / SE / SO) au coût d’une énergie.
- Une cellule ne peut pas se déplacer sur un espace occupé par une autre cellule vivante.
- Une cellule ne peut pas sortir de la grille.
- Déplacer sur un cadavre cellulaire détruit le cadavre.
Attaque: une cellule attaque une cellule adjacente et lui inflige 1 à 3 dégâts en dépensant 1 à 3 points d'énergie.
- Une cellule peut attaquer dans n'importe quelle direction (N / S / E / W / NE / NW / SE / SW).
- Il est légal d'attaquer les cellules amies.
Diviser: la cellule se divise et crée une nouvelle cellule sur un espace adjacent, au prix de 5 en énergie.
- Une cellule peut se diviser dans n'importe quelle direction (N / S / E / W / NE / NW / SE / SW).
- La nouvelle cellule dispose de toutes les capacités HP conformément à vos spécifications de cellule d'origine.
- La nouvelle cellule a autant d’énergie que sa cellule mère après soustraction du coût de division. (Par exemple, une cellule parent avec une valeur initiale de 8 points d’énergie sera réduite à 3 et produira une cellule enfant de 3).
- Une nouvelle cellule ne peut pas agir avant votre prochain tour.
- Une cellule ne peut pas se diviser en un espace occupé par une cellule vivante, mais peut se diviser en un espace occupé par un cadavre de cellule morte (ceci détruit le cadavre).
Manger: Une cellule mange un cadavre cellulaire adjacent et gagne 4 points d'énergie.
- Une cellule peut manger dans n'importe quelle direction (N / S / E / W / NE / NW / SE / SW).
Reste: une cellule ne fait rien pendant un tour, récupérant 2 énergies.
Exploser: lorsqu'une cellule a 3 HP ou moins et plus d'énergie que HP, elle peut choisir d'exploser et d'infliger des dégâts aux huit cellules adjacentes.
- Les dommages à chaque cellule adjacente est
(exploding cell HP) + (explodng cell acidity)
- Une cellule explosée meurt et laisse derrière elle un cadavre, comme toutes les cellules tuées lors de l'explosion.
- Les dommages à chaque cellule adjacente est
Protocole
Installer
Votre programme fonctionnera avec la chaîne BEGIN
fournie sur stdin. Votre programme doit écrire une liste stdout séparés par un espace de 3 entiers non négatifs, représentant HP, l' énergie et l' acidité pour vos espèces cellulaires: par exemple, 5 6 1
. Les chiffres doivent totaliser 12. L’acidité peut être0
si vous le souhaitez. (Les autres attributs peuvent aussi être nuls, mais ce faisant, le jeu est automatiquement perdu!)
Vous commencez avec une cellule, dans le coin nord-ouest ou sud-est, à un espace de chaque bord. La cellule de départ a plein de HP et d’énergie.
Chaque cellule agit
A chaque tour, votre programme sera invoqué une fois pour chaque cellule en vie de votre équipe (à l'exception des cellules que vous venez de créer ce tour) afin que cette cellule puisse agir. Votre programme contient des données sur stdin incluant l'état de la boîte de Pétri et des informations sur cette cellule:
10 4
..........
..xx.c....
...c...o..
......o...
6 3 5 7
Les deux premiers chiffres indiquent la largeur et la hauteur de l'arène: ici, il y a une arène de 10 sur 4.
- Les
o
cellules sont à vous; lesx
cellules sont vos ennemis. (Ceci est toujours vrai; chaque joueur voit toujours ses propres cellules commeo
.) - Les
.
espaces sont vides. - Les
c
espaces représentent des cadavres de cellules comestibles.
Les chiffres après la ligne vide représentent des informations sur cette cellule:
- Les deux premiers chiffres sont des
x,y
coordonnées, indexées0,0
en haut à gauche (on6 3
parle ici du plus au sud.o
cellule la ). - Le troisième nombre est le HP de la cellule; le quatrième nombre est l'énergie de la cellule.
Votre programme doit afficher (sur la sortie standard) une action. Dans les exemples ci-dessous, nous allons utiliser N
comme exemple une direction, mais il peut s'agir de n'importe quelle direction légale pour cette action ( N
/ S
/ E
/ W
/ NE
/ NW
/ SE
/ SW
). Tous les résultats du programme ne sont pas sensibles à la casse, mais les exemples utiliseront des majuscules. Toute action de sortie non valide (en raison d'une syntaxe non valide ou d'une tentative d'action illégale) est ignorée et entraîne la cellule REST
(et gagne donc 2 points d'énergie).
MOVE N
DIVIDE N
EAT N
ATTACK N 2
- le nombre représente la force de l'attaque (1 - 3)REST
EXPLODE
Le tour de votre équipe consiste à donner à toutes vos cellules l’occasion d’agir, une par une. Toutes vos cellules agissent avant les cellules de l'adversaire. Une fois que toutes vos cellules ont agi, votre tour se termine et le tour de votre adversaire commence. Une fois que toutes les cellules de votre adversaire ont agi, votre tour recommence. À votre tour, chaque cellule a la priorité d'agir en fonction de son âge: les cellules les plus anciennes de votre équipe agissent d'abord avant les cellules plus jeunes.
Exemple
Voici comment un programme pourrait se comporter. L'entrée de stdin est notée ici avec des >
flèches de tête (séparées de l'entrée réelle par un espace de clarification) et la sortie sur stdout a des <
flèches.
> BEGIN
< 5 6 1
Ensuite, le programme est à nouveau appelé:
> 10 4
> ..........
> .o........
> ........x.
> ..........
>
> 1 1 5 6
< DIVIDE SE
Après le tour de votre adversaire (qui a décidé d' DIVIDE W
utiliser la cellule de départ unique), votre programme est appelé deux fois, une fois pour chaque cellule:
> 10 4
> ..........
> .o........
> ..o....xx.
> ..........
>
> 1 1 5 1
< MOVE E
Pour la seconde invocation à votre tour:
> 10 4
> ..........
> ..o.......
> ..o....xx.
> ..........
>
> 2 2 5 1
< MOVE SE
Notez que cette deuxième cellule voit l'état du tableau mis à jour en fonction du mouvement de l'autre cellule plus tôt dans votre tour. Notez également que cette cellule a été créée avec 1 énergie, car la cellule mère avait 6 énergies lors de la dernière division (donc la 6 originale, moins le coût de la division en 5 énergies, a créé une cellule enfant avec 1 énergie).
Maintenant, votre tour est terminé et le tour de votre adversaire commence. Les deux cellules adverses auront une chance d'agir et votre prochain tour commence.
La victoire
Vous pouvez gagner soit:
- Détruire toutes les cellules opposées, ou
- Avoir plus de cellules que votre adversaire après que chaque joueur ait terminé 150 tours
La notation sera basée sur le nombre de victoires en 100 matchs contre chaque autre soumission. Dans la moitié des simulations, votre programme sera autorisé à commencer.
Les parties nulles (c'est-à-dire exactement le même nombre de cellules après 150 tours, ou les seules cellules restantes sont tuées ensemble lors d'une explosion) ne sont pas comptabilisées dans le total des gains des joueurs.
Les autres informations
- Votre programme ne doit pas essayer de maintenir l’état (au-delà de l’utilisation de l’état de la boîte de Petri): les organismes monocellulaires n’ont pas une très bonne mémoire et réagissent au monde entier instant après instant. En particulier, l'écriture dans un fichier (ou un autre magasin de données), la communication avec un serveur distant ou la définition de variables d'environnement sont explicitement interdites.
- Les soumissions seront exécutées / compilées sur Ubuntu 12.04.4.
- Les spécificités des 100 matchs marqués ne sont pas encore confirmées, mais elles impliqueront probablement plusieurs tailles d'arène (par exemple, 50 courses sur une petite arène et 50 courses sur une plus grande arène). Pour une arène plus grande, je peux augmenter le nombre de tours maximum pour m'assurer qu'une bataille appropriée peut avoir lieu.
Ressources
Voici le code de pilote qui exécute la simulation, écrit pour Node.js, appelé par node petri.js 'first program' 'second program'
. Par exemple, l’opposition d’une cellule écrite en Python à une cellule écrite en Java peut ressembler ànode petri.js 'python some_cell.py' 'java SomeCellClass'
.
De plus, je comprends que la lecture et l’analyse de plusieurs lignes sur stdin peuvent être très pénibles. C’est pourquoi j’ai rédigé quelques exemples de cellules complètes dans différentes langues que vous êtes libre de construire, de réviser complètement ou d’ignorer complètement.
- Cellule Java
- Cellule python
- Cellule JavaScript (à utiliser avec Node.js)
Bien sûr, vous êtes libre d’écrire une cellule dans une autre langue; Ce sont simplement trois langues pour lesquelles j'ai décidé d'écrire du code standard afin de gagner du temps.
Si vous rencontrez des problèmes pour exécuter le pilote, n'hésitez pas à m'envoyer une requête dans la salle de discussion que j'ai créée pour ce défi . Si votre réputation n'est pas suffisante pour le chat, laissez simplement un commentaire.
la source
'node c:/cell/cell_template.js'
pour chaque argument, exactement comme'java CellTemplate'
pour le code Java. Je le préciserai plus clairement dans le texte du défi. Si vous rencontrez toujours des problèmes, nous (et toute autre personne ayant des problèmes techniques) pouvons poursuivre la discussion sur un forum de discussion que je viens de créer .Réponses:
Voici mon bot relativement simple, que j'ai programmé en Ruby. Fondamentalement, il donne la priorité à la division en premier et tente de se diviser en deux pour obtenir le contrôle du terrain. Sa deuxième priorité est de manger, et la troisième est d'attaquer. Il bat facilement la cellule échantillon Python.
la source
$
.$
est utilisé pour indiquer une variable globale. Oui, ils sont diaboliques, mais dans ce petit programme, cela n’a aucune importance.Amibe
D'abord, il se divise en quatre, puis tente de se rendre au milieu pour limiter l'espace de réplication de l'adversaire. Puis commence à reproduire. Lors du déplacement ou de la réplication, trouve le chemin optimal vers l'ennemi le plus proche et se déplace ou se divise vers lui pour tenter de supprimer l'espace disponible de l'ennemi.
Si un ennemi est adjacent ou à une case de distance, il attaquera ou se dirigera toujours vers lui, permettant ainsi à la rangée derrière de ne rien faire pour combler les espaces vides.
Je n'ai pas testé cela par rapport à d'autres propositions, je n'ai donc aucune idée de la qualité de ses résultats.
la source
Cellule simple réalisée en
node.js
. Testé contre des exemples de cellule de noeud et contre Kostronor, il les bat.Mise à jour
Toujours assez simple, essayez de vous rapprocher de l’ennemi ou de vous diviser.
la source
Évolution
Cette soumission a évolué et n'est plus un simple organisme à cellules singe! Il essaie d'attaquer / d'exploser autant que possible, sinon il se divise ou se dirige vers l'ennemi. Bouger devrait résoudre le problème d’une cellule entourée de cellules amies avec une énergie maximale, incapable de faire quelque chose d’utile.
Après avoir bougé, il reste toujours 3 points d'énergie pour frapper l'ennemi le plus fort possible.
la source
Berserker
Parce que j'ai utilisé Clojure, qui a quelques limitations, principalement le temps de démarrage énorme, j'ai pris un peu de vie. Quand le programme est donné,
BEGIN
il sort4 6 2 LOOP
, indiquant qu'il ne s'arrête pas. Ensuite, il prend les entrées comme un flux continu et se termine parEND
. Cela ne sauvegarde aucun état, ce qui est clairement indiqué en n'utilisant aucune variable globale ou en réutilisant les valeurs de retour. Comme l'implémentation de cette action en boucle n'a pas encore été effectuée, je n'ai pas pu tester complètement le code (j'espère que le code est suffisamment clair).La cellule tire son nom de sa nature à exploser chaque fois que possible (et donc à avoir de l'acidité) et à donner la priorité à l'attaque juste après la division.
J'ai téléchargé le fichier JAR généré sur ma Dropbox . Courir avec
java -jar petridish-clojure.jar
Juste pour clarifier:
Journal de mise à jour
la source
Bot affamé
Voici une entrée dans R. J'espère avoir bien compris quelles étaient les spécifications techniques sur la façon de communiquer avec votre programme. Devrait être déclenché avec
Rscript Hungryhungrybot.R
.S'il a au moins 6 d'énergie, il se divise, de préférence dans la direction de l'ennemi. Sinon, il mange ce qui se trouve à côté ou ce qui est accessible. Si aucune nourriture n'est joignable, elle explosera s'il y aura plus d'ennemis que de cellules sœurs ou se battra avec des ennemis proches. Ne repose que si l’énergie est égale à 0 et que rien n’est disponible pour manger.
la source
Error: unexpected 'else' in "else"
dans votre code. J'ai bien peur de ne pas connaître R du tout, alors je ne peux pas commencer à résoudre cette erreur. Pour référence, je reçois cette erreur à la fois lorsque je l'exécute dans le pilote et lorsque je lance simplement le programme et que je tape manuellementBEGIN
.Error in if (dir[1] < 0) where <- paste(where, "N", sep = "") : missing value where TRUE/FALSE needed
Error: object 'food' not found
(face à la soumission d'Alex par Ruby, éventuellement d'autres)Bactéries coordonnées
J'espère que je ne suis pas trop en retard.
Gagnez contre d'autres adversaires (et toujours en les tuant tous), dans mes tests, et la bataille ne se terminera jamais si elle se fait face, preuve que la stratégie est forte.
Lorsque vous êtes unicellulaire, vous pouvez mémoriser l'état précédent, mais vous pouvez exploiter votre propre position pour se comporter différemment! =)
Ceci divisera les bactéries en diviseur et en moteur, et ainsi, gardera plus de bactéries utiles au lieu de se limiter à la ligne de front, tout en maintenant la position de défense.
Il coordonne également ses attaques pour se concentrer sur un ennemi spécifique, afin que les ennemis soient tués plus rapidement (c'est pour faire face à mon autre cellule unique qui se concentre sur HP).
En milieu de partie, ce qui est détecté par le nombre de cellules sur le plateau, ils tenteront de pénétrer dans le territoire ennemi en les contournant. C'est la stratégie gagnante clé.
Cela a le taux de croissance le plus élevé comparé à tous les autres adversaires actuellement, mais il a un départ lent, donc cela fonctionne mieux sur une grande arène.
Le courir avec
java CoordinatedBacteria
la source
Je pense que je vais poster ma soumission, car vous êtes si généreux d'ajouter la logique standard ...
Il y avait un problème dans votre logique, où l'action manger émettrait une ATTACK au lieu d'un EAT et gaspillerait le cadavre.
J'ai tout aussi bien modifié votre idée de base pour avoir une solution efficace, qui devrait fonctionner relativement bien. Il commence avec 4 ch et 8 énergies, donc après une scission et un repos, les deux cellules peuvent se scinder à nouveau. Il essaiera de se multiplier, d’attaquer les ennemis, de manger des cadavres et de se reposer, dans cet ordre. Ainsi, les cellules internes stockent leurs 8 points d’énergie, pour remplacer rapidement les cellules externes tuées et leur laisser 3 points d’énergie pour effectuer une attaque de 3 points ou se multiplier après un tour de repos. Les 4 ch doivent survivre à au moins une attaque en force.
L'acide semble être une perte de points pour moi alors je l'ai gardé dehors ...
Je n'ai pas testé la soumission, car c'était une chose de 2 minutes;)
voici mon code:
la source
Bombardier finement répandu
Puisque vous avez si gentiment fourni le code standard, j'ai décidé de créer ma propre cellule simple; Cette cellule a 4 acidité, seulement 1 cv et 7 énergie. Il essaie de sortir des alliances et attend ensuite (ou mange si possible) jusqu'à ce qu'il ait la chance de sauter ou de se reproduire. Attaque seulement si c'est la seule option.
C’est une stratégie plutôt délicate qui donnera probablement de mauvais résultats, mais je suis curieux de voir comment. Je vais le tester et l'améliorer plus tard aujourd'hui, peut-être.
la source
node c:/cells/petri.js 'node c:/cells/bomber.js' 'node c:/cells/sample.js
. Lorsque je tape ceci dans la console d'application du nœud, je ne reçois que trois points. Lorsque j'essaie de l'exécuter dans la commande cmd de Windows, je reçois: 'nœud' n'est pas reconnu en tant que commande interne ou externe, programme utilisable ou fichier de commandes. J'ai enregistré tous les fichiers au format .js dans le bon dossier. Toute aide pour un noob? J'irais au chat ou commenterais ailleurs, mais mon représentant est trop bas.if((nearbyEnemies.length - nearbyFriendlies.length > 1 ¦¦
- ceux¦¦
-ci ne semblent pas être un opérateur valide et vous avez des parenthèses incohérentes. Je pense que le formatage du code a peut-être été gâché lorsque vous l'avez posté?=
) lorsque vous voulez une comparaison d’égalité (==
).