public Difficulty GetDifficulty(CellsGrid inputGrid) { Grid = inputGrid.TrueClone(); if (!IsValid()) { return(Difficulty.Unsolvable); } Grid = inputGrid.TrueClone(); if (!SolveEasy()) { Grid = inputGrid.TrueClone(); if (!SolveMedium()) { Grid = inputGrid.TrueClone(); if (!SolveHard()) { return(Difficulty.Unsolvable); } else { return(Difficulty.Hard); } } else { return(Difficulty.Medium); } } else { return(Difficulty.Easy); } }
public Generator() { Generated = new CellsGrid(); grid = new CellsGrid(); random = new Random(); XElement element; using (Stream reader = new FileStream(".\\Data\\solved.xml", FileMode.Open)) { element = XElement.Load(reader); } var tempList = element.Descendants("sudoku").ToList().Select(d => { d.Value.Trim(); return(d.Value.Split("\n").Select(x => x.Trim()).Where(x => !string.IsNullOrEmpty(x.ToString()))); }) .ToArray().Select(x => x.Select(y => y.Split(" ").Select(d => int.Parse(d)))).ToArray(); int tempIndex = random.Next(tempList.Length); //Debug.Print("Starting: " + tempIndex); var temp = tempList[tempIndex]; int x = 0; int y = 0; foreach (var item in temp) { if (x > 8) { x = 0; } foreach (var num in item) { if (y > 8) { y = 0; } grid[x, y] = num; y++; } x++; } Generated = grid.TrueClone(); //Switches random numbers for (int i = 0; i < 9; i++) { int num1 = Next(); int num2 = Next(); while (num1 == num2) { num2 = Next(); } NumberSwitch(num1, num2); } }
public Solver(CellsGrid inputGrid) : base(inputGrid) { Grid = inputGrid.TrueClone(); possible = new List <List <List <int> > >(); for (int i = 0; i < 9; i++) { possible.Add(new List <List <int> >()); for (int j = 0; j < 9; j++) { possible[i].Add(new List <int>()); } } Steps = new List <CellsGrid>(); Steps.Add(Grid.TrueClone()); }
/// <summary> /// Tries to generate random sudoku. Older algorithm. /// </summary> /// <param name="difficulty">Dificulty parameter</param> private void GenerateHelp2(int difficulty) { int left = 20; switch (difficulty) { case 0: left = 25; break; case 1: left = 24; break; case 2: left = 24; break; } Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); int reset = 0; CellsGrid gridTested = grid.TrueClone(); Solver solver = new Solver(gridTested); while (reset < 100) { reset++; while (gridTested.Count > left) { gridTested[Next(), Next()] = 0; } solver.Grid = gridTested.TrueClone(); switch (difficulty) { case 0: solver.SolveAll(true, true, 4, 4); //solver.SolveEasy(); break; case 1: solver.SolveAll(true, true, 0, 4); //solver.SolveMedium(); break; case 2: solver.SolveAll(true, true, 4, 0); //solver.SolveHard(); break; } if (solver.IsSolved()) { break; } gridTested = grid.TrueClone(); Debug.Print(reset.ToString() + "\t" + stopwatch.ElapsedMilliseconds.ToString()); } Generated = gridTested.TrueClone(); stopwatch.Stop(); Debug.Print(reset.ToString() + "\t" + stopwatch.ElapsedMilliseconds.ToString()); }
/// <summary> /// Generates sudoku into Generated property. /// </summary> /// <param name="difficulty">Relative difficulty of generated sudoku</param> private void GenerateHelpTestingOnly(Difficulty difficulty, int left, int returning) { int resetsMax = 300; CellsGrid gridTested = grid.TrueClone(); CellsGrid gridSolved = grid.TrueClone(); List <List <int> > NotNullList; int resets = 1; int iterations = 0; int last = 0; int backDebug = 0; Solver solver = new Solver(gridTested); for (; ;) { if (Generated.Count <= left) { return; //Stops generating if any other thread generated } if (gridSolved.Count <= left) { if (new Solver(gridSolved).GetDifficulty() == difficulty) { break; } } if (resets >= resetsMax) { break; } iterations++; NotNullList = NotNull(gridTested); List <int> item = NotNullList[random.Next(NotNullList.Count)]; gridTested[item[0], item[1]] = 0; solver.Grid = gridTested.TrueClone(); switch (difficulty) { case Difficulty.Easy: solver.SolveEasy(); break; case Difficulty.Medium: solver.SolveMedium(); break; case Difficulty.Hard: solver.SolveHard(); break; } if (solver.IsSolved()) { gridSolved = gridTested.TrueClone(); last = 0; } else { gridTested = gridSolved.TrueClone(); backDebug++; last++; if (last > gridSolved.Count / returning) { backDebug = 0; iterations = 0; resets++; gridTested = grid.TrueClone(); gridSolved = grid.TrueClone(); } } } Generated = gridSolved.TrueClone(); }
/// <summary> /// Generates sudoku into Generated property. /// </summary> /// <param name="difficulty">Relative difficulty of generated sudoku</param> /// <param name="offset">Subtract from left numbers to create harder sudoku, CPU intensive</param> private void GenerateHelp3(Difficulty difficulty) { int resetsMax = 300; int left = 30; int returning = 2; switch (difficulty) { case Difficulty.Easy: left = 25; returning = 2; break; case Difficulty.Medium: left = 26; returning = 3; break; case Difficulty.Hard: left = 35; returning = 7; break; } Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); CellsGrid gridTested = grid.TrueClone(); CellsGrid gridSolved = grid.TrueClone(); List <List <int> > NotNullList; int resets = 1; int iterations = 0; int last = 0; int backDebug = 0; Solver solver = new Solver(gridTested); for (; ;) { if (Generated.Count <= left) { return; //Stops generating if any other thread generated } if (gridSolved.Count <= left) { if (new Solver(gridSolved).GetDifficulty() == difficulty) { break; } } if (resets >= resetsMax) { break; } iterations++; NotNullList = NotNull(gridTested); List <int> item = NotNullList[random.Next(NotNullList.Count)]; gridTested[item[0], item[1]] = 0; solver.Grid = gridTested.TrueClone(); switch (difficulty) { case Difficulty.Easy: solver.SolveEasy(); break; case Difficulty.Medium: solver.SolveMedium(); break; case Difficulty.Hard: solver.SolveHard(); break; } if (solver.IsSolved()) { gridSolved = gridTested.TrueClone(); last = 0; } else { gridTested = gridSolved.TrueClone(); backDebug++; last++; if (last > gridSolved.Count / returning) { Debug.Print(resets.ToString() + "\t" + backDebug.ToString() + "\t" + iterations.ToString() + "\t" + gridSolved.Count.ToString() + "\t" + stopwatch.ElapsedMilliseconds.ToString()); stopwatch.Restart(); backDebug = 0; iterations = 0; resets++; gridTested = grid.TrueClone(); gridSolved = grid.TrueClone(); } } } Generated = gridSolved.TrueClone(); stopwatch.Stop(); Debug.Print(resets.ToString() + "\t" + backDebug.ToString() + "\t" + iterations.ToString() + "\t" + gridSolved.Count.ToString() + "\t" + stopwatch.ElapsedMilliseconds.ToString()); }
/// <summary> /// Generates sudoku into Generated property. /// </summary> /// <param name="difficulty">Relative difficulty of generated sudoku</param> /// <param name="offset">Subtract from left numbers to create harder sudoku, CPU intensive</param> private void GenerateHelp(int difficulty, int offset = 0) { int left = 20; switch (difficulty) { case 0: left = 25 - offset; break; case 1: left = 24 - offset; break; case 2: left = 24 - offset; break; } Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); CellsGrid gridTested = grid.TrueClone(); CellsGrid gridSolved = grid.TrueClone(); List <List <int> > NotNullList; int resets = 1; int iterations = 0; int last = 0; int backDebug = 0; Solver solver = new Solver(gridTested); while (gridSolved.Count > left && resets < 30) { if (Generated.Count <= left) { return; //Stops generating if any other thread generated } iterations++; NotNullList = NotNull(gridTested); List <int> item = NotNullList[random.Next(NotNullList.Count)]; gridTested[item[0], item[1]] = 0; solver.Grid = gridTested.TrueClone(); switch (difficulty) { case 0: //solver.SolveAll(true, true, 4, 4); solver.SolveEasy(); break; case 1: //solver.SolveAll(true, true, 0, 4); solver.SolveMedium(); break; case 2: //solver.SolveAll(true, true, 2, 0); solver.SolveHard(); break; } if (solver.IsSolved()) { gridSolved = gridTested.TrueClone(); last = 0; } else { gridTested = gridSolved.TrueClone(); backDebug++; last++; if (last > gridSolved.Count / 2) { Debug.Print(resets.ToString() + "\t" + backDebug.ToString() + "\t" + iterations.ToString() + "\t" + gridSolved.Count.ToString() + "\t" + stopwatch.ElapsedMilliseconds.ToString()); stopwatch.Restart(); backDebug = 0; iterations = 0; resets++; gridTested = grid.TrueClone(); gridSolved = grid.TrueClone(); } } } Generated = gridSolved.TrueClone(); stopwatch.Stop(); Debug.Print(resets.ToString() + "\t" + backDebug.ToString() + "\t" + iterations.ToString() + "\t" + gridSolved.Count.ToString() + "\t" + stopwatch.ElapsedMilliseconds.ToString()); }
public int[] ShowNext(CellsGrid inputGrid, Difficulty difficulty) { bool possiblePair = true; int hidden = 0; int same = 0; switch (difficulty) { case Difficulty.Easy: possiblePair = false; break; case Difficulty.Medium: same = 2; break; case Difficulty.Hard: hidden = 4; same = 4; break; } Grid = inputGrid.TrueClone(); //Adding numbers to possible. for (int x = 0; x < 9; x++) { for (int y = 0; y < 9; y++) { if (Grid[x, y] == 0) { Intersect(x, y); } } } //Removing numbers from possible. for (int x = 0; x < 9; x++) { for (int y = 0; y < 9; y++) { if (Grid[x, y] != 0) { RemovePossible(x, y); } } } if (possiblePair) { for (int x = 0; x < 9; x++) { for (int y = 0; y < 9; y++) { if (Grid[x, y] == 0) { RemovePair(x, y); } } } } if (hidden != 0) { for (int x = 0; x < 9; x++) { for (int y = 0; y < 9; y++) { if (Grid[x, y] == 0) { RemoveHidden(x, y); if (hidden > 2) { RemoveHidden(x, y, 3); } if (hidden > 3) { RemoveHidden(x, y, 4); } } } } } if (same != 0) { for (int x = 0; x < 9; x++) { for (int y = 0; y < 9; y++) { if (Grid[x, y] == 0) { RemoveSame(x, y); if (same > 2) { RemoveSame(x, y, 3); } if (same > 3) { RemoveSame(x, y, 4); } } } } } //Adding numbers to grid. for (int x = 0; x < 9; x++) { for (int y = 0; y < 9; y++) { if (Grid[x, y] == 0) { if (Count(x, y)) { return(new int[] { x, y, Grid[x, y] }); } else if (AlonePossible(x, y)) { return(new int[] { x, y, Grid[x, y] }); } } } } return(new int[] { -1, -1 }); }