コード例 #1
0
ファイル: Board.cs プロジェクト: lukas-m/Sudoku
        /// <summary>
        /// If two cells in one segment contains the same two candidates only,
        /// then these candidates in other cells can be removed.
        /// </summary>
        private void NakedPair(List <Cell> changes)
        {
            using (var cacheItem = _cache.Get <Candidates, int>())
            {
                var dic = cacheItem.Dictionary;
                foreach (var seg in Segments)
                {
                    if (seg.FreeCells < 3)
                    {
                        continue;
                    }

                    dic.Clear();
                    foreach (var cell in seg)
                    {
                        if (cell.HasValue)
                        {
                            continue;
                        }
                        if (dic.ContainsKey(cell.Candidates))
                        {
                            dic[cell.Candidates]++;
                        }
                        else
                        {
                            dic[cell.Candidates] = 1;
                        }
                    }

                    foreach (var pair in dic)
                    {
                        if (pair.Value < 2 || pair.Value >= seg.FreeCells)
                        {
                            continue;
                        }
                        if (CandidatesHelper.Count(pair.Key) != pair.Value)
                        {
                            continue;
                        }
                        foreach (var cell in seg)
                        {
                            if (cell.HasValue || cell.Candidates == pair.Key)
                            {
                                continue;
                            }
                            var old = cell.Candidates;
                            cell.RemoveCandidates(pair.Key);
                            if (cell.Candidates != old)
                            {
                                changes.Add(cell);
                            }
                        }
                    }
                }
            }
        }
コード例 #2
0
ファイル: Cell.cs プロジェクト: lukas-m/Sudoku
 public void RemoveCandidates(Candidates candidates)
 {
     if (HasValue)
     {
         return;
     }
     Candidates   &= ~candidates;
     Possibilities = CandidatesHelper.Count(Candidates);
     OnChanged();
 }
コード例 #3
0
ファイル: Cell.cs プロジェクト: lukas-m/Sudoku
 public bool HasCandidate(int value)
 {
     if (HasValue || (Candidates & CandidatesHelper.ToCandidate(value)) == 0)
     {
         return(false);
     }
     else
     {
         return(true);
     }
 }
コード例 #4
0
 private new void Add(Cell cell)
 {
     base.Add(cell);
     if (!cell.HasValue)
     {
         FreeCells++;
     }
     else
     {
         Values |= CandidatesHelper.ToCandidate(cell.Value);
     }
 }
コード例 #5
0
ファイル: Cell.cs プロジェクト: lukas-m/Sudoku
 public void SetCandidates(Candidates candidates)
 {
     if (HasValue)
     {
         throw new InvalidOperationException("Cell has already a value.");
     }
     if ((Candidates | candidates) != Candidates)
     {
         throw new InvalidOperationException("Cannot add new candidates.");
     }
     Candidates    = candidates;
     Possibilities = CandidatesHelper.Count(Candidates);
     OnChanged();
 }
コード例 #6
0
ファイル: Cell.cs プロジェクト: lukas-m/Sudoku
 public void SetSingleCandidate(int value)
 {
     if (value < Cell.MinValue || value > Cell.MaxValue)
     {
         throw new ArgumentOutOfRangeException("Invalid value.");
     }
     if (HasValue)
     {
         throw new InvalidOperationException("Cell has already a value.");
     }
     Candidates    = CandidatesHelper.ToCandidate(value);
     Possibilities = 1;
     OnChanged();
 }
コード例 #7
0
ファイル: Cell.cs プロジェクト: lukas-m/Sudoku
 public void Reset()
 {
     if (HasValue)
     {
         foreach (var seg in Segments.Keys)
         {
             seg.FreeCells++;
             seg.Values &= ~CandidatesHelper.ToCandidate(Value);
         }
     }
     _value        = Cell.EmptyValue;
     IsFixed       = false;
     Candidates    = Cell.AllCandidates;
     Possibilities = CandidatesHelper.Count(Candidates);
     OnChanged();
 }
コード例 #8
0
ファイル: Cell.cs プロジェクト: lukas-m/Sudoku
 public void RemoveSingleCandidate(int value)
 {
     if (value < Cell.MinValue || value > Cell.MaxValue)
     {
         throw new ArgumentOutOfRangeException("Invalid value.");
     }
     if (HasValue)
     {
         return;
     }
     if (!HasCandidate(value))
     {
         return;
     }
     Candidates &= ~CandidatesHelper.ToCandidate(value);
     Possibilities--;
     OnChanged();
 }
コード例 #9
0
 public bool HasValue(int value)
 {
     return((Values & CandidatesHelper.ToCandidate(value)) != 0);
 }
コード例 #10
0
ファイル: Board.cs プロジェクト: lukas-m/Sudoku
        /// <summary>
        /// If two candidates in one segment are contained in the same two cells only,
        /// then other candidates in those cells can be removed.
        /// </summary>
        private void HiddenPair(List <Cell> changes)
        {
            using (var cacheItem = _cache.Get <int, SinglePairInfo>())
            {
                var dic = cacheItem.Dictionary;                 // cells -> count, Candidates
                foreach (var seg in Segments)
                {
                    if (seg.FreeCells < 3)
                    {
                        continue;
                    }

                    dic.Clear();
                    for (int i = Cell.MinValue; i <= Cell.MaxValue; i++)
                    {
                        if (seg.HasValue(i))
                        {
                            continue;
                        }

                        List <Cell> cells    = new List <Cell>();
                        int         cellMask = 0;
                        int         mask     = 1;
                        foreach (var cell in seg)
                        {
                            if (cell.HasCandidate(i))
                            {
                                cellMask |= mask;
                                cells.Add(cell);
                            }
                            mask <<= 1;
                        }

                        SinglePairInfo info;
                        if (dic.TryGetValue(cellMask, out info))
                        {
                            info.Count++;
                            info.Candidates |= CandidatesHelper.ToCandidate(i);
                        }
                        else
                        {
                            dic[cellMask] = new SinglePairInfo()
                            {
                                Cells = cells, Count = 1, Candidates = CandidatesHelper.ToCandidate(i)
                            };
                        }
                    }

                    foreach (var info in dic.Values)
                    {
                        if (info.Count < 2 || info.Cells.Count != info.Count)
                        {
                            continue;
                        }
                        foreach (var cell in info.Cells)
                        {
                            if (cell.Possibilities != info.Count)
                            {
                                cell.SetCandidates(info.Candidates);
                                changes.Add(cell);
                            }
                        }
                    }
                }
            }
        }