Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

ALGORITHME DE PATHFINDING A STAR (A*)


Information sur la source

Catégorie :Maths & Algorithmes Source .NET ( DotNet ) Classé sous : astar, star, pathfinding, algorithme, algo Niveau : Initié Date de création : 23/01/2007 Date de mise à jour : 03/01/2009 18:29:08 Vu / téléchargé: 13 253 / 879

Note :
10 / 10 - par 3 personnes
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (5)
Ajouter un commentaire et/ou une note


Description

Cliquez pour voir la capture en taille normale
A Star (A*) Algorithme C# - Pathfinding

A* est un algorithme de type pathfinding. C'est à dire que c'est un algorithme qui est capable de trouver un chemin entre deux points, en prenant en compte certaines contraintes. Il existe plusieurs algorithmes de type pathfinding, mais AStar est un des meilleurs en termes de simplicité, performance et ressource.

Presque tous les jeux récents utilisent ce genre d'algorithme (avec bien entendu des améliorations faites maison). Pensez, par exemple, à un jeu où l'ordinateur qui est votre adversaire doit déplacer des unités: il doit les amener d'un point de la map à un autre, en respectant certaines contraintes telles que des unités ennemies, des montagnes où les unités avancent moins vites, peut-être des ruisseaux, etc.

A* est capable de prendre en compte ces différentes contraintes et de calculer le chemin le plus court pour aller de A à B. Le net grouille d'informations qui explique le fonctionnement (assez simple) de cet algorithme, je ne vais donc pas le réexpliquer ici. Vous trouverez néamoins un fichier html qui décrit de manière très simple le fonctionnement (j'ai implémenté l'algorithme grâce à ce document que j'ai trouvé sur le web).

La solution contient trois projets: un projet library qui contient A Star (A*) à proprement parlé, un autre qui contient les classes pour représenter graphiquement le résultat de l'algorithme (cf. capture) et un projet Windows qui utilise les deux autres projets pour qu'on puisse tester.

J'ai rajouté également des maps au projet pour qu'on puisse voir le résultat instantanément. Dans le cas de la map "laby" par exemple, vous verrez des cases bleues et rouges. Ces cases représentent des contraintes, c'est à dire qu'elles ont une certaine pondérations (x2 pour la case bleue, x5 pour la case rouge). Autrement dit, l'algorithme va calculer le chemin le plus adapté en partant du principe que s'il passe sur une case rouge ça lui prendra 5x plus de temps que de passer sur une case normale (pour reprendre la comparaison ci-dessus, ça pourrait être l'équivalent d'un passage dans du sable où les unités sont ralenties).

Il est naturellement possible d'améliorer ce projet, par exemple en gérant les déplacements diagonaux, en prenant en compte des contraintes plus complexes, en améliorant la rapidé de l'algorithme AStar, etc.
Le projet qui implémente l'algo A Star est donc pratiquement prêt à l'emplois tel quel, suffit de le rajouter à votre solution...

N'hésitez pas à soumettre vos remarques, je tâcherai de les prendre en compte dans une future version.
 

Source

  • public List<MapPoint> CalculateBestPath()
  • {
  • Node.Map = this._map;
  • Node startNode = new Node(null, this._map.StartPoint);
  • this._open.Add(startNode);
  • while (this._open.Count > 0)
  • {
  • Node best = this._open.RemoveFirst(); // This is the best node
  • if (best.MapPoint == _map.EndPoint) // We are finished
  • {
  • List<MapPoint> sol = new List<MapPoint>(); // The solution
  • while (best.Parent != null)
  • {
  • sol.Add(best.MapPoint);
  • best = best.Parent;
  • }
  • return sol; // Return the solution when the parent is null (the first point)
  • }
  • this._close.Add(best);
  • this.AddToOpen(best, best.GetPossibleNode());
  • }
  • // No path found
  • return null;
  • }
        public List<MapPoint> CalculateBestPath()
        {
            Node.Map = this._map;
            Node startNode = new Node(null, this._map.StartPoint);
            this._open.Add(startNode);

            while (this._open.Count > 0)
            {
                Node best = this._open.RemoveFirst();   // This is the best node
                if (best.MapPoint == _map.EndPoint)     // We are finished
                {
                    List<MapPoint> sol = new List<MapPoint>(); // The solution
                    while (best.Parent != null)
                    {
                        sol.Add(best.MapPoint);
                        best = best.Parent;
                    }
                    return sol; // Return the solution when the parent is null (the first point)
                }
                this._close.Add(best);
                this.AddToOpen(best, best.GetPossibleNode());
            }
            // No path found
            return null;
        }

Conclusion

Remarquez qu'au niveau du Control qui s'occupe de représenter la map en cours, il y a actuellement un petit bug avec les threads que je n'ai pas encore réussi à résoudre, mais j'espère corriger dans une prochaine version.
 

Fichier Zip

Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

Historique

24 janvier 2007 15:29:39 :
Corrections de quelques fautes dans le texte, ajout d'une map dans le projet, prise en compte des commentaires (ajouts dichotomique, RemoveAt)
25 janvier 2007 22:25:27 :
Petites corrections (détails) dans le code
19 février 2007 21:36:15 :
Correction de la description
04 novembre 2008 19:55:25 :
Rien rien :)
03 janvier 2009 18:29:09 :
Class plus générique

Commentaires et avis

signaler à un administrateur
Commentaire de MoDDiB le 23/01/2007 22:50:07

Je n'ai pas regardé la source mais juste la preview du code :
Node best = this._open[0]; // This is the best node
this._open.Remove(best);

Comme c'est un algo coûteux :
this._open.RemoveAt(0);  
sera un peu plus rapide (à cause du IndexOf dans la fonction Remove (je me doute que tu le sais, je le dis pour les autres :) ))
Ca n'est pas grand chose mais dans un jeu ou dans project hoshimi ça peut être très bénéfique :)

signaler à un administrateur
Commentaire de Bidou le 24/01/2007 07:11:58 administrateur CS

Merci pour le commentaire.
Ce n'est pas un algo trop coûteux justement, mais concernant le Remove tu as bien sûr raison (ça sera corrigé dans la prochaine version).
Il est clair que c'est plus rapide d'aller supprimer à un élément précis, que de devoir itérer pour retrouver cet élément [ Remove(object o) fait un IndexOf pour avoir l'index puis un RemoveAt, en gros on gagne donc un IndexOf(). En même temps, puisqu'il s'agit toujours d'un RemoveAt(0), IndexOf n'aura qu'une itération à faire, ce qui est relativement négligeable ]

signaler à un administrateur
Commentaire de MoDDiB le 24/01/2007 09:53:04

Oui effectivement le gain n'est pas trop important comme il est en première position.
Disons que j'ai du utiliser cet algo il y a 3 ans pour un jeu de stratégie temps réel avec 70 unités en même temps sur une carte 500*500 et forcément là il vaut mieux tout faire pour être le plus performant.
Comme par exemple pour l'insertion tu utilises un comparer alors que normalement la liste est déjà entièrement triée : tu peux donc obtenir l'index où insérer en faisant une recherche dichotomique.
De la même manière pour tester si un noeud appartient à la liste open tu fais un Contains alors qu'un tableau à 2 dimensions de booléens seraient beaucoup plus rapide.
Bien entendu pour présenter une source à code source j'aurais fait comme toi et préféré un joli code plutôt qu'un code moche et performant : ces indications sont surtout pour ceux qui veulent l'utiliser dans un jeu temps réél.
Enfin bref 10 : l'algo aussi bien présenté manquait à csharpfr :)

signaler à un administrateur
Commentaire de Bidou le 24/01/2007 11:12:39 administrateur CS

Merci pour la note ;-)
Le but est effectivement de présenter l'algorithme de manière agréable et comme je l'ai précisé il s'agit d'une version de base qui peut (qui doit) être améliorée. En tout cas merci pour les différentes idées, j'en tiendrai certainement compte pour les prochaines versions!

signaler à un administrateur
Commentaire de sebmafate le 24/01/2007 16:06:31 administrateur CS

sympa... ca me ramène quelques années en arrière... à l'époque où j'apprenais le LISP :)
c'était sympa la fac :p

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

recherche algo de trie alphabetique en C [ par mikolemarseillais ] salut à tousje souhaite créer une fonction en C qui pourra trier les donnés d'un fichier(par ex: trier par nom) par ordre alphabetique.Merci de m'aide Je comprends pas cette algorithme [ par kaiwoo ] private bool AUneVirgule (double nb){long tmp = (long)nb;if (tmp == nb)return false;elsereturn true;}Pour info, il a été fait par un super membre du f Algorithme de placement [ par oberown ] Je cherche des noms d'algorithmes ou des idées, pour résoudre ce genre de problème.On a trois jours, et chaque jours 2 personnes peut se présenter. On conversion algo / C++ [ par Kirdream ] Bonjour, j'ai commencé à écrire la programmation de la fenêtre et des menus mais je bute sur la fonction de la conversion.Est-ce que vous auriez une i Algorithme Mot Caché [ par nuns ] Salut tout le monde,Je voudrais savoir si il y a quelqu ' un qui aurait un générateur de mot Caché, le jeux, avec les grille ou il faut chercher les m PathFinding A* [ par gomoz ] Bonjour, je dois programmer un PathFinding mais j'ai vraiment du mal :(.Est-ce que vous pourriez m'aider &#224; comprendre le fonctionnement de A* ?Vo algorithme génétique programmé en c# [ par johelle ] slt,je veux savoir si'il ya quelqu'un dans ce forum qui a un programme d'un algorithme g&#233;n&#233;tique en c#et merci. Algorithme de dijkstra [ par RM50Man ] Est - ce que quelqu'un pourrait comment trouver la matrice ligneds l algorithme de dijkstra!!!!Merci!!!RM50man Algo FFT de multiplication rapide [ par Gruh ] &nbsp;&nbsp;&nbsp;Voil&#224;, je suis en deuxi&#232;me ann&#233;e de pr&#233;pa maths et je suis au d&#233;s&#233;spoir pour mon Tipe ( travail perso ca c'est un beug pour lse star de C# [ par hred1 ] Bonjour,J'ai rajout&#233; cette partie du code dons mon projet et depuis mon programe beug public struct TUserData {<FO


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,718 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.