// Constructeur avec un parent (copie + mutations)
 public MazeIndividual(MazeIndividual father)
 {
     this.genome = new List <IGene>(); // Creation du genome du fils du pere passé en paramètre.
     foreach (MazeGene g in father.genome)
     {
         this.genome.Add(new MazeGene(g)); // Copie gene a gene du genome du pere au fils.
     }
     Mutate();                             // Suppression | Ajout | Remplacement gène par gène.
 }
        public Individual getIndividual(String type, Individual father, Individual mother)
        {
            // Creation d'un individu à partir de deux parents.
            Individual ind = null;

            switch (type)
            {
            case "Maze":
                ind = new MazeIndividual((MazeIndividual)father, (MazeIndividual)mother);
                break;

            case "TSP":
                ind = new TSPIndividual((TSPIndividual)father, (TSPIndividual)mother);
                break;
            }
            return(ind);
        }
        public Individual getIndividual(String type)
        {
            // Creation dun individu aleatoirement.
            // Paramètre : le problème à résoudre sous la forme d’une chaîne & puis les parents potentiels.
            Individual ind = null;

            switch (type)
            {
            case "Maze":
                ind = new MazeIndividual();
                break;

            case "TSP":
                ind = new TSPIndividual();
                break;
            }
            return(ind);
        }
        // Constructeur avec deux parents (crossover et mutations)
        public MazeIndividual(MazeIndividual father, MazeIndividual mother)
        {
            // Creation du genome du fils du pere et de la mere passés en paramètre.
            this.genome = new List <IGene>();
            // Crossover
            int cuttingPoint = Parameters.randomGenerator.Next(father.genome.Count); // Position du point coupure.

            foreach (MazeGene g in father.genome.Take(cuttingPoint))
            {
                this.genome.Add(new MazeGene(g));
                // Copie gene a gene du genome du pere au fils jusqu'au pt de coupure.
            }
            foreach (MazeGene g in mother.genome.Skip(cuttingPoint))
            {
                this.genome.Add(new MazeGene(g));
                // Remplissage du genome fils avec les genes du genome de la mere en commencant au pt de coupure.
            }
            // Mutation
            Mutate();             // Suppression | Ajout | Remplacement gène par gène.
        }
        internal static double Evaluate(MazeIndividual individual)
        {
            Case currentPosition = entrance; // La case courant est case de depart.

            bool end = false;

            foreach (MazeGene g in individual.genome)             // on s'arrete lorsqu’il n’y a plus de gènes à appliquer.
            {
                switch (g.direction)
                {
                case Direction.Bottom:
                    while (IsPossible(currentPosition, new Case(currentPosition.i + 1, currentPosition.j)) && !end)

                    /*La direction demandée est gardée jusqu’à ce qu’il ne soit plus possible d’avancer
                     * ou qu’on arrive à un carrefour.*/
                    {
                        currentPosition.i++;                             // on change à chaque déplacement la case sur laquelle on est.
                        end = IsJunction(currentPosition) || currentPosition.Equals(exit);
                    }
                    end = false;
                    break;

                case Direction.Top:
                    while (IsPossible(currentPosition, new Case(currentPosition.i - 1, currentPosition.j)) && !end)
                    {
                        currentPosition.i--;                            // on change à chaque déplacement la case sur laquelle on est.
                        end = IsJunction(currentPosition) || currentPosition.Equals(exit);
                    }
                    end = false;
                    break;

                case Direction.Right:
                    while (IsPossible(currentPosition, new Case(currentPosition.i, currentPosition.j + 1)) && !end)
                    {
                        currentPosition.j++;                             // on change à chaque déplacement la case sur laquelle on est.
                        end = IsJunction(currentPosition) || currentPosition.Equals(exit);
                    }
                    end = false;
                    break;

                case Direction.Left:
                    while (IsPossible(currentPosition, new Case(currentPosition.i, currentPosition.j - 1)) && !end)
                    {
                        currentPosition.j--;                             // on change à chaque déplacement la case sur laquelle on est.
                        end = IsJunction(currentPosition) || currentPosition.Equals(exit);
                    }
                    end = false;
                    break;
                }
                if (currentPosition.Equals(exit))
                {
                    // On s’arrête lorsqu’on arrive sur la case d’arrivée.
                    return(0);
                }
            }

            int distance = Math.Abs(exit.i - currentPosition.i) + Math.Abs(exit.j - currentPosition.j);

            // On calcule enfin la distance de Manhattan à la sortie, que l’on renvoie.
            return(distance);
        }