Ejemplo n.º 1
0
        public bool IsIn3X3(PuzzleGrid g, int row, int col, int value, out int ii, out int jj)
        {
            int rLow;
            int cLow;

            ii   = -1;
            jj   = -1;
            rLow = 3 * GroupNum(row); //Index of smallest number row in grid
            cLow = 3 * GroupNum(col); //Index of smallest number columin in grid
            bool result = false;

            for (int i = rLow; i < rLow + 3; i++)     //Check all 3 rows in subgrid
            {
                for (int j = cLow; j < cLow + 3; j++) //Check all 3 columns
                {                                     //Compare value of cell with value being sought
                    if (Math.Abs(g.Grid[i, j]) == value)
                    {
                        result = true;
                        ii     = i;
                        jj     = j;
                    }
                }
            }
            return(result);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// FillSingleChoices iterates through empty cells. For any empty cell
        /// with only one possible value, it fills in that value.
        /// </summary>
        /// <param name="grid">Current state of grid</param>
        public void FillSingleChoices(PuzzleGrid grid)
        {
            bool anyChanges = false; //Set if cell value set
            int  numChoices;         //Number of choices found

            do                       //While changes have been made AND grid is not solved
            {
                anyChanges = false;
                for (int i = 0; i < 9; i++)      //Iterate through every row
                {
                    for (int j = 0; j < 9; j++)  //Iterate through every column
                    {
                        if (grid.Grid[i, j] == 0)
                        {                        //Get number of choices available in grid[i, j]
                            numChoices = ListPossible(i, j, grid);
                            if (numChoices == 1) //If only one choice set value
                            {
                                grid.UserSetCell(i, j, FirstTrue());
                                //Changes made, anyChanges = true
                                anyChanges = (grid.Grid[i, j] != 0);
                            }
                        }
                    }
                }
            } while (anyChanges == true && !IsSolved(grid));
        }
Ejemplo n.º 3
0
 /// <summary>
 /// FillSingleChoices iterates through empty cells. For any empty cell
 /// with only one possible value, it fills in that value.
 /// </summary>
 /// <param name="grid">Current state of grid</param>
 public void FillSingleChoices(PuzzleGrid grid)
 {
     bool anyChanges = false;                    //Set if cell value set
     int numChoices;                           //Number of choices found
     do            //While changes have been made AND grid is not solved
     {
         anyChanges = false;
         for (int i = 0; i < 9; i++)         //Iterate through every row
         {
             for (int j = 0; j < 9; j++)  //Iterate through every column
             {
                 if (grid.Grid[i, j] == 0)
                 {       //Get number of choices available in grid[i, j]
                     numChoices = ListPossible(i, j, grid);
                     if (numChoices == 1) //If only one choice set value
                     {
                         grid.UserSetCell(i, j, FirstTrue());
                         //Changes made, anyChanges = true
                         anyChanges = (grid.Grid[i, j] != 0);
                     }
                 }
             }
         }
     } while (anyChanges == true && !IsSolved(grid));
 }
Ejemplo n.º 4
0
        /// <summary>
        /// FindFewestChoices finds the first cell having the smallest number
        /// of available choices, and sets the row and column of that cell for
        /// use in SolveGrid
        /// </summary>
        /// <param name="grid">Current state of the grid</param>
        /// <param name="r">OUTPUT sets r for use in caller</param>
        /// <param name="c">OUTPUT sets c for use in caller</param>
        /// <param name="numChoices">OUTPUT sets var for use in caller</param>
        /// <returns>Returns true if valid cell found, false if not</returns>
        public bool FindFewestChoices(PuzzleGrid grid, out int r, out int c,
                                      out int numChoices)
        {
            bool[] minList = new bool[10];
            int    numCh, minR, minC, minChoice, i, j;
            bool   bad, result;

            minChoice = 10;
            minR      = 0;
            minC      = 0;
            for (i = 1; i < 10; i++)              //Initialize minList to FALSE
            {
                minList[i] = false;
            }
            bad = false;
            i   = 0;
            while (!bad && i < 9) //While not a bad solutn and trying valid row
            {
                j = 0;
                while (!bad && j < 9) //not a bad solutn and trying valid column
                {
                    if (grid.Grid[i, j] == 0)
                    {
                        numCh = ListPossible(i, j, grid); //Get # of choices
                        if (numCh == 0)                   //If no choices found, bad solution
                        {
                            bad = true;
                        }
                        else                             //If not bad solutn...
                        {
                            if (numCh < minChoice)       //If less than current min
                            {
                                minChoice = numCh;       //Set new min value
                                list.CopyTo(minList, 0); //Save list of possible
                                minR = i;                //set row of cell with least
                                minC = j;                //set col of cell with least
                            }
                        }
                    }
                    j++;
                }
                i++;
            }
            if (bad || minChoice == 10)  //If bad solutn or minChoice never set
            {
                result     = false;      //No fewest possible choices
                r          = 0;
                c          = 0;
                numChoices = 0;
            }
            else
            {
                result     = true; //Valid cell found, return information to caller
                r          = minR;
                c          = minC;
                numChoices = minChoice;
                minList.CopyTo(list, 0);
            }
            return(result);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// </summary>
        /// <returns>Returns a fully solved PuzzleGrid</returns>
        public PuzzleGrid InitGrid()
        {
            //Randomly fill in the first row and column of puzzlegrid
            PuzzleGrid tempGrid = new PuzzleGrid {
            };                                                             //temporary grid to assign values into
            int row             = 0;                                       //variable for navigating 'rows'
            int col             = 0;                                       //variable for navigating 'columns'
            int newVal;                                                    //value to place into grid
            //bool solved;
            List <int> valueSet = new List <int>(Enumerable.Range(-9, 9)); //range of numbers that can be added to the grid

            List <int> valueSet2 = new List <int>();                       //placeholder values in column 0
            Random     rnd       = new Random();                           //random variable for choosing random number
            int        randIndex = 0;                                      //index in valueSet/valueSet2 that is accessed

            randIndex = rnd.Next(0, 8);                                    //get a random number and place in grid(0,0)
            newVal    = valueSet[randIndex];
            tempGrid.InitSetCell(row, col, newVal);
            valueSet.Remove(newVal);                                    //remove placed value from options
            for (row = 1; row < 9; row++)
            {
                //fills in column 0 with remaining possible values, storing in place-
                //holder as it goes so as to preserve when placing in row 0 later
                randIndex = rnd.Next(0, valueSet.Count);
                newVal    = valueSet[randIndex];
                valueSet2.Add(newVal);
                valueSet.Remove(newVal);
                tempGrid.InitSetCell(row, col, newVal);
            }
            row = 0;                                               //reset row to 0
            for (col = 1; col < 3; col++)
            {                                                      //fills in col 1,2 of row 0, checking that don't duplicate the
                //values in rows 1,2 of col 0
                randIndex = rnd.Next(0, valueSet2.Count);
                newVal    = valueSet2[randIndex];
                while ((newVal == tempGrid.Grid[1, 0] || (newVal == tempGrid.Grid[2, 0])))
                {
                    randIndex = rnd.Next(0, valueSet2.Count);
                    newVal    = valueSet2[randIndex];
                }
                valueSet2.Remove(newVal);
                tempGrid.InitSetCell(row, col, newVal);
            }
            for (col = 3; col < 9; col++)
            {                                                                                    //fill in remainder of row 0 with remaining possible values
                randIndex = rnd.Next(0, valueSet2.Count);
                newVal    = valueSet2[randIndex];
                valueSet2.Remove(newVal);
                tempGrid.InitSetCell(row, col, newVal);
            }
            do
            {
                puzzleSolver = new PuzzleSolver();
                puzzleSolver.SolveGrid((PuzzleGrid)tempGrid.Clone(), false); //Solve to fill remainder of grid
                SolutionGrid = puzzleSolver.SolutionGrid;
            } while (SolutionGrid == null || SolutionGrid.IsBlank());
            PermaGrid = Blanker(SolutionGrid); //call Blanker to carry out the
            return(PermaGrid);                 //blanking of fileds,then return the grid to user to solve
        }
Ejemplo n.º 6
0
        /// <summary>
        /// IsPossible returns true if IsInRow, IsInCol & IsIn3x3 return false
        /// </summary>
        /// <param name="g">Current state of the grid</param>
        /// <param name="row">row of target cell</param>
        /// <param name="col">column of target cell</param>
        /// <param name="value">value being sought</param>
        /// <returns>True if value can occupy cell at [row, col]</returns>
        public bool IsPossible(PuzzleGrid g, int row, int col, int value)
        {                     //Return true if value can go into [row, col] now
            bool result;

            result = (!IsInRow(g, row, value) && !IsInCol(g, col, value) &&
                      !IsIn3X3(g, row, col, value));
            return(result);
        }
Ejemplo n.º 7
0
        public Standard(Difficulty diff) : base(diff)
        {
            puzzleGrid      = new PuzzleGrid();
            puzzleSolver    = new PuzzleSolver();
            puzzleGenerator = new PuzzleGenerator(diff);

            puzzleGenerator.InitGrid();
            base.solution = puzzleGenerator.SolutionGrid.Grid;
            base.mask     = puzzleGenerator.PermaGrid.Grid;//check for negative values
        }
Ejemplo n.º 8
0
        /// <summary>
        /// IsInRow checks if given value occurs in the given row
        /// </summary>
        /// <param name="grid">Current state of puzzle grid</param>
        /// <param name="row">Row to check</param>
        /// <param name="value">Value to look for</param>
        /// <returns></returns>
        public bool IsInRow(PuzzleGrid grid, int row, int value)
        {
            bool result = false;

            for (int i = 0; i < 9; i++) //Iterate through row
            {                           //check if cell holds value being sought
                result = result || (Math.Abs(grid.Grid[row, i]) == value);
            }
            return(result);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// IsInColumn checks if given value occurs in the given row.
        /// </summary>
        /// <param name="grid">Current state of the grid</param>
        /// <param name="col">Column being check</param>
        /// <param name="value">Value being sought</param>
        /// <returns></returns>
        public bool IsInCol(PuzzleGrid grid, int col, int value)
        {
            bool result = false;

            for (int i = 0; i < 9; i++) //Iterate through column
            {                           //check if cell holds value being sought
                result = result || (Math.Abs(grid.Grid[i, col]) == value);
            }
            return(result);
        }
Ejemplo n.º 10
0
        //	Call SolveGrid to solve puzzlegrid
        //Store solved gamegrid as the correct solution in solutiongrid


        /// <summary>
        /// Removes x fields from solvedGrid, depending on difficulty level
        /// </summary>
        /// <param name="solvedGrid">The grid that needs to be blanked</param>
        /// <returns></returns>
        public PuzzleGrid Blanker(PuzzleGrid solvedGrid)
        {                          //enable blanking of squares based on difficulty
            PuzzleGrid tempGrid;
            PuzzleGrid saveCopy;
            //temporary grids to save between tests
            bool unique      = true;     //flag for if blanked form has unique soln
            int  totalBlanks = 0;        //count of current blanks
            int  tries       = 0;        //count of tries to blank appropriately
            int  desiredBlanks;          //amount of blanks desired via difficulty
            int  symmetry = 0;           //symmetry type

            tempGrid = (PuzzleGrid)solvedGrid.Clone();
            //cloned input grid (no damage)
            Random rnd = new Random(); //allow for random number generation

            switch (difficulty)        //set desiredBlanks via chosen difficulty
            {
            case Difficulty.Easy:      //easy difficulty
                desiredBlanks = 2;
                break;

            case Difficulty.Medium:     //medium difficulty
                desiredBlanks = 50;
                break;

            case Difficulty.Hard:     //hard difficulty
                desiredBlanks = 60;
                break;

            default:     //easy difficulty
                desiredBlanks = 40;
                break;
            }

            symmetry = rnd.Next(0, 2);                   //Randomly select symmetry
            do
            {                                            //call RandomlyBlank() to blank random squares symmetrically
                saveCopy = (PuzzleGrid)tempGrid.Clone(); // in case undo needed
                tempGrid = RandomlyBlank(tempGrid, symmetry, ref totalBlanks);
                //blanks 1 or 2 squares according to symmetry chosen
                puzzleSolver = new PuzzleSolver();
                unique       = puzzleSolver.SolveGrid((PuzzleGrid)tempGrid.Clone(), true);   // will it solve uniquely?
                if (!unique)
                {
                    tempGrid = (PuzzleGrid)saveCopy.Clone();
                    tries++;
                }
            } while ((totalBlanks < desiredBlanks) && (tries < 1000));
            solvedGrid = tempGrid;
            solvedGrid.Finish();
            return(solvedGrid);
        }
Ejemplo n.º 11
0
 /// <summary>
 /// This clones the object.
 /// </summary>
 /// <returns>A clone of itself.</returns>
 public object Clone()
 {
     //enable cloning for safe copying of the object
     PuzzleGrid p = new PuzzleGrid();
     for (int i = 0; i < Max; i++)
     {
         for (int j = 0; j < Max; j++)
         {
             p.InitSetCell(i, j, Grid[i, j]);
         }
     }
     return p;
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Randomly blanks PuzzleGrid to get the required final grid
        /// </summary>
        /// <param name="tempGrid">The grid that needs to be blanked</param>
        /// <param name="sym">Kind of symmetry. 0 - Vertical, 1 - Horizontal, 2 - Diagonal</param>
        /// <param name="blankCount">Number of fields that come out blanked.</param>
        /// <returns>Blanked PuzzleGrid object</returns>
        public PuzzleGrid RandomlyBlank(PuzzleGrid tempGrid, int sym, ref int blankCount)
        {
            //blank one or two squares(depending on if on center line) randomly
            Random rnd    = new Random();           //allow random number generation
            int    row    = rnd.Next(0, 8);         //choose randomly the row
            int    column = rnd.Next(0, 8);         //and column of cell to blank

            while (tempGrid.Grid[row, column] == 0) //don't blank a blank cell
            {
                row    = rnd.Next(0, 8);
                column = rnd.Next(0, 8);
            }
            tempGrid.InitSetCell(row, column, 0); //clear chosen cell
            blankCount++;                         //increment the count of blanks
            switch (sym)
            {
            //based on symmetry, blank a second cell
            case 0:                                       //vertical symmetry
                if (tempGrid.Grid[row, 8 - column] != 0)  //if not already blanked
                {
                    blankCount++;                         //increment blank counter
                }
                tempGrid.InitSetCell(row, 8 - column, 0); //blank opposite cell
                break;

            case 1:     //horizontal symmetry
                if (tempGrid.Grid[8 - row, column] != 0)
                {
                    blankCount++;
                }
                tempGrid.InitSetCell(8 - row, column, 0);
                break;

            case 2:     //diagonal symmetry
                if (tempGrid.Grid[column, row] != 0)
                {
                    blankCount++;
                }
                tempGrid.InitSetCell(column, row, 0);
                break;

            default:     //diagonal symmetry
                if (tempGrid.Grid[row, 8 - column] != 0)
                {
                    blankCount++;
                }
                tempGrid.InitSetCell(column, row, 0);
                break;
            }
            return(tempGrid);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// This clones the object.
        /// </summary>
        /// <returns>A clone of itself.</returns>
        public object Clone()
        {
            //enable cloning for safe copying of the object
            PuzzleGrid p = new PuzzleGrid();

            for (int i = 0; i < Max; i++)
            {
                for (int j = 0; j < Max; j++)
                {
                    p.InitSetCell(i, j, Grid[i, j]);
                }
            }
            return(p);
        }
Ejemplo n.º 14
0
        //    Call SolveGrid to solve puzzlegrid
        //Store solved gamegrid as the correct solution in solutiongrid
        /// <summary>
        /// Removes x fields from solvedGrid, depending on difficulty level
        /// </summary>
        /// <param name="solvedGrid">The grid that needs to be blanked</param>
        /// <returns></returns>
        public PuzzleGrid Blanker(PuzzleGrid solvedGrid)
        {
            //enable blanking of squares based on difficulty
            PuzzleGrid tempGrid;
            PuzzleGrid saveCopy;
            //temporary grids to save between tests
            bool unique = true;          //flag for if blanked form has unique soln
            int totalBlanks = 0;	                      //count of current blanks
            int tries = 0;                  //count of tries to blank appropriately
            int desiredBlanks;            //amount of blanks desired via difficulty
            int symmetry = 0;                                       //symmetry type
            tempGrid = (PuzzleGrid)solvedGrid.Clone();
            //cloned input grid (no damage)
            Random rnd = new Random();         //allow for random number generation

            switch (difficulty)           //set desiredBlanks via chosen difficulty
            {
                case Difficulty.Easy: //easy difficulty
                    desiredBlanks = 2;
                    break;
                case Difficulty.Medium: //medium difficulty
                    desiredBlanks = 50;
                    break;
                case Difficulty.Hard: //hard difficulty
                    desiredBlanks = 60;
                    break;
                default: //easy difficulty
                    desiredBlanks = 40;
                    break;
            }

            symmetry = rnd.Next(0, 2);                   //Randomly select symmetry
            do
            {          //call RandomlyBlank() to blank random squares symmetrically
                saveCopy = (PuzzleGrid)tempGrid.Clone();     // in case undo needed
                tempGrid = RandomlyBlank(tempGrid, symmetry, ref totalBlanks);
                //blanks 1 or 2 squares according to symmetry chosen
                puzzleSolver = new PuzzleSolver();
                unique = puzzleSolver.SolveGrid((PuzzleGrid)tempGrid.Clone(), true);         // will it solve uniquely?
                if (!unique)
                {
                    tempGrid = (PuzzleGrid)saveCopy.Clone();
                    tries++;
                }
            } while ((totalBlanks < desiredBlanks) && (tries < 1000));
            solvedGrid = tempGrid;
            solvedGrid.Finish();
            return solvedGrid;
        }
Ejemplo n.º 15
0
        public bool IsInRow(PuzzleGrid grid, int row, int value, out int ii, out int jj)
        {
            bool result = false;

            ii = -1;
            jj = -1;
            for (int i = 0; i < 9; i++) //Iterate through row
            {                           //check if cell holds value being sought
                if (Math.Abs(grid.Grid[row, i]) == value)
                {
                    result = true;
                    ii     = row;
                    jj     = i;
                }
            }
            return(result);
        }
Ejemplo n.º 16
0
        public bool IsInCol(PuzzleGrid grid, int col, int value, out int ii, out int jj)
        {
            bool result = false;

            ii = -1;
            jj = -1;
            for (int i = 0; i < 9; i++) //Iterate through column
            {                           //check if cell holds value being sought
                if (Math.Abs(grid.Grid[i, col]) == value)
                {
                    result = true;
                    ii     = i;
                    jj     = col;
                }
            }
            return(result);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// IsSolved checks to see if all cells in the grid contain a value.
        /// If so, due to how the solve algorithm solves, the puzzle must be
        ///  solved correctly.
        /// </summary>
        /// <param name="grid">Current state of the puzzle grid</param>
        /// <returns>TRUE: Puzzle is solved, FALSE: Not solved</returns>
        public bool IsSolved(PuzzleGrid grid)
        {
            bool result = true;                       //Assume puzzle is solved
            int  r, c;

            r = 0;
            while (result == true && r < 9)                   //Check every row
            {
                c = 0;
                while (result == true && c < 9) //Check every column
                {                               //If an empty cell is found, result gets FALSE
                    result = (result && grid.Grid[r, c] != 0);
                    c++;
                }
                r++;
            }
            return(result);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// ListPossible populates list[] with "true" at each index
        /// representing that value is a possible value for cell at [row, col].
        /// It returns the total count of possible values in that square
        /// </summary>
        /// <param name="row">Row of target cell</param>
        /// <param name="col">Column of target cell</param>
        /// <param name="g">current state of grid</param>
        /// <returns>Integer count of possible values for given cell</returns>
        public int ListPossible(int row, int col, PuzzleGrid g)
        {
            int count = 0;

            ClearList();                                //Create a fresh list for bool population
            for (int i = 1; i < 10; i++)                //For i = 1..9 (valid values)
            {
                if (IsPossible(g, row, col, i) == true) //If i can go in cell
                {
                    list[i] = true;
                    count++;
                }
                else                     //Value of i found in Row, Col, or 3x3
                {
                    list[i] = false;
                }
            }
            return(count);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Return object of type Standard:Sudoku
        /// </summary>
        /// <param name="diff">Difficulty of Sudoku</param>
        public Standard(Difficulty diff) : base(diff)
        {
            base.scheme     = scheme;
            puzzleGrid      = new PuzzleGrid();
            puzzleSolver    = new PuzzleSolver();
            puzzleGenerator = new PuzzleGenerator(diff);

            puzzleGenerator.InitGrid();

            base.solution = puzzleGenerator.SolutionGrid.Grid;
            base.mask     = puzzleGenerator.PermaGrid.Grid;//check for negative values
            userGrid.Initialize();
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    mask[i, j]     = -mask[i, j];
                    userGrid[i, j] = mask[i, j];
                }
            }
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Return object of type Standard:Sudoku
        /// </summary>
        /// <param name="diff">Difficulty of Sudoku</param>
        public Standard(Difficulty diff)
            : base(diff)
        {
            base.scheme = scheme;
            puzzleGrid = new PuzzleGrid();
            puzzleSolver = new PuzzleSolver();
            puzzleGenerator = new PuzzleGenerator(diff);

            puzzleGenerator.InitGrid();

            base.solution = puzzleGenerator.SolutionGrid.Grid;
            base.mask = puzzleGenerator.PermaGrid.Grid;//check for negative values
            userGrid.Initialize();
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    mask[i, j] = -mask[i, j];
                    userGrid[i, j] = mask[i, j];
                }
            }
        }
Ejemplo n.º 21
0
 public bool IsInCol(PuzzleGrid grid, int col, int value,out int ii, out int jj)
 {
     bool result = false;
     ii = -1;
     jj = -1;
     for (int i = 0; i < 9; i++)                //Iterate through column
     {                          //check if cell holds value being sought
         if (Math.Abs(grid.Grid[i, col]) == value)
         {
             result = true;
             ii = i;
             jj = col;
         }
     }
     return result;
 }
Ejemplo n.º 22
0
        /// <summary>
        /// SolveGrid attempts to solve a puzzle by checking through all
        /// possible values for each cell, discarding values that do not lead
        /// to a valid solution. On a try, it recursively calls itself to
        /// maintain previous states of the grid to back track to if the
        /// current path fails. It creates a local version of the grid to
        /// facilitate this. It also checks if the puzzle is uniquely solvable.
        /// </summary>
        /// <param name="g">Current state of the grid</param>
        /// <param name="checkUnique">Do we care if it has unique soln?</param>
        /// <returns></returns>
        public bool SolveGrid(PuzzleGrid g, bool checkUnique)
        {
            PuzzleGrid grid = new PuzzleGrid();
            grid = (PuzzleGrid)g.Clone();                 //Copy the input grid
            int i, choice, r, c, numChoices;
            bool done, got_one, solved, result;
            got_one = false;
            recursions++;
            FillSingleChoices(grid);  //First, fill in all single choice values
            if (IsSolved(grid))                        //If it's already solved
            {
                if (numSolns > 0)               //If another soln already found
                {
                    stoplooking = true;                   //Don't look for more
                    result = false;              //Return false, no UNIQUE soln
                }
                else                               //If no other soln found yet
                {
                    numSolns++;
                    final[numSolns] = (PuzzleGrid)g.Clone();  //Save found soln
                    result = true;
                    SolutionGrid = grid;
                }
            }
            else                                            //If not solved yet
            {
                if (!FindFewestChoices(grid, out r, out c, out numChoices))
                {
                    result = false;                          //Invalid solution
                }
                else                                 //Current grid still valid
                {
                    i = 1;
                    done = false;
                    got_one = false;
                    while (!done && i <= numChoices)
                    {
                        choice = PickOneTrue();         //Pick a possible value
                        list[choice] = false;      //Won't want to use it again
                        grid.UserSetCell(r, c, choice);

                        if (recursions < MaxDepth)
                        {
                            //-----------We must go deeper. SUDCEPTION!-----------//
                            solved = (SolveGrid(grid, checkUnique)); //Recurse
                        }
                        else
                        {
                            solved = false;
                        }
                        if (stoplooking == true)
                        {
                            done = true;
                            got_one = true;
                        }
                        else
                        {
                            got_one = (got_one || solved);
                            if (!checkUnique)  //If not looking for unique soln
                            {
                                done = got_one;       //Then we have a solution
                            }
                        }
                        i++;
                    }
                    result = got_one;
                }
            }
            return result;
        }
Ejemplo n.º 23
0
        /// <summary>
        /// </summary>
        /// <returns>Returns a fully solved PuzzleGrid</returns>
        public PuzzleGrid InitGrid()
        {
            //Randomly fill in the first row and column of puzzlegrid
            PuzzleGrid tempGrid = new PuzzleGrid { };       //temporary grid to assign values into
            int row = 0;                         		    //variable for navigating 'rows'
            int col = 0;                        			//variable for navigating 'columns'
            int newVal;                        	            //value to place into grid
            //bool solved;
            List<int> valueSet = new List<int>(Enumerable.Range(-9, 9));   //range of numbers that can be added to the grid

            List<int> valueSet2 = new List<int>(); 			//placeholder values in column 0
            Random rnd = new Random(); 						//random variable for choosing random number
            int randIndex = 0;       						//index in valueSet/valueSet2 that is accessed
            randIndex = rnd.Next(0, 8); 						//get a random number and place in grid(0,0)
            newVal = valueSet[randIndex];
            tempGrid.InitSetCell(row, col, newVal);
            valueSet.Remove(newVal);            			//remove placed value from options
            for (row = 1; row < 9; row++)
            {
                //fills in column 0 with remaining possible values, storing in place-
                //holder as it goes so as to preserve when placing in row 0 later
                randIndex = rnd.Next(0, valueSet.Count);
                newVal = valueSet[randIndex];
                valueSet2.Add(newVal);
                valueSet.Remove(newVal);
                tempGrid.InitSetCell(row, col, newVal);
            }
            row = 0;                                               //reset row to 0
            for (col = 1; col < 3; col++)
            {        								//fills in col 1,2 of row 0, checking that don't duplicate the
                //values in rows 1,2 of col 0
                randIndex = rnd.Next(0, valueSet2.Count);
                newVal = valueSet2[randIndex];
                while ((newVal == tempGrid.Grid[1, 0] || (newVal == tempGrid.Grid[2, 0])))
                {
                    randIndex = rnd.Next(0, valueSet2.Count);
                    newVal = valueSet2[randIndex];
                }
                valueSet2.Remove(newVal);
                tempGrid.InitSetCell(row, col, newVal);
            }
            for (col = 3; col < 9; col++)
            {          										 //fill in remainder of row 0 with remaining possible values
                randIndex = rnd.Next(0, valueSet2.Count);
                newVal = valueSet2[randIndex];
                valueSet2.Remove(newVal);
                tempGrid.InitSetCell(row, col, newVal);
            }
            do
            {
                puzzleSolver = new PuzzleSolver();
                puzzleSolver.SolveGrid((PuzzleGrid)tempGrid.Clone(), false); //Solve to fill remainder of grid
                SolutionGrid = puzzleSolver.SolutionGrid;
            } while (SolutionGrid == null || SolutionGrid.IsBlank());
            PermaGrid = Blanker(SolutionGrid);       //call Blanker to carry out the
            return PermaGrid;         //blanking of fileds,then return the grid to user to solve
        }
Ejemplo n.º 24
0
 /// <summary>
 /// IsPossible returns true if IsInRow, IsInCol & IsIn3x3 return false
 /// </summary>
 /// <param name="g">Current state of the grid</param>
 /// <param name="row">row of target cell</param>
 /// <param name="col">column of target cell</param>
 /// <param name="value">value being sought</param>
 /// <returns>True if value can occupy cell at [row, col]</returns>
 public bool IsPossible(PuzzleGrid g, int row, int col, int value)
 {
     //Return true if value can go into [row, col] now
     bool result;
     result = (!IsInRow(g, row, value) && !IsInCol(g, col, value) &&
         !IsIn3X3(g, row, col, value));
     return result;
 }
Ejemplo n.º 25
0
 public bool IsIn3X3(PuzzleGrid g, int row, int col, int value,out int ii, out int jj)
 {
     int rLow;
     int cLow;
     ii = -1;
     jj = -1;
     rLow = 3 * GroupNum(row);    //Index of smallest number row in grid
     cLow = 3 * GroupNum(col);//Index of smallest number columin in grid
     bool result = false;
     for (int i = rLow; i < rLow + 3; i++) //Check all 3 rows in subgrid
     {
         for (int j = cLow; j < cLow + 3; j++)     //Check all 3 columns
         {               //Compare value of cell with value being sought
             if (Math.Abs(g.Grid[i, j]) == value)
             {
                 result = true;
                 ii = i;
                 jj = j;
             }
         }
     }
     return result;
 }
Ejemplo n.º 26
0
 /// <summary>
 /// FindFewestChoices finds the first cell having the smallest number
 /// of available choices, and sets the row and column of that cell for
 /// use in SolveGrid
 /// </summary>
 /// <param name="grid">Current state of the grid</param>
 /// <param name="r">OUTPUT sets r for use in caller</param>
 /// <param name="c">OUTPUT sets c for use in caller</param>
 /// <param name="numChoices">OUTPUT sets var for use in caller</param>
 /// <returns>Returns true if valid cell found, false if not</returns>
 public bool FindFewestChoices(PuzzleGrid grid, out int r, out int c,
     out int numChoices)
 {
     bool[] minList = new bool[10];
     int numCh, minR, minC, minChoice, i, j;
     bool bad, result;
     minChoice = 10;
     minR = 0;
     minC = 0;
     for (i = 1; i < 10; i++)              //Initialize minList to FALSE
     {
         minList[i] = false;
     }
     bad = false;
     i = 0;
     while (!bad && i < 9) //While not a bad solutn and trying valid row
     {
         j = 0;
         while (!bad && j < 9) //not a bad solutn and trying valid column
         {
             if (grid.Grid[i, j] == 0)
             {
                 numCh = ListPossible(i, j, grid);    //Get # of choices
                 if (numCh == 0)     //If no choices found, bad solution
                 {
                     bad = true;
                 }
                 else                             //If not bad solutn...
                 {
                     if (numCh < minChoice)   //If less than current min
                     {
                         minChoice = numCh;          //Set new min value
                         list.CopyTo(minList, 0);//Save list of possible
                         minR = i;          //set row of cell with least
                         minC = j;          //set col of cell with least
                     }
                 }
             }
             j++;
         }
         i++;
     }
     if (bad || minChoice == 10)  //If bad solutn or minChoice never set
     {
         result = false;                    //No fewest possible choices
         r = 0;
         c = 0;
         numChoices = 0;
     }
     else
     {
         result = true; //Valid cell found, return information to caller
         r = minR;
         c = minC;
         numChoices = minChoice;
         minList.CopyTo(list, 0);
     }
     return result;
 }
Ejemplo n.º 27
0
 /// <summary>
 /// IsInColumn checks if given value occurs in the given row.
 /// </summary>
 /// <param name="grid">Current state of the grid</param>
 /// <param name="col">Column being check</param>
 /// <param name="value">Value being sought</param>
 /// <returns></returns>
 public bool IsInCol(PuzzleGrid grid, int col, int value)
 {
     bool result = false;
     for (int i = 0; i < 9; i++)                //Iterate through column
     {                          //check if cell holds value being sought
         result = result || (Math.Abs(grid.Grid[i, col]) == value);
     }
     return result;
 }
Ejemplo n.º 28
0
 /// <summary>
 /// ListPossible populates list[] with "true" at each index
 /// representing that value is a possible value for cell at [row, col].
 /// It returns the total count of possible values in that square
 /// </summary>
 /// <param name="row">Row of target cell</param>
 /// <param name="col">Column of target cell</param>
 /// <param name="g">current state of grid</param>
 /// <returns>Integer count of possible values for given cell</returns>
 public int ListPossible(int row, int col, PuzzleGrid g)
 {
     int count = 0;
     ClearList();              //Create a fresh list for bool population
     for (int i = 1; i < 10; i++)          //For i = 1..9 (valid values)
     {
         if (IsPossible(g, row, col, i) == true)   //If i can go in cell
         {
             list[i] = true;
             count++;
         }
         else                     //Value of i found in Row, Col, or 3x3
         {
             list[i] = false;
         }
     }
     return count;
 }
Ejemplo n.º 29
0
 /// <summary>
 /// Randomly blanks PuzzleGrid to get the required final grid
 /// </summary>
 /// <param name="tempGrid">The grid that needs to be blanked</param>
 /// <param name="sym">Kind of symmetry. 0 - Vertical, 1 - Horizontal, 2 - Diagonal</param>
 /// <param name="blankCount">Number of fields that come out blanked.</param>
 /// <returns>Blanked PuzzleGrid object</returns>
 public PuzzleGrid RandomlyBlank(PuzzleGrid tempGrid, int sym, ref int blankCount)
 {
     //blank one or two squares(depending on if on center line) randomly
     Random rnd = new Random(); //allow random number generation
     int row = rnd.Next(0, 8); //choose randomly the row
     int column = rnd.Next(0, 8); //and column of cell to blank
     while (tempGrid.Grid[row, column] == 0) //don't blank a blank cell
     {
         row = rnd.Next(0, 8);
         column = rnd.Next(0, 8);
     }
     tempGrid.InitSetCell(row, column, 0); //clear chosen cell
     blankCount++; //increment the count of blanks
     switch (sym)
     {
         //based on symmetry, blank a second cell
         case 0: //vertical symmetry
             if (tempGrid.Grid[row, 8 - column] != 0) //if not already blanked
                 blankCount++; //increment blank counter
             tempGrid.InitSetCell(row, 8 - column, 0); //blank opposite cell
             break;
         case 1: //horizontal symmetry
             if (tempGrid.Grid[8 - row, column] != 0)
                 blankCount++;
             tempGrid.InitSetCell(8 - row, column, 0);
             break;
         case 2: //diagonal symmetry
             if (tempGrid.Grid[column, row] != 0)
                 blankCount++;
             tempGrid.InitSetCell(column, row, 0);
             break;
         default: //diagonal symmetry
             if (tempGrid.Grid[row, 8 - column] != 0)
                 blankCount++;
             tempGrid.InitSetCell(column, row, 0);
             break;
     }
     return tempGrid;
 }
Ejemplo n.º 30
0
 /// <summary>
 /// IsInRow checks if given value occurs in the given row
 /// </summary>
 /// <param name="grid">Current state of puzzle grid</param>
 /// <param name="row">Row to check</param>
 /// <param name="value">Value to look for</param>
 /// <returns></returns>
 public bool IsInRow(PuzzleGrid grid, int row, int value)
 {
     bool result = false;
     for (int i = 0; i < 9; i++)                   //Iterate through row
     {                          //check if cell holds value being sought
         result = result || (Math.Abs(grid.Grid[row, i]) == value);
     }
     return result;
 }
Ejemplo n.º 31
0
        public bool IsInRow(PuzzleGrid grid, int row, int value,out int ii, out int jj)
        {
            bool result = false;
            ii = -1;
            jj = -1;
            for (int i = 0; i < 9; i++)                   //Iterate through row
            {                          //check if cell holds value being sought
                if (Math.Abs(grid.Grid[row, i]) == value)
                {
                    result = true;
                    ii = row;
                    jj = i;
                }

            }
            return result;
        }
Ejemplo n.º 32
0
        private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
        {
            if (dataGridView1.SelectedCells.Count > 0)
            {
                //dataGridView1.SelectedCells[0].Value = "";
                var selected = dataGridView1.SelectedCells[0];
                int sel_i    = selected.RowIndex;
                int sel_j    = selected.ColumnIndex;
                if (CellMap[sel_i, sel_j] == LOCKED)
                {
                    return;
                }
                if (!(e.KeyValue >= 49 && e.KeyValue <= 57 || e.KeyValue >= 97 && e.KeyValue <= 105))
                {
                    //MessageBox.Show(String.Format("{0}",e.KeyValue));

                    if (e.KeyValue == 27 || e.KeyValue == 8 || e.KeyValue == 46)   // Use e.KeyCode == Keys.Enter  etc.
                    {
                        selected.Value = "";
                    }
                }
                else
                {
                    int value = -1;
                    if (e.KeyValue >= 49 && e.KeyValue <= 57)
                    {
                        selected.Value = e.KeyValue - 48;
                        value          = e.KeyValue - 48;
                    }
                    else
                    {
                        selected.Value = e.KeyValue - 96;
                        value          = e.KeyValue - 96;
                    }

                    if (standardGrid != null)
                    {
                        standardGrid.Grid[sel_i, sel_j] = value;
                    }
                    else if (squigglyGrid != null)
                    {
                        squigglyGrid.Grid[sel_i, sel_j] = value;
                    }

                    highlightSelectedNumber();
                }
            }
            if (standardGrid != null)
            {
                if (standardSolver.IsSolved(standardGrid))
                {
                    MessageBox.Show("Congratulations!!!");
                    standardGrid = null;
                }
            }
            else if (squigglyGrid != null)
            {
                if (squigglySolver.IsSolved(squigglyGrid))
                {
                    MessageBox.Show("Congratulations!!!");
                    squigglyGrid = null;
                }
            }
        }
Ejemplo n.º 33
0
 /// <summary>
 /// IsSolved checks to see if all cells in the grid contain a value.
 /// If so, due to how the solve algorithm solves, the puzzle must be 
 ///  solved correctly.
 /// </summary>
 /// <param name="grid">Current state of the puzzle grid</param>
 /// <returns>TRUE: Puzzle is solved, FALSE: Not solved</returns>
 public bool IsSolved(PuzzleGrid grid)
 {
     bool result = true;                       //Assume puzzle is solved
     int r, c;
     r = 0;
     while (result == true && r < 9)                   //Check every row
     {
         c = 0;
         while (result == true && c < 9)            //Check every column
         {                //If an empty cell is found, result gets FALSE
             result = (result && grid.Grid[r, c] != 0);
             c++;
         }
         r++;
     }
     return result;
 }
Ejemplo n.º 34
0
        /// <summary>
        /// SolveGrid attempts to solve a puzzle by checking through all
        /// possible values for each cell, discarding values that do not lead
        /// to a valid solution. On a try, it recursively calls itself to
        /// maintain previous states of the grid to back track to if the
        /// current path fails. It creates a local version of the grid to
        /// facilitate this. It also checks if the puzzle is uniquely solvable.
        /// </summary>
        /// <param name="g">Current state of the grid</param>
        /// <param name="checkUnique">Do we care if it has unique soln?</param>
        /// <returns></returns>
        public bool SolveGrid(PuzzleGrid g, bool checkUnique)
        {
            PuzzleGrid grid = new PuzzleGrid();

            grid = (PuzzleGrid)g.Clone();                 //Copy the input grid
            int  i, choice, r, c, numChoices;
            bool done, got_one, solved, result;

            got_one = false;
            recursions++;
            FillSingleChoices(grid);     //First, fill in all single choice values
            if (IsSolved(grid))          //If it's already solved
            {
                if (numSolns > 0)        //If another soln already found
                {
                    stoplooking = true;  //Don't look for more
                    result      = false; //Return false, no UNIQUE soln
                }
                else                     //If no other soln found yet
                {
                    numSolns++;
                    final[numSolns] = (PuzzleGrid)g.Clone();  //Save found soln
                    result          = true;
                    SolutionGrid    = grid;
                }
            }
            else                                            //If not solved yet
            {
                if (!FindFewestChoices(grid, out r, out c, out numChoices))
                {
                    result = false;                  //Invalid solution
                }
                else                                 //Current grid still valid
                {
                    i       = 1;
                    done    = false;
                    got_one = false;
                    while (!done && i <= numChoices)
                    {
                        choice       = PickOneTrue(); //Pick a possible value
                        list[choice] = false;         //Won't want to use it again
                        grid.UserSetCell(r, c, choice);

                        if (recursions < MaxDepth)
                        {
                            //-----------We must go deeper. SUDCEPTION!-----------//
                            solved = (SolveGrid(grid, checkUnique)); //Recurse
                        }
                        else
                        {
                            solved = false;
                        }
                        if (stoplooking == true)
                        {
                            done    = true;
                            got_one = true;
                        }
                        else
                        {
                            got_one = (got_one || solved);
                            if (!checkUnique)   //If not looking for unique soln
                            {
                                done = got_one; //Then we have a solution
                            }
                        }
                        i++;
                    }
                    result = got_one;
                }
            }
            return(result);
        }
Ejemplo n.º 35
0
        public void setGrid(gameType type, Difficulty level)
        {
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    dataGridView1.Rows[i].Cells[j].Value = "";
                }
            }
            if (type == gameType.Standard)
            {
                squigglyGrid = null;

                PuzzleGenerator gen  = new PuzzleGenerator(level);
                PuzzleGrid      grid = gen.InitGrid();
                standardSolver = new PuzzleSolver();
                standardSolver.SolutionGrid = gen.SolutionGrid;
                standardGrid = new PuzzleGrid();
                for (int i = 0; i < 9; i++)
                {
                    for (int j = 0; j < 9; j++)
                    {
                        if (grid.Grid[i, j] != 0)
                        {
                            dataGridView1.Rows[i].Cells[j].Value = -grid.Grid[i, j];
                        }
                        standardGrid.Grid[i, j] = -grid.Grid[i, j];
                        ColorMap[i, j]          = Color.White;
                    }
                }
            }
            else
            {
                standardGrid = null;

                schemeBuilder();
                Random r = new Random();
                int[,] scheme = Schemes[r.Next(6)];

                bool           Completed    = false;
                CustomSquiggly squigglyGrid = null;
                squigglySolver = new SquigglySolver(scheme);
                while (squigglyGrid == null && !Completed)
                {
                    squigglyGrid = Limex(() => new CustomSquiggly(scheme, level), 4000, out Completed);
                }

                for (int i = 0; i < 9; i++)
                {
                    for (int j = 0; j < 9; j++)
                    {
                        if (squigglyGrid.Grid[i, j] != 0)
                        {
                            dataGridView1.Rows[i].Cells[j].Value = -squigglyGrid.Grid[i, j];
                        }
                        dataGridView1.Rows[i].Cells[j].Style.BackColor = colors[scheme[i, j]];
                        ColorMap[i, j] = colors[scheme[i, j]];
                    }
                }


                string rez = "$$$$$$ try\n";
                for (int ii = 0; ii < 9; ii++)
                {
                    for (int jj = 0; jj < 9; jj++)
                    {
                        rez += CustomSquiggly.solution[ii, jj] + " ";
                    }
                    rez += "\n";
                }
                MessageBox.Show(rez);
            }
            LockCellMap();
        }