/// <summary>
        /// When the File -> Save Game Unsolved menu item is chosen
        /// </summary>
        private void FileSaveGameUnsolvedClick(object sender, EventArgs e)
        {
            Grid unsolvedGrid = grid.Copy();

            unsolvedGrid.ForEachSquare((row, col, val) =>
            {
                if (unsolvedGrid.IsEditable(row, col))
                {
                    unsolvedGrid.Clear(row, col);
                }
            });
            GameManager.SaveGame(unsolvedGrid);
        }
        /// <summary>
        /// Helper function: count the blank squares in the given grid.
        /// </summary>
        /// <returns>the number of blank squares</returns>
        private int CountBlank(Grid grid)
        {
            int nBlanks = 0;

            grid.ForEachSquare((row, col, val) =>
            {
                if (val == 0)
                {
                    nBlanks += 1;
                }
            });
            return(nBlanks);
        }
Exemple #3
0
        /// <summary>
        /// When the player transitions from "edit grid" mode to "play this game" mode
        /// </summary>
        internal static void PlayThisPuzzle(Grid oldGrid, Form form)
        {
            // Set all the squares as non-editable
            Grid grid = oldGrid.Copy();

            grid.ForEachSquare((row, col, val) =>
            {
                if (val != 0)
                {
                    grid.SetEditable(false, row, col);
                }
            });

            // Tries to solve the grid. If the grid has no unique solution, warn first.
            Grid copyGrid = grid.Copy(); // yes another copy; the solver will mess with this one.
            bool result   = (new Solver().Solve(copyGrid));

            if (result)
            {
                SaveGame(grid);
                form.Hide();
                GameForm gform = new GameForm(grid, true);
                gform.ShowDialog();
                form.Close();
            }
            else
            {
                if (MessageBox.Show(copyGrid.IsFull()? "This puzzle can be solved in more than one way. Play anyway?" : "This puzzle cannot be solved. Play anyway?", "Unsolvable Puzzle", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    SaveGame(grid);
                    form.Hide();
                    GameForm gform = new GameForm(grid, true);
                    gform.ShowDialog();
                    form.Close();
                }
            }
        }
 /// <summary>
 /// Helper function: count the blank squares in the given grid.
 /// </summary>
 /// <returns>the number of blank squares</returns>
 private int CountBlank(Grid grid)
 {
     int nBlanks = 0;
     grid.ForEachSquare((row, col, val) =>
     {
         if (val == 0)
         {
             nBlanks+=1;
         }
     });
     return nBlanks;
 }
        /// <summary>
        /// Generates a grid with the given difficulty level.
        /// </summary>
        public Grid Generate(DifficultyLevel difficulty)
        {
            // Generates stuff
            // 1. Randomnly fill in the top and left part of the grid.
            // 2. Try to solve it
            // 3. Until we have enough blanks:
            //      remove some blanks
            //      if it isn't uniquely solvable, add those two blanks again.
            Grid grid = GenerateBlankGrid();

            Grid result;

            // Top row
            List <int> row = Enumerable.Range(1, 9).OrderBy((i) => rand.Next()).ToList();

            for (int i = 0; i < 9; i++)
            {
                grid.Set(row[i], false, i, 0);
            }

            // Top column
            row = Enumerable.Range(1, 9).OrderBy((i) => rand.Next()).ToList();
            row.Remove(grid.Get(0, 0));
            for (int i = 0; i < 8; i++)
            {
                grid.Set(row[i], false, 0, i + 1);
            }

            if (solver.FindErrors(grid).Count > 0)
            {
                // This is not enough to guarantee correctness.
                // If we get an invalid grid, try try again!
                result = Generate(difficulty);
            }
            else
            {
                solver.Solve(grid);

                // How many blanks do we need?
                int targetBlanks = 0;
                switch (difficulty)
                {
                case DifficultyLevel.Easy:
                    targetBlanks = 30;
                    break;

                case DifficultyLevel.Medium:
                    targetBlanks = 45;
                    break;

                case DifficultyLevel.Hard:
                    targetBlanks = 50;
                    break;
                }

                // Remove squares until we have the right number of blanks.
                int tries = 0;
                while (tries < 100 && CountBlank(grid) < targetBlanks)
                {
                    Grid saveCopy = grid.Copy();
                    // Solving is expensive. Blanking squares is easy!
                    // When the grid is mostly full, you can blank squares
                    // in relative safety without generating a non-unique
                    // puzzle. When the puzzle gets more sparse, you
                    // need to be more careful.
                    // That's what we're doing here. Quick optimization.
                    for (int i = 0; i < (targetBlanks - CountBlank(grid)) / 2 + 1; i++)
                    {
                        MaybeRandomBlank(grid);
                    }
                    if (!solver.Solve(grid.Copy()))
                    {
                        // it failed
                        grid = saveCopy;
                    }
                    tries++;
                }
                //Console.WriteLine("Generated puzzle in " + tries + " tries with "+CountBlank(grid)+" blanks");

                // Finally, set every square to be not editable
                grid.ForEachSquare((r, c, val) =>
                {
                    if (val != 0)
                    {
                        grid.SetEditable(false, r, c);
                    }
                });

                result = grid;
            }
            return(result);
        }