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 void Search(DomainStore dstore, Sudoku sudoku)
 {
     if (_cts.IsCancellationRequested)
     {
         return;
     }
     // Try to solve sudoku via constraint propagation only
     while (Propagate(dstore))
     {
     }
     dstore.UpdateSudoku(sudoku);
     if (sudoku.IsSolved())
     {
         return;
     }
     // If that didn't work, perform a recursive search
     SearchRec(dstore, sudoku);
 }