/// <summary>
        /// Checks if the imported puzzle string is valid for a sudoku puzzle.
        /// Checks:-
        /// -number of distinct numbers
        /// -number of given numbers
        /// -if two of the same numbers share a group
        /// </summary>
        /// <returns></returns>
        private bool ValidPuzzle()
        {
            char[][] grid = new char[9][];

            for (int r = 0, count = 0; r < 9; r++)
            {
                grid[r] = new char[9];
                for (int c = 0; c < 9; c++, count++)
                {
                    grid[r][c] = import_txtbx.Text[count];
                }
            }
            bool invalid     = false;
            int  blockNumber = 0;


            PuzzleGenerator gen          = new PuzzleGenerator();
            Regex           rgx          = new Regex(@"[1-9]");
            int             givenCounter = 0;
            List <char>     numList      = new List <char> {
                '1', '2', '3', '4', '5', '6', '7', '8', '9'
            };

            for (int r = 0; r < 9; r++)
            {
                for (int c = 0; c < 9; c++)
                {
                    if (rgx.IsMatch(grid[r][c].ToString()))
                    {
                        givenCounter++;
                        numList.Remove(grid[r][c]);
                        int[] indexes = new int[2];
                        blockNumber = (r / 3) * 3 + (c / 3) + 1;
                        indexes     = gen.BlockIndexGetter(blockNumber);
                        for (int i = 0; i < 9; i++)
                        {
                            if (grid[r][c] == grid[r][i] && i != c)
                            {
                                invalid = true;
                            }
                            if (grid[r][c] == grid[i][c] && i != r)
                            {
                                invalid = true;
                            }
                            if (grid[indexes[0]][indexes[1]] == grid[r][c] && indexes[0] != r && indexes[1] != c)
                            {
                                invalid = true;
                            }
                            indexes[1]++;
                            if (indexes[1] == 3 || indexes[1] == 6 || indexes[1] == 9)
                            {
                                indexes[0]++;
                                indexes[1] -= 3;
                            }
                        }
                    }
                }
            }
            if (numList.Count > 1 || invalid || givenCounter < 17)
            {
                string s = "";
                if (givenCounter < 17)
                {
                    s += "Puzzle invalid: insufficient amount of given numbers\r\n\r\n";
                }
                if (numList.Count > 1)
                {
                    s += "Puzzle invalid: insufficient amount of unique numbers\r\n\r\n";
                }
                if (invalid)
                {
                    s += "Puzzle invalid: at least two of the same numbers share a group";
                }
                MessageBox.Show(s);
                return(false);
            }
            return(true);
        }
예제 #2
0
        /// <summary>
        /// Function that reacts to the button click and generates the given number of puzzles
        /// </summary>
        /// <param name="numPuzzles"></param>
        public void GeneratePuzzles(int numPuzzles)
        {
            List <SudokuGrid> sudokuPuzzles = new List <SudokuGrid>();
            PuzzleGenerator   gen           = new PuzzleGenerator();

            try
            {
                XDocument doc;
                string    filename = @"Puzzles/SudokuPuzzles.xml";
                int       ID       = 0;
                if (File.Exists(filename))
                {
                    doc = XDocument.Load(filename);
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.Load(filename);
                    XmlNode types      = xmlDoc.DocumentElement.SelectSingleNode("/SudokuPuzzles");
                    XmlNode notStarted = types.FirstChild;
                    foreach (XmlNode item in notStarted.ChildNodes)
                    {
                        ID += item.ChildNodes.Count;
                    }
                }
                else
                {
                    doc = new XDocument(
                        new XDeclaration("1.0", "utf-8", "yes"),
                        new XComment("Sudoku Puzzle Storage For SudokuSolverSetter App"),
                        new XElement("SudokuPuzzles",
                                     new XElement("NotStarted",
                                                  new XElement("Beginner"),
                                                  new XElement("Moderate"),
                                                  new XElement("Advanced"),
                                                  new XElement("Extreme")
                                                  ),
                                     new XElement("Started",
                                                  new XElement("Beginner"),
                                                  new XElement("Moderate"),
                                                  new XElement("Advanced"),
                                                  new XElement("Extreme")
                                                  ),
                                     new XElement("Completed",
                                                  new XElement("Beginner"),
                                                  new XElement("Moderate"),
                                                  new XElement("Advanced"),
                                                  new XElement("Extreme")
                                                  )
                                     )
                        );
                }
                StreamWriter ratingWrite = new StreamWriter(@"Puzzles/ratings.txt", true);
                StreamWriter difficWrite = new StreamWriter(@"Puzzles/difficulties.txt", true);
                StreamWriter givensWrite = new StreamWriter(@"Puzzles/givens.txt", true);
                StreamWriter IDsWrite    = new StreamWriter(@"Puzzles/IDs.txt", true);
                StreamWriter stepsWrite  = new StreamWriter(@"Puzzles/steps.txt", false);
                #region Strategy Files
                StreamWriter NS = new StreamWriter(@"Puzzles/StratsCounts/nakedsingles.txt", true), HS = new StreamWriter(@"Puzzles/StratsCounts/hiddensingles.txt", true), NP = new StreamWriter(@"Puzzles/StratsCounts/nakedpair.txt", true),
                             HP = new StreamWriter(@"Puzzles/StratsCounts/hiddenpair.txt", true), PP = new StreamWriter(@"Puzzles/StratsCounts/pointline.txt", true), BLR = new StreamWriter(@"Puzzles/StratsCounts/blocklinereduc.txt", true), NT = new StreamWriter(@"Puzzles/StratsCounts/nakedtriple.txt", true),
                             HT = new StreamWriter(@"Puzzles/StratsCounts/hiddentriple.txt", true), XW = new StreamWriter(@"Puzzles/StratsCounts/xwing.txt", true), YW = new StreamWriter(@"Puzzles/StratsCounts/ywing.txt", true), XYZ = new StreamWriter(@"Puzzles/StratsCounts/xyzwing.txt", true),
                             SC = new StreamWriter(@"Puzzles/StratsCounts/singlechains.txt", true), UR1 = new StreamWriter(@"Puzzles/StratsCounts/uniquerecttyp1.txt", true), BT = new StreamWriter(@"Puzzles/StratsCounts/backtrack.txt", true);
                #endregion
                Stopwatch Timer = new Stopwatch();
                Timer.Start();
                for (int i = 0; i < numPuzzles; i++)
                {
                    sudokuPuzzles.Add(gen.Setter());
                    string            puzzleString = gen.GridToString(sudokuPuzzles[i]);
                    PuzzleSolverAdvDS solver       = new PuzzleSolverAdvDS();
                    long rating = GetDifficulty(sudokuPuzzles[i], puzzleString, solver);
                    doc.Element("SudokuPuzzles").Element("NotStarted").Element(sudokuPuzzles[i].Difficulty).Add(
                        new XElement("puzzle",
                                     new XElement("ID", ++ID),
                                     new XElement("DifficultyRating", rating),
                                     new XElement("SudokuString", puzzleString)
                                     )
                        );

                    int givens = 0;
                    for (int x = 0; x < puzzleString.Length; x++)
                    {
                        if (puzzleString[x] != '0')
                        {
                            givens++;
                        }
                    }
                    switch (sudokuPuzzles[i].Difficulty)
                    {
                    case "Beginner":
                        difficWrite.WriteLine("1");
                        break;

                    case "Moderate":
                        difficWrite.WriteLine("2");
                        break;

                    case "Advanced":
                        difficWrite.WriteLine("3");
                        break;

                    default:
                        difficWrite.WriteLine("4");
                        break;
                    }
                    ratingWrite.WriteLine(rating);
                    givensWrite.WriteLine(givens);
                    IDsWrite.WriteLine(ID);
                    stepsWrite.WriteLine(solver.g_StepCounter);

                    NS.WriteLine(solver.g_StrategyCount[1]); HS.WriteLine(solver.g_StrategyCount[2]); NP.WriteLine(solver.g_StrategyCount[3]);
                    HP.WriteLine(solver.g_StrategyCount[4]); PP.WriteLine(solver.g_StrategyCount[5]); BLR.WriteLine(solver.g_StrategyCount[6]);
                    NT.WriteLine(solver.g_StrategyCount[7]); HT.WriteLine(solver.g_StrategyCount[8]); XW.WriteLine(solver.g_StrategyCount[9]);
                    YW.WriteLine(solver.g_StrategyCount[10]); XYZ.WriteLine(solver.g_StrategyCount[11]); SC.WriteLine(solver.g_StrategyCount[12]);
                    UR1.WriteLine(solver.g_StrategyCount[13]); BT.WriteLine(solver.g_StrategyCount[0]);
                }
                Timer.Stop();
                ratingWrite.Close();
                IDsWrite.Close();
                difficWrite.Close();
                givensWrite.Close();
                stepsWrite.Close();
                NS.Close(); HS.Close(); NP.Close(); HP.Close(); PP.Close(); BLR.Close(); NT.Close();
                HT.Close(); XW.Close(); YW.Close(); XYZ.Close(); SC.Close(); UR1.Close(); BT.Close();
                doc.Save(filename);
                MessageBox.Show("Successfully added " + numPuzzles + " puzzles.\r\nThe generator took " + Timer.Elapsed + " to generate and store all of those puzzles.", "Success!");
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error with writing: " + ex);
                throw;
            }
        }