예제 #1
0
        private int[] ImpossibleValues(int[] possibleValues)
        {
            ValuesPool numbers = new ValuesPool();

            foreach (var value in possibleValues)
            {
                numbers.MakeUnavailable(value);
            }

            return(numbers.GetAvailableValues().ToArray());
        }
예제 #2
0
        public IEnumerable <int> GetImpossibleValuesForCell(Board board, Cell cellChecked)
        {
            foreach (var thermometer in Thermometers)
            {
                var themoDataForCellChecked = thermometer.GetDataForCell(cellChecked);

                if (themoDataForCellChecked != null)
                {
                    #region Sequencial thermometer (unusual)
                    // This code was created for sequencial thermometers (1, 2, 3...).
                    // Thermometers usually are not sequencial, they just need to get bigger (2, 4, 8...)

                    /*
                     * // Check if any cell inside the thermometer is already set - this should define the entire sequence of the thermometer
                     * bool sequenceIsFixed = false;
                     * foreach (var thermoData in thermometer.CoordinateDatas)
                     * {
                     *  var cellFromThermometer = board.CellsByRow[thermoData.Row].First(boardCell => boardCell.Column == thermoData.Column);
                     *
                     *  if(cellFromThermometer.CurrentNumber.HasValue)
                     *  {
                     *      // If any cell inside the thermometer already has a value defined, all the numbers that don't satisfy the sequence are impossible
                     *      int onlyValidNumber;
                     *
                     *      int difference = thermoData.SequenceIndex - themoDataForCellChecked.SequenceIndex;
                     *      if (difference < 0) difference = -difference;
                     *
                     *      if (thermoData.SequenceIndex > themoDataForCellChecked.SequenceIndex)
                     *          onlyValidNumber = cellFromThermometer.CurrentNumber.Value - difference;
                     *      else
                     *          onlyValidNumber = cellFromThermometer.CurrentNumber.Value + difference;
                     *
                     *      foreach (var impossibleNumber in new AvailableValues().MakeUnavailable(onlyValidNumber).GetAvailableValues())
                     *          yield return impossibleNumber;
                     *
                     *      sequenceIsFixed = true;
                     *      break;
                     *  }
                     * }
                     *
                     * if (!sequenceIsFixed)
                     * {
                     *  foreach (var value in themoDataForCellChecked.ImpossibleValues)
                     *  {
                     *      yield return value;
                     *  }
                     * }
                     */
                    #endregion

                    foreach (var thermoData in thermometer.CoordinateDatas)
                    {
                        var cellFromThermometer = board.GetCell(cellChecked.Row, cellChecked.Column);

                        if (cellFromThermometer.CurrentNumber.HasValue)
                        {
                            var validNumbers = new ValuesPool();

                            if (themoDataForCellChecked.SequenceIndex < thermoData.SequenceIndex)
                            {
                                validNumbers.MakeUnavailableIfBiggerThan(cellFromThermometer.CurrentNumber.Value);
                            }
                            else
                            {
                                validNumbers.MakeUnavailableIfSmallerThan(cellFromThermometer.CurrentNumber.Value);
                            }

                            validNumbers.MakeUnavailable(cellFromThermometer.CurrentNumber.Value);

                            // Method return invalid numbers
                            foreach (var impossibleValues in validNumbers.CreateReverse().GetAvailableValues())
                            {
                                yield return(impossibleValues);
                            }

                            break;
                        }
                    }

                    foreach (var value in themoDataForCellChecked.ImpossibleValues)
                    {
                        yield return(value);
                    }
                }
            }
        }