Exemplo n.º 1
0
        /// <summary>
        /// Inspiré de : https://openclassrooms.com/courses/le-backtracking-par-l-exemple-resoudre-un-sudoku
        /// </summary>
        private bool resoudre(int position, IObserverResolution observer)
        {
            observer.progressionResolution((int)((double)(position) / 81 * 100));
            // On a résolu la grille, on arrête
            if (position == DIMENSION * DIMENSION)
            {
                return(true);
            }

            // On transforme la position "linéaire" en i,j (multidimensions)
            int i = position / DIMENSION;
            int j = position % DIMENSION;

            // Si la case n'est pas vide, on passe à la prochaine
            // On est face à une case "non modifiable".
            if (!this.cases[i, j].Vide)
            {
                return(resoudre(position + 1, observer));
            }

            // Nous sommes faces à une case vide, donc il faut trouver un chiffre possible.
            // C'est ici que la "magie" du backtracking prend place. Pour une case donnée,
            // nous trouvons la première possibilité de chiffre valide. Ensuite, nous
            // enchaînons avec la prochaine case (resoudre(position++)). Si l'algorithme
            // n'arrive pas à trouver un chiffre valide à la prochaine case avec l'état
            // actuel de la grille, alors nous revenons à l'appel d'avant et nous tentons
            // de trouver le prochain chiffre valide et rappelons encore resoudre(position++).
            // Ce pattern ce répète jusqu'à la résolution de la grille complète ou bien après
            // avoir essayé toute les possibilités et finalement retourner false pour indiquer
            // que la grille n'est pas résolvable...
            for (byte chiffre = 1; chiffre <= DIMENSION; chiffre++)
            {
                if (absentSurLigne(i, chiffre) && absentSurColonne(j, chiffre) &&
                    absentDansSousGrille(i, j, chiffre))
                {
                    this.cases[i, j].Chiffre = chiffre;

                    // On passe à la prochaine case
                    if (resoudre(position + 1, observer))
                    {
                        return(true);
                    }
                }
            }

            // On a rien trouvé, on remet la case à "vide"
            this.cases[i, j].Chiffre = 0;

            return(false);
        }
Exemplo n.º 2
0
        public void resoudre(IObserverResolution observer)
        {
            if (!this.partieTerminee)
            {
                grille.resoudre(observer);
                this.partieTerminee = true;

                if (partieSauvee != null)
                {
                    daoPartie.deleteTransfertObject(partieSauvee.Id);
                    this.partieSauvee = null;
                }
            }
        }
Exemplo n.º 3
0
        internal void resoudre(IObserverResolution observer)
        {
            // On remet à l'état initial la grille
            foreach (Case c in this.cases)
            {
                if (c.Modifable)
                {
                    c.Chiffre = 0;
                }
            }

            if (!resoudre(0, observer))
            {
                throw new JeuSudokuException("La grille ne possède pas de solution!");
            }

            if (!estValide())
            {
                throw new JeuSudokuException("L'algorithme de résolution fournie une solution non valide... WTF!");
            }
        }