예제 #1
0
파일: Grille.cs 프로젝트: Elomidas/Sudoku
 //Créé une copie de la grille en paramètre
 public Grille(Grille g)
 {
     Init();
     for (int i = 0; i < 9; i++)
     {
         for (int j = 0; j < 9; j++)
         {
             m_cases[i, j].Set(g.Get(i, j));
         }
     }
 }
예제 #2
0
파일: Grille.cs 프로젝트: Elomidas/Sudoku
        //Retourne la liste des solutions possibles
        public int NbSolve()
        {
            //On regarde pour quelle case on a le moins de possibilités
            //On en profite pour remplir toutes les cases avec une seule possibilites
            //Si on a rempli au moins une case, les possibilités sont diminuées donc on recommence
            int  i, j;
            bool valeursSimples;

            Console.WriteLine("Nb possibles : " + m_cases[4, 4].NbDispo());
            do
            {
                //On fait les vérifications à chaque itération qui a pu changer une valeur
                //Si la grille est pleine et sans incohérance, on retourne 1
                if (Possible() && Remplie())
                {
                    return(1);
                }
                //Si elle n'est pas cohérente, on retourne 0
                if (!Possible())
                {
                    return(0);
                }
                //On regarde les possibilités
                i = 0;
                j = 0;
                //On réinitialise notre valeur pour ne pas avoir de boucle infinie
                valeursSimples = false;
                for (int x = 0; (x < 9); x++)
                {
                    for (int y = 0; (y < 9); y++)
                    {
                        if (m_cases[x, y].NbDispo() == 0)
                        {
                            return(0);
                        }
                        if (m_cases[x, y].NbDispo() == 1)
                        {
                            bool[] temp = Possibilites(x, y);
                            valeursSimples = true;
                            for (int z = 0; z < 9; z++)
                            {
                                if (temp[z])
                                {
                                    Set(x, y, (z + 1));
                                }
                            }
                        }
                        else if ((!valeursSimples) && (m_cases[x, y].NbDispo() < m_cases[i, j].NbDispo()))
                        {
                            i = x;
                            j = y;
                        }
                    }
                }
            } while (valeursSimples);
            //On fait en fonction des possibilités disponnibles
            bool[] dispo = Possibilites(i, j);
            int    res   = 0;

            for (int k = 0; k < 9; k++)
            {
                Console.WriteLine((1 + k) + " " + (dispo[k] ? "dispo" : "pas dispo"));
                if (dispo[k])
                {
                    Console.WriteLine("Supposition : " + (k + 1));
                    Grille temp = new Grille(this);
                    temp.Set(i, j, (k + 1));
                    res += temp.NbSolve();
                }
            }
            return(res);
        }
예제 #3
0
파일: Grille.cs 프로젝트: Elomidas/Sudoku
        //Retourne la liste des solutions possibles
        public Grille[] Solve()
        {
            //On charche pour quelle case on a le moins de possibilités
            //Pour optimiser l'algorithme on remplie toutes les cases avec une seule possibilité
            //Si on a rempli au moins une case, les possibilités sont diminuées donc on recommence la recherche
            //Enfin s'il n'y a plus que des cases avec plusieurs possibilités, on selectionne celle qui en a le moins
            //On créé une nouvelle grille pour chaque possibilité de la case choisie et on réappelle cette fonction pour essayer de resoudre la grille
            int  i, j;
            bool valeursSimples;

            Console.WriteLine("Nb possibles : " + m_cases[4, 4].NbDispo());
            do
            {
                //On fait les vérifications à chaque itération car une valeur a pu être entrée alors qu'elle est erronnée
                //Si la grille est pleine et sans incohérance, on retourne 1
                if (Possible() && Remplie())
                {
                    return(new Grille[0]);
                }
                //Si elle n'est pas cohérente, on retourne 0
                //Une grille est incohérente si on a une case vide avec aucune possibilité ou plusieurs fois le même chiffre dans des carrés, colonnes ou lignes
                if (!Possible())
                {
                    return(new Grille[0]);
                }
                //On regarde les possibilités
                i = 0;
                j = 0;
                //On réinitialise notre valeur de test de while() pour ne pas avoir de boucle infinie
                valeursSimples = false;
                for (int x = 0; (x < 9); x++)
                {
                    for (int y = 0; (y < 9); y++)
                    {
                        //Si on a une case vide sans valeurs possible la grille est incohérente
                        if (m_cases[x, y].NbDispo() == 0)
                        {
                            return(new Grille[0]);
                        }
                        if (m_cases[x, y].NbDispo() == 1)
                        {
                            //Si on trouve une case avec une seule valeur possible, on rentre cette valeur
                            bool[] temp = Possibilites(x, y);
                            //L'ajout d'une valeur a modifié les possibilités des cases sur ses ligne, colonne et carré
                            //Il faut donc revérifier les cases au dessus de celle-ci, c'est pourquoi on recommence la boucle
                            valeursSimples = true;
                            for (int z = 0; z < 9; z++)
                            {
                                if (temp[z])
                                {
                                    Set(x, y, (z + 1));
                                }
                            }
                        }
                        else if ((!valeursSimples) && (m_cases[x, y].NbDispo() < m_cases[i, j].NbDispo()))
                        {
                            //On ne continue de chercher la case avec le moins de possibilité que si aucune case ayant une seule possibilité n'a été trouvée
                            //En effet, dans ce cas les probabilités ont changé donc la recherche est faussée pour cette boucle
                            i = x;
                            j = y;
                        }
                    }
                }
            } while (valeursSimples);
            //On fait en fonction des possibilités disponnibles
            bool[]   dispo = Possibilites(i, j);
            Grille[] res   = new Grille[0];
            for (int k = 0; k < 9; k++)
            {
                if (dispo[k])
                {
                    Grille temp = new Grille(this);
                    temp.Set(i, j, (k + 1));
                    Grille[] rTemp   = temp.Solve();
                    int      taille  = res.Length + rTemp.Length;
                    Grille[] resTemp = new Grille[taille];
                    for (int a = 0; a < taille; a++)
                    {
                        resTemp[a] = (a < res.Length) ? res[a] : rTemp[a - res.Length];
                    }
                    res = resTemp;
                }
            }
            return(res);
        }