/*****************************************************************************
**
** Square.cs
**
*****************************************************************************/
using System;
class Square
{/* -----------------------------------------------------------------------
VARIABLES
----------------------------------------------------------------------- */
protected readonly int _index = -1;
protected int _iCandidates = -1;
protected int _iValue = -1;
protected BitSet _candidates = new BitSet();
/* -----------------------------------------------------------------------
CONSTRUCTOR
----------------------------------------------------------------------- */
///
/// <summary>
/// Constructor for the square class
/// </summary>
/// <param name="index">Index of the square</param>
/// <exception cref="IndexOutOfRangeException">
/// Raised if the iHouse is not valid.
/// </exception>
/// <remarks>
/// Since squares should never be moved around on the grid, set the iHouse
/// once via the CTOR, then leave it alone.
/// </remarks>
///
public
Square(int index)
{ if (!Grid.IsValidIndex(index))
throw new IndexOutOfRangeException();
_index = index;
Reset();
} /* end of Square::Square() */
/* -----------------------------------------------------------------------
METHODS
----------------------------------------------------------------------- */
///
/// <summary>
/// Clears a candidate for the square
/// </summary>
/// <returns>TRUE if candidate eliminated, FALSE otherwise</returns>
/// <param name="iValue">Value to eliminate</param>
/// <exception cref="ValueOutOfRangeException">
/// Raised if the value is outside the range of Grid.ValueMin to Grid.ValueMax
/// </exception>
/// <exception cref="UnsolvableSquareException">
/// Raised if the square ends up with no viable candidates
/// </exception>
///
public bool
ClearCandidate(int iValue)
{ if (!Grid.IsValidValue( iValue ))
throw new ArgumentOutOfRangeException( "iValue" );
if (IsEmpty && _candidates.Test( iValue ))
{ _iCandidates--;
_candidates.Clear(iValue);
if (_candidates.Empty)
throw new UnsolvableSquareException(_index);
return true;
}
return false;
} /* end of Square::ClearCandidate() */
///
/// <summary>
/// Clears all candidates for the square
/// </summary>
///
public void
ClearAllCandidates()
{ _iCandidates = 0;
_candidates.ClearAll();
} /* end of Square::ClearAllCandidates() */
///
/// <summary>
/// Clears the square, setting it to it's initial state
/// </summary>
///
public void
Reset()
{ _iCandidates = (Grid.ValueMax - Grid.ValueMin) + 1;
_iValue = Grid.ValueNone;
_candidates.SetRange( Grid.ValueMin, Grid.ValueMax );
} /* end of Square::Reset() */
///
/// <summary>
/// Clears a candidate for the square
/// </summary>
/// <returns>TRUE if candidate eliminated, FALSE otherwise</returns>
/// <param name="iValue">Value to eliminate</param>
/// <exception cref="ValueOutOfRangeException">
/// Raised if the value is outside the range of Grid.ValueMin to Grid.ValueMax
/// </exception>
/// <exception cref="UnsolvableSquareException">
/// Raised if the square ends up with no viable candidates
/// </exception>
///
public bool
SetCandidate(int iValue)
{ if (!Grid.IsValidValue( iValue ))
throw new ArgumentOutOfRangeException( "iValue" );
if (IsEmpty && !_candidates.Test( iValue ))
{ _iCandidates++;
_candidates.Set(iValue);
return true;
}
return false;
} /* end of Square::SetCandidate() */
/* -----------------------------------------------------------------------
PROPERTIES
----------------------------------------------------------------------- */
///
/// <summary>
/// Returns a bitset representing the valid candidates for this square
/// </summary>
/// <returns>Bitset by value</returns>
///
public BitSet
Candidates
{ get
{ return _candidates; } } /* end of Square::Candidates() */
///
/// <summary>
/// Returns a count of the valid candidates for this square
/// </summary>
/// <returns>Count</returns>
///
public int
CandidateCount
{ get
{ return _iCandidates; } } /* end of Square::CandidateCount() */
///
/// <summary>
/// The position of the square on the puzzle grid.
/// </summary>
/// <returns>Index of the square</returns>
///
public int
Index
{ get
{ return _index; } } /* end of Square::Index() */
///
/// <summary>
/// Evaluates if a square is empty (blank)
/// </summary>
/// <returns>TRUE if square is empty</returns>
///
public bool
IsEmpty
{ get
{ return (_iValue == Grid.ValueNone); } } /* end of Square::IsEmpty() */
///
/// <summary>
/// The square's value
/// </summary>
/// <returns>Value, or ValueNone if empty</returns>
///
public int
Value
{ get
{ return _iValue; } set
{ if (!(value == Grid.ValueNone || Grid.IsValidValue(value)))
throw new ValueOutOfRangeException();
_iValue = value;
if (value == Grid.ValueNone)
Reset();
else if (_candidates.Test(_iValue))
{ _iCandidates = 0;
_candidates.ClearAll();
}
else
throw new IllegalValueException(_index, _iValue);
}
} /* end of Square::Value() */
};
/*****************************************************************************
**
** End of Square.cs
**
*****************************************************************************/