J'ai trouvé beaucoup de références à l'intelligence artificielle des fantômes dans Pacman, mais aucune d'elles n'a mentionné comment les yeux retrouvent leur chemin vers le trou central des fantômes après qu'un fantôme a été dévoré par Pacman.
Dans mon implémentation, j'ai implémenté une solution simple mais affreuse. Je viens de coder en dur à chaque coin, quelle direction devrait être prise.
Existe-t-il une meilleure/ou la meilleure solution? Peut-être un générique qui fonctionne avec des conceptions de niveaux différents?
En fait, je dirais que votre approche est une solution assez impressionnante, avec un coût en temps d'exécution quasi nul par rapport à n'importe quel type de recherche exploratoire.
Si vous en avez besoin pour généraliser à des cartes arbitraires, vous pouvez utiliser n'importe quel algorithme de recherche de chemin - la recherche en largeur d'abord est simple à mettre en œuvre, par exemple - et l'utiliser pour calculer les directions à encoder à chacun des coins avant l'exécution du jeu.
EDIT (11 août 2010): On vient de me référer à une page très détaillée sur le système Pacman: The Pac-Man Dossier , et comme j'ai la réponse acceptée ici, je pense que je devrais la mettre à jour. L'article ne semble pas couvrir l'acte de retourner explicitement dans la maison du monstre, mais il indique que le parcours direct dans Pac-Man est le cas suivant:
J'ai résolu ce problème pour les niveaux génériques de cette façon: Avant le début du niveau, je fais une sorte de "remplissage d'inondation" à partir du trou du monstre; chaque tuile du labyrinthe qui n'est pas un mur porte un nombre indiquant à quelle distance il se trouve du trou. Ainsi, lorsque les yeux sont sur une tuile avec une distance de 68, ils regardent laquelle des tuiles voisines a une distance de 67; c'est la voie à suivre alors.
Pour une alternative aux algorithmes de recherche de chemins plus traditionnels, vous pouvez jeter un oeil au modèle (nommé de manière appropriée!) modèle anti-objet Pac-Man Scent .
Vous pouvez diffuser l'odeur du monstre-trou autour du labyrinthe au démarrage et laisser les yeux le suivre à la maison.
Une fois que l'odeur est configurée, le coût d'exécution est très faible.
Edit: malheureusement l'article de Wikipédia a été supprimé, donc WayBack Machine à la rescousse ...
Vous devriez jeter un oeil sur un algorithme de recherche de chemin, comme algorithme de Dijkstra ou algorithme A * . Voici quel est votre problème: un problème de graphique/chemin.
Toute solution simple qui fonctionne est maintenable, fiable et performante est une bonne solution. Il me semble que vous avez déjà trouvé une bonne solution ...
Une solution de recherche de chemin sera probablement plus compliquée que votre solution actuelle et, par conséquent, nécessitera probablement un débogage. Ce sera probablement aussi plus lent.
IMO, si ce n'est pas cassé, ne le répare pas.
EDIT
IMO, si le labyrinthe est corrigé alors votre solution actuelle est bon/code élégant. Ne faites pas l'erreur d'associer "bon" ou "élégant" à "intelligent". Un code simple peut aussi être "bon" et "élégant".
Si vous avez des niveaux de labyrinthe configurables, alors vous devriez peut-être simplement faire le cheminement lors de la configuration initiale des labyrinthes. Le plus simple serait de demander au concepteur de labyrinthe de le faire à la main. Je ne prendrais la peine d'automatiser cela que si vous avez des labyrinthes incroyables ... ou si les utilisateurs peuvent les concevoir.
(De plus, si les itinéraires sont configurés manuellement, le concepteur de labyrinthe pourrait rendre un niveau plus intéressant en utilisant des itinéraires non optimaux ...)
Dans le Pacman original, le fantôme a trouvé le mangeur de pilule jaune grâce à son "odeur", il laissait une trace sur la carte. le joueur. Chaque fois que Pacman se déplaçait, les "valeurs des odeurs" étaient diminuées de 1.
Maintenant, un moyen simple d’inverser le processus consiste à créer une "pyramide d’odeur de fantôme", dont le point le plus élevé se trouve au centre de la carte. Le fantôme se déplace alors dans la direction de cette odeur.
En supposant que vous ayez déjà la logique nécessaire pour poursuivre pacman, pourquoi ne pas le réutiliser? Il suffit de changer de cible. On dirait que ce serait beaucoup moins de travail que d'essayer de créer une toute nouvelle routine en utilisant exactement la même logique.
Ce fut la meilleure source que j'ai pu trouver sur la façon dont cela fonctionnait réellement.
http://gameai.com/wiki/index.php?title=Pac-Man#Respawn Lorsque les fantômes sont tués, leurs yeux désincarnés reviennent à leur emplacement de départ. Ceci est simplement accompli en plaçant la tuile cible du fantôme à cet endroit. La navigation utilise les mêmes règles.
Cela a du sens. Peut-être pas la plus efficace au monde, mais une belle façon de ne pas avoir à vous soucier d’un autre État ou de quoi que ce soit du genre, si vous changez d’objectif.
Note latérale: Je ne savais pas à quel point ces programmeurs de pac-man étaient géniaux: ils ont en fait créé un système de messagerie complet dans un espace très restreint avec une mémoire très limitée ... c'est incroyable.
Que diriez-vous de chaque carré ayant une valeur de distance au centre? De cette façon, pour chaque carré donné, vous pouvez obtenir les valeurs des carrés voisins immédiats dans toutes les directions possibles. Vous choisissez la case avec la valeur la plus basse et vous vous déplacez vers cette case.
Les valeurs seraient pré-calculées à l'aide de tout algorithme disponible.
C'est un problème de découverte. Pour un algorithme populaire, voir http://wiki.gamedev.net/index.php/A* .
la suggestion de dtb23 consistant à choisir une direction aléatoire à chaque coin et vous finirez par découvrir que le monstre-trou semble horriblement inefficace.
Cependant, vous pouvez utiliser son algorithme de retour à la maison inefficace pour rendre le jeu plus amusant en introduisant plus de variation dans la difficulté du jeu. Pour ce faire, appliquez l'une des approches ci-dessus, telles que vos points de cheminement ou le remplissage de la source d'inondation, sans le faire de manière déterministe. Donc, à chaque coin, vous pouvez générer un nombre aléatoire pour décider de prendre la meilleure façon ou une direction aléatoire.
Au fur et à mesure que le joueur progresse, vous réduisez le risque qu'une direction aléatoire soit prise. Cela ajouterait un autre levier sur le niveau de difficulté général en plus du niveau de vitesse, de la vitesse fantôme, de la pause pour manger la pilule (etc.). Vous avez plus de temps pour vous détendre alors que les fantômes ne sont que des yeux inoffensifs, mais ce temps devient de plus en plus court à mesure que vous progressez.
Réponse courte, pas très bien. :) Si vous modifiez le labyrinthe Pac-Man, les yeux ne reviendront pas nécessairement. Certains des hacks qui circulent ont ce problème. Donc, cela dépend d'un labyrinthe coopératif.
Je pense que votre solution est bonne pour le problème, plus simple que cela, est de rendre une nouvelle version plus "réaliste" où les yeux fantômes peuvent traverser les murs =)
Voici un analogue et un pseudo-code de l'idée d'inondation d'ammoQ.
queue q
enqueue q, ghost_Origin
set visited
while q has squares
p <= dequeue q
for each square s adjacent to p
if ( s not in visited ) then
add s to visited
s.returndirection <= direction from s to p
enqueue q, s
end if
next
next
L’idée est qu’il s’agit d’une recherche en profondeur, de sorte que chaque fois que vous rencontrez un nouveau carré adjacent, le meilleur chemin à suivre est p. C'est O(N) je crois.
Je ne sais pas trop comment vous avez implémenté votre jeu, mais vous pouvez faire ce qui suit:
Quelques pseudocodes:
x = getRelativeOppositeLatitudinalCoord()
y
origX = x
while(eyesNotInPen())
x = getRelativeOppositeLatitudinalCoordofGate()
y = getRelativeOppositeLongitudinalCoordofGate()
if (getRelativeOppositeLatitudinalCoordofGate() == 0 && move(y) == false/*assume zero is neither left or right of the the gate and false means wall is in the way */)
while (move(y) == false)
move(origX)
x = getRelativeOppositeLatitudinalCoordofGate()
else if (move(x) == false) {
move(y)
endWhile
Je proposerais que le fantôme enregistre le chemin qu'il a emprunté du trou au Pacman. Donc, dès que le fantôme meurt, il peut suivre ce chemin mémorisé en sens inverse.
Prendre plaisir!
Mon approche nécessite un peu de mémoire (du point de vue de l’ère Pacman), mais vous n’avez besoin que de calculer une fois et cela fonctionne pour n’importe quel niveau de conception (y compris les sauts).
Lorsque vous chargez un niveau pour la première fois, étiquetez tous les nœuds du repaire du monstre 0 (représentant la distance du repaire). Étiquetez ensuite les nœuds connectés 1, les nœuds qui leur sont connectés 2, etc., jusqu'à ce que tous les nœuds soient étiquetés. (note: cela fonctionne même si le repaire a plusieurs entrées)
Je suppose que vous avez déjà des objets représentant chaque nœud et des connexions à leurs voisins. Le pseudo-code pourrait ressembler à ceci:
public void fillMap(List<Node> nodes) { // call passing lairNodes
int i = 0;
while(nodes.count > 0) {
// Label with distance from lair
nodes.labelAll(i++);
// Find connected unlabelled nodes
nodes = nodes
.flatMap(n -> n.neighbours)
.filter(!n.isDistanceAssigned());
}
}
Une fois que tous les nœuds sont étiquetés, le routage des yeux est trivial ... il suffit de choisir le nœud voisin avec l'étiquette de distance la plus basse (remarque: si plusieurs nœuds ont la même distance, peu importe laquelle est choisie). Pseudo code:
public Node moveEyes(final Node current) {
return current.neighbours.min((n1, n2) -> n1.distance - n2.distance);
}
Sachant que les chemins de pacman ne sont pas aléatoires (chaque niveau spécifique compris entre 0 et 255, inky, blinky, pinky et clyde fonctionnera exactement de la même manière pour ce niveau).
Je prendrais ceci et devinerais alors qu'il y a quelques chemins principaux qui enveloppent tout le labyrinthe comme un "chemin de retour" qu'un objet de globe oculaire prend en attente où il se trouve quand l'homme de poche a mangé le fantôme.
Les fantômes de pacman suivent des schémas plus ou moins prévisibles s’agissant d’essayer de faire correspondre X ou Y en premier jusqu’à ce que l’objectif soit atteint. J'ai toujours supposé que c'était exactement la même chose pour les yeux retrouvant leur chemin.
Pour mon jeu PacMan, j’ai créé un algorithme un peu " shortest multiple path home
" qui fonctionne pour tous les labyrinthes que je lui ai fournis (dans mon ensemble de règles). Cela fonctionne également à travers ces tunnels.
Lorsque le niveau est chargé, tous les path home data in every crossroad
Sont vides (valeur par défaut) et une fois que les fantômes commencent à explorer le labyrinthe, ils crossroad path home information
Continuent à être mis à jour chaque fois qu'ils rencontrent un "nouveau" carrefour ou par un chemin différent, trébuchez à nouveau sur leur carrefour connu.