Example #1
0
        /// <summary>
        /// Checks if a given SudokuEntry is valid for the current sudoku.
        /// </summary>
        /// <param name="sudokuEntry">The SudokuEntry that we want to check.</param>
        /// <returns>True if the given SudokuEntry is valid for the current sudoku, otherwise false.</returns>
        private bool EntryIsValid(SudokuEntry sudokuEntry)
        {
            foreach (SudokuEntry entry in Entries)
            {
                // First, we check if there is a SudokuEntry with the same value as sudokuEntry in the same block, column or row as sudokuEntry.
                // If there is, sudokuEntry is invalid, so we return false.
                if (entry.Value == sudokuEntry.Value)
                {
                    if (entry.BlockIndex == sudokuEntry.BlockIndex)
                    {
                        return(false);
                    }
                    if (entry.ColumnIndex == sudokuEntry.ColumnIndex)
                    {
                        return(false);
                    }
                    if (entry.RowIndex == sudokuEntry.RowIndex)
                    {
                        return(false);
                    }
                }

                // Second, we check whether there already is a SudokuEntry at the same location as sudokuEntry
                // and if there is, and it's locked, sudokuEntry is also invalid, so we return false.
                if (entry.ColumnIndex == sudokuEntry.ColumnIndex && entry.RowIndex == sudokuEntry.RowIndex && entry.Locked)
                {
                    return(false);
                }
            }

            return(true);
        }
Example #2
0
        /// <summary>
        /// Checks whether a SudokuEntry is locked or not.
        /// </summary>
        /// <param name="columnIndex">The columnIndex of the SudokuEntry that we want to check.</param>
        /// <param name="rowIndex">The rowIndex of the SudokuEntry that we want to check.</param>
        /// <returns>True if the SudokuEntry for the given rowIndex and columnIndex is locked, otherwise false.</returns>
        public bool EntryIsLocked(int columnIndex, int rowIndex)
        {
            SudokuEntry sudokuEntry = FindEntry(columnIndex, rowIndex);

            // If there isn't a SudokuEntry for the specified rowIndex and columnIndex, it çan't be locked.
            if (sudokuEntry == null || sudokuEntry.Locked == false)
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
Example #3
0
        /// <summary>
        /// Removes a SudokuEntry from the 'Entries' list.
        /// </summary>
        /// <param name="columnIndex">The columnIndex of the SudokuEntry that needs to be removed.</param>
        /// <param name="rowIndex">The rowIndex of the SudokuEntry that needs to be removed.</param>
        /// <returns>True if the SudokuEntry was removed successfully, otherwise false.</returns>
        public bool RemoveEntry(int columnIndex, int rowIndex)
        {
            SudokuEntry sudokuEntry = FindEntry(columnIndex, rowIndex);

            // If there isn't a SudokuEntry for the specified rowIndex and columnIndex,
            // or the found SudokuEntry is locked, we can't remove it, so return false.
            if (sudokuEntry == null || sudokuEntry.Locked)
            {
                return(false);
            }
            else
            {
                Entries.Remove(sudokuEntry);
                return(true);
            }
        }
Example #4
0
        /// <summary>
        /// Solve the sudoku.
        /// </summary>
        /// <param name="sudokuViewer">The current ViewerForm instance.</param>
        public void Solve(ViewerForm sudokuViewer)
        {
            // Here 'i' represents the columnIndex, while 'i2' respresents the rowIndex.
            for (int i = 0; i < GridSize; i++)
            {
                for (int i2 = 0; i2 < GridSize; i2++)
                {
                    int blockIndex = Convert.ToInt32((Math.Floor((double)(i / BlockSize.Horizontal))) +
                                                     ((Math.Floor((double)(i2 / BlockSize.Vertical))) * (GridSize / BlockSize.Horizontal)));

                    SudokuEntry currentEntry = EntriesList.FindEntry(i, i2);

                    // If there isn't a SudokuEntry at this location yet, set current value to 0.
                    int value = currentEntry == null ? 0 : currentEntry.Value;

                    // If the SudokuEntry at this location is locked, continue to the next location by incrementing the inner for-loop.
                    if (currentEntry != null && currentEntry.Locked)
                    {
                        continue;
                    }

                    // If there already is a SudokuEntry at this location, which is unlocked, remove it from the 'EntriesList'
                    // so we don't end up with multiple instances of SudokuEntry for the same location.
                    if (value > 0)
                    {
                        EntriesList.RemoveEntry(i, i2);
                    }

                    // Here we increment 'value' so we don't end up in an endless loop where Solve() constantly finds the same value for the same location
                    // after backtracking.
                    if (Solve((value + 1), blockIndex, i, i2) == false)
                    {
                        // If we couldn't find a valid value for this location, backtrack.
                        int[] vars = DetermineNext(i, i2);
                        i  = vars[0];
                        i2 = vars[1];
                    }

                    // Update the progress bar to reflect current progress.
                    (sudokuViewer.Controls[1] as ProgressBar).Value = (int)Math.Round((100d / ((double)GridSize * (double)GridSize)) * ((double)(i + 1) * (double)(GridSize)));
                }
            }
            // Set the progress bar to 100% when we are finished, to account for the user entering a sudoku
            // where the final column is already completely solved.
            (sudokuViewer.Controls[1] as ProgressBar).Value = 100;
        }
Example #5
0
        /// <summary>
        /// Adds a new SudokuEntry to the 'Entries' list, provided the new SudokuEntry is valid for the current sudoku.
        /// </summary>
        /// <param name="value">The 'value' the new SudokuEntry should take.</param>
        /// <param name="blockIndex">The 'blockIndex' for the new SudokuEntry.</param>
        /// <param name="columnIndex">The 'columnIndex' for the new SudokuEntry.</param>
        /// <param name="rowIndex">The 'rowIndex' for the new SudokuEntry.</param>
        /// <param name="initialRead">
        /// Is true when the SudokuEntry is being added through Sudoku.ReadEntries(),
        /// which means that the value for this SudokuEntry was added by the user, so it should be locked.
        /// </param>
        /// <returns>True if the new SudokuEntry is valid and was added successfully, otherwise false.</returns>
        public bool AddEntry(int value, int blockIndex, int columnIndex, int rowIndex, bool initialRead)
        {
            // A value in a sudoku must always be >=1, so a value of 0 is invalid.
            if (value == 0)
            {
                return(false);
            }

            SudokuEntry sudokuEntry = new SudokuEntry(value, blockIndex, rowIndex, columnIndex, initialRead);

            // If sudokuEntry is valid for the current sudoku, add it to the 'Entries' list and return true, otherwise return false.
            if (EntryIsValid(sudokuEntry))
            {
                Entries.Add(sudokuEntry);
                return(true);
            }
            else
            {
                return(false);
            }
        }