Example #1
0
        public PuzzleSet([NotNull] PuzzleSet other)
        {
            if (other == null)
            {
                throw new ArgumentNullException(nameof(other));
            }

            MaxValue = other.MaxValue;
            Bits     = new BitArray(other.Bits);
        }
Example #2
0
        /// <summary>
        /// Analyzes the puzzle's values to determine its current status.
        /// </summary>
        /// <param name="puzzle"></param>
        /// <returns>The state of the puzzle.</returns>
        public static PuzzleStatus GetPuzzleStatus(this Puzzle puzzle)
        {
            if (puzzle == null)
            {
                throw new ArgumentNullException(nameof(puzzle));
            }

            // buffer for tracking used numbers in a ror, column or box
            var       puzzleSize = puzzle.Size.ToInt32();
            PuzzleSet numbersUsed;

            // Make sure every column contains the right numbers.  It's ok if a column has holes
            // as long as those cells have possibilities, in which case it's a puzzle in progress.
            // However, two numbers can't be used in the same column, even if there are holes.
            foreach (var row in puzzle.ByRow())
            {
                numbersUsed = new PuzzleSet(puzzle.Size);
                foreach (var cell in row)
                {
                    if (cell.Value.HasValue)
                    {
                        var value = cell.Value.Value;
                        if (numbersUsed.Contains(value))
                        {
                            return(PuzzleStatus.Invalid);
                        }

                        numbersUsed.Add(value);
                    }
                }
            }

            // Same for columns
            foreach (var col in puzzle.ByCol())
            {
                numbersUsed = new PuzzleSet(puzzle.Size);
                foreach (var cell in col)
                {
                    if (cell.Value.HasValue)
                    {
                        var value = cell.Value.Value;
                        if (numbersUsed.Contains(value))
                        {
                            return(PuzzleStatus.Invalid);
                        }

                        numbersUsed.Add(value);
                    }
                }
            }

            // Same for boxes
            foreach (var box in puzzle.ByBox())
            {
                numbersUsed = new PuzzleSet(puzzle.Size);
                foreach (var cell in box)
                {
                    if (cell.Value.HasValue)
                    {
                        var value = cell.Value.Value;
                        if (numbersUsed.Contains(value))
                        {
                            return(PuzzleStatus.Invalid);
                        }

                        numbersUsed.Add(value);
                    }
                }
            }

            // Now figure out if this is a solved puzzle or a work in progress
            // based on if there are any holes
            for (var row = 0; row < puzzleSize; row++)
            {
                for (var col = 0; col < puzzleSize; col++)
                {
                    var coord = new PuzzleCoordinate(row, col);
                    if (!puzzle[coord].HasValue)
                    {
                        return(PuzzleStatus.InProgress);
                    }
                }
            }

            // If we made it this far, this state is a valid solution!  Woo hoo!
            return(PuzzleStatus.Solved);
        }