private void SearchRec(DomainStore dstore, Sudoku sudoku)
        {
            // Select the sudoku cell with the smallest domain and try to fill it first
            Field f = dstore.GetFieldWithSmallestDomain();

            if (f == null)
            {
                // There's no cell with a domain size > 1 left, the sudoku is filled completely
                dstore.UpdateSudoku(sudoku);
                return;
            }
            // Try to solve the sudoku with every possible value of the cell's domain
            HashSet <int> domain = dstore.GetDomain(f);

            foreach (int digit in domain)
            {
                DomainStore dstoreClone = new(dstore);
                dstoreClone.SetDomain(f, new HashSet <int>()
                {
                    digit
                });
                Search(dstoreClone, sudoku);
                if (sudoku.IsSolved())
                {
                    return;
                }
                else
                {
                    // Prune this try and take a step back
                    dstore.UpdateSudoku(sudoku);
                }
            }
        }
        private bool Eliminate(DomainStore dstore, IEnumerable <Field> fields)
        {
            bool domainsHaveChanged = false;
            // Go through the cells and remeber the digits you see
            HashSet <int> seenDigits = new();

            foreach (Field f in fields)
            {
                if (dstore.GetDomainSize(f) == 1)
                {
                    HashSet <int> domain = dstore.GetDomain(f);
                    foreach (int digit in domain) // Workaround to access first HashSet value quickly
                    {
                        seenDigits.Add(digit);
                        break;
                    }
                }
            }
            // Now, go through the cells again and update each cell's domain considering the digits you saw in the other cells
            foreach (Field f in fields)
            {
                // If a cells's domain has just a single digit left, it does not have to be changed anymore
                if (dstore.GetDomainSize(f) == 1)
                {
                    continue;
                }
                HashSet <int> domain           = dstore.GetDomain(f);
                HashSet <int> impossibleDigits = new(seenDigits);
                HashSet <int> subtraction      = Util.Subtract(domain, impossibleDigits);
                // Prune this try if no digit can't be assigned to the cell
                if (subtraction.Count == 0)
                {
                    return(false);
                }
                // If a cell's domain has to be updated based on the seen digits, do it and note that there was a change
                if (!domain.SetEquals(subtraction))
                {
                    domainsHaveChanged = true;
                    dstore.SetDomain(f, subtraction);
                }
            }
            return(domainsHaveChanged);
        }
 public DomainStore(DomainStore dstore)
 {
     InitFieldsByDomainSize();
     for (int x = 0; x < Sudoku.Size; x++)
     {
         for (int y = 0; y < Sudoku.Size; y++)
         {
             SetDomain(x, y, dstore.GetDomain(x, y));
         }
     }
 }