Castlevania Bot

Qu'est ce que c'est


CastlevaniaBot est un plugin pour l'émulateur NES Nintaco qui joue dans Castlevania. Si vous l'exécutez sur l'écran de démarrage, le plugin parcourra tout le jeu du début à la fin. Ou vous pouvez l'exécuter n'importe où dans le jeu afin qu'il passe par une partie de celui-ci.


Dans cet article, je vais vous expliquer comment créer un bot capable de passer Castlevania et comment créer quelque chose de similaire pour n'importe quel jeu sur NES.



Structure basée sur les connaissances


Ce projet n'a pas utilisé d'apprentissage automatique. Le développement peut plutôt être appelé «apprentissage automatique». Je sais passer Castlevania. La difficulté était d'écrire mes connaissances dans un programme informatique. Le résultat a été un système qui simule le même processus de prise de décision que j'effectue avec le contrôleur entre mes mains. Pour le créer, il était nécessaire d'énoncer clairement les détails détaillés de la physique qui contrôle le monde de bits de Simon Belmont, et toutes les tactiques nécessaires à un chasseur de vampires expérimenté.

CastlevaniaBot a accès à un ensemble de stratégies pour faire face à un large éventail de situations. La plupart d'entre eux sont conçus pour fonctionner avec un type spécifique d'objets de jeu. Par exemple, il existe une stratégie de contrôle du squelette, une autre pour les poissons, pour briser les bougies, pour rassembler les cœurs, etc.

CastlevaniaBot surveille en permanence l'état du jeu et, si nécessaire, bascule entre différentes stratégies. Dans le processus de prise de décision, la fonction fitness est utilisée, classant tous les objets du jeu à l'écran. En haut de la liste se trouve l'objectif principal, et lorsqu'il change, le bot change de stratégie. Par exemple, CastlevaniaBot pourrait se préparer à frapper les bougies lorsqu'une chauve-souris vole dans le cadre. Selon la distance par rapport à la chauve-souris, CastlevaniaBot peut réagir en passant d'une stratégie de bougie à une stratégie de chauve-souris. Détruisant la chauve-souris, il continuera de travailler avec des bougies.

Avant de décider de passer, CastlevaniaBot passe en revue son objectif et sa stratégie actuels. S'il ne réussit pas, il peut être coincé dans un cycle sans fin, alternant entre deux buts avec une priorité égale ou presque égale. Pour éviter cela, lorsqu'un nouvel objectif principal apparaît, qui n'est que légèrement plus élevé en priorité de l'objectif actuel, CastlevaniaBot peut décider de poursuivre la stratégie actuelle.

Certaines stratégies sont lancées automatiquement lorsqu'elles tombent dans une certaine zone. Habituellement, ils sont destinés au traitement simultané de plusieurs objets de jeu. Par exemple, dans un couloir avec un tas de têtes de méduses volantes, il est préférable d'aller de l'avant et de ne pas viser chaque tête individuellement.

Certaines stratégies peuvent varier en fonction de l'arme secondaire actuelle et du nombre de cœurs collectés, notamment dans les combats de boss. CastlevaniaBot essaie de prendre la meilleure décision en fonction des outils dont il dispose et de la situation actuelle.



Planifier un monde 8 bits


Lorsque je travaille sur de tels projets, je cherche principalement à simplifier la tâche. J'ai imaginé à quoi ressemblerait Castlevania s'il n'y avait pas d'ennemis, de bougies ou d'objets à collecter sur les niveaux. Dans ce cas, il suffirait simplement de passer du début à la fin du niveau. Je me suis demandé - si je peux apprendre au bot comment faire cela, à quel point sera-t-il difficile de détruire plusieurs ennemis en cours de route?

Pour apprendre au bot à se déplacer, j'avais besoin de cartes d'arrière-plan et de comprendre comment les niveaux sont organisés. Le jeu se compose de six niveaux, chacun se terminant par un boss.


Chaque niveau est divisé en 3 ou 4 étapes. Les scènes sont généralement séparées par des portes en bois qui s'ouvrent avec un grincement et claquent derrière le dos du joueur.


Les portes sont des points de contrôle (points de contrôle). Si un joueur est tué, il retourne au début de l'étape, mais seulement s'il n'a pas mis fin à sa vie. Si vous continuez le jeu après la fin de la partie, le joueur est renvoyé au tout début du niveau.

Le numéro de l'étape indique le nombre total de points de contrôle terminés depuis le début de la partie. La dernière étape est le numéro 18. Mais si vous tuez Dracula, le jeu commence dès le début en mode difficile, et le nombre d'étapes continue d'augmenter jusqu'à 19 et au-delà. Si vous passez par le mode difficile, le troisième cycle du jeu ne devient pas plus difficile, mais le nombre d'étapes continue d'augmenter.


Chaque étape consiste en une ou plusieurs barres de défilement horizontales de l'arrière-plan, que j'appelle des «sous-étapes». Si vous quittez l'écran le long des escaliers menant vers le haut ou vers le bas, le jeu passe d'une sous-étape à l'autre et ne défile pas verticalement.


Le jeu utilise 3 octets pour suivre le numéro de cycle de jeu, le numéro d'étape et le numéro de sous-étape. Le cycle de jeu en mode normal (mode normal) a une valeur de 0; les valeurs de 1 et plus indiquent le mode difficile. Quel que soit le cycle de jeu, les étapes ont toujours une numérotation de 0 à 18. Et les sous-étapes ont toujours une valeur de 0 ou 1, car les étapes ne contiennent jamais plus de 2 bandes horizontales. CastlevaniaBot suit ces octets pour savoir où il se trouve.

Pour ma commodité, j'ai enregistré la bande de fond de chaque sous-étape dans un fichier graphique distinct. Si j'avais besoin de trouver les coordonnées exactes d'un objet, je pourrais les trouver rapidement à l'aide d'un éditeur graphique. J'ai enregistré les fichiers à l'aide de l'outil Map Maker intégré à Nintaco. Je l'ai allumé puis j'ai parcouru tout le match. Certaines des images résultantes contenaient plusieurs sous-étapes reliées entre elles, qui étaient faciles à séparer.

Cartographe de Nintaco

Après avoir examiné les images d'arrière-plan, j'ai réalisé que les seules tuiles importantes sont les plates-formes et les escaliers. Tout le reste peut être considéré comme un espace vide. Les escaliers sont de deux types: menant vers l'avant ou vers l'arrière (ils peuvent être représentés comme les bords gauche et droit d'un triangle isocèle). Parfois, les escaliers se terminent par une plate-forme sur laquelle le joueur peut marcher.


Il n'y a que 5 types de tuiles importantes, et à chaque niveau, elles ont une apparence différente. Je les ai copiés et collés dans des fichiers image 16 × 16 séparés. Ensuite, j'ai écrit un programme comparant chaque tuile dans chaque sous-étape avec l'ensemble d'images correspondant. J'ai donc obtenu les types de matrice de tuiles pour toutes les sous-étapes.

Les matrices pourraient être extraites directement de la ROM, mais je n'ai pas pu trouver la documentation sur comment et où les données sont stockées. L'espace ROM étant limité, les données de niveau sont généralement présentées sous une forme compressée ressemblant à un format graphique vectoriel. Chaque jeu utilise son propre format, je n'ai donc pas jugé nécessaire de mener des recherches, car j'avais Map Maker. De plus, j'avais toujours besoin d'images graphiques des sous-étapes. Si je n'avais pas capturé les bandes d'arrière-plans, alors je devrais écrire un programme qui génère des images à partir de matrices.



Recherche de chemin


Après avoir créé les matrices, j'ai voulu appliquer l'algorithme de recherche de chemin, à savoir l'algorithme Floyd-Warshall , qui donne le tableau de sortie contenant les chemins les plus courts entre chacune des paires de sommets du graphique dirigé avec des bords pondérés. L'idée était de pré-calculer les tables et de les écrire dans des fichiers, puis de les charger pendant le jeu. Ayant des tables en mémoire, le bot peut rechercher et trouver instantanément le chemin le plus court entre deux tuiles de plateforme.

Le graphique se compose d'arêtes et de sommets. Si les tuiles de plate-forme sont des sommets, les arêtes ne sont que les opérations que Simon peut effectuer pour passer d'une plate-forme à une autre. Les opérations effectuées dans une seule tuile sont interdites. Par exemple, dans un plan à partir de tuiles, Simon ne peut déplacer qu'une seule tuile vers la gauche ou une seule tuile vers la droite.


De même, si Simon est dans les escaliers, il peut déplacer une tuile dans l'une des deux directions possibles.


Ce sont des opérations valides. Mais des actions telles que le déplacement du point central de la tuile au bord de la tuile sont trop fractionnaires, car elles ne correspondent pas à la transition d'un sommet du graphique à un autre.

En plus de marcher à gauche et à droite, de descendre et de monter des escaliers, Simon peut sauter sur une autre tuile. Et il peut sauter à gauche ou à droite, à partir de n'importe lequel des 16 pixels de la surface de la tuile. Pour réduire le nombre d'arêtes dans le graphique (et la taille de la table de recherche), je n'ai considéré que cinq points de répulsion possibles:


En ajoutant l'opération "ne rien faire", j'ai eu 15 opérations. Tous sont assez simples pour que le bot puisse facilement déterminer la séquence d'appuis sur les boutons nécessaires à leur exécution pendant l'exécution du jeu.

Pour construire un graphe complet, j'ai créé une simulation très simple de la physique du monde de Simon. Dans cette simulation, les 15 opérations sont effectuées à partir de chaque tuile de plate-forme. Le graphique est construit en observant simplement où se trouve Simon. Plus précisément, lors de la spécification des coordonnées initiales et du fonctionnement, la simulation donne les coordonnées finales en sortie. S'il n'y a pas de coordonnées finales, par exemple, lorsque Simon essaie de pénétrer dans un mur ou dans un trou, le programme retourne que l'opération n'est pas valide et ce bord ne fait pas partie du graphique.

Pour créer cette simulation, une étude approfondie de Simon Belmont était nécessaire. Contrairement aux autres plateformes classiques, où le joueur peut passer de la marche à la course, Simon, lorsqu'il se déplace horizontalement, se déplace toujours exactement de 1 pixel par image. Cela est vrai pour marcher, sauter, monter des escaliers, et même lors du recul lorsque vous attaquez des ennemis.

La limitation de la vitesse horizontale simplifie considérablement la reconnaissance des barrières. Le jeu vérifie s'il y a un mur à un pixel devant le personnage, et si nécessaire arrête le mouvement. Le contrôle est effectué en dessous du niveau de la tête, ce qui permet à la tête de passer sous des plafonds bas sans interférence avec le mouvement horizontal.

Le mouvement vertical est un peu plus compliqué. Si Simon sort du bord de la plateforme, au lieu d'une accélération progressive, il tombe instantanément à une vitesse de 8 pixels par image. Étant donné que chaque tuile a une hauteur de 16 pixels (ce qui est un multiple de 8), la reconnaissance du sol est simplifiée. Dans le même temps, le joueur maintient une vitesse horizontale de 1 pixel par image dans la direction obtenue immédiatement avant la chute.

Le sprite de Simon a une largeur de 16 pixels, et pourtant il peut survoler le bloc par un maximum de ± 4 pixels à partir de son milieu. Si vous bougez un peu plus, il tombera en dessous.


Il est intéressant de noter que s'il quitte la plate-forme et tombe exactement 1 tuile à une vitesse de 1 horizontal et 8 pixels verticaux par image, alors il ne se tiendra pas exactement sur le bloc à l'atterrissage. L'une de ses jambes restera à l'intérieur du mur jusqu'à une profondeur de 2 pixels.


Après cela, il pourra sortir du mur, mais pas y entrer.

Simon ne peut pas changer de direction pendant le saut. Après avoir appuyé sur le bouton A, il fait un chemin fixe le long de la parabole.


Au sommet, Simon monte de 36 pixels, ce qui lui permet de sauter sur les plateformes à 2 tuiles de haut. Et le sommet de la "parabole" est étonnamment plat. Il semble qu'il gèle dans l'espace pour 9 images complètes, peut-être afin de simplifier les coups de fouet dans l'air. Si Simon n'a rien sur quoi atterrir, le mouvement de parabole continue jusqu'à ce qu'il revienne à sa hauteur d'origine. Après cela, il commence à tomber à une vitesse de 8 pixels par image, c'est-à-dire avec la même vitesse constante de chute de la plate-forme.

Lorsqu'il y a une plateforme directement au-dessus de la tête du personnage, le saut n'est pas autorisé.


Sinon, il «saute» partiellement dans les tuiles de la plate-forme.


Comme indiqué précédemment, si Simon touche plus que le haut de sa tête, il cesse de se déplacer horizontalement. C'est assez ennuyeux à la fin de la première étape du niveau 4, lorsque le joueur essaie de sortir de la grotte.


Les escaliers vous permettent de vous déplacer librement verticalement entre les plates-formes.


Dans un cas, Simon monte les escaliers en passant par la tuile de la plate-forme. Étant dans les escaliers, il peut passer librement à travers le mur.


Sur les plates-formes mobiles de niveau 4, le joueur est généralement accroupi sous des stalactites basses. Cependant, vous pouvez vous lever et vous reposer contre eux. Dans une telle situation, le jeu restreint les mouvements horizontaux, entraînant rapidement Simon dans un piège à eau.


Un simulateur physique qui génère des graphiques orientés considère Simon comme un rectangle. Le mouvement de ce rectangle est limité par les règles de mouvement décrites ci-dessus. Pour que le bot ne saute pas d'un endroit à l'autre comme un lapin, les bords des sauts du comte ont été affectés à un coût plus élevé que les bords de la marche et du déplacement le long des escaliers.

Le tableau généré par l'algorithme de recherche de chemin contient la distance la plus courte pour chaque tuile de début et de fin (coût total du chemin) et une description de la première étape du chemin. Cette description comprend la première opération qui doit être effectuée sur ce chemin, et la tuile sur laquelle le personnage se trouvera une fois terminée. Le chemin entier peut être recréé par des recherches répétées dans le tableau, chacune donnant l'étape suivante dans la direction de la tuile finale.

Dans certaines sous-étapes, les colonnes ne sont pas entièrement connectées. Par exemple, au niveau 4, les plateformes sont le seul moyen de traverser l'abîme. Dans ces sous-étapes, le tableau contient des méthodes pour se déplacer dans chacune des îles, mais pas entre elles.


Certains blocs destructibles contiennent des objets cachés. Et la destruction des blocs change ce graphique. Pour contourner ce problème, un algorithme de recherche de chemins avec et sans blocs fractionnés a été appliqué aux sous-étapes. Au moment de l'exécution, CastlevaniaBot surveille les états des blocs à diviser et utilise la table de recherche appropriée.




État du jeu


CastlevaniaBot s'intègre à Nintaco via son API . Il enregistre l'implémentation de FrameListener pour recevoir un retour dans chaque trame. Étant donné que l'émulateur fonctionne à environ 60 images par seconde, cet écouteur doit être renvoyé à temps; de longs calculs ou des temps d'arrêt ralentiront ou bloqueront l'émulateur. Dans un court laps de temps, CastlevaniaBot lit l'état du jeu, détermine son objectif principal, change de stratégie si l'objectif a changé et remplit la stratégie actuelle.

CastlevaniaBot lit l'état actuel de Simon Belmont directement à partir de la RAM du processeur. Mais je ne peux pas déterminer comment les autres objets du jeu sont représentés en mémoire. Par conséquent, CastlevaniaBot lit directement à partir de la mémoire des attributs des objets (Object Attribute Memory, OAM) - une zone qui stocke une liste des sprites affichés.


Cette technique fonctionne et est généralement applicable à d'autres jeux, mais présente de nombreux inconvénients. L'ordre des sprites dans OAM est en constante évolution. S'il y a plusieurs instances du même type d'ennemi sur l'écran en même temps, alors la seule façon de les suivre est de déterminer leur proximité, de comparer les dernières coordonnées du sprite avec les coordonnées de l'image précédente.


Certains objets de jeu consistent en des sprites répétitifs, tels que des tours en os.


Les plates-formes mobiles se composent d'un sprite se répétant 4 fois.


Le tri de ces deux cas nécessite une logique supplémentaire, facile à mettre en œuvre. Les améliorations d'armes secondaires et certains types d'armes secondaires utilisent eux-mêmes les mêmes sprites. Pire, au niveau 5, les Chevaliers empruntent les sprites d'armes secondaires de Simon.


Heureusement, à l'exception de l'eau bénite, CastlevaniaBot n'utilise que des armes secondaires où les améliorations ne sont généralement pas disponibles, comme dans les combats de boss. Et le sprite de mise à niveau de l'eau bénite est différent du sprite utilisé lors de son lancement.


Certains objets de jeu clignotent lors de la création, par exemple, des boules de cristal à la fin des combats de boss, des tresses de mort et le corps de Dracula. Les sprites clignotants apparaissent et disparaissent de OAM, donc une logique supplémentaire est nécessaire pour suivre ces objets.


Il convient également de noter qu'en raison des limitations matérielles, NES ne peut afficher que 8 images-objets par ligne raster. Étant donné que la priorité des sprites dépend en partie de leurs indices dans OAM, l'ordre dans chaque image est mélangé de manière aléatoire pour éviter un décalage qui rend un sprite invisible en permanence. Plusieurs sprites clignotent à leur tour, changeant progressivement leur priorité. Ce clignotement n'affecte pas la lecture des sprites d'OAM. Les données restent là, mais le matériel émulé ne les affiche pas. Cela diffère de la situation décrite ci-dessus avec un clignotement lors de la création de sprites. De plus, Nintaco dispose d'une option qui réduit considérablement le clignotement du matériel.


Et enfin, une petite partie de l'état du jeu est lue à partir des tables de noms PPU - une zone de mémoire contenant toutes les données d'arrière-plan. Cela comprend la vérification des blocs destructibles et le suivi des positions de «l'écrasement» au niveau 2.




Machines à états heuristiques


Les stratégies sont des machines à états. CastlevaniaBot les définit comme une classe abstraite avec des méthodes init et step . La méthode init est appelée lorsque CastlevaniaBot passe à la stratégie appropriée, permettant à la machine d'état de se réinitialiser. Et la méthode step exécute la stratégie. Par exemple, la méthode de stratégie par step pour les poissons vérifie si un poisson est à portée d'un fouet, et si c'est le cas, le bot frappe avec un fouet. Sinon, il vérifie s'il est possible d'atteindre la distance de frappe par un saut, et si c'est le cas, le bot saute. Et enfin, si le bot est trop proche de l'ennemi, il s'en éloigne. Avec ces règles simples, CastlevaniaBot bat le poisson humain.

Pour simplifier au maximum les stratégies d'écriture, j'ai créé une bibliothèque d'actions possibles à réaliser. Par exemple, au lieu d'appuyer et de relâcher le bouton A pour sauter, le bot appelle simplement la méthode de saut depuis la bibliothèque. Et avant cela, il demande à la bibliothèque si Simon est sur la plate-forme et peut sauter.

L'approche et l'éloignement de la cible sont des actions standard effectuées à l'aide des opérations de la table créée par l'algorithme de recherche de chemin. Par exemple, la stratégie de bougie utilise la méthode de bibliothèque routeAndFace , qui non seulement dirige Simon vers certaines coordonnées spécifiées, mais la fait également pivoter vers la gauche ou la droite après les avoir frappées. De plus, selon la hauteur des bougies, la stratégie effectue un saut ou un squat avant de frapper un fouet. Un objet qui est tombé des bougies sera créé dans l'air et tombera ou tombera lentement au sol. Une stratégie de ramassage dirige Simon vers la tuile la plus proche juste en dessous de lui avant que l'objet ne touche le sol.

Pour s'éloigner des ennemis, la bibliothèque doit savoir comment se déplacer à gauche ou à droite sans tomber dans les stands. En général, cela est accompli en recherchant des chemins vers les bords gauche ou droit du sous-étage. Mais dans certaines régions, le chemin le plus court vers le bord gauche nécessite initialement de se déplacer vers la droite, et vice versa. Lorsque de tels problèmes sont apparus, j'ai ajouté une logique spécifiquement pour les sous-étapes, en dirigeant Simon vers les bords gauche et droit de la plate-forme actuelle.



Procédure pas à pas


Dans cette section, je décrirai en détail les stratégies utilisées par CastlevaniaBot, en commentant la procédure pas à pas.

Le jeu commence dans la cour devant le château. Les objets dans le cadre sont disposés pour sélectionner la cible principale, qui dans ce cas est une colonne avec une flamme. La stratégie de colonne indique au bot d'approcher la colonne et d'utiliser le fouet lorsqu'il est à portée de main.


Après avoir frappé le fouet et détruit la colonne, un élément est créé. La priorité de tous les articles est supérieure à celle des colonnes de flammes. Par conséquent, CastlevaniaBot réagit à cela en utilisant une stratégie pour collecter l'élément qui apparaît avant de passer aux colonnes suivantes.

Lors du classement des objets, CastlevaniaBot prend toujours en compte un objectif à long terme: terminer un niveau avant la fin du temps imparti. Lors de la création d'une liste d'objectifs potentiels, une porte vers le niveau suivant y est toujours ajoutée. La porte se voit attribuer une faible priorité, mais après la destruction de toutes les colonnes et la collecte de tous les objets, elle devient une priorité. À une seule exception près: CastlevaniaBot sait découvrir tous les trésors cachés et saute par-dessus l'entrée du château pour créer un sac d'argent clignotant.


Après être entré dans le château, CastlevaniaBot voit des fantômes et des bougies. Les bougies et les objets fabriqués ont priorité jusqu'à ce que les fantômes se rapprochent.


Il semble souvent que le fouet détruit les ennemis sans les toucher. J'ai trouvé une table de rectangle de collision dans la ROM du jeu, donc CastlevaniaBot sait exactement quand quelque chose est à portée de fouet. Et comme les rectangles de collision dépassent souvent légèrement au-delà des limites des sprites, le fouet peut frapper la «partie invisible».

Dans la plupart des cas, lors de la destruction de bougies, CastlevaniaBot saute verticalement, plutôt que vers l'avant. Il s'agit d'une tactique d'évitement des risques. Étant donné qu'il est en l'air, il est impossible de changer la direction du mouvement, une foule d'ennemis en approche peut compliquer un atterrissage en toute sécurité ou le rendre impossible. De plus, avec un saut vertical, CastlevaniaBot reste sur le même bloc; il n'a pas besoin de vérifier si le saut entraînera une chute sur la plate-forme inférieure ou au fond de la fosse.

Lorsqu'il n'y a pas de bougies à détruire ou d'objets à collecter, CastlevaniaBot commence à chasser les fantômes. Mais la «stratégie Panther» lui ordonne de rester immobile, en attendant que l'ennemi tombe dans les limites d'un coup de fouet.


En plus du fait que les bougies servent de sources de coeurs et d'autres objets, elles guident le joueur tout au long de la scène. Par exemple, dans l'image ci-dessous, les bougies dans le coin supérieur droit «invitent» le joueur à monter les escaliers. Cependant, pour monter les escaliers, le joueur doit d'abord aller à gauche, c'est pourquoi les bougies disparaissent de l'écran. Étant donné que les solutions CastlevaniaBot sont basées sur la hiérarchisation des objets visibles à l'écran, cette situation peut conduire à un cycle sans fin où le bot sélectionne alternativement le chemin le plus court vers les bougies (à gauche) ou le chemin le plus court vers la porte de sortie (à droite).


Des problèmes similaires peuvent être résolus de plusieurs manières. Par exemple, CastlevaniaBot peut être équipé de stockage d'objets, sachant que les objets continuent d'exister, même s'ils ne sont pas visibles. Mais pour cela, il faut tout de même les voir dès le début. Si les bougies étaient encore plus à droite, alors après leur détection, il faudrait remonter encore plus loin.

Dans cet esprit, j'ai ajouté des incitations qui poussent CastlevaniaBot à explorer des zones de la scène qu'il ignorerait normalement. Ces incitations fonctionnent de la même manière que les portes de sortie, entraînant CastlevaniaBot là où il doit aller. De plus, j'ai ajouté des règles qui lui font ignorer les bougies et les objets trop éloignés (en termes de distance parcourue, et non en ligne droite).

Après avoir monté les escaliers et détruit les bougies, de l'eau bénite est créée - la plus précieuse de toutes les armes secondaires. CastlevaniaBot le sélectionne en lui échangeant un poignard.


Comme avec le sac d'argent au début du jeu, CastlevaniaBot connaît tous les blocs destructibles avec des objets cachés, et pour utiliser le fouet pour détruire les blocs, il utilise une stratégie similaire à la stratégie des bougies.


Avec un mouvement supplémentaire de CastlevaniaBot, vous remarquerez qu'il commence à utiliser de l'eau bénite pour détruire les fantômes et les bougies. Cela peut sembler redondant, mais sert un objectif important. Castlevania récompense les joueurs pour l'utilisation d'armes secondaires avec double et triple exposition. En d'autres termes, CastlevaniaBot broie les améliorations d'armes secondaires.


Après avoir appuyé sur le bouton B, il y a un délai de 16 images avant de frapper un fouet. Le fouet reste long pendant 10 images supplémentaires, mais n'est valable que dans la première de ces dix. CastlevaniaBot utilise ce fait pour améliorer la visée. En particulier, il suit la vitesse de tous les objets dans le cadre, en supposant que la cible principale continuera de se déplacer le long d'un chemin linéaire. Il appuie ensuite sur le bouton B 16 images avant que la cible ne rencontre un fouet. L'ennemi peut toujours changer de direction pendant ces 16 images, mais généralement cette simple opération heuristique fonctionne.

Cependant, après avoir franchi la porte, CastlevaniaBot rencontre des chauves-souris rouges. Comme les têtes de méduses, les chauves-souris rouges volent à travers l'écran, traversant une sinusoïde à travers des plates-formes et des escaliers. Pour prédire où sera la chauve-souris rouge après 16 images, j'ai enregistré le mouvement de l'une d'elles dans un tableau. Pendant l'exécution du jeu, CastlevaniaBot suit les chauves-souris et attend les pics ou les creux de la trajectoire où la vitesse verticale change de signe. Ensuite, il est capable de comparer les coordonnées avec les valeurs d'une table pré-créée. Cela permet à la stratégie appropriée de frapper la batte rouge avec un fouet, de se pencher ou de rebondir dessus.

Lors du passage (speedrana) de Castlevania, les joueurs effectuent des manœuvres qui rendent le jeu aussi déterministe que possible. Par exemple, ils ont constaté que si à la fin du niveau 1 pour détruire le bloc et ramasser une amélioration d'arme dans une certaine séquence de temps, le boss se comporterait conformément au schéma souhaité, lui permettant de vaincre rapidement.

Peu importe le niveau d'expérience, ils ne peuvent pas apprivoiser complètement le générateur de nombres aléatoires. Néanmoins, étant donné que CastlevaniaBot peut contrôler les pressions sur les boutons avec une précision image par image, il peut amener le concept de passage de vitesse à sa limite, en passant chaque fois le jeu d'une manière absolument identique. S'il le faisait, ce ne serait pas mieux que de passer le TAS . Par conséquent, CastlevaniaBot ajoute arbitrairement des erreurs et des retards à ses actions en utilisant un générateur de nombres aléatoires externe pour éviter un gameplay déterministe. Par exemple, quand il frappe avec un fouet une bougie placée haut, il ajoute délibérément un délai pour un nombre aléatoire d'images au saut et à la frappe. Ces petits changements affectent considérablement la progression du jeu.

Bien que CastlevaniaBot cherche à éviter le déterminisme, il a néanmoins emprunté un concept à speedrunning: les dégâts augmentent . Dans 50% des cas, CastlevaniaBot évite complètement le passage du donjon de poissons humains en sautant sur la chauve-souris rouge, qui la jette sur une plate-forme autrement inaccessible.


Dans l'autre moitié des cas, CastlevaniaBot choisit de se battre avec des poissons humains. Leurs boules de feu ont une priorité élevée et CastlevaniaBot les frappe avec un fouet, esquive ou rebondit selon la situation.


En raison de l'imprévisibilité de créer des ennemis et leurs boules de feu, la plupart des joueurs exécutent généralement une partie avec des poissons humains. Mais CastlevaniaBot passe du temps sur eux, recueille tous les cœurs et même un trésor caché dans le bord très droit. Le bot sait exactement quels objets sont contenus dans chaque bougie, et comme il préfère utiliser de l'eau bénite, il saute les bougies dans lesquelles les chronomètres sont cachés. Cependant, si vous restez dans cette partie et que vous vous battez avec des poissons, vous pouvez parfois inévitablement prendre un chronomètre.

Les étapes se terminent souvent par des croix détruisant tous les ennemis à l'écran. Si vous êtes curieux, je dirai que les croix ne peuvent pas tuer les boss à la fin d'un niveau. En fait, des croix sont parfois créées même pendant les combats de boss. Par exemple, dans la bataille avec Méduse, des croix apparaissent parfois lors de la mort de serpents. Mais ces croix ne peuvent tuer que d'autres serpents.


Après avoir franchi la porte, CastlevaniaBot rencontre à nouveau des fantômes. Dans la capture d'écran ci-dessous, il veut sauter sur la plate-forme inférieure, mais les fantômes l'empêchent de bouger. Lorsqu'une table créée par un algorithme de recherche de chemin indique à CastlevaniaBot de sauter, il examine l'espace autour de la plate-forme cible. S'il s'avère qu'il atterrit sur des ennemis, le saut n'est pas effectué. Dans ce cas, ce mécanisme oblige CastlevaniaBot à attendre que les fantômes libèrent sa place.


Cette règle «vérifier les ennemis avant de sauter» illustre l'un des principes de la structure CastlevaniaBot: elle doit être régie par des règles simples et aussi généralisées que possible. Dans certaines parties du jeu, il est nécessaire d'utiliser des stratégies ponctuelles qui résolvent des problèmes très spécifiques. Mais dans la plupart du jeu, les actions des bots sont motivées par des heuristiques réutilisables. Je n'ai pas écrit une équipe qui l'a fait s'arrêter à ce point particulier et attendre que les fantômes se déplacent. Ce comportement résulte de l'heuristique.

CastlevaniaBot complète le niveau en tuant la chauve-souris fantôme avec une triple eau bénite. Mais sa stratégie d'attaque est déterminée par son arme secondaire. En fait, s'il n'avait pas d'arme secondaire, il était prêt à tuer le boss avec un seul fouet. Un cas particulièrement intéressant est le meurtre d'une chauve-souris fantôme avec une hache. Comme dans le cas de la chauve-souris rouge, j'ai enregistré dans le tableau le mouvement de la hache le long de la parabole. Pendant l'exécution du jeu, CastlevaniaBot effectue un décalage de table en l'associant à chacune des tuiles de sol. Cela vous permet de calculer le point optimal pour tuer le boss avec une hache.


Juste avant de ramasser la boule de cristal, CastlevaniaBot lance l'arme secondaire dans différentes directions, sachant qu'elle gèlera dans l'air après avoir touché la balle. Puis il saute au hasard à plusieurs reprises et frappe avec un fouet, espérant se figer dans une pose étrange.


Au début du niveau 2, CastlevaniaBot évite les premières bougies dans lesquelles le boomerang est caché. La stratégie de travailler avec un chevalier-lancier est une campagne contre les stratégies des fantômes ou des poissons, mais c'est le premier ennemi à tuer qui a besoin de deux coups. La chauve-souris noire sommeille jusqu'à ce que vous vous en approchiez, après quoi elle décolle et se déplace suffisamment linéairement pour être tuée avec un fouet en utilisant les heuristiques simples mentionnées ci-dessus.


Ayant détruit les briques du mur, dans 50% des cas, CastlevaniaBot semble quitter la pièce sans lever sa couronne. Mais en est-il ainsi? En fait, dans de tels cas, il ramasse la couronne en utilisant le bug du jeu. Puisque l'extrémité de l'échelle supérieure coïncide horizontalement avec l'emplacement de la couronne, le joueur, en passant devant et derrière l'écran, est momentanément baissé. Si vous écoutez le son ou regardez les lunettes, vous pouvez voir que le bot prend réellement la couronne.


Au niveau 2, les ennemis n'attaquent pas le joueur lorsqu'il se trouve sur une plate-forme mobile. CastlevaniaBot doit simplement attendre que la plate-forme approche, entrer dans la plate-forme, attendre qu'elle atteigne l'autre côté, puis descendre. Il existe une légère variation pour les plates-formes qui ne touchent pas les carreaux d'autre part. Dans de tels cas, CastlevaniaBot ne descend pas, mais saute de la plate-forme.


Une porte mène dans un couloir rempli de têtes volantes, et CastlevaniaBot réagit à cela en avançant. Comme c'est le cas avec les plateformes mobiles, CastlevaniaBot sait que cette stratégie doit être appliquée en fonction de sa position, et non en fonction de la priorité des objets de jeu à l'écran. Cependant, dès que toutes les têtes de méduses passent, il revient à cette technique pour choisir la stratégie qui sera utilisée plus loin.


Une autre stratégie, en fonction de la position, est déclenchée après avoir gravi l'échelle suivante menant à la zone remplie de têtes de méduses. Dans 50% des cas, CastlevaniaBot saute intentionnellement sur la tête d'une méduse pour obtenir un boost de dégâts, le poussant vers la plate-forme supérieure à côté de la porte menant à l'étape suivante. Ce sont les deux seuls bonus de dégâts que CastlevaniaBot connaît. Contrairement aux coureurs de vitesse, il ne l'exécute pas pour gagner du temps, c'est juste une autre contribution au non-déterminisme du passage.


Passer à travers l'écrasement est une stratégie basée sur la position intéressante, répétée trois fois. CastlevaniaBot attend que le «crush» le plus proche à gauche de celui-ci atteigne la position souhaitée, après quoi il le traverse. Après l'avoir dépassé, il s'arrête, se retourne, frappe les bougies avec un fouet, ramasse l'objet créé et répète l'opération avec le «coup de cœur» ultérieur. L'un des objets pourrait potentiellement être de l'eau bénite, donc il détruit toujours ces bougies.


Après «l'écrasement», les fantômes et les tours d'os apparaissent pour la première fois. Les fantômes sont très faciles à viser, mais pour les tuer, vous avez besoin de quelques coups. Il est encore plus facile de viser les tours en os car elles ne bougent pas. La même stratégie est utilisée pour leurs boules de feu que pour les boules poissons-humains.


Le niveau 2 se termine généralement avec CastlevaniaBot tuant instantanément Medusa avec un flux infini d'eau bénite. Cependant, il est prêt à travailler avec tout autre type d'arme secondaire.


Au niveau 3, des cavaliers apparaissent. CastlevaniaBot réagit à eux en attendant qu'ils sautent dans les limites du fouet. Si les sauteurs sautent le joueur, alors CastlevaniaBot se déplace dans la direction opposée et les frappe avec un fouet avant qu'ils ne touchent le sol.


Ensuite, des squelettes blancs apparaissent. Ils ont un schéma très aléatoire. De plus, ils jettent des os. Au niveau 3, CastlevaniaBot essaie d'éviter d'être touché. Mais j'ai trouvé qu'aux niveaux suivants, les os ne font que distraire, et il sera plus efficace de simplement les ignorer. La stratégie de CastlevaniaBot pour les squelettes blancs consiste simplement à les battre.


CastlevaniaBot attend que les corbeaux s'envolent. Ensuite, en fonction de la hauteur du corbeau par rapport au joueur, il calcule avec précision quand frapper avec un fouet après le saut.


Après être passé à l'étape suivante, CastlevaniaBot frappe indépendamment les bougies d'où le chronomètre apparaît, puis attend jusqu'à ce qu'il disparaisse. Un peu devant et derrière l'écran est un corbeau. Le bot détruit des bougies avant un combat de corbeau afin de réduire le risque de les toucher accidentellement et d'obtenir des armes secondaires indésirables.


Juste en face de l'emplacement des momies, CastlevaniaBot va à gauche sur la plate-forme pour déclencher l'apparition d'un sac d'argent caché. Il le fait simplement par intérêt, car il ne peut le soulever d'aucune façon.


Ensuite, CastlevaniaBot frappe intentionnellement les bougies d'où tombe la dague. Comme dans le cas du chronomètre, il le fait pour ne pas le reprendre par hasard lors des actions suivantes.


Et enfin, les momies sont vaincues par la pluie de l'eau bénite.


CastlevaniaBot est prêt à utiliser n'importe quelle arme secondaire pour combattre tous les boss. En fait, les stratégies d'utilisation des armes secondaires changent complètement si, pour une raison quelconque, un bloc contenant un morceau de porc est détruit. Sans ce bloc, il est impossible de monter sur la plate-forme supérieure, c'est pourquoi vous devez vous battre au niveau inférieur.

Au niveau 4, les plateformes mobiles reviennent. Et cette fois, il y a une chance que des chauves-souris rouges apparaissent sur le chemin. Pour réduire la probabilité de leur attaque, il s'attend à ce que l'arrivée de la plate-forme coïncide avec la destruction de la chauve-souris rouge. Étant donné que les souris rouges apparaissent à intervalles fixes, cela donne à CastlevaniaBot suffisamment de temps pour traverser la fosse d'eau sans chauves-souris. Il est prêt à faire face aux chauves-souris et aux poissons apparaissant au hasard sur la plate-forme, mais cela rend très dangereux de sauter sur et depuis la plate-forme. La stratégie utilisée par CastlevaniaBot augmente les chances de succès.


La même stratégie se répète au milieu de la scène. Cette fois, le saut vers la plate-forme mobile est beaucoup plus long, il est donc essentiel de détruire la chauve-souris rouge avant le saut.


Comme le montre la capture d'écran ci-dessus, les bougies sont toujours situées à une distance de 64 pixels les unes des autres. C'est peut-être un artefact du fait que les données de niveau sont présentées dans la ROM dans un format similaire aux graphiques vectoriels, économisant de l'espace. Mais pour une raison quelconque, les concepteurs ont décidé d'aligner les bougies non pas avec les centres, mais avec les bords des carreaux. Dans ce cas, les bougies sont alignées avec les deux extrémités de la plate-forme. Par conséquent, après les avoir touchés, un objet qui apparaît peut tomber directement dans l'abîme sous eux.

Je pense qu'à un moment donné, les concepteurs ont réalisé ce problème. Mais d'ici là, déplacer toute la série de bougies à tous les niveaux finis pour les aligner avec le centre des carreaux pourrait causer d'autres problèmes. Au lieu de cela, ils ont décidé de déplacer au hasard les bougies d'un pixel vers la droite ou la gauche de l'endroit où elles ont été créées. Par conséquent, après avoir frappé les bougies du côté droit de la capture d'écran, il y a 50% de chances que l'eau bénite qu'ils contiennent tombe sur la plate-forme. Dans la moitié restante des cas, il tombe à l'eau.

CastlevaniaBot évite généralement complètement ces bougies car il conserve avec succès l'eau bénite. Mais s'il en a besoin, il se rapproche de ces bougies pour garantir la sélection de l'eau bénite qui en est tombée.

CastlevaniaBot rencontre un tas de cavaliers. Dans cette zone, après avoir tué des cavaliers, des haches apparaissent souvent. CastlevaniaBot les évite, car l'eau bénite est particulièrement utile pour combattre le boss.


Lors du passage à la dernière étape du niveau, CastlevaniaBot ignore complètement le dragon osseux.


Mais il se débarrasse des deux suivants avec des coups de fouet rapides.


Le monstre de Frankenstein et Igor sont détruits par un flux constant de coups avec un fouet et de l'eau bénite. Comme avec d'autres patrons, CastlevaniaBot peut également gérer d'autres armes secondaires, ou sans elles. Cependant, les chances de survie sans eau bénite sont réduites.


Au niveau 5, CastlevaniaBot s'occupe à nouveau des squelettes blancs. Mais cette fois, il utilise des variations de stratégie rarement vues au niveau 3. Selon l'endroit où elles apparaissent, CastlevaniaBot jette de l'eau bénite puis recule pour attirer les squelettes en flammes. Près des escaliers, il passe sous les squelettes pour les diriger là où ils devraient être.


Au niveau 5, les squelettes rouges renaissent d'abord. CastlevaniaBot suit l'heure du dernier coup sur eux, afin de savoir quand il est sûr de passer par les os rouges.


La première salle de l'étape 14 est entièrement traitée par une énorme stratégie. CastlevaniaBot tue d'abord le cavalier. Il attend ensuite que le chevalier inférieur lance la hache, frappe la hache avec un fouet et monte lentement les escaliers inférieurs. Cela pousse le chevalier inférieur derrière l'écran, ce qui entraîne sa disparition. Il attend ensuite que la zone supérieure soit libre d'axes, frappe les bougies et récupère les objets qui sont apparus. Puis il s'approche de la base des escaliers menant au chevalier supérieur. Lorsque le haut chevalier lance la hache haut, CastlevaniaBot court après lui. Cela pousse le chevalier supérieur vers la gauche et presque complètement de l'écran, mais ne le détruit pas. CastlevaniaBot se penche sous la hache de retour, et peut-être sous la deuxième hache abandonnée, puis s'approche enfin des escaliers vers la sous-étape suivante. Hourra!


Après avoir passé plusieurs escaliers, CastlevaniaBot rencontre à nouveau un chevalier avec une hache. Il utilise de l'eau bénite pour l'étourdir, puis le termine avec un fouet. S'il n'y a pas d'eau bénite, il continue de battre avec un fouet, pourchassant le chevalier jusqu'à sa mort.


En montant les escaliers du niveau 5, CastlevaniaBot doit souvent attendre que le squelette rouge s'éloigne du haut ou du bas des escaliers. Vers la fin du niveau, la tour d'os rend cette tâche encore plus difficile. Selon la façon dont les squelettes décident de se déplacer, CastlevaniaBot descend et monte les escaliers jusqu'à ce qu'il puisse passer.


Pour traiter des groupes de squelettes rouges, une logique supplémentaire est requise afin que le bot ne tombe pas dans une boucle sans fin. Si CastlevaniaBot les battra séparément avec un fouet, avec un intervalle tel que le premier coup a le temps de revivre, alors il tombera dans un cycle où il continuera à détruire des squelettes ressuscitant sans fin. Pour éviter cela, CastlevaniaBot ne frappera pas avec un fouet d'un squelette rouge debout à côté d'un tas d'os rouges. Cette règle permet aux os rouges de renaître à côté du squelette rouge encore vivant, ce qui permet de les toucher tous les deux en même temps. Sans un intervalle entre leur destruction, aucun cycle ne sera créé.


Pour éviter les têtes de méduses dans le long couloir menant à la mort, le bot ne s'arrête jamais, étourdissant les chevaliers qui apparaissent généralement sur le chemin. Il profite du fait que le joueur peut traverser des ennemis étourdis par l'eau bénite sans subir de dégâts.


S'il n'y a pas d'eau bénite, alors juste en face du couloir CastlevaniaBot peut prendre un boomerang. Avec un ensemble de circonstances réussi, il l'utilise pour détruire les chevaliers, ainsi que pour obtenir des améliorations d'armes.


CastlevaniaBot étourdit la mort avec de l'eau bénite avant qu'elle ne commence à lancer des tresses, la tuant rapidement. Il peut également vaincre Death avec un triple boomerang, mais cela nécessite généralement plusieurs tentatives.


La stratégie principale de CastlevaniaBot en passant le pont au début du niveau 6 est de continuer à bouger. Il frappe un fouet d'énormes chauves-souris d'en haut pour les étourdir, puis rebondit sur les énormes chauves-souris apparaissant d'en bas. De plus, de temps en temps, il doit éviter les boules de feu lancées par les chauves-souris ou les battre avec un fouet.


Le passage sur le pont n'est pas garanti. Tout dépend de la convivialité des énormes chauves-souris.

Dans la sous-étape suivante, CastlevaniaBot utilise le chronographe du pont deux fois ou plus pour passer par des aigles et des cavaliers. Sans chronographe, il essaie de se frayer un chemin avec un fouet.


Lorsque CastlevaniaBot atteint la tour de Dracula, il peut monter et descendre les escaliers plusieurs fois pour créer à nouveau des bougies, ce qui vous permet de collecter au moins 20 cœurs.


Les bougies les plus à droite dans les chambres de Dracula donnent de l'eau bénite, ce qui est nécessaire pour combattre la deuxième forme de Dracula.

Pour vaincre la première forme de Dracula, il faut 16 coups à la tête. CastlevaniaBot s'approche de Dracula plusieurs fois, attend qu'il tire avec des boules de feu, puis saute par-dessus les balles et frappe la tête de Dracula avec un fouet.


La deuxième forme de Dracula, appelée Cookie Monster, est assommée par l'eau bénite par le bot et frappe plusieurs fois la tête avec un fouet. De temps en temps, Cookie Monster saute sur le joueur, tandis que CastlevaniaBot esquive. Cookie Monster lance également des boules de feu, qui peuvent généralement être détruites avec de l'eau bénite et un fouet. Parfois, vous pouvez obtenir une mise à niveau d'arme. Et l'eau bénite double attrape Cookie Monster dans un cycle d'étourdissement constant menant à une victoire rapide.


CastlevaniaBot n'est pas en mesure de passer par le mode difficile, qui commence après le générique final. Cependant, après avoir redémarré le jeu dans la cour du château, il remet à zéro l'octet du cycle de jeu, le basculant en mode normal. Cela permet à CastlevaniaBot de jouer sans fin.




Fichiers


CastlevaniaBot_2018-12-09.zip

Le fichier .zipcontient:

  • src - arbre source.
  • CastlevaniaBot.jar — .
  • lgpl-2.1.txt — .



Lancement



  • Nintaco — NES.
  • Castlevania (U) (PRG1) [!].nes — ROM .


  1. Nintaco Castlevania (U) (PRG1) [!].nes .
  2. CastlevaniaBot.jar .zip .
  3. Run Program, Tools | Run Program...
  4. JAR , Find JAR....
  5. Load JAR, .
  6. Run.

Copyright © 2018 meatfighter.com

. / LGPLv2.1.

Source: https://habr.com/ru/post/fr432784/


All Articles