Example #1
0
        private void Fetch(uint value, SimpleList <int> intersection, SudokuRegion intersected, SudokuState state, ICollection <IEvent> events)
        {
            IEvent result = NoReduction.Instance;
            var    mask   = ~value;

            foreach (var index in intersected)
            {
                // items in the shared section should be skipped.
                if (intersection.Contains(index))
                {
                    continue;
                }
                var test = state.And <ReducePointingPairs>(index, mask);

                if (test is ValueFound)
                {
                    events.Add(test);
                }
                else if (test is ReducedOption)
                {
                    result = test;
                }
            }

            if (result is ReducedOption)
            {
                events.Add(ReducedOptions.Ctor <ReduceNakedPairs>());
            }
        }
Example #2
0
        private void ReduceRegion(int skip, SudokuRegion region, SudokuState state, ICollection <IEvent> events)
        {
            var quad = 0u;

            buffer.Clear();

            foreach (var index in region.Skip(skip))
            {
                var value = state[index];

                if (SudokuCell.Count(value) < 4)
                {
                    quad |= value;

                    // Joined the represent more then 3 values.
                    if (SudokuCell.Count(quad) > 4 || buffer.Count > 3)
                    {
                        return;
                    }
                    buffer.Add(index);
                }
            }

            if (buffer.Count == 4)
            {
                Fetch(quad, buffer, region, state, events);
            }
        }
Example #3
0
        private void Fetch(uint quad, SimpleList <int> buffer, SudokuRegion region, SudokuState state, ICollection <IEvent> events)
        {
            var reduced = false;
            var mask    = ~quad;

            foreach (var index in region)
            {
                if (buffer.Contains(index))
                {
                    continue;
                }
                var result = state.And <ReduceNakedTriples>(index, mask);
                if (result is ValueFound)
                {
                    events.Add(result);
                }
                else if (result is ReducedOption)
                {
                    reduced = true;
                }
            }

            if (reduced)
            {
                events.Add(ReducedOptions.Ctor <ReduceNakedTriples>());
            }
        }
Example #4
0
        private void Fetch(uint nakedPair, SudokuRegion region, SudokuState state, ICollection <IEvent> events)
        {
            IEvent result = NoReduction.Instance;
            var    mask   = ~nakedPair;

            foreach (var index in region)
            {
                var value = state[index];
                if (value != nakedPair)
                {
                    var test = state.And <ReduceNakedPairs>(index, mask);

                    if (test is ValueFound)
                    {
                        events.Add(test);
                    }
                    else if (test is ReducedOption)
                    {
                        result = test;
                    }
                }
            }

            if (result is ReducedOption)
            {
                events.Add(ReducedOptions.Ctor <ReduceNakedPairs>());
            }
        }
Example #5
0
        private void ReduceRegion(uint pair, SudokuRegion region, SudokuState state, ICollection <IEvent> events)
        {
            HiddenPairs.Clear();

            foreach (var index in region)
            {
                var and = state[index] & pair;

                // at least on of the two is pressent.
                if (and != 0)
                {
                    // If not both are present or we already had 2, return.
                    if (and != pair || HiddenPairs.Count > 1)
                    {
                        return;
                    }
                    HiddenPairs.Add(index);
                }
            }

            if (HiddenPairs.Count == 2)
            {
                Fetch(pair, HiddenPairs, state, events);
            }
        }
Example #6
0
        private void ReduceRegion(SudokuRegion region, SudokuState state, ICollection <IEvent> events)
        {
            var nakedPair = 0u;
            var count     = 0;

            foreach (var index in region)
            {
                var value = state[index];

                // nothing found yet.
                if (nakedPair == default)
                {
                    if (SudokuCell.Count(value) == 2)
                    {
                        nakedPair = value;
                        count++;
                    }
                }

                // Equal to the first (potential) naked pair.
                else if (value == nakedPair && count++ > 2)
                {
                    throw new InvalidPuzzleException();
                }
            }

            if (count > 1)
            {
                Fetch(nakedPair, region, state, events);
            }
        }
Example #7
0
        private void CheckCells(SudokuState state, SudokuRegion region, uint singleValue, ICollection <IEvent> events)
        {
            var hidden = NoIndex;

            foreach (var index in region)
            {
                var value = state[index];

                // the cell has the value.
                if ((singleValue & value) != 0)
                {
                    // Already value, try next.
                    if (singleValue == value)
                    {
                        return;
                    }

                    // not the first
                    if (hidden != NoIndex)
                    {
                        return;
                    }
                    hidden = index;
                }
            }

            if (hidden == NoIndex)
            {
                return;
            }
            events.Add(state.And <ReduceHiddenSingles>(hidden, singleValue));
        }
Example #8
0
        /// <summary>Initializes all column regions.</summary>
        private void InitializeColumnRegions(int size2)
        {
            for (var column = 0; column < size2; column++)
            {
                var region = new SudokuRegion(SudokuRegionType.Column);
                Regions.Add(region);

                for (var height = 0; height < size2; height++)
                {
                    region.Add(Grid[height, column]);
                }
            }
        }
Example #9
0
        /// <summary>Initializes all row regions.</summary>
        private void InitializeRowRegions(int size2)
        {
            for (int row = 0; row < size2; row++)
            {
                var region = new SudokuRegion(SudokuRegionType.Row);
                Regions.Add(region);

                for (int width = 0; width < size2; width++)
                {
                    region.Add(Grid[row, width]);
                }
            }
        }
Example #10
0
        public void Solve(uint value, SudokuRegion first, SudokuRegion second, SudokuRegionType otherType, SudokuState state, ICollection <IEvent> events)
        {
            buffer.Clear();

            for (var index = 0; index < 9; index++)
            {
                var indexFirst  = first[index];
                var indexSecond = second[index];
                var joinFirst   = state[indexFirst] & value;
                var joinSecond  = state[indexSecond] & value;

                if (joinFirst == 0)
                {
                    if (joinSecond != 0)
                    {
                        return;
                    }
                }
                else
                {
                    if (joinSecond == 0 || buffer.Count > 3)
                    {
                        return;
                    }
                    buffer.Add(indexFirst);
                    buffer.Add(indexSecond);
                }
            }
            if (buffer.Count == 4)
            {
                var reducded = Fetch(
                    value,
                    first.Intersected.FirstOrDefault(r => r.RegionType == otherType),
                    state,
                    events);

                reducded |= Fetch(
                    value,
                    second.Intersected.FirstOrDefault(r => r.RegionType == otherType),
                    state,
                    events);

                if (reducded)
                {
                    events.Add(ReducedOptions.Ctor <ReduceXWing>());
                }
            }
        }
Example #11
0
        /// <summary>Initializes all sub square regions.</summary>
        private void InitializeSubSquareRegions(int size)
        {
            for (var xSub = 0; xSub < size; xSub++)
            {
                for (var ySub = 0; ySub < size; ySub++)
                {
                    var region = new SudokuRegion(SudokuRegionType.Block);
                    Regions.Add(region);

                    for (var x = 0; x < size; x++)
                    {
                        for (var y = 0; y < size; y++)
                        {
                            region.Add(Grid[xSub * size + x, ySub * size + y]);
                        }
                    }
                }
            }
        }
Example #12
0
        /// <summary>Returns true if the other has a intersection with this region of at least 2 cells, but is not the same region.</summary>
        public bool HasIntersectionOf2OrMoreSquares(SudokuRegion other)
        {
            if (other == this)
            {
                return(false);
            }
            var count = 0;

            foreach (var index in this)
            {
                if (other.Contains(index))
                {
                    count++;
                }
                if (count > 1)
                {
                    break;
                }
            }
            return(count > 1);
        }
Example #13
0
        private void Solve(SudokuState state, SudokuRegion region, SudokuRegion intersected, uint value, ICollection <IEvent> events)
        {
            var count = 0;

            foreach (var index in region)
            {
                if ((state[index] & value) != 0)
                {
                    if (intersection.Contains(index))
                    {
                        count++;
                    }
                    else
                    {
                        return;
                    }
                }
            }
            if (count > 1)
            {
                Fetch(value, intersection, intersected, state, events);
            }
        }
Example #14
0
        private bool Fetch(uint value, SudokuRegion region, SudokuState state, ICollection <IEvent> events)
        {
            var reducded = false;
            var mask     = ~value;

            foreach (var index in region)
            {
                if (buffer.Contains(index))
                {
                    continue;
                }
                var result = state.And <ReduceXWing>(index, mask);
                if (result is ValueFound)
                {
                    events.Add(result);
                }
                else if (result is ReducedOption)
                {
                    reducded = true;
                }
            }
            return(reducded);
        }