Trouver des mouvements possibles pour une entité dans un jeu en mosaïque 2D

10

Je rencontre des problèmes avec un terme de recherche spécifique pour cela, mais comment trouver les mouvements possibles dans un jeu de stratégie au tour par tour 2D (par exemple FF: Tactics, Fire Emblem, Advance Wars).

entrez la description de l'image ici

Je ne pense pas tellement au terrain (ou même à la collision) à ce stade. Je me demande simplement quel algorithme je peux utiliser pour comprendre que l'entité X peut déplacer 5 tuiles et attaquer 2 tuiles plus loin que cela.

Je sais que je peux utiliser quelque chose comme Dijkstra pour trouver la distance entre deux points. Une implémentation possible est de commencer à l'emplacement des joueurs, puis de bifurquer à partir de là jusqu'à ce que la distance renvoyée par Dijkstra soit supérieure au nombre de coups.

Je me demandais simplement si quelqu'un pouvait m'orienter dans la bonne direction (c.-à-d. Nom des algorithmes, technique, articles, etc.).

NRaf
la source
Je pense que cela s'appelle la recherche de chemin, pour un terme de recherche? Si vous utilisez la recherche de chemin, vous pourriez avoir des compteurs pour gérer ce dont vous avez besoin
Exikle
Cela fait essentiellement partie de la recherche de chemin (calcul des métadonnées pour les coûts de déplacement). Vous ne déterminez que les emplacements qui sont à portée, mais vous ne déterminez pas nécessairement l'itinéraire que vous emprunteriez également.
Mario
1
Ce n'est pas en temps réel (RTS) si c'est au tour par tour à la FFTactics. : p
Alayric
En 2d, vous pouvez utiliser le calcul Taxicab / Manhattan en.wikipedia.org/wiki/Taxicab_geometry
Gerben Jacobs

Réponses:

5

Je pense qu'un Dijkstra délimité est précisément ce que vous voulez utiliser. La façon dont Dijkstra trouve la distance entre deux points est de tracer la distance à chaque nœud à partir d'un nœud d'origine, puis de «sélectionner» le chemin le plus court à partir de cette carte de distance. Vous voulez faire pratiquement la même chose, sauf que vous voulez que le graphe de nœuds de distance qu'il crée en tant que sortie, plutôt qu'un chemin vers un point particulier.

La seule modification que vous voudrez faire est de sauter le calcul de la distance des nœuds qui ont déjà dépassé votre plage de mouvement maximale. Ensuite, vous aurez un graphique des nœuds de tous les nœuds vers lesquels l'unité peut se déplacer, plus une bordure, alors découpez simplement les nœuds qui ont une distance supérieure à la tolérance de mouvement.

Alto.

En d'autres termes, à peu près ce que vous avez décrit dans votre question est ce que vous devez faire. Il a également l'avantage de pouvoir utiliser la sortie pour effectuer la recherche de chemin, sans avoir à effectuer d'autres calculs.

TASagent
la source
Je pense que Dijkstra est exagéré dans ce cas. L'OP n'a pas besoin d'un chemin vers toutes les destinations de mouvement possibles, juste une réponse oui / non pour savoir si un agent peut y arriver. Il peut calculer un chemin plus tard une fois que l'utilisateur en a choisi un.
Michael Kristofik
Le coût d'utilisation de l'algorithme de Dijkstra pour calculer le chemin après qu'une destination a été décidée est presque exactement le même que de l'utiliser à l'avance (sauf si vous utilisez une approche heuristique comme A * pour le cheminement). Ne pas le faire à l'avance crée simplement un travail redondant, car Dijkstra répondrait à la fois aux questions «où puis-je aller» et «comment y arriver?». Il permet également d'ajouter des complications à l'environnement qui modifient le coût du mouvement, bien que cela puisse être inutile pour l'application. De plus, l'approche est bien documentée, ce qui est utile pour le réalisateur.
TASagent
1
En examinant la réponse de Mario, il décrit en fait l'algorithme de Dijkstra, sauf qu'il inverse la distance et ne mentionne pas qu'il s'agit de Dijkstra.
TASagent
1
Je ne dirais pas que c'est Dijkstra, car vous ne cherchez pas vraiment l'itinéraire le plus court et vous n'essayez pas d'atteindre un point précis. C'est essentiellement la première partie de l'algorithme de Dijkstra, c'est vrai cependant. Le problème avec votre formulation, en utilisant Dijkstra, peut être trompeur et je pense que c'est aussi ce qui a dérouté Michael. Il pensait probablement que vous aviez suggéré d'utiliser Dijkstra une fois pour chaque champ / cellule.
Mario
1
Finir d'utiliser cette approche car elle a bien fonctionné et est très facile à étendre pour gérer les obstacles.
NRaf
12

L'approche la plus simple (et probablement la plus naïve) à laquelle je puisse penser en ce moment:

  • Commencez par votre personnage et marquez tous les champs environnants comme steps - 1.
  • Itérer sur tous les champs nouvellement marqués et marquer une fois de plus leurs champs environnants comme steps - 1stepsserait le numéro d'étape du champ actuel, sauf si le nouveau champ a un numéro déjà plus élevé.
  • Répétez la dernière étape jusqu'à ce que vous manquiez d'étapes.
Mario
la source
1
Cet algorithme a un nom: Flood Fill .
Michael Kristofik
6
@MichaelKristofik: Je dirais que c'est la première recherche étendue . Le remplissage d'inondation ne permet pas de suivre les distances.
BlueRaja - Danny Pflughoeft
2

Je pense que ce que vous cherchez pourrait être Manhattan Distance . En supposant qu'il n'y ait pas d'obstacles, vous pouvez dire qu'un carré est accessible simplement si:

| toX-fromX | + | toY-fromY | <maxMoveDistance

Cet algorithme peut ne pas être la bonne direction à suivre si vous rencontrez des obstacles plus tard; une façon possible de l'adapter pourrait consister à faire projeter des ombres par des obstacles et à réévaluer à partir du point le plus proche.

EDIT (parce que j'ai un peu plus de temps libre maintenant):

Par «ombres», je veux dire quelque chose comme ceci, si 0 est un carré accessible, C est le caractère et X est un obstacle:

 012345678
0    0
1   00
2  000X
3 000C000
4  00000
5   000
6    0
 012345678

Puisque (5, 2) est un obstacle, vous commencez par supposer que vous ne pouvez rien faire avec x> = 5 ET y <= 2. Vous pouvez ensuite recalculer à partir d'un autre carré; si vous voulez aller à (5, 1), vous pouvez calculer la distance manhattan de (4, 1) et voir si cette distance + du personnage à (4, 1) est inférieure à la distance de mouvement du joueur.

Ceci est un exemple assez banal, mais si vous avez plusieurs obstacles et / ou une plage de mouvement un peu plus longue, il devrait être capable de gérer la complexité.

Que ce soit en fait mieux que le simple remplissage, que ce soit en termes de complexité de programmation ou d'efficacité d'exécution, je n'ai aucune idée. Cela semblait être un moyen plus intéressant de résoudre le problème.

L'homme d'étain
la source
Que voulez-vous dire par projeter des ombres?
NRaf
1
Modifié pour clarification.
Tin Man