示例#1
0
 public void TestFindPath()
 {
     Pathfinding path = Pathfinding.Singleton();
     int[,] res = new int[5, 5] { { 0, 0, 0, 0, 0 }, { 0, 9, 9, 9, 9 }, { 0, 0, 0, 0, 0 }, { 9, 9, 9, 9, 0 }, { 0, 0, 0, 0, 0 } };//[0,4] = 5ieme lement du premier
     Coordonnees depart = new Coordonnees(0, 4);
     Coordonnees arrive = new Coordonnees(4, 0);
     var resultat = path.FindPath(res, depart, arrive);
     Assert.AreEqual(resultat.Count, 13, "le chemin en serpent est erronné");
     res = new int[6, 10]
               {
                   {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {9, 9, 9, 0, 9, 9, 0, 9, 0, 0},
                   {0, 0, 0, 0, 0, 0, 0, 9, 0, 0}, {0, 9, 9, 9, 9, 9, 9, 9, 9, 9},
                   {0, 9, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 9, 9, 9, 9, 9, 0, 0}
               };
     resultat = path.FindPath(res, new Coordonnees(0, 0), new Coordonnees(5, 9));
     Assert.AreEqual(resultat.Count, 17, "Le chemin trouvé ne correspond pas à la solution 1");
     res = new int[6, 10]
               {
                   {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {9, 9, 9, 0, 9, 9, 0, 9, 0, 0},
                   {0, 0, 0, 0, 0, 0, 0, 9, 0, 0}, {0, 9, 9, 9, 9, 9, 9, 9, 0, 9},
                   {0, 9, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 9, 9, 9, 9, 9, 0, 0}
               };
     resultat = path.FindPath(res, new Coordonnees(0, 0), new Coordonnees(5, 9));
     Assert.AreEqual(resultat.Count, 13, "Le chemin trouvé ne correspond pas au plus court");
 }
示例#2
0
        public void CalculerH(Coordonnees cible, int horizontal, int diagonal)
        {
            int h = 0;
            var diff = (pos - cible).Abs();
            if (diagonal < 2 * horizontal) //si diagonal est utile
            {
                while (diff.X > 0 && diff.Y > 0)
                {
                    h += diagonal;
                    diff -= new Coordonnees(1, 1);
                }

                while (diff.X + diff.Y > 0)
                {
                    h += horizontal;
                    diff.X -= 1;

                }
            }
            else //sinon inutile : on compte le nombre de deplacement
            {
                while (diff.X + diff.Y > 0)
                {
                    h += horizontal;
                    diff.X -= 1;

                }
            }

            this._H = h;
        }
示例#3
0
        /// <summary>
        /// REtourne le chemin possible entre le depart et son arrivée
        /// </summary>
        /// <param name="tab">Labyrinthe, avec 9 = 0bstacle, int[y,x]</param>
        /// <param name="depart"></param>
        /// <param name="arrive"></param>
        /// <returns></returns>
        public List<Node> FindPath(int[,] tab, Coordonnees depart, Coordonnees arrive)
        {
            var tabNode = PreparerTableau(tab);
            var result = new List<Node>();
            var listeOuverte = new List<Node>();
            var listeFerme = new List<Node>();
            if (!tabNode[depart.X, depart.Y].Obstacle && !tabNode[arrive.X, arrive.Y].Obstacle)
            {
                listeOuverte.Add(tabNode[depart.X, depart.Y]);
                while (listeOuverte.Count>0 && !listeFerme.Contains(tabNode[arrive.X,arrive.Y]))
                {
                    //on recupere le plus petit F de la liste ouverte
                    listeOuverte = listeOuverte.OrderBy(cont => cont.F).ToList();
                    var current = listeOuverte.First();
                    //on le vire de la liste ouverte
                    listeOuverte.Remove(current);
                    //on ajoute à la liste fermé
                    listeFerme.Add(current);
                    foreach (var node in GetAdjacents(current.pos, tabNode))
                    {
                        //obstalce ou deja dans liste fermée, ou c'est le depart; on skipe
                        if (node.Obstacle || listeFerme.Contains(node) || node.pos==depart)
                            continue;

                        //si pas dans liste ouverte
                        if (!listeOuverte.Contains(node))
                        {//on l'ajoute et on indique son parent
                            listeOuverte.Add(node);
                            node.Parent = current;
                            node.CalculerG(this.vertical,this.diag);
                            node.CalculerH(arrive, this.vertical,this.diag);

                        }
                        else if (listeOuverte.Contains(node))
                        {
                            var newG = node.SimulateCalculerG(current, this.vertical,this.diag);
                            if (newG < node.G && newG > 0)
                            {
                                node.Parent = current;
                                node.CalculerG(this.vertical, this.diag);
                            }
                        }
                    }
                }

            }

            var t = tabNode[arrive.X, arrive.Y];
            //si l'arrivée à un parent, le chemin est faisable
            while(t.Parent!=null)
            {
                result.Add(t);
                t = t.Parent;
            }
            if(result.Count>0)
                result.Add(t);
            return result;
        }
示例#4
0
 static void Main(string[] args)
 {
     int[,] res = new int[5, 5] { { 0, 0, 0, 0, 0 }, { 0, 9, 9, 9, 9 }, { 0, 0, 0, 0, 0 }, { 9, 9, 9, 9, 0 }, {0,0,0,0,0}};//[0,4] = 5ieme lement du premier
     Coordonnees depart = new Coordonnees(0,4);
     Coordonnees arrive = new Coordonnees(4,0);
     var resultat = Pathfinding.Singleton().FindPath(res, depart, arrive);
     resultat.ForEach(x=> Console.WriteLine(x.pos));
     Console.ReadLine();
 }
示例#5
0
 public void TestCustomDiag()
 {
     Pathfinding path = Pathfinding.Singleton(99, 1000,true);
     int[,] res = new int[5, 5] { { 0, 0, 0, 0, 0 }, { 0, 9, 9, 9, 9 }, { 0, 0, 0, 0, 0 }, { 9, 9, 9, 9, 0 }, { 0, 0, 0, 0, 0 } };//[0,4] = 5ieme lement du premier
     Coordonnees depart = new Coordonnees(0, 4);
     Coordonnees arrive = new Coordonnees(4, 0);
     var resultat = path.FindPath(res, depart, arrive);
     Assert.AreEqual(resultat.Count, 17, "le chemin en serpent est erronné");
     res = new int[6, 10]
               {
                   {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {9, 9, 9, 0, 9, 9, 0, 9, 0, 0},
                   {0, 0, 0, 0, 0, 0, 0, 9, 0, 0}, {0, 9, 9, 9, 9, 9, 9, 9, 9, 9},
                   {0, 9, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 9, 9, 9, 9, 9, 0, 0}
               };
 }
示例#6
0
        /// <summary>
        /// Calcule le chemin (prenant en compte les obstacles) pour aller d'un point à un autre
        /// </summary>
        /// <param name="oDepart">Coordonnee de depart</param>
        /// <param name="oArrivee">coordonnee d'arrivee</param>
        /// <returns>Chemin à emprunter pour y arriver</returns>
        public Chemin CalculerChemin(Coordonnees oDepart, Coordonnees oArrivee)
        {
            var c = new Chemin();

            var a = oDepart.X;
            var b = oArrivee.X;
            var cpt = oDepart.X;
            var res = this.GetChemin(oDepart, oArrivee);
            List<Coordonnees> result = res.Select(t => t.pos).Reverse().ToList();
            for (int i = 0; i < result.Count - 1; i++)
            {
                var diff = (result[i + 1] - result[i]);
                c.AddMouvementFin(new Vecteur(diff));
            }

            Console.WriteLine("Chemin calculé pour aller de " + oDepart + " à " + oArrivee + " : ");
            Console.WriteLine(c.ToString());

            return c;
        }
示例#7
0
        /// <summary>
        /// REtourne les coordonnées d'arrivée pour le chemin depuis des coordonnées de depart
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        public Coordonnees AppliquerAPosition(Coordonnees c)
        {
            Coordonnees res = new Coordonnees(c.X,c.Y);
            foreach (Vecteur parcour in parcours)
            {
                res = res + parcour;
            }

            return res;
        }
示例#8
0
        public List<Node> GetAdjacents(Coordonnees c, Node[,] table)
        {
            List<Node> list = new List<Node>();
            bool flagXMin = c.X > 0;
            bool flagXMax = c.X < table.GetLength(0) - 1;
            bool flagYMin = c.Y > 0;
            bool flagYMax = c.Y < table.GetLength(1) - 1;
            var flagDiagoOk = this.diag < 2*this.vertical;
            //if (flagXMin)
            //{
            //    if (flagYMin)
            //        list.Add(table[c.X - 1, c.Y - 1]);
            //    list.Add(table[c.X - 1, c.Y]);
            //    if (flagYMax)
            //        list.Add(table[c.X - 1, c.Y + 1]);

            //}

            //if (flagXMax)
            //{
            //    if (flagYMin)
            //        list.Add(table[c.X + 1, c.Y - 1]);
            //    list.Add(table[c.X + 1, c.Y]);
            //    if (flagYMax)
            //        list.Add(table[c.X + 1, c.Y + 1]);

            //}

            //if (flagYMin)
            //    list.Add(table[c.X, c.Y - 1]);
            //if (flagYMax)
            //    list.Add(table[c.X, c.Y + 1]);
            if (flagXMin)
                list.Add(table[c.X - 1, c.Y]);
            if (flagXMax)
                list.Add(table[c.X + 1, c.Y]);

            if (flagYMin)
                list.Add(table[c.X, c.Y - 1]);
            if (flagYMax)
                list.Add(table[c.X, c.Y + 1]);

            var flagUseDiago = list.Where(x => !x.Obstacle).Count() < 2; //necessité utiliser diago pour avancer
            if(flagDiagoOk || (flagUseDiago)) //si les diago sont ok pour utiliser ou si on a pas le choix
            {
                if(flagXMin&&flagYMin)
                    list.Add(table[c.X - 1, c.Y - 1]);
                if(flagXMin&&flagYMax)
                    list.Add(table[c.X - 1, c.Y + 1]);

                if(flagXMax&&flagYMin)
                    list.Add(table[c.X + 1, c.Y - 1]);
                if(flagXMax&&flagYMax)
                    list.Add(table[c.X + 1, c.Y + 1]);
            }

            return list;
        }
示例#9
0
 private void GererDemandeDeplacementPerso(MouseState ms)
 {
     this.CoolDownClick = CoolDownClickValue;
     var coo = new Coordonnees(ms.X/TailleCaseX, ms.Y/TailleCaseY);
     var c = this._carteEcran.CalculerChemin(this._personnage.Coordonnees, coo);
     this._personnage.CheminPerso = c;
     IMessage m = MessageFactory.GetInstanceOf(TypeMessage.DemandeDeplacement);
     m.PreparerMessage(new object[] {c});
     this._emmeteur.envoyer(m);
     this._personnage.CoordonneesAvantValidation = this._personnage.Coordonnees;
 }
示例#10
0
        private List<Node> GetChemin(Coordonnees depart, Coordonnees arrivee)
        {
            //modifier : utiliser une classe pour representer le tableau de cases, qui à un getter en int[,]
            var temp = new int[this.NombreCasesX,this.NombreCasesY];
            for (int i = 0; i < this.NombreCasesX; i++)
            {
                for (int j = 0; j < this.NombreCasesY; j++)
                {
                    temp[i, j] = this._casesContenues[i, j].Franchissable ? 0 : 9;
                }

            }

            var res = Pathfinding.Singleton(100,300,true).FindPath(temp, depart, arrivee);

            return res;
        }
示例#11
0
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
                if (Compteur < 0 && Flagdepl)
                {
                    Vecteur v;
                    // pour eviter deplacement auto lors de la premiere cases : on ne passe dedans que après un premier compteur déroulé
                    if (this._cheminPrevu.PremierPeekNextFait)
                    {
                        v = this._cheminPrevu.PeekNext();
                        this.Move(v);
                        this._cheminPrevu.RemoveFirst();
                    }
                      v = this._cheminPrevu.PeekNext();
                    this._nextCase = this.Coordonnees + v;
                     if (Flagdepl) //flagdep sera remit à false si pas de chemin dans peeknext
                     {
                         ((Game1)this.Game).DeplacementPerso(v, this);
                         this.Compteur = Game1.NombreTickDeplacement;
                     }
                }
                if (Flagdepl && Compteur > -1)
                    Compteur--;
            if(Flagdepl && this._cheminPrevu!=null)
                Tick();

                #region WIP : gestion de l'arrivée sur une case
                if (this.Compteur == 0)
                {
                    var caseCible = ((Game1) this.Game)._carteEcran.GetCase(this._nextCase);
                    var temp = CaseFactory.GetCaseType(caseCible);

                    Console.WriteLine("Case testée : " + this._nextCase + "de type " + temp);
                    Console.WriteLine("********************************************\r\n" + caseCible.OnOver() +
                                      "\r\n********************************************\r\n");
                    if (temp == typeof(CaseTelep))
                    {
                        var caseTelep = caseCible as CaseTelep;
                        ((Game1) Game).DemanderTeleportation(caseTelep.idTelep);
                    }
                }
                #endregion
        }
示例#12
0
 public Vecteur(Coordonnees a)
     : this(a.X,a.Y)
 {
 }
示例#13
0
 public bool DifferenceSurDeuxAxes(Coordonnees c)
 {
     var tx = this.X - c.X;
     var ty = this.Y - c.Y;
     return Math.Abs(tx + ty) > 1;
 }
示例#14
0
 public static Coordonnees FromString(string t)
 {
     var temp = t.Split(',');
     var c = new Coordonnees(Convert.ToInt32(temp[0]), Convert.ToInt32(temp[1]));
     return c;
 }
示例#15
0
        /// <summary>
        /// Constructeur d'un personnage
        /// </summary>
        /// <param name="posX"></param>
        /// <param name="posY"></param>
        /// <param name="g">Game </param>
        public Personnage(int posX, int posY, Game g)
            : this(g)
        {
            this._position = new Coordonnees { X = posX, Y = posY };

            this.OffsetCaseDepl = Vecteur.Zero;
            this.Direction = 2;
            this.Compteur = -1;
            // this.compteur = 0;
            this._cheminPrevu = new Chemin();
            this._cfh = this.FinCheminPrevu;
            this._flagdepl = false;

        }
示例#16
0
 public Node(int x, int y, bool ob = false)
 {
     this.Parent = null;
        this.pos = new Coordonnees(x,y);
     this.Obstacle = ob;
 }
示例#17
0
 public CaseBase GetCase(Coordonnees pos)
 {
     return this.GetCase(pos.X, pos.Y);
 }
示例#18
0
 /// <summary>
 /// Setter des sprites pour le perso
 /// </summary>
 /// <param name="spriteHaut"></param>
 /// <param name="spriteBas"></param>
 /// <param name="spriteGauche"></param>
 /// <param name="spriteDroit"></param>
 public void SetSprites(AnimatedSprite spriteHaut, AnimatedSprite spriteBas, AnimatedSprite spriteGauche, AnimatedSprite spriteDroit)
 {
     this._spritesAnimees = new[] { spriteHaut, spriteDroit, spriteBas, spriteGauche };
     for (var i = 0; i < 4; i++)
         this._spritesAnimees[i].InitialiserAnimation();
     this.OffsetCaseSprite = new Coordonnees(((Game1.TailleCaseX - this.GetSprite.Width) / 2), ((Game1.TailleCaseY - this.GetSprite.Height) / 2));
 }