/// <summary> /// Enter the solution to this Cell /// </summary> /// <exception cref="ApplicationException">Thrown when all possible solutions have been disqualified</exception> /// <exception cref="ApplicationException">Thrown when argument has been previously disqualified</exception> /// <param name="value">Correct value for this Cell</param> public void Set(char value) { // Check whether prior disqualifications have caused an unsolvable situation if (!Solvable) { throw new ApplicationException("This puzzle cannot be solved - all possibilities have been disqualified"); } // Verify that the specified choice has not itself been disqualified earlier if (!IsPotentialSolution(value)) { throw new ApplicationException(string.Format( "{0} is not valid for this Cell - only {1} allowed", value, string.Join(", ", this.RemainingPossibilities))); } // Save value as the unique solution for this Cell CurrentValue = value; // Disqualify all other choices - once a value is set, nothing else is possible // (foreach won't work - InvalidOperation is thrown due to changes to collection) for (int index = RemainingPossibilities.Count - 1; index >= 0; index--) { if (RemainingPossibilities[index] != value) { RemainingPossibilities.RemoveAt(index); } } }
/// <summary> /// Determine if a potential solution value is still possible /// </summary> /// <exception cref="ArgumentOutOfRangeException">Thrown when argument is too small or too large</exception> /// <param name="value">Value to check</param> public bool IsPotentialSolution(char value) { // Range validation if (value < MinValue || value > MaxValue) { throw new ArgumentOutOfRangeException("IsPotentialSolution", string.Format("Argument ({0:d}) must be between {1} and {2}", value, MinValue, MaxValue)); } // True if not yet disqualified return(RemainingPossibilities.Contains(value)); }
/// <summary> /// Remove a potential solution value from consideration /// </summary> /// <exception cref="ArgumentOutOfRangeException">Thrown when argument is too small or too large</exception> /// <param name="value">Value to exclude from consideration</param> public void Disqualify(char value) { // Range validation if (value < MinValue || value > MaxValue) { throw new ArgumentOutOfRangeException("Disqualify", string.Format("Argument ({0:d}) must be between {1} and {2}", value, MinValue, MaxValue)); } // Remove if value is currently qualified; ignore (benignly) if previously disqualified if (RemainingPossibilities.Contains(value)) { RemainingPossibilities.Remove(value); } }