Пример #1
0
        //Retourne un Jeu avec une grille de sudoku générée
        //Difficulté (d) comprise entre 1 et 8 (1 très simple, 8 très compliqué)
        static public Jeu Generer(int d)
        {
            Random rand = new Random();
            Jeu    res  = new Jeu();

            Jeu[] tab = res.RempAlea(rand);
            res = tab[0];
            //Arrivé ici, res contient une grille complète
            //On détermine les chiffres que l'ont peut enlever
            //Si la difficulté n'est pas une valeur correcte, on choisi 1 par défaut
            res.Masquer(((d > 0) && (d <= 9)) ? d : 1, rand);
            return(res);
        }
Пример #2
0
        //Remplie aléatoirement une grille
        protected Jeu[] RempAlea(Random rand)
        {
            //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;

            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())
                {
                    //Console.WriteLine("Fin normale");
                    return(new Jeu[] { this });
                }
                //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())
                {
                    //Console.WriteLine("Fin impossible");
                    return(new Jeu[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_tab_jeu[x, y].NbDispo() == 0)
                        {
                            return(new Jeu[0]);
                        }
                        if (m_tab_jeu[x, y].NbDispo() == 1)
                        {
                            //Si on trouve une case avec une seule valeur possible, on rentre cette valeur
                            bool[] temp = m_tab_jeu[x, y].Dispo();
                            //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_tab_jeu[x, y].NbDispo() < m_tab_jeu[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  = m_tab_jeu[i, j].Dispo();
            int    taille = m_tab_jeu[i, j].NbDispo();
            bool   continuer;

            Jeu[] res;
            do
            {
                //On choisie une valeur aléatoire parmi celles disponnibles
                continuer = false;
                int valRand = rand.Next(taille);
                int valeur  = 0;
                for (int k = 0; valeur == 0; k++)
                {
                    if (dispo[k])
                    {
                        if (valRand == 0)
                        {
                            valeur = k + 1;
                        }
                        else
                        {
                            valRand--;
                        }
                    }
                }
                //On regarde si on peut faire une grille avec cette valeur
                Jeu temp = new Jeu(this);
                temp.Set(i, j, valeur);
                res = temp.RempAlea(rand);
                if ((taille > 1) && (res.Length == 0))
                {
                    //Si aucune grille n'a pu être remplie avec cette valeur, on la supprime des possibilités et on recommence
                    taille--;
                    dispo[valeur - 1] = false;
                    continuer         = true;
                }
            } while (continuer);
            //Lorsqu'on arrive là, on a deux possibilités
            // > res est un tableau d'une case contenant la grille aléatoire terminée
            // > res est un tableau de 0 case et le problème sera traité par la fonction précédente dans la récursion
            return(res);
        }