/// <summary> /// Saves the current puzzle to a file. /// </summary> /// <returns>true if file write was successful.</returns> public bool SavePuzzle() { if (currentPuzzle != null) { try { Stream bStream = File.Open(this.saveGameFile, FileMode.Create); BinaryFormatter bFormatter = new BinaryFormatter(); bFormatter.Serialize(bStream, currentPuzzle); bStream.Close(); currentPuzzle.Clear(); currentPuzzle = null; } catch { DialogResult result = MessageBox.Show("Could not save your game file. " + "Do you have write permissions to the file\n " + System.IO.Directory.GetCurrentDirectory() + "\\savegame.dat", "Sorry", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error); if (result == DialogResult.Retry) { return this.SavePuzzle(); } else { return false; } } return true; } return false; }
/// <summary> /// NewPuzzle(DifficultyLevel level) clears previous puzzle, /// if it exists, and creates a new one of specified difficulty. /// <remarks>Precondition: PuzzlesAvailable() returns true.</remarks> /// </summary> /// <param name="level">difficulty level of the new puzzle</param> public bool NewPuzzle(DifficultyLevel level) { if (morePuzzles[(int)level].Count > 0) { // If a puzzle is already in existence, get rid of it: if (currentPuzzle != null) { currentPuzzle.Clear(); } // Randomly choose puzzle int i = new Random().Next(morePuzzles[(int)level].Count); // Create puzzle currentPuzzle = new Puzzle(this, (string)morePuzzles[(int)level][i]); // if game is unfinished, // the puzzlestring in puzzle will be re-added to // morePuzzles iff they didn't save game. // remove new puzzle from the morePuzzles list morePuzzles[(int)level].RemoveAt(i); puzzlesAvailable--; // decrease the level of puzzlesAvailable. return true; } else { MessageBox.Show("No puzzles available in that difficulty. \n" + "Please add more puzzles or choose a " + "different difficulty", "No more puzzles!", MessageBoxButtons.OK); return false; } }
/// <summary> /// Loads an unfinished puzzle from a file. /// </summary> /// <returns>true if file read was successful.</returns> public bool LoadPuzzle() { if (this.currentPuzzle != null) { this.currentPuzzle.Clear(); } try //to read the file { Stream bStream = File.Open(this.saveGameFile, FileMode.Open); BinaryFormatter bFormatter = new BinaryFormatter(); this.currentPuzzle = (Puzzle)bFormatter.Deserialize(bStream); this.currentPuzzle.Load(this); // then load will InitButtons(). bStream.Close(); } catch { // display error message? return false; } // if all is well, puzzle is loaded. return true; }
/// <summary> /// Guess a value by forking new puzzle instances. /// </summary> private bool Guess() { int leastPossibilities = 10; int bestCandidate = -1; for (int ci=0; ci<81; ci++) { Cell cell = Grid.Cells[ci]; if (cell.Value == 0 && cell.Possibilities.Count < leastPossibilities) { leastPossibilities = cell.Possibilities.Count; bestCandidate = ci; } } if (bestCandidate > -1) { foreach(int p in Grid.Cells[bestCandidate].Possibilities) { Grid newGrid = new Grid(); newGrid.LoadState(Grid.SaveState()); newGrid.Cells[bestCandidate].Value = p; Puzzle puzzle = new Puzzle(Name, newGrid); puzzle.SaveStateHistory = SaveStateHistory; puzzle.Solve("Guess"); if(puzzle.Solved) { Grid.LoadState(newGrid.SaveState()); State.Concat(puzzle.State); Solved = true; return true; } } } return false; }
public static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("Usage: sudoku <filename.txt>"); return; } string filename = args[0]; if (!File.Exists(filename)) { Console.WriteLine("File not found: {0}", filename); return; } // parse file List<Tuple<string, List<string>>> grids = new List<Tuple<string, List<string>>>(); List<string> current = null; foreach (string lineFull in File.ReadLines(filename)) { string line = lineFull.Trim(); if (line.Length == 0) continue; char fc = line[0]; // Assume any line that starts with a number is a puzzle row if (fc >= 48 && fc <= 57) { // is number if (current == null) throw new Exception("No grid name defined"); current.Add(line); } else { current = new List<string>(); grids.Add(new Tuple<string, List<string>>(line, current)); } } // solve puzzles List<Task> tasks = new List<Task>(); List<Puzzle> puzzles = new List<Puzzle>(); foreach (Tuple<string, List<string>> pair in grids) { string gridString = string.Join("", pair.Item2); Puzzle puzzle = new Puzzle(pair.Item1, gridString); puzzle.SaveStateHistory = true; puzzles.Add(puzzle); // Start new threads if deemed useful Task task = Task.Factory.StartNew(puzzle.Solve); tasks.Add(task); } Task.WaitAll(tasks.ToArray()); // output results int count = 0; int solved = 0; int tripleSum = 0; int totalChecks = 0; int totalChanges = 0; foreach (Puzzle puzzle in puzzles) { count++; if (puzzle.Solved) { solved++; tripleSum += puzzle.GetTriple(); } Console.WriteLine(puzzle.Name); Console.WriteLine(puzzle.Grid); int checks = puzzle.State.States.Count; int changes = puzzle.State.States.Where((gs, i) => i > 0 && gs.HasChanged(puzzle.State.States[i-1])).Count(); totalChecks += checks; totalChanges += changes; Console.WriteLine("Changes/checks: {0}/{1}", changes, checks); Console.WriteLine("JSON history:"); Console.WriteLine(puzzle.State.ToJson()); Console.WriteLine(); } Console.WriteLine("Puzzles solved {0}/{1}", solved, count); Console.WriteLine("Total changes/checks: {0}/{1}", totalChanges, totalChecks); Console.WriteLine("Triple sum: {0}", tripleSum); }
public MutablePuzzle(IndexablePosition[] cells) { _cells = cells; Puzzle = new Puzzle(_cells); }