Example #1
0
 private SquareTracker(SquareTracker <TPuzzle> other)
 {
     // Puzzle is guaranteed to be of type TPuzzle.
     _puzzle = (TPuzzle)other._puzzle.DeepCopy();
     // Copy matrix, focusing only on 'Unknown' possible square values and (therefore) unsatisfied constraints.
     _matrix    = other._matrix.CopyUnknowns();
     _setCoords = new Stack <Coordinate>(_puzzle.NumEmptySquares);
 }
Example #2
0
        public SolveStats GetStatsForAllSolutions(TPuzzle puzzle)
        {
            if (!_AreValuesUnique(puzzle.AllPossibleValues))
            {
                throw new ArgumentException(
                          $"{nameof(puzzle.AllPossibleValues)} must all be unique. Received values: {puzzle.AllPossibleValues.ToString()}.");
            }
            var puzzleCopy = (TPuzzle)puzzle.DeepCopy();
            var matrix     = new ExactCoverMatrix(puzzleCopy);

            foreach (IConstraint?constraint in _constraints)
            {
                constraint.Constrain(puzzleCopy, matrix);
            }
            return(_TryAllSolutions(new SquareTracker <TPuzzle>(puzzleCopy, matrix)));
        }
Example #3
0
        public static ConstraintHeader CreateConnectedHeader(
            ExactCoverMatrix matrix, ReadOnlySpan <PossibleValue> possibleSquares)
        {
            var header = new ConstraintHeader(matrix);

            matrix.Attach(header);
            foreach (PossibleValue?possibleSquare in possibleSquares)
            {
                _ = Link.CreateConnectedLink(possibleSquare, header);
            }
            if (header.Count == 0)
            {
                throw new ArgumentException(
                          $"Must provide at least one {nameof(PossibleValue)} when creating a {nameof(ConstraintHeader)}.");
            }
            return(header);
        }
Example #4
0
        internal ConstraintHeader CopyToMatrix(ExactCoverMatrix matrix)
        {
            Debug.Assert(FirstLink != null, $"Can't copy a header with a null {nameof(FirstLink)}.");
            Debug.Assert(!IsSatisfied, $"Can't copy a header that's already satisfied.");
            var copy = new ConstraintHeader(matrix);

            foreach (Link?link in GetLinks())
            {
                Square?square = matrix.GetSquare(link.PossibleSquare.Square.Coordinate);
                Debug.Assert(square != null,
                             $"Tried to copy a square link for a null square at {link.PossibleSquare.Square.Coordinate}.");
                PossibleValue?possibleSquare = square.GetPossibleValue(link.PossibleSquare.ValueIndex);
                Debug.Assert(possibleSquare != null, "Tried to link header to null possible square value.");
                _ = Link.CreateConnectedLink(possibleSquare, copy);
            }
            return(copy);
        }
Example #5
0
        public void SolveRandomly(TPuzzle puzzle)
        {
            if (!_AreValuesUnique(puzzle.AllPossibleValues))
            {
                throw new ArgumentException(
                          $"{nameof(puzzle.AllPossibleValues)} must all be unique. Received values: {puzzle.AllPossibleValues.ToString()}.");
            }
            var matrix = new ExactCoverMatrix(puzzle);

            foreach (IConstraint?constraint in _constraints)
            {
                constraint.Constrain(puzzle, matrix);
            }
            if (!_TrySolveRandomly(new Random(), new SquareTracker <TPuzzle>(puzzle, matrix)))
            {
                throw new ArgumentException($"Failed to solve the given puzzle.");
            }
        }
Example #6
0
 internal ConstraintHeader(ExactCoverMatrix matrix)
 {
     Matrix     = matrix;
     NextHeader = PreviousHeader = this;
 }
Example #7
0
 internal SquareTracker(TPuzzle puzzle, ExactCoverMatrix matrix)
 {
     _puzzle    = puzzle;
     _matrix    = matrix;
     _setCoords = new Stack <Coordinate>(puzzle.NumEmptySquares);
 }