private void FillSingleChoices(PuzzleGrid grid)
        {
            bool anyChanges = false;
            int  numChoices;

            do
            {
                anyChanges = false;
                for (int i = 0; i < 9; i++)
                {
                    for (int j = 0; j < 9; j++)
                    {
                        if (grid.Grid[i, j] == 0)
                        {
                            numChoices = ListPossible(i, j, grid);
                            if (numChoices == 1)
                            {
                                grid.UserSetCell(i, j, FirstTrue());
                                anyChanges = (grid.Grid[i, j] != 0);
                            }
                        }
                    }
                }
            } while (anyChanges == true && !IsSolved(grid));
        }
        private 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++)
            {
                minList[i] = false;
            }

            bad = false;
            i   = 0;
            while (!bad && i < 9)
            {
                j = 0;
                while (!bad && j < 9)
                {
                    if (grid.Grid[i, j] == 0)
                    {
                        numCh = ListPossible(i, j, grid);
                        if (numCh == 0)
                        {
                            bad = true;
                        }
                        else
                        {
                            if (numCh < minChoice)
                            {
                                minChoice = numCh;
                                list.CopyTo(minList, 0);
                                minR = i;
                                minC = j;
                            }
                        }
                    }
                    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);
        }
        static void Main(string[] args)
        {
            // use File Handler to load save files
            FileHandler fh       = new FileHandler();
            string      filename = "board.txt";
            PuzzleGrid  grid;

            if (File.Exists(filename))
            {
                grid = fh.OpenFile("filename");
            }
            else
            {
                grid = new PuzzleGrid(); // fix
            }

            do
            {
                //File.Open("filename", GameBoard);
                PrintBoard(grid);
                Console.ReadKey();
            } while (true);
            // control code:
            // while the game is not over:
            //    print out the board
            //    let the user type in a row/column and number
            //    change the board
            //    check if they won the game
        }
示例#4
0
        public PuzzleGrid InitGrid()
        {
            PuzzleGrid tempGrid = new PuzzleGrid {
            };
            int        row      = 0;
            int        col      = 0;
            int        newVal;
            List <int> valueSet = new List <int>(Enumerable.Range(-9, 9));

            List <int> valueSet2 = new List <int>();
            Random     rnd       = new Random();
            int        randIndex = 0;

            newVal = valueSet[randIndex];
            tempGrid.InitSetCell(row, col, newVal);
            valueSet.Remove(newVal);
            for (row = 1; row < 9; row++)
            {
                randIndex = rnd.Next(0, valueSet.Count);
                newVal    = valueSet[randIndex];
                valueSet2.Add(newVal);
                valueSet.Remove(newVal);
                tempGrid.InitSetCell(row, col, newVal);
            }
            row = 0;
            for (col = 1; col < 3; col++)
            {
                randIndex = rnd.Next(0, valueSet.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);
            }
            for (col = 3; col < 9; col++)
            {
                randIndex = rnd.Next(0, valueSet2.Count);
                newVal    = valueSet2[randIndex];
                valueSet2.Remove(newVal);
                tempGrid.InitSetCell(row, col, newVal);
            }
            for (col = 3; col < 9; col++)
            {
                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);
                SolutionGrid = puzzleSolver.SolutionGrid;
            } while (SolutionGrid == null || SolutionGrid.IsBlank());
            PermaGrid = Blanker(SolutionGrid);
            return(PermaGrid);
        }
        public bool IsPossible(PuzzleGrid g, int row, int col, int value)
        {
            bool result;

            result = (!IsInRow(g, row, value) && !IsInCol(g, col, value) &&
                      !IsIn3X3(g, row, col, value));
            return(result);
        }
        private bool IsInCol(PuzzleGrid grid, int col, int value)
        {
            bool result = false;

            for (int i = 0; i < 9; i++)
            {
                result = result || (Math.Abs(grid.Grid[i, col]) == value);
            }
            return(result);
        }
        private bool IsInRow(PuzzleGrid grid, int row, int value)
        {
            bool result = false;

            for (int i = 0; i < 9; i++)
            {
                result = result || (Math.Abs(grid.Grid[row, i]) == value);
            }
            return(result);
        }
示例#8
0
        public PuzzleGrid Blanker(PuzzleGrid solveGrid)
        {
            PuzzleGrid tempGrid;
            PuzzleGrid saveCopy;

            bool unique      = true;
            int  totalBlanks = 0;
            int  tries       = 0;
            int  desiredBlanks;
            int  symmetry = 0;

            tempGrid = (PuzzleGrid)solveGrid.Clone();

            Random rnd = new Random();

            switch (difficulty)
            {
            case Difficulty.Easy:
                desiredBlanks = 40;
                break;

            case Difficulty.Medium:
                desiredBlanks = 45;
                break;

            case Difficulty.Hard:
                desiredBlanks = 50;
                break;

            default:
                desiredBlanks = 40;
                break;
            }

            symmetry = rnd.Next(0, 2);
            do
            {
                saveCopy     = (PuzzleGrid)tempGrid.Clone();
                tempGrid     = RandomlyBlank(tempGrid, symmetry, ref totalBlanks);
                puzzleSolver = new PuzzleSolver();
                unique       = puzzleSolver.SolveGrid((PuzzleGrid)tempGrid.Clone(), true);
                if (!unique)
                {
                    tempGrid = (PuzzleGrid)saveCopy.Clone();
                    tries++;
                }
            } while ((totalBlanks < desiredBlanks) && (tries < 1000));
            solveGrid = tempGrid;
            solveGrid.Finish();
            return(solveGrid);
        }
示例#9
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);
        }
示例#10
0
        static void PrintBoard(PuzzleGrid grid)
        {
            int numRows    = grid.Grid.GetLength(0);
            int numColumns = grid.Grid.GetLength(1);

            for (int i = 0; i < numRows; i++)
            {
                for (int j = 0; j < numColumns; j++)
                {
                    Console.Write(grid.Grid[i, j]);
                }
                Console.WriteLine();
            }
        }
示例#11
0
        public PuzzleGrid RandomlyBlank(PuzzleGrid tempGrid, int sym, ref int blankCount)
        {
            Random rnd    = new Random();
            int    row    = rnd.Next(0, 8);
            int    column = rnd.Next(0, 8);

            while (tempGrid.Grid[row, column] == 0)
            {
                row    = rnd.Next(0, 8);
                column = rnd.Next(0, 8);
            }
            tempGrid.InitSetCell(row, column, 0);
            blankCount++;
            switch (sym)
            {
            case 0:
                if (tempGrid.Grid[row, 8 - column] != 0)
                {
                    blankCount++;
                }
                tempGrid.InitSetCell(row, 8 - column, 0);
                break;

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

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

            default:
                if (tempGrid.Grid[row, 8 - column] != 0)
                {
                    blankCount++;
                }
                tempGrid.InitSetCell(column, row, 0);
                break;
            }
            return(tempGrid);
        }
        private bool IsSolved(PuzzleGrid grid)
        {
            bool result = true;
            int  r, c;

            r = 0;
            while (result == true && r < 9)
            {
                c = 0;
                while (result == true && c < 9)
                {
                    result = (result && grid.Grid[r, c] != 0);
                    c++;
                }
                r++;
            }
            return(result);
        }
示例#13
0
        /// <summary>
        /// This function opens a game.
        /// </summary>
        public PuzzleGrid OpenFile(String fileName)
        {
            PuzzleGrid openedPuzzle = new PuzzleGrid();
            int        i            = 0; //mnemonic: row
            int        j            = 0; //mnemonic: column
            int        cellVal      = 0;
            bool       eOF          = false;

            using (StreamReader reader = new StreamReader(fileName))
            {
                for (i = 0; i < 9; i++)
                {
                    string currentLine;
                    if ((currentLine = reader.ReadLine()) != null)
                    {
                        for (j = 0; j < 9; j++)
                        {
                            cellVal = (int)currentLine[2 * j] - '0';
                            if (currentLine[(2 * j) + 1] == '+')
                            {
                                openedPuzzle.InitSetCell(i, j, cellVal);
                            }
                            else if (currentLine[(2 * j) + 1] == '-')
                            {
                                openedPuzzle.InitSetCell(i, j, -(cellVal));
                            }
                        }
                    }
                    else
                    {
                        eOF = true;
                    }
                }
            }
            if (eOF)
            {
                return(null);
            }
            else
            {
                return(openedPuzzle);
            }
        }
        private int ListPossible(int row, int col, PuzzleGrid g)
        {
            int count = 0;

            ClearList();
            for (int i = 1; i < 10; i++)
            {
                if (IsPossible(g, row, col, i) == true)
                {
                    list[i] = true;
                    count++;
                }
                else
                {
                    list[i] = false;
                }
            }
            return(count);
        }
        private bool IsIn3X3(PuzzleGrid g, int row, int col, int value)
        {
            int rLow;
            int cLow;

            rLow = 3 * GroupNum(row);
            cLow = 3 * GroupNum(col);
            bool result = false;

            for (int i = rLow; i < rLow + 3; i++)
            {
                for (int j = cLow; j < cLow + 3; j++)
                {
                    if (Math.Abs(g.Grid[i, j]) == value)
                    {
                        result = true;
                    }
                }
            }
            return(result);
        }
示例#16
0
    {/// <summary>
     /// This function saves a game.
     /// </summary>
        public bool SaveFile(PuzzleGrid board, String fileName, bool unsolved = false)
        {
            int        i      = 0; //mnemonic: row
            int        j      = 0; //mnemonic: column
            TextWriter writer = new StreamWriter(fileName);
            int        cellVal;

            for (i = 0; i < 9; i++)
            {
                string currentLine = "";
                for (j = 0; j < 9; j++)
                {
                    cellVal = board.Grid[i, j];
                    if (cellVal < 0)
                    {
                        currentLine += Math.Abs(cellVal).ToString();
                        currentLine += "-";
                    }
                    else
                    {
                        if (unsolved)
                        {
                            currentLine += "0";
                        }
                        else
                        {
                            currentLine += cellVal.ToString();
                        }

                        currentLine += "+";
                    }
                }
                writer.WriteLine(currentLine);
            }
            writer.Close();
            return(true);
        }
        /// <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);
        }