Пример #1
0
 private void NarrowDownIndependantCellGrouping(List<SudokuCell> cells, CellGroupingType type)
 {
     bool overallFoundOne;
     bool innerfoundOne;
     do
     {
         overallFoundOne = false;
         do
         {
             innerfoundOne = false;
             CheckForSolitarySolutionInGroup(cells, ref innerfoundOne);
             overallFoundOne |= innerfoundOne;
             if (!CheckValid()) break;
         } while (innerfoundOne);
         if (!CheckValid()) break;
         do
         {
             innerfoundOne = false;
             CheckForMultiplesInGroup(cells, type, ref innerfoundOne);
             if (!CheckValid()) break;
             overallFoundOne |= innerfoundOne;
         } while (innerfoundOne);
         if (!CheckValid()) break;
         do
         {
             innerfoundOne = false;
             CheckForLockingSituations(cells, type, ref innerfoundOne);
             if (!CheckValid()) break;
             overallFoundOne |= innerfoundOne;
         } while (innerfoundOne);
         if (!CheckValid()) break;
     } while (overallFoundOne);
 }
Пример #2
0
 private List<SudokuCell> GetCellGroupingFor(SudokuCell cell, CellGroupingType type)
 {
     int col = cell.Col;
     int row = cell.Row;
     List<SudokuCell> cells = new List<SudokuCell>();
     switch (type)
     {
         case CellGroupingType.Horizontal:
             for (int i = 0; i < 9; i++)
             {
                 cells.Add(solvedData[i, row]);
             }
             break;
         case CellGroupingType.Vertical:
             for (int i = 0; i < 9; i++)
             {
                 cells.Add(solvedData[col, i]);
             }
             break;
         case CellGroupingType.Square:
             int gridCol = col / 3;
             int gridRow = row / 3;
             int gridX = 3 * gridCol;
             int gridY = 3 * gridRow;
             for (int x = gridX; x - gridX < 3; x++)
             {
                 for (int y = gridY; y - gridY < 3; y++)
                 {
                     cells.Add(solvedData[x, y]);
                 }
             }
             break;
     }
     return cells;
 }
Пример #3
0
        private void CheckForMultiplesInGroup(List<SudokuCell> cells, CellGroupingType type, ref bool foundSome)
        {
            WeedOutExistingFoundNumbers(cells);

            int numCellsUnsolved = 0;
            foreach (SudokuCell cell in cells)
            {
                numCellsUnsolved += (cell.Number == 0) ? 1 : 0;
            }

            if (numCellsUnsolved == 0) return;

            // check to see if there's a multiple of cells each with the same set of numbers
            // then that set of numbers should be removed from all the other cells
            // in this cell group, which aren't one of the multiples of cells.
            // such as a two cells have 4/6 left each.  All the other cells in that line cannot have 4/6 then.

            for (int numMultiples = 2; numMultiples < numCellsUnsolved; numMultiples++)
            {
                List<SudokuCell> multiplesCells = new List<SudokuCell>();
                foreach (SudokuCell cell in cells)
                {
                    if (cell.Possibilities.StartsWith(numMultiples.ToString()))
                    {
                        multiplesCells.Add(cell);
                    }
                }
                foreach (SudokuCell checkCell in multiplesCells) // multuplesCells is like 4/6, 1/3, 4/6, and 7/8
                {
                    List<SudokuCell> matchingCells = new List<SudokuCell>();
                    matchingCells.Add(checkCell);
                    string theseUsed = checkCell.Possibilities;
                    foreach (SudokuCell possibleMatchingCell in multiplesCells)
                    {
                        if (checkCell == possibleMatchingCell)
                            continue;
                        if (theseUsed == possibleMatchingCell.Possibilities)
                        {
                            matchingCells.Add(possibleMatchingCell);
                        }
                    }

                    if (numMultiples == matchingCells.Count)
                    {
                        // this set of 4/6
                        foundSome |= CleanOtherCells(cells, theseUsed);

                        // loop thru each individual number and see if they match up in a row/col/square lock based upon the type they're not.
                        for (int i = 1; i < 10; i++)
                        {
                            if (theseUsed.Substring(i, 1) != "-")
                            {
                                ClearOutLockingSituations(matchingCells, i, type, ref foundSome);
                            }
                        }
                    }
                }
            }
        }
Пример #4
0
        private void ClearOutLockingSituations(List<SudokuCell> matches, int checkNum, CellGroupingType type, ref bool foundOne)
        {
            if (matches.Count > 0)
            {
                switch (type)
                {
                    case CellGroupingType.Horizontal:
                    case CellGroupingType.Vertical:
                        // if type is a col/row, then see if the poss falls in same square
                        int sqRow = matches[0].Row / 3;
                        int sqCol = matches[0].Col / 3;
                        bool sameSquare = true;
                        foreach (SudokuCell match in matches)
                        {
                            if (sqRow != (match.Row / 3) || sqCol != (match.Col / 3))
                                sameSquare = false;
                        }
                        if (sameSquare)
                        {
                            List<SudokuCell> cellsInSquare = GetCellGroupingFor(matches[0], CellGroupingType.Square);
                            foreach (SudokuCell cell in cellsInSquare)
                            {
                                if (matches.Contains(cell))
                                    continue; // don't update one of the matches by accident
                                foundOne |= SetCellPossibilityToFalse(cell, checkNum);

                            }
                        }
                        break;
                    case CellGroupingType.Square:
                        // if type is group, then see if they are all possible in same row
                        int rowMatch = matches[0].Row;
                        bool sameRow = true;
                        foreach (SudokuCell match in matches)
                        {
                            if (rowMatch != match.Row) sameRow = false;
                        }
                        if (sameRow)
                        {
                            for (int col = 0; col < 9; col++)
                            {
                                SudokuCell updateThisCell = solvedData[col, rowMatch];
                                if (matches.Contains(updateThisCell))
                                    continue; // don't update one of the matches by accident
                                foundOne |= SetCellPossibilityToFalse(updateThisCell, checkNum);
                            }
                        }
                        // if type is group, then see if they are all possible in same column
                        int colMatch = matches[0].Col;
                        bool sameCol = true;
                        foreach (SudokuCell matchedCell in matches)
                        {
                            if (colMatch != matchedCell.Col) sameCol = false;
                        }
                        if (sameCol)
                        {
                            for (int row = 0; row < 9; row++)
                            {
                                SudokuCell updateThisCell = solvedData[colMatch, row];
                                if (matches.Contains(updateThisCell))
                                    continue; // don't update one of the matches by accident
                                foundOne |= SetCellPossibilityToFalse(updateThisCell, checkNum);
                            }
                        }
                        break;
                }
            }
        }
Пример #5
0
        private void CheckForLockingSituations(List<SudokuCell> cells, CellGroupingType type, ref bool foundOne)
        {
            for (int checkNum = 1; checkNum < 10; checkNum++)
            {
                List<SudokuCell> matches = new List<SudokuCell>();
                foreach (SudokuCell cell in cells)
                {
                    if (cell.Number == 0)
                    {
                        if (cell.PossibleNumbers[checkNum])
                            matches.Add(cell);
                    }
                }
                ClearOutLockingSituations(matches, checkNum, type, ref foundOne);

            }
        }