Beispiel #1
0
        protected override bool isSolution(IState state)
        {
            SudokuState s = (SudokuState)state;

            return(s.Rozwiazanie());
            //    return state.H == 0.0;
        }
Beispiel #2
0
        public SudokuState(SudokuState parent, int newValue, int x, int y) : base(parent)
        {
            this.table = new int[GRID_SIZE, GRID_SIZE];

            // Skopiowanie stanu sudoku do nowej tabeli
            Array.Copy(parent.table, this.table, this.table.Length);

            // Ustawienie nowej wartosci w wybranym polu sudoku
            this.table[x, y] = newValue;



            StringBuilder builder = new StringBuilder(parent.id);

            builder[x * GRID_SIZE + y] = (char)(newValue + 48);
            this.id = builder.ToString();

            this.h = ComputeHeuristicGrade(x, y, false);

            //Tworzymy tablice heurystyk komórek węzła z Talicy
            for (int i = 0; i < GRID_SIZE; ++i)
            {
                for (int j = 0; j < GRID_SIZE; ++j)
                {
                    this.heuristic_array[i, j] = ComputeHeuristicGrade(i, j, true);
                }
            }

            //Console.Clear();
            //this.Print();
            //Thread.Sleep(15);
        }
Beispiel #3
0
        static void Main(string [] args)
        {
            Stopwatch sw = Stopwatch.StartNew();

            //string sudokuPattern = "123456789123456789123456789123456789123456789123456789123456789123456789123456789"; //sudoku w postaci stringa np.: " 010330218... "
            //string sudokuPattern = "294167358315489627678253491456312879983574216721698534562941783839726145147835962"; //sudoku w postaci stringa np.: " 010330218... "
            string sudokuPattern = "204107358315489627678053491406302879983004216721698534002941783039726045147835062"; //sudoku w postaci stringa np.: " 010330218... "
            //string sudokuPattern = "004100308010000620008200400000302809000070000701608000562001703030000040100005000";

            SudokuState  startState = new SudokuState(sudokuPattern);
            SudokuSearch searcher   = new SudokuSearch(startState);

            searcher.DoSearch();

            IState state = searcher.Solutions [0];

            List <SudokuState> solutionPath = new List <SudokuState>();

            while (state != null)
            {
                solutionPath.Add(( SudokuState )state);
                state = state.Parent;
            }
            solutionPath.Reverse();

            foreach (SudokuState s in solutionPath)
            {
                s.Print();
            }
            sw.Stop();
            Console.WriteLine("Czas: " + sw.ElapsedMilliseconds + "ms");
            Console.ReadKey();
        }
Beispiel #4
0
        public static void start(string sudokuPattern)
        {
            Stopwatch stopWatch_search = new Stopwatch();
            Stopwatch stopWatch_print  = new Stopwatch();

            SudokuState  startState = new SudokuState(sudokuPattern);
            SudokuSearch searcher   = new SudokuSearch(startState);


            stopWatch_search.Start();

            searcher.DoSearch();
            stopWatch_search.Stop();

            TimeSpan t_search = stopWatch_search.Elapsed;

            IState state = searcher.Solutions[0];

            List <SudokuState> solutionPath = new List <SudokuState>();

            while (state != null)
            {
                solutionPath.Add((SudokuState)state);
                state = state.Parent;
            }
            solutionPath.Reverse();

            int[,] table_tmp1 = new int[9, 9];
            int[,] table_tmp2 = new int[9, 9];

            table_tmp1 = solutionPath[0].Table;


            stopWatch_print.Start();

            foreach (SudokuState s in solutionPath)
            {
                table_tmp2 = table_tmp1;
                table_tmp1 = s.Table;

                s.Print(table_tmp2, table_tmp1);
            }
            stopWatch_print.Stop();
            TimeSpan t_print = stopWatch_print.Elapsed;

            string SearchTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                              t_search.Hours, t_search.Minutes, t_search.Seconds,
                                              t_search.Milliseconds / 10);

            Console.WriteLine("Czas przeszukiwania " + SearchTime);

            string PrintTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                             t_print.Hours, t_print.Minutes, t_print.Seconds,
                                             t_print.Milliseconds / 10);

            Console.WriteLine("Czas wyswietlania " + PrintTime);
        }
        //Konstruktor tworzący stany potomne na podstawie rodzica
        //Kopiuje pola stanu rodzicielskiego, wstawia nową wartość i oblicza wartość heurystyczną nowego stanu
        public SudokuState(SudokuState parent, int newValue, int x, int y) : base(parent)
        {
            this.table = new int[GRID_SIZE, GRID_SIZE];
            Array.Copy(parent.table, this.table, this.table.Length);
            this.table[x, y] = newValue;

            StringBuilder builder = new StringBuilder(parent.id);

            builder[x * GRID_SIZE + y] = (char)(newValue + 48);
            this.id = builder.ToString();

            this.h = ComputeHeuristicGrade();
        }
Beispiel #6
0
        protected override void buildChildren(IState parent)
        {
            SudokuState state = (SudokuState)parent;

            // poszukiwanie wolnego pola
            for (int i = 1; i < 10; i++)
            {
                if (state._tab[i] == 0)
                {
                    SudokuState child = new SudokuState(state, i, state._x, state._y);
                    parent.Children.Add(child);
                }
            }
        }
Beispiel #7
0
 public SudokuState(SudokuState aParent, int aRows, int aColumns, int aNumber) // tworzymy stan jako dziecko stanu rodzicielskiego (analogicznie jak np. w drzewie BST)
 {                                                                             // stan taki bedzie identyczny jak jego rodzic z tym, ze 1 komorka bedzie inna (liczba ktora dodalismy na plansze w jakiejs kratce)
     this.board = new int[9, 9];
     for (int i = 0; i < 9; ++i)
     {
         for (int j = 0; j < 9; ++j)
         {
             this.board [i, j] = aParent.board [i, j];                     // kopiujemy plansze od rodzica
         }
     }
     this.Parent = aParent;                 // ustawiamy, ze rodzic tego stanu to podany aParent
     this.board[aRows, aColumns] = aNumber; // ustawiamy dana komorke planszy na inna wartosc, okresla ja aNumber
     aParent.Children.Add(this);            // ustawiamy w rodzicu, ze ten stan bedzie jednym z jego dzieci
     this.h = ComputeHeuristicGrade();      // obliczamy heurystyke tego stanu
 }
        protected override void buildChildren(IState parent)
        {
            SudokuState state = (SudokuState)parent;

            state.findBeginField(useAdvancedHeuristic);

            for (int k = 1; k < SudokuState.GRID_SIZE + 1; k++)
            {
                //Console.Write(String.Format("k: {0}, xy({1},{2})\n", k, state.xyBegin[0], state.xyBegin[1]));
                if (state.isNumberCorrect(k, state.xyBegin[0], state.xyBegin[1]))
                {
                    SudokuState child = new SudokuState(state, k, state.xyBegin[0], state.xyBegin[1]);
                    parent.Children.Add(child);
                }
            }
            return;
        }
Beispiel #9
0
        public SudokuState(SudokuState parent, int newValue, int x, int y)
            : base(parent)
        {
            this.table = new int[GRID_SIZE, GRID_SIZE];
            // Skopiowanie stanu sudoku do nowej tabeli
            Array.Copy(parent.table, this.table, this.table.Length);
            // Ustawienie nowej wartosci w wybranym polu sudoku
            this.table[x, y] = newValue;

            // Utworzenie nowego id odpowiadajacemu aktualnemu stanowi planszy
            StringBuilder builder = new StringBuilder(parent.id);

            builder[x * GRID_SIZE + y] = (char)(newValue + 48);
            this.id = builder.ToString();

            this.h = ComputeHeuristicGrade();
        }
Beispiel #10
0
        static void Main(string[] args)
        {
            //string sudokuPattern = "000079065000003002005060093340050106000000000608020059950010600700600000820390000";
            string sudokuPattern = "002008050000040070480072000008000031600080005570000600000960048090020000030800900";
            //  String sudokuPattern = "219685743400000001800000005600000007547218936900000004100000008700000009386549172";


            SudokuState startState = new SudokuState(sudokuPattern);

            startState.Print();

            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();


            SudokuSearch searcher = new SudokuSearch(startState);

            searcher.DoSearch();


            IState state = searcher.Solutions [0];

            List <SudokuState> solutionPath = new List <SudokuState>();

            while (state != null)
            {
                solutionPath.Add(( SudokuState )state);
                state = state.Parent;
            }

            stopwatch.Stop();

            solutionPath.Reverse();
            foreach (SudokuState s in solutionPath)
            {
                Console.Clear();
                s.Print();
                Console.ReadKey();
            }
            Console.WriteLine();
            Console.WriteLine("Czas obliczen: {0}", stopwatch.Elapsed);

            Console.ReadKey();
        }
Beispiel #11
0
        static void sudoku(bool UseAdvancedSearch)
        {
            string[] heuristicType = { "Simple", "Advanced" };
            string[] hash          = { "800030000930007000071520900005010620000050000046080300009076850060100032000040006", "000000600600700001401005700005900000072140000000000080326000010000006842040002930", "457682193600000007100000004200000006584716239300000008800000002700000005926835471", "000012034000056017000000000000000000480000051270000048000000000350061000760035000", "000700800000040030000009001600500000010030040005001007500200600030080090007000002", "100040002050000090008000300000509000700080003000706000007000500090000040600020001", "600040003010000070005000800000502000300090002000103000008000900070000050200030004", "000000000000003085001020000000507000004000100090000000500000073002010000000040009", "000040700080000000010000020000800006700000050400000200302070000000000000000006018" };
            string   SudokuPattern;

            int m = getInt("Choice Sudoku: ");

            SudokuPattern = hash[(m > hash.Length ? hash.Length - 1 : m)];

            SudokuState  startState = new SudokuState(SudokuPattern);
            SudokuSearch searcher   = new SudokuSearch(startState, UseAdvancedSearch);

            searcher.DoSearch();

            IState             state        = searcher.Solutions[0];
            List <SudokuState> solutionPath = new List <SudokuState>();

            while (state != null)
            {
                solutionPath.Add((SudokuState)state);
                state = state.Parent;
            }
            solutionPath.Reverse();


            foreach (SudokuState s in solutionPath)
            {
                s.Print();
            }

            string data = string.Format("{0} heuristic: \nSteps: {1}, \ncreated {2} board objects",
                                        heuristicType[UseAdvancedSearch ? 0 : 1], solutionPath.Count, SudokuState.counter);

            Console.Write(data);
            Console.Write("\nOpen: " + searcher.Open.Count);
            Console.Write("\nClose: " + searcher.Closed.Count);
            Console.Write("\n\nPress key to menu -> ");

            // Cleaning
            SudokuState.counter  = 0;
            SudokuState.slowdown = false;
        }
Beispiel #12
0
        }                                                                   // dziedziczy cały konstruktor po AStartSearch

        protected override void buildChildren(IState parent)
        {
            SudokuState state = (SudokuState)parent;

            // Każdy węzeł ma swoją tablice heurystyczna tworzoną w jego kontruktorze.

            double F_max = 0;

            for (int i = 0; i < SudokuState.GRID_SIZE; ++i)
            {
                for (int j = 0; j < SudokuState.GRID_SIZE; ++j)
                {
                    if ((state.Heuristic_array[i, j] > F_max) && (state.Heuristic_array[i, j] != state.infinity))
                    {
                        F_max = state.Heuristic_array[i, j];
                    }
                }
            }


            for (int m = 1; m <= F_max; m++)// nie wiem czy m od 0 czy od 1
            {
                for (int i = 0; i < SudokuState.GRID_SIZE; ++i)
                {
                    for (int j = 0; j < SudokuState.GRID_SIZE; ++j)
                    {
                        //ważne aby rodzic dzieci tylko w pustych miejscach - inaczej bedziemy mieli konflikt id
                        if ((state.Heuristic_array[i, j] == m))
                        {
                            for (int k = 1; k < SudokuState.GRID_SIZE + 1; ++k)
                            {
                                SudokuState child = new SudokuState(state, k, i, j);
                                parent.Children.Add(child);
                            }
                            break; //zastanawia mnie ten break; po co wychodzi
                        }
                    }
                }
            }
        }
Beispiel #13
0
        protected override void buildChildren(IState parent)
        {
            SudokuState        state          = (SudokuState)parent;      //Pobranie stanu rodzicielskiego, z którego tworzymy stany potomne
            List <SudokuField> minMovesFields = new List <SudokuField>(); //Lista pól wymagających najmniej ruchów
            SudokuField        minMovesField  = state.emptyFields[0];     //Pobranie pierwszego pustego pola ze stanu rodzicielskiego

            //Wyszukiwanie pola wymagającego najmniej ruchów
            for (int i = 1; i < state.emptyFields.Count; ++i)
            {
                if (state.emptyFields[i].availableMoves.Count < minMovesField.availableMoves.Count)
                {
                    minMovesField = state.emptyFields[i];
                }
            }
            minMovesFields.Add(minMovesField);  //Zapisanie pierwszego pola wymagającego najmniej ruchów

            //Wyszukiwanie pól wymagających tyle samo ruchów
            foreach (SudokuField i in state.emptyFields)
            {
                if (i != minMovesField)
                {
                    if (i.availableMoves.Count == minMovesField.availableMoves.Count)
                    {
                        minMovesFields.Add(i);
                    }
                }
            } //Lista minMovesFields zawiera pola wymagające najmniej ruchów

            //Tworzenie nowych stanów potomnych:
            foreach (SudokuField i in minMovesFields)                            //dla wszystkich pustych pól o minimanej liczbie ruchów
            {
                foreach (int j in i.availableMoves)                              //dla każdego możliwego ruchu (zawsza taka sama ilość dla konkretnego stanu rodzicielskiego)
                {
                    SudokuState child = new SudokuState(state, j, i.row, i.col); // parent, value, row, col
                    parent.Children.Add(child);
                }
            }
        }
        static void Main(string[] args)
        {
            SudokuState  theState    = new SudokuState("800030000930007000071520900005010620000050000046080300009076850060100032000040006");
            SudokuSearch theSearcher = new SudokuSearch(theState);                // tworzymy szukacz na podstawie pierwszego stanu

            theSearcher.DoSearch();                                               // szukacz wykonuje algorytm A*  znajduje droge od pierwszego stanu do rozwiazania
            List <SudokuState> states    = new List <SudokuState>();              // tworzymy liste stanow
            SudokuState        theResult = (SudokuState)theSearcher.Solutions[0]; // do zmiennej theResult przypisujemy stan z rozwiazaniem znalezionym przez szukacz

            while (theResult != null)                                             // do kolejnych elementow listy states wpisujemy kolejne stany po drodze od stanu poczatkowego do rozwiazania
            {
                states.Add(theResult);
                theResult = (SudokuState)theResult.Parent;
            }
            for (int i = states.Count() - 1; i > 0; --i)            // od tylu wypisujemy stany; od poczatku do rozwiazania
            {
                states.ElementAt(i).Write();
                Console.WriteLine("Jeszcze " + i + " stanow do rozwiazania");
                Thread.Sleep(300);
                Console.Clear();         // czyscimy konsole
            }
            states.ElementAt(0).Write(); // wypisujemy ostateczne rozwiazanie na sam koniec
        }
Beispiel #15
0
        protected override void buildChildren(IState parent)
        {
            SudokuState state = ( SudokuState )parent;

            // poszukiwanie wolnego pola
            //Console.WriteLine("trzy");
            for (int i = 0; i < SudokuState.GRID_SIZE; ++i)
            {
                for (int j = 0; j < SudokuState.GRID_SIZE; ++j)
                {
                    if (state.Table[i, j] == 0)
                    {
                        // wstawianie kolejnych potomkow w wolne pole
                        for (int k = 1; k < SudokuState.GRID_SIZE + 1; ++k)
                        {
                            SudokuState child = new SudokuState(state, k, i, j);
                            parent.Children.Add(child);
                        }
                        break;
                    }
                }
            }
        }
 public SudokuSearch(SudokuState aState) : base(aState, true, true)
 {
 }
        public SudokuSearch(SudokuState state, bool advancedHeuristic = false) : base(state)
        {
            useAdvancedHeuristic = advancedHeuristic;

            state.findBeginField(useAdvancedHeuristic);
        }
Beispiel #18
0
        static void Main(string[] args)
        {
            Console.BufferHeight = 1000;

            DialogResult dialogResult_sudoku = MessageBox.Show("Chesz zobaczyć sudoku? ( ͡° ͜ʖ ͡°)", "", MessageBoxButtons.YesNo);

            if (dialogResult_sudoku == DialogResult.Yes)
            {
                string sudokuPattern = "083279465409583710270461893342058176597106284618720359954812037701645908826397540"; // sudoku w postaci stringa np .:" 010330218... "
                #region test
                //040000065469583712275461893342958176597136284618724359954812637731645928826397541
                //183279465469583712275461893342958176597136284618724359954812637731645928826397541

                /*"040 000 065
                 * 469 583 712
                 * 275 461 893
                 *
                 * 342 958 176
                 * 597 136 284
                 * 618 724 359
                 *
                 * 954 812 637
                 * 731 645 928
                 * 826 397 541"
                 */
                //000000465469583712275461893342958176597136284618724359954812637731645928826397541
                //000079065000003002005060093340050106000000000608020059950010600700600000820390000
                #endregion //test

                SudokuState.start(sudokuPattern);
                Console.ReadLine();
            }

            DialogResult dialogResult_puzzle = MessageBox.Show("A puzzle? ( ͡° ͜ʖ ͡°)", "", MessageBoxButtons.YesNo);
            if (dialogResult_puzzle == DialogResult.Yes)
            {
                int puzzlesize = 3;
                PuzzleState.PuzzleSize = puzzlesize;
                Laboratory1_m.PuzzleState.PuzzleSize = puzzlesize;
                gen();

                Stopwatch stopWatch_tails = new Stopwatch();
                stopWatch_tails.Start();
                PuzzleState.start(puzzlesize);
                stopWatch_tails.Stop();

                Stopwatch stopWatch_man = new Stopwatch();
                stopWatch_man.Start();
                Laboratory1_m.PuzzleState.start(puzzlesize);
                stopWatch_man.Stop();

                TimeSpan t_search   = stopWatch_tails.Elapsed;
                string   SearchTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                                    t_search.Hours, t_search.Minutes, t_search.Seconds,
                                                    t_search.Milliseconds / 10);
                Console.WriteLine("Calkowity czas tails: " + SearchTime);

                t_search   = stopWatch_man.Elapsed;
                SearchTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                           t_search.Hours, t_search.Minutes, t_search.Seconds,
                                           t_search.Milliseconds / 10);
                Console.WriteLine("Calkowity czas man: " + SearchTime);

                Console.ReadLine();
            }
        }
Beispiel #19
0
 public SudokuSearch(SudokuState state) : base(state, true, true)
 {
 }                                                                   // dziedziczy cały konstruktor po AStartSearch
Beispiel #20
0
 public SudokuSearch(SudokuState state) : base(state)
 {
 }
Beispiel #21
0
        static void Main(string[] args)
        {
            bool puzzle = true;
            bool sudoku = false;

            if (sudoku)
            {
                List <string> sudokuPatterns = new List <string>();
                sudokuPatterns.Add("800030000930007000071520900005010620000050000046080300009076850060100032000040006");
                sudokuPatterns.Add("000000600600700001401005700005900000072140000000000080326000010000006842040002930");
                sudokuPatterns.Add("457682193600000007100000004200000006584716239300000008800000002700000005926835471");
                //sudokuPatterns.Add("000012034000056017000000000000000000480000051270000048000000000350061000760035000"); //not enough memory
                //sudokuPatterns.Add("000700800000040030000009001600500000010030040005001007500200600030080090007000002"); //not enough memory
                //sudokuPatterns.Add("100040002050000090008000300000509000700080003000706000007000500090000040600020001"); //not enough memory

                foreach (string pattern in sudokuPatterns)
                {
                    //Sprawdzenie ilości pustych pól
                    int emptyFieldsCount = 0;
                    for (int i = 0; i < pattern.Length; ++i)
                    {
                        if (pattern[i] == '0')
                        {
                            emptyFieldsCount++;
                        }
                    }

                    SudokuState  startState = new SudokuState(pattern); //Stan startowy
                    SudokuSearch searcher   = new SudokuSearch(startState);

                    System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
                    watch.Start();
                    searcher.DoSearch();
                    watch.Stop();

                    IState             state        = searcher.Solutions[0];
                    List <SudokuState> solutionPath = new List <SudokuState>();

                    while (state != null)
                    {
                        solutionPath.Add((SudokuState)state);
                        state = state.Parent;
                    }
                    solutionPath.Reverse();

                    foreach (SudokuState s in solutionPath)
                    {
                        s.Print();
                        Console.WriteLine();
                    }
                    Console.WriteLine("Empty fields count: {0}", emptyFieldsCount);
                    Console.WriteLine("States count in Open: {0}", searcher.Open.Count);
                    Console.WriteLine("States count in Closed: {0}", searcher.Closed.Count);
                    Console.WriteLine("Time: {0}s", watch.ElapsedMilliseconds / 1000.0);

                    Console.ReadKey();
                }
            }

            if (puzzle)
            {
                const int TESTS_NUMBER = 100;
                Console.WriteLine("Creating {0} puzzles.", TESTS_NUMBER);

                PuzzleState[] startStatesMisplaced = new PuzzleState[TESTS_NUMBER];
                PuzzleState[] startStatesManhattan = new PuzzleState[TESTS_NUMBER];
                Random        random = new Random();

                for (int i = 0; i < TESTS_NUMBER; ++i) //Tworzenie 100 stanów startowych puzzli
                {
                    startStatesMisplaced[i] = new PuzzleState(random, true);
                    startStatesManhattan[i] = new PuzzleState(startStatesMisplaced[i], false);
                }

                double misplacedTilesTimeSum = 0.0;
                double manhattanTimeSum      = 0.0;

                long misplacedTilesOpenSum   = 0;
                long misplacedTilesClosedSum = 0;
                long manhattanOpenSum        = 0;
                long manhattanClosedSum      = 0;

                double misplacedTilesPathLength = 0.0;
                double manhattanPathLength      = 0.0;

                Console.WriteLine("Attempting to solve the puzzles using Misplaced Tiles heuristic:");
                for (int i = 0; i < TESTS_NUMBER; ++i)
                {
                    Console.WriteLine("Puzzle no. " + i);
                    PuzzleSearch searcher = new PuzzleSearch(startStatesMisplaced[i]);
                    searcher.DoSearch();
                    IState             state        = searcher.Solutions[0];
                    List <PuzzleState> solutionPath = new List <PuzzleState>();

                    while (state != null)
                    {
                        solutionPath.Add((PuzzleState)state);
                        state = state.Parent;
                    }
                    solutionPath.Reverse();

                    foreach (PuzzleState s in solutionPath)
                    {
                        s.Print();
                        Console.WriteLine();
                    }

                    System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
                    watch.Start();
                    searcher.DoSearch();
                    watch.Stop();

                    misplacedTilesTimeSum    += watch.ElapsedMilliseconds;
                    misplacedTilesOpenSum    += searcher.Open.Count;
                    misplacedTilesClosedSum  += searcher.Closed.Count;
                    misplacedTilesPathLength += searcher.Solutions[0].G;

                    Console.WriteLine("\tNumber of states in Open set: " + searcher.Open.Count);
                    Console.WriteLine("\tNumber of states in Closed set: " + searcher.Closed.Count);
                    Console.WriteLine("\tSolution path length: " + searcher.Solutions[0].G);
                    Console.WriteLine("\tElapsed time: {0}s.", watch.ElapsedMilliseconds / 1000.0);
                }

                Console.WriteLine();
                Console.WriteLine("Attempting to solve the puzzles using Manhattan heuristic: ");
                for (int i = 0; i < TESTS_NUMBER; ++i)
                {
                    Console.WriteLine("Puzzle no. {0}.", i + 1);
                    PuzzleSearch searcher = new PuzzleSearch(startStatesManhattan[i]);

                    System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
                    watch.Start();
                    searcher.DoSearch();
                    watch.Stop();

                    manhattanTimeSum    += watch.ElapsedMilliseconds;
                    manhattanOpenSum    += searcher.Open.Count;
                    manhattanClosedSum  += searcher.Closed.Count;
                    manhattanPathLength += searcher.Solutions[0].G;

                    Console.WriteLine("\tNumber of states in Open set: " + searcher.Open.Count);
                    Console.WriteLine("\tNumber of states in Closed set: " + searcher.Closed.Count);
                    Console.WriteLine("\tSolution path length: " + searcher.Solutions[0].G);
                    Console.WriteLine("\tElapsed time: {0}s.", watch.ElapsedMilliseconds / 1000.0);
                }
                Console.WriteLine();

                Console.WriteLine("Misplaced Tiles heuristic: ");
                Console.WriteLine("\tAverage time: {0}s.", misplacedTilesTimeSum / 1000.0 / TESTS_NUMBER);
                Console.WriteLine("\tAverage Open states number: " + misplacedTilesOpenSum / TESTS_NUMBER);
                Console.WriteLine("\tAverage Closed states number: " + misplacedTilesClosedSum / TESTS_NUMBER);
                Console.WriteLine("\tAverage solution path length: " + misplacedTilesPathLength / TESTS_NUMBER);
                Console.WriteLine();

                Console.WriteLine("Manhattan heuristic: ");
                Console.WriteLine("\tAverage time: {0}s.", manhattanTimeSum / 1000.0 / TESTS_NUMBER);
                Console.WriteLine("\tAverage Open states number: " + manhattanOpenSum / TESTS_NUMBER);
                Console.WriteLine("\tAverage Closed states number: " + manhattanClosedSum / TESTS_NUMBER);
                Console.WriteLine("\tAverage solution path length: " + manhattanPathLength / TESTS_NUMBER);
                Console.ReadKey();
            }
        }
        protected override void buildChildren(IState aParent)
        {
            SudokuState state = (SudokuState)aParent;
            int         x     = 0;
            int         y     = 0;

            int [] tab;
            int [] tab2 = new int[9];
            for (int i = 0; i < 9; ++i)
            {
                tab2[i] = 0;
            }
            int spr, tmp = 0;

            for (int i = 0; i < 9; ++i)
            {
                for (int j = 0; j < 9; ++j)
                {
                    tab = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
                    spr = 0;
                    if (state.Board[i, j] == 0)
                    {
                        for (int k = 0; k < 9; ++k)
                        {
                            if (state.Board [i, k] != 0 && k != j)
                            {
                                tab[state.Board[i, k] - 1] = 0;
                            }
                            if (state.Board [k, j] != 0 && k != i)
                            {
                                tab[state.Board[k, j] - 1] = 0;
                            }

                            for (int l = 0; l < 9; ++l)
                            {
                                if (k == i && l == j)
                                {
                                    continue;
                                }

                                if (i <= 2 && k > 2)
                                {
                                    continue;
                                }
                                if (j <= 2 && l > 2)
                                {
                                    continue;
                                }

                                if (i > 2 && i <= 5 && (k <= 2 || k > 5))
                                {
                                    continue;
                                }
                                if (j > 2 && j <= 5 && (l <= 2 || l > 5))
                                {
                                    continue;
                                }

                                if (i > 5 && k <= 5)
                                {
                                    continue;
                                }
                                if (j > 5 && l <= 5)
                                {
                                    continue;
                                }

                                if (state.Board[k, l] != 0)
                                {
                                    tab[state.Board[k, l] - 1] = 0;
                                }
                            }
                        }
                        for (int k = 0; k < 9; ++k)
                        {
                            if (tab[k] == 0)
                            {
                                ++spr;
                            }
                        }
                        if (spr > tmp)
                        {
                            tmp  = spr;
                            x    = i;
                            y    = j;
                            tab2 = tab;
                        }
                    }
                }
            }
            for (int i = 0; i < 9; ++i)
            {
                if (tab2[i] != 0)
                {
                    new SudokuState(state, x, y, tab2[i]);
                }
            }
        }