示例#1
0
        public bool VyresRekurzivne(Bunka dalsiBunka)   //dalsiBunka je bunka s minimem vhodnych kandidatu
        {
            //Vyřešeno
            if (dalsiBunka.Equals(new Bunka(-1, -1)))
            {
                Console.WriteLine("Sudoku is solved, Huray!");
                return(true);
            }

            foreach (int kandidat in omezeniBunek[dalsiBunka.Radek, dalsiBunka.Sloupec])
            {
                ZvolKandidata(dalsiBunka, kandidat);

                //Backtracking
                if (VyresRekurzivne(DalsiBunka()) == false)
                {
                    OdeberKandidata(dalsiBunka, kandidat);
                    continue;
                }
                //Vyřešeno dříve
                else
                {
                    return(true);
                }
            }

            //Nemůže pokračovat dále, postup neodpovídá řešení
            return(false);
        }
示例#2
0
        public Bunka DalsiBunka()
        {
            pocetKroku++;
            if (nevyresene.Count == 0)
            {
                return(new Bunka(-1, -1));
            }

            Bunka min = nevyresene.First();

            foreach (Bunka bunka in nevyresene)
            {
                min = (omezeniBunek[bunka.Radek, bunka.Sloupec].Pocet < omezeniBunek[min.Radek, min.Sloupec].Pocet) ? bunka : min;
            }

            return(min);
        }
示例#3
0
        public void OdeberKandidata(Bunka bunka, int kandidat)
        {
            sudokuResene[bunka.Radek, bunka.Sloupec] = 0;

            //Vypnout omezení Řádek, Sloupec, Region
            omezeniRadku[bunka.Radek][kandidat]     = false;
            omezeniSloupce[bunka.Sloupec][kandidat] = false;
            omezeniRegionu[bunka.Radek / 3, bunka.Sloupec / 3][kandidat] = false;

            //Nastavi cislo zpet jako vhodneho kandidata pro zmenene bunky
            omezeniBunek[bunka.Radek, bunka.Sloupec][kandidat] = true;
            foreach (Bunka b in zmenene.Pop())
            {
                omezeniBunek[b.Radek, b.Sloupec][kandidat] = true;
            }

            vyresene.Remove(bunka);
            nevyresene.Add(bunka);
        }
示例#4
0
        //Dosazeni omezeni do nevyresenych poli
        private void OmezitKandidaty()
        {
            for (int radek = 0; radek < 9; radek++)
            {
                for (int sloupec = 0; sloupec < 9; sloupec++)
                {
                    //V případě, že pole je vyřešené
                    if (sudokuResene[radek, sloupec] > 0)
                    {
                        //Vyřešené pole nepotřebuje kandidáty
                        omezeniBunek[radek, sloupec].NastavVsechnyNaHodnotu(false);
                        vyresene.Add(new Bunka(radek, sloupec));
                    }
                    else
                    {
                        //Najdu nevyřešené číslo a chci mu přiřadit omezení na kandidáty
                        //1) Podívám se jestli tam vůbec nějaké omezení je:
                        //2) Pokud ano, překopíruji číslo z omezení a v kandidátu buňky ho nastavým jako neplatné
                        foreach (int cislo in omezeniRadku[radek])
                        {
                            omezeniBunek[radek, sloupec][cislo] = false;
                        }

                        foreach (int cislo in omezeniSloupce[sloupec])
                        {
                            omezeniBunek[radek, sloupec][cislo] = false;
                        }


                        foreach (int cislo in omezeniRegionu[radek / 3, sloupec / 3])
                        {
                            omezeniBunek[radek, sloupec][cislo] = false;
                        }

                        Bunka b = new Bunka(radek, sloupec);
                        nevyresene.Add(b);
                    }
                }
            }
        }
示例#5
0
        public void ZvolKandidata(Bunka bunka, int kandidat)
        {
            HashSet <Bunka> zmeneneBunky = new HashSet <Bunka>();

            // Vybrat prvního kandidáta
            sudokuResene[bunka.Radek, bunka.Sloupec]           = kandidat;
            omezeniBunek[bunka.Radek, bunka.Sloupec][kandidat] = false;

            omezeniRadku[bunka.Radek][kandidat]     = true;
            omezeniSloupce[bunka.Sloupec][kandidat] = true;
            omezeniRegionu[bunka.Radek / 3, bunka.Sloupec / 3][kandidat] = true;


            // Odeberu kandidáty z polí souvisejici se zmenenou bunkou
            for (int i = 0; i < 9; i++)
            {
                if (sudokuResene[bunka.Radek, i] == 0)
                {
                    // radek
                    if (omezeniBunek[bunka.Radek, i][kandidat] == true)
                    {
                        omezeniBunek[bunka.Radek, i][kandidat] = false;

                        zmeneneBunky.Add(new Bunka(bunka.Radek, i));
                    }
                }

                if (sudokuResene[i, bunka.Sloupec] == 0)
                {
                    // sloupec
                    if (omezeniBunek[i, bunka.Sloupec][kandidat] == true)
                    {
                        omezeniBunek[i, bunka.Sloupec][kandidat] = false;

                        zmeneneBunky.Add(new Bunka(i, bunka.Sloupec));
                    }
                }
            }

            // region
            int pocatek_radkuR   = bunka.Radek / 3 * 3;
            int pocatek_sloupceR = bunka.Sloupec / 3 * 3;

            for (int radek = pocatek_radkuR; radek < pocatek_radkuR + 3; radek++)
            {
                for (int sloupec = pocatek_sloupceR; sloupec < pocatek_sloupceR + 3; sloupec++)
                {
                    // only change unsolved cells containing the candidate
                    if (sudokuResene[radek, sloupec] == 0)
                    {
                        if (omezeniBunek[radek, sloupec][kandidat] == true)
                        {
                            //remove the candidate
                            omezeniBunek[radek, sloupec][kandidat] = false;

                            //update changed cells (for backtracking)
                            zmeneneBunky.Add(new Bunka(radek, sloupec));
                        }
                    }
                }
            }

            nevyresene.Remove(bunka);
            vyresene.Add(bunka);
            zmenene.Push(zmeneneBunky);
        }