Beispiel #1
0
        public void SolveBoard()
        {
            ReducePossibleValues(Board);

            //int a=int.TryParse()

            var linearIndices = Enumerable.Range(0, 9)
                                .SelectMany(i => Enumerable.Range(0, 9)
                                            .Select(j => new { Row = i, Col = j }));

            var list = linearIndices
                       .Select(t => new { SudoCell = Board.SudoArray[t.Row, t.Col], RowIndex = t.Row, ColumnIndex = t.Col })
                       .Where(x => x.SudoCell.CellValue == 0 && x.SudoCell.PossibleValues != null)
                       .Select(x => new { x.SudoCell, x.RowIndex, x.ColumnIndex, PVCount = x.SudoCell.PossibleValues.Count })
                       .OrderBy(x => x.PVCount)
                       .ToList();

            // this looks like a bad logic (iterating over every single possible value and running the algorithm)
            // but in reality the board will be solved much earlier ... needs more testing though
            foreach (var a in list)
            {
                foreach (var pv in a.SudoCell.PossibleValues)
                {
                    var newBoard = Board.CreateCopy();
                    newBoard.SolveCell(pv, a.RowIndex, a.ColumnIndex);
                    bool isSolved = SudokuHelper.IsBoardSolved(newBoard);
                    if (isSolved)
                    {
                        //IsSolved = true;
                        Board = newBoard;
                        return;
                    }
                }
            }
        }
Beispiel #2
0
        public static SudokoBoard CreateBoard(int[,] array)
        {
            SudokoBoard newBoard = new SudokoBoard
            {
                SudoArray = new SudokuCell[9, 9],
                Rows      = new List <int> [9],
                Columns   = new List <int> [9]
            };

            //populate the rows and columns arrays
            for (int i = 0; i < 9; i++)
            {
                newBoard.Rows[i] = new List <int>();
                for (int j = 0; j < 9; j++)
                {
                    if (array[i, j] != 0)
                    {
                        newBoard.Rows[i].Add(array[i, j]);
                    }
                }
            }
            for (int i = 0; i < 9; i++)
            {
                newBoard.Columns[i] = new List <int>();
                for (int j = 0; j < 9; j++)
                {
                    if (array[j, i] != 0)
                    {
                        newBoard.Columns[i].Add(array[j, i]);
                    }
                }
            }

            // fill board and possible values
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    newBoard.SudoArray[i, j]           = new SudokuCell();
                    newBoard.SudoArray[i, j].CellValue = array[i, j];

                    // if the cell dosent't have a number
                    if (array[i, j] == 0)
                    {
                        //first PossibleValues array with all values from 1-9
                        newBoard.SudoArray[i, j].PossibleValues = new List <int> {
                            1, 2, 3, 4, 5, 6, 7, 8, 9
                        };
                    }
                }
            }

            return(newBoard);
        }
Beispiel #3
0
        public SudokoBoard CreateCopy()
        {
            SudokoBoard newBoard = new SudokoBoard
            {
                SudoArray = new SudokuCell[9, 9],
                Rows      = new List <int> [9],
                Columns   = new List <int> [9]
            };

            // Todo : optimize this method

            //populate the rows and columns arrays
            for (int i = 0; i < 9; i++)
            {
                newBoard.Rows[i] = new List <int>();
                for (int j = 0; j < 9; j++)
                {
                    if (this.SudoArray[i, j].CellValue != 0)
                    {
                        newBoard.Rows[i].Add(this.SudoArray[i, j].CellValue);
                    }
                }
            }
            for (int i = 0; i < 9; i++)
            {
                newBoard.Columns[i] = new List <int>();
                for (int j = 0; j < 9; j++)
                {
                    if (this.SudoArray[j, i].CellValue != 0)
                    {
                        newBoard.Columns[i].Add(this.SudoArray[j, i].CellValue);
                    }
                }
            }

            // fill board and possible values
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    newBoard.SudoArray[i, j]           = new SudokuCell();
                    newBoard.SudoArray[i, j].CellValue = this.SudoArray[i, j].CellValue;

                    var possibleValues = this.SudoArray[i, j].PossibleValues;
                    if (possibleValues != null)
                    {
                        newBoard.SudoArray[i, j].PossibleValues = possibleValues.Select(x => x).ToList();
                    }
                }
            }
            return(newBoard);
        }
Beispiel #4
0
        private static void ReducePossibleValues(SudokoBoard pBoard)
        {
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    SudokuCell cell = pBoard.SudoArray[i, j];

                    if (cell.CellValue == 0)
                    {
                        //cell.PossibleValues = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

                        List <int> boxValues = null;

                        foreach (var pv in cell.PossibleValues.ToList())
                        {
                            if (pBoard.Rows[i].Contains(pv))
                            {
                                cell.PossibleValues.Remove(pv);
                            }
                            else if (pBoard.Columns[j].Contains(pv))
                            {
                                cell.PossibleValues.Remove(pv);
                            }
                            else
                            {
                                if (boxValues == null)
                                {
                                    boxValues = pBoard.GetBoxValues(i, j); // new List<int>();
                                }

                                if (boxValues.Contains(pv))
                                {
                                    cell.PossibleValues.Remove(pv);
                                }
                            }
                        }

                        if (cell.PossibleValues.Count == 1)
                        {
                            cell.CellValue = cell.PossibleValues[0];
                            pBoard.Rows[i].Add(cell.CellValue);
                            pBoard.Columns[j].Add(cell.CellValue);
                            cell.PossibleValues = null;
                        }
                    }
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Checks whether a sudoku board is valid or not based on repetition of values in a column, row or box
        /// </summary>
        /// <param name="board">Sudoku board to be tested for solution</param>
        /// <returns>True if input board is valid</returns>
        public static bool IsBoardValid(SudokoBoard board)
        {
            if (board.Rows.Any(lst => lst.Count(x => x != 0) != lst.Where(x => x != 0).Distinct().Count()))
            {
                return(false);
            }
            if (board.Columns.Any(lst => lst.Count(x => x != 0) != lst.Where(x => x != 0).Distinct().Count()))
            {
                return(false);
            }

            var boxValuesList = board.GetBoxValuesList();

            if (boxValuesList.Any(lst => lst.Count(x => x != 0) != lst.Where(x => x != 0).Distinct().Count()))
            {
                return(false);
            }

            return(true);
        }
Beispiel #6
0
        /// <summary>
        /// Checks whether a sudoku board is solved or not based on column, row or box sums
        /// </summary>
        /// <param name="board">Sudoku board to be tested for solution</param>
        /// <returns>True if input board is solved</returns>
        public static bool IsBoardSolved(SudokoBoard board)
        {
            if (board.Rows.Any(row => row.GetDistinctSum() != 45))
            {
                return(false);
            }
            else if (board.Columns.Any(col => col.GetDistinctSum() != 45))
            {
                return(false);
            }
            else
            {
                var lists = board.GetBoxValuesList();
                if (lists.Any(list => list.GetDistinctSum() != 45))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #7
0
        //private bool IsSolved { get; set; }

        public SudokoSolver(SudokoBoard board)
        {
            Board = board;
        }