Esempio n. 1
0
        public void TrySelectAndDeselectPossibility_WithMultipleRequired_Works()
        {
            var puzzle        = new Puzzle(4);
            var matrix        = ExactCoverGraph.Create(puzzle);
            var possibilities = new FakePossibility[] {
                new FakePossibility(),
                new FakePossibility(),
            };
            var        firstSelected     = possibilities[0];
            var        secondSelected    = possibilities[1];
            var        concreteObjective = Objective.CreateFullyConnected(matrix, possibilities, 2);
            IObjective objective         = concreteObjective;

            Assert.True(objective.TrySelectPossibility(firstSelected.AttachedObjectives.First()));
            Assert.NotEqual(NodeState.SELECTED, concreteObjective.State);
            Assert.Equal(1, concreteObjective.CountUnknown);
            Assert.Single(objective.GetUnknownDirectPossibilities(), secondSelected);
            Assert.Contains(concreteObjective, matrix.GetUnsatisfiedRequiredObjectivesWithConcretePossibilities());

            Assert.True(objective.TrySelectPossibility(secondSelected.AttachedObjectives.First()));
            Assert.Equal(NodeState.SELECTED, concreteObjective.State);
            Assert.Equal(0, concreteObjective.CountUnknown);
            Assert.True(!matrix.GetUnsatisfiedRequiredObjectivesWithConcretePossibilities().Contains(concreteObjective) ||
                        matrix.GetUnsatisfiedRequiredObjectivesWithConcretePossibilities().Count() == 1);

            objective.DeselectPossibility(secondSelected.AttachedObjectives.First());
            Assert.NotEqual(NodeState.SELECTED, concreteObjective.State);
            Assert.Equal(1, concreteObjective.CountUnknown);
            Assert.Single(objective.GetUnknownDirectPossibilities(), secondSelected);
            Assert.Contains(concreteObjective, matrix.GetUnsatisfiedRequiredObjectivesWithConcretePossibilities());

            objective.DeselectPossibility(firstSelected.AttachedObjectives.First());
            Assert.Equal(2, concreteObjective.CountUnknown);
        }
Esempio n. 2
0
        public void TrySelectAndDeselectPossibility_Succeeds()
        {
            var fakePossibilities = new FakePossibility[] {
                new FakePossibility(),
                new FakePossibility(),
            };
            var childOptional = OptionalObjective.CreateWithPossibilities(
                Possibilities.CreatePossibilities(new(), 2), 1);
            var          optional            = OptionalObjective.CreateWithPossibilities(fakePossibilities, 2);
            var          linkToChildOptional = Link.CreateConnectedLink(childOptional, optional);
            var          parent       = new FakeObjective(isRequired: true);
            var          linkToParent = Link.CreateConnectedLink(optional, parent);
            IPossibility possibility  = optional;
            IObjective   objective    = optional;

            Assert.True(objective.TrySelectPossibility(fakePossibilities[0].AttachedObjectives.First()));
            Assert.Equal(NodeState.UNKNOWN, optional.State);
            Assert.Equal(NodeState.UNKNOWN, childOptional.State);
            Assert.All(((IObjective)childOptional).GetUnknownDirectPossibilities().Cast <Possibility>(),
                       p => Assert.Equal(NodeState.UNKNOWN, p.State));
            Assert.Empty(fakePossibilities[0].DroppedFromObjectives);
            Assert.Empty(fakePossibilities[1].DroppedFromObjectives);
            Assert.Empty(parent.SelectedPossibilities);

            Assert.True(objective.TrySelectPossibility(fakePossibilities[1].AttachedObjectives.First()));
            Assert.Equal(NodeState.SELECTED, optional.State);
            Assert.Equal(NodeState.UNKNOWN, childOptional.State);
            Assert.All(((IObjective)childOptional).GetUnknownDirectPossibilities().Cast <Possibility>(),
                       p => Assert.Equal(NodeState.UNKNOWN, p.State));
            Assert.Single(parent.SelectedPossibilities, linkToParent);
            Assert.Empty(fakePossibilities[0].DroppedFromObjectives);
            Assert.Empty(fakePossibilities[1].DroppedFromObjectives);

            objective.DeselectPossibility(fakePossibilities[1].AttachedObjectives.First());
            Assert.Equal(NodeState.UNKNOWN, optional.State);
            Assert.Equal(NodeState.UNKNOWN, childOptional.State);
            Assert.All(((IObjective)childOptional).GetUnknownDirectPossibilities().Cast <Possibility>(),
                       p => Assert.Equal(NodeState.UNKNOWN, p.State));
            Assert.Empty(fakePossibilities[0].DroppedFromObjectives);
            Assert.Empty(fakePossibilities[1].DroppedFromObjectives);
            Assert.Empty(parent.SelectedPossibilities);

            objective.DeselectPossibility(fakePossibilities[0].AttachedObjectives.First());
            Assert.Equal(NodeState.UNKNOWN, optional.State);
            Assert.Equal(NodeState.UNKNOWN, childOptional.State);
            Assert.All(((IObjective)childOptional).GetUnknownDirectPossibilities().Cast <Possibility>(),
                       p => Assert.Equal(NodeState.UNKNOWN, p.State));
            Assert.Empty(fakePossibilities[0].DroppedFromObjectives);
            Assert.Empty(fakePossibilities[1].DroppedFromObjectives);
            Assert.Empty(parent.SelectedPossibilities);
        }
Esempio n. 3
0
        public void TrySelectPossibility_WhenRejectedByParent_LeavesUnchanged()
        {
            var fakePossibilities = new FakePossibility[] {
                new FakePossibility(),
                new FakePossibility(),
            };
            var childOptional = OptionalObjective.CreateWithPossibilities(
                Possibilities.CreatePossibilities(new(), 2), 1);
            var optional            = OptionalObjective.CreateWithPossibilities(fakePossibilities, 1);
            var linkToChildOptional = Link.CreateConnectedLink(childOptional, optional);
            var parent = new FakeObjective(isRequired: true);

            parent.CanSelectPossibilities = false;
            var          linkToParent = Link.CreateConnectedLink(optional, parent);
            IPossibility possibility  = optional;
            IObjective   objective    = optional;

            Assert.False(objective.TrySelectPossibility(fakePossibilities[0].AttachedObjectives.First()));
            Assert.Equal(NodeState.UNKNOWN, optional.State);
            Assert.Equal(NodeState.UNKNOWN, childOptional.State);
            Assert.All(((IObjective)childOptional).GetUnknownDirectPossibilities().Cast <Possibility>(),
                       p => Assert.Equal(NodeState.UNKNOWN, p.State));
            Assert.Empty(fakePossibilities[0].DroppedFromObjectives);
            Assert.Empty(fakePossibilities[1].DroppedFromObjectives);
            Assert.Empty(parent.SelectedPossibilities);
        }
Esempio n. 4
0
        public void TrySelectPossibility_WithUndetachablePossibility_Fails()
        {
            var puzzle        = new Puzzle(4);
            var matrix        = ExactCoverGraph.Create(puzzle);
            var possibilities = new FakePossibility[] {
                new FakePossibility(),
                new FakePossibility(),
                new FakePossibility(),
            };
            var toSelect     = possibilities[0];
            var undetachable = possibilities[2];

            undetachable.CanBeDetached = false;
            var        concreteObjective = Objective.CreateFullyConnected(matrix, possibilities, 1);
            IObjective objective         = concreteObjective;

            Assert.False(objective.TrySelectPossibility(toSelect.AttachedObjectives.First()));
            Assert.Empty(possibilities[1].DroppedFromObjectives);
            Assert.Empty(undetachable.DroppedFromObjectives);
            Assert.Contains(objective, matrix.GetUnsatisfiedRequiredObjectivesWithConcretePossibilities());
            Assert.Contains(toSelect, objective.GetUnknownDirectPossibilities());
            Assert.Contains(possibilities[1], objective.GetUnknownDirectPossibilities());
            Assert.Contains(undetachable, objective.GetUnknownDirectPossibilities());
        }
Esempio n. 5
0
        public void TrySelectPossibility_CausesCascadingDrop_SelectsAndDeselectsCorrectly()
        {
            var puzzle            = new Puzzle(4);
            var matrix            = ExactCoverGraph.Create(puzzle);
            var fakePossibilities = new FakePossibility[] {
                new FakePossibility(),
                new FakePossibility(),
            };
            var optional = OptionalObjective.CreateWithPossibilities(fakePossibilities, 1);
            var fakesOnParentToSelect = new FakePossibility[] {
                new FakePossibility(),
                new FakePossibility(),
            };
            var parentToSelect = OptionalObjective.CreateWithPossibilities(
                fakesOnParentToSelect.Cast <IPossibility>().Prepend(optional).ToArray(), 2);
            var fakeOnParentToDrop = new FakePossibility();
            var parentToDrop       = OptionalObjective.CreateWithPossibilities(
                new IPossibility[] {
                fakeOnParentToDrop,
                optional,
            }, 2);
            var required = Objective.CreateFullyConnected(
                matrix,
                new IPossibility[] { parentToSelect, parentToDrop },
                1);
            IObjective objective = optional;

            ;
            // Select one fake on parentToSelect so that selecting this optional will satisfy the
            // objective.
            Assert.True(((IObjective)parentToSelect).TrySelectPossibility(fakesOnParentToSelect[0].AttachedObjectives.First()));
            Assert.True(objective.TrySelectPossibility(fakePossibilities[0].AttachedObjectives.First()));
            Assert.Equal(NodeState.SELECTED, optional.State);
            Assert.Equal(NodeState.SELECTED, parentToSelect.State);
            Assert.Empty(fakesOnParentToSelect[1].DroppedFromObjectives);
            Assert.Equal(NodeState.SELECTED, required.State);
            Assert.Equal(NodeState.DROPPED, parentToDrop.State);
            Assert.Empty(fakeOnParentToDrop.DroppedFromObjectives);

            objective.DeselectPossibility(fakePossibilities[0].AttachedObjectives.First());
            Assert.Equal(NodeState.UNKNOWN, optional.State);
            Assert.Equal(NodeState.UNKNOWN, parentToSelect.State);
            Assert.Empty(fakesOnParentToSelect[1].DroppedFromObjectives);
            Assert.Equal(NodeState.UNKNOWN, required.State);
            Assert.Equal(NodeState.UNKNOWN, parentToDrop.State);
            Assert.Empty(fakeOnParentToDrop.DroppedFromObjectives);

            // Select a possibility on parentToDrop first. This should result in no change overall.
            Assert.True(((IObjective)parentToDrop).TrySelectPossibility(fakeOnParentToDrop.AttachedObjectives.First()));

            // Selecting the objective would satisfy both optional parents, which violates the
            // required objective.
            Assert.False(objective.TrySelectPossibility(fakePossibilities[0].AttachedObjectives.First()));

            // Deselect a possibility from parentToSelect so that we can now select parentToDrop.
            ((IObjective)parentToSelect).DeselectPossibility(fakesOnParentToSelect[0].AttachedObjectives.First());
            Assert.True(objective.TrySelectPossibility(fakePossibilities[0].AttachedObjectives.First()));
            Assert.Equal(NodeState.SELECTED, optional.State);
            Assert.Equal(NodeState.DROPPED, parentToSelect.State);
            Assert.Empty(fakesOnParentToSelect[1].DroppedFromObjectives);
            Assert.Equal(NodeState.SELECTED, required.State);
            Assert.Equal(NodeState.SELECTED, parentToDrop.State);
            Assert.Empty(fakeOnParentToDrop.DroppedFromObjectives);
        }