/*****************************************************************************
**
**    brute.cs
**
*****************************************************************************/
using System;
using System.Diagnostics;
 
class BruteForceSolver
    {
/*    -----------------------------------------------------------------------
    DECLARATIONS
    -----------------------------------------------------------------------    */
#region "DECLARATIONS"
 
#endregion
/*    -----------------------------------------------------------------------
    VARIABLES
    -----------------------------------------------------------------------    */
#region "VARIABLES"
    private int        _iSolutions;
    private Grid    _grid;
#endregion
/*    -----------------------------------------------------------------------
    STATIC METHODS
    -----------------------------------------------------------------------    */
#region "STATIC METHODS"
 
#endregion
/*    -----------------------------------------------------------------------
    CONSTRUCTOR
    -----------------------------------------------------------------------    */
#region "CONSTRUCTOR"
    ///
    ///    <summary>
    ///    Constructor for the "brute force solver" class
    ///    </summary>
    ///    
    public
    BruteForceSolver()
        {
        _grid = new Grid();
        _iSolutions = 0;
        }    /* end of BruteForceSolver::BruteForceSolver() */
#endregion        
/*    -----------------------------------------------------------------------
    PUBLIC METHODS
    -----------------------------------------------------------------------    */
#region "PUBLIC METHODS"
    ///
    /// <summary>
    /// Attempts to solve the puzzle
    /// </summary>
    /// <param name="grid">Grid to solve</param>
    /// <param name="bFindAll">TRUE to find all solutions, FALSE to stop after second</param>
    /// <param name="bListSolutions">TRUE to list all solutions</param>
    /// <returns>Number of solutions found</returns>
    /// 
    public int
    Solve( Grid grid, bool bFindAll, bool bListSolutions )
        {
        if (grid == null)
            return 0;
 
        _iSolutions = 0;
        _grid = (Grid) grid.Clone();
 
        search( !bFindAll, bListSolutions );
 
        return _iSolutions;
        }
    ///
    /// <summary>
    /// Recursive search
    /// </summary>
    /// <param name="bQuick">TRUE to stop after second solution</param>
    /// <param name="bListSolutions">TRUE to list all solutions</param>
    ///
    private void
    search( bool bQuick, bool bListSolutions )
        {
        if (_grid.EmptyCount == 0)
            {
//            Console.WriteLine( _grid.DisplayShortForm('.'));
            _iSolutions++;
            return;
            }
        //
        //    Find the square with the fewest candidates
        //
        int        iCount;
        int        iBest = Grid.BadIndex;
        int        iMinCount = Grid.Size + 1;
 
        for (int index = 0; index < Grid.Squares; ++index)
            {
            if (_grid[index].IsEmpty &&
                (iCount = _grid[index].CandidateCount) < iMinCount)
                {
                if (iCount == 0)
                    return;    // impossible puzzle
 
                iMinCount = iCount;
                iBest = index;
                }
            }
        //
        //    Now try all of the values in the best square, one at a time
        //
        if (Grid.IsValidIndex(iBest))
            {
            for (int iValue = Grid.ValueMin; iValue <= Grid.ValueMax; ++iValue)
                {
                if (_grid[iBest].Candidates.Test(iValue))
                    {
                    try
                        {
                        if (_grid.Set(iBest, iValue))
                            search(bQuick, bListSolutions);
                        }
                    catch (Exception)
                        { /* DO NOTHING */ }
 
                    if (bQuick && _iSolutions > 1)
                        return;
 
                    _grid.SetEmpty(iBest);
                    }
                }
            }
        }    /* end of BruteForceSolver::solve() */
#endregion
/*    -----------------------------------------------------------------------
    PROPERTIES
    -----------------------------------------------------------------------    */
#region "PROPERTIES"
    public int
    Solutions
        {
        get
            {
            return _iSolutions;
            }
        }
    }
#endregion
/*****************************************************************************
**
**    End of dlx.cs
**
*****************************************************************************/