public void DynamicState_CreateEmpty_DoesNotThrowUponReadCalls()
        {
            DynamicState empty = DynamicState.CreateEmpty(10);  // Arbitrary number

            Assert.DoesNotThrow(() => empty.GetEdge(2, 5));
            Assert.DoesNotThrow(() => empty.GetEdge(1, 2));
            Assert.DoesNotThrow(() => empty.GetEdge(7, 3));

            DynamicState.AreaEdge e1 = empty.GetEdge(2, 5);
            DynamicState.AreaEdge e2 = empty.GetEdge(1, 2);
            DynamicState.AreaEdge e3 = empty.GetEdge(7, 3);

            Assert.DoesNotThrow(() => { bool b = e1.IsCausingClearEffect; });
            Assert.DoesNotThrow(() => { bool b = e2.IsCausingPotentialEnemiesEffect; });
            Assert.DoesNotThrow(() => { int i = e1.ToNodeId; });

            for (int i = 0; i < 10; i++)
            {
                Assert.DoesNotThrow(() => empty.IsEnemyAreaReader()(i));
                Assert.DoesNotThrow(() => empty.IsControlledByTeamReader()(i));
                Assert.DoesNotThrow(() => empty.IsContestedAreaReader()(i));
                Assert.DoesNotThrow(() => empty.TakingFireMagnitudeLevelReader()(i));

                DynamicState.AreaNode n;
                Assert.DoesNotThrow(() => empty.GetNodeData(i));
                n = empty.GetNodeData(i);
                Assert.DoesNotThrow(() => { int d = n.TakingFireMagnitudeLevel; });
                Assert.DoesNotThrow(() => { bool b = n.IsControlledByTeam; });

                Assert.DoesNotThrow(() => { Dictionary <FactType, Fact> f = DynamicStateInternalReader.GetNodeFact(i, empty); });
                Assert.DoesNotThrow(() => { Dictionary <EffectType, EffectSum> f = DynamicStateInternalReader.GetNodeEffectSum(i, empty); });
            }
        }
        public static void CheckTestDynamicState(DynamicState toTest)
        {
            // Test node data reads
            Assert.IsTrue(toTest.GetNodeData(0).SquadMemberPresence == 2);
            Assert.IsTrue(toTest.GetNodeData(0).EnemyPresence == 0);
            Assert.IsTrue(toTest.GetNodeData(0).IsFriendlyArea);
            Assert.IsTrue(toTest.GetNodeData(0).IsClear);
            Assert.IsTrue(toTest.GetNodeData(0).IsControlledByTeam);
            Assert.IsTrue(toTest.GetNodeData(0).LastKnownEnemyPosition == 0);
            Assert.IsTrue(!toTest.GetNodeData(1).IsControlledByTeam);
            Assert.IsTrue(toTest.GetNodeData(1).IsClear);
            Assert.IsTrue(toTest.GetNodeData(1).VisibleToEnemies);
            Assert.IsTrue(!toTest.GetNodeData(1).PotentialEnemies);
            Assert.IsTrue(toTest.GetNodeData(2).EnemyPresence == 3);
            Assert.IsTrue(toTest.GetNodeData(2).IsEnemyArea);
            Assert.IsTrue(!toTest.GetNodeData(2).IsContestedArea);
            Assert.IsTrue(!toTest.GetNodeData(2).IsClear);
            Assert.IsTrue(toTest.GetNodeData(2).IsControlledByEnemies);
            Assert.IsTrue(toTest.GetNodeData(2).VisibleToEnemies);
            Assert.IsTrue(toTest.GetNodeData(3).IsClear);
            Assert.IsTrue(toTest.GetNodeData(3).IsControlledByTeam);
            Assert.IsTrue(!toTest.GetNodeData(3).IsControlledByEnemies);
            Assert.IsTrue(toTest.GetNodeData(3).LastKnownEnemyPosition == 0);
            Assert.IsTrue(toTest.GetNodeData(3).LastKnownFriendlyPosition == 0);
            Assert.IsTrue(!toTest.GetNodeData(4).IsControlledByEnemies);
            Assert.IsTrue(toTest.GetNodeData(4).SquadMemberPresence == 1);
            Assert.IsTrue(toTest.GetNodeData(4).IsFriendlyArea);
            Assert.IsTrue(toTest.GetNodeData(5).TakingFireMagnitudeLevel == 5);
            Assert.IsTrue(toTest.GetNodeData(5).VisibleToEnemies);
            Assert.IsTrue(toTest.GetNodeData(5).PotentialEnemies);
            Assert.IsTrue(toTest.GetNodeData(5).IsClear == false);
            Assert.IsTrue(toTest.GetNodeData(6).PotentialEnemies);
            Assert.IsTrue(toTest.GetNodeData(6).IsEnemyArea == false);
            Assert.IsTrue(toTest.GetNodeData(6).IsControlledByTeam == false);
            Assert.IsTrue(toTest.GetNodeData(6).LastKnownFriendlyPosition == 2);
            Assert.IsTrue(toTest.GetNodeData(6).LastKnownEnemyPosition == 0);
            Assert.IsTrue(!toTest.GetNodeData(7).IsControlledByTeam);
            Assert.IsTrue(toTest.GetNodeData(7).EnemyPresence == 0);
            Assert.IsTrue(toTest.GetNodeData(7).SquadMemberPresence == 0);
            Assert.IsTrue(toTest.GetNodeData(1).NoKnownPresence);
            Assert.IsTrue(toTest.GetNodeData(3).NoKnownPresence);
            Assert.IsTrue(toTest.GetNodeData(7).NoKnownPresence);
            Assert.IsTrue(toTest.GetNodeData(8).NoKnownPresence);
            Assert.IsTrue(toTest.GetNodeData(9).NoKnownPresence);
            Assert.IsTrue(toTest.GetNodeData(7).PotentialEnemies);
            Assert.IsTrue(!toTest.GetNodeData(0).NoKnownPresence);
            Assert.IsTrue(toTest.GetNodeData(0).VisibleToSquad);
            Assert.IsTrue(toTest.GetNodeData(1).VisibleToSquad);
            Assert.IsTrue(toTest.GetNodeData(3).VisibleToSquad);
            Assert.IsTrue(toTest.GetNodeData(4).VisibleToSquad);
            Assert.IsTrue(!toTest.GetNodeData(2).VisibleToSquad);
            Assert.IsTrue(toTest.GetNodeData(8).LastKnownEnemyPosition == 1);
            Assert.IsTrue(!toTest.GetNodeData(8).VisibleToEnemies);
            Assert.IsTrue(toTest.GetNodeData(8).PotentialEnemies);
            Assert.IsTrue(!toTest.GetNodeData(9).PotentialEnemies);
            Assert.IsTrue(toTest.GetNodeData(8).EnemyPresence == 0);
            Assert.IsTrue(!toTest.GetNodeData(8).IsEnemyArea);
            Assert.IsTrue(!toTest.GetNodeData(8).IsContestedArea);
            Assert.IsTrue(toTest.GetNodeData(9).TakingFireMagnitudeLevel == 1);
            Assert.IsTrue(toTest.GetNodeData(8).SourceOfEnemyFire);

            // Do the same tests but using the graph-subset reader functions
            Func <int, bool> visf = toTest.VisibleToSquadReader();

            Assert.IsTrue(visf(0) && visf(1) && visf(3) && visf(4) && !visf(5) && !visf(6) && !visf(7) && !visf(2));
            Func <int, int> friends = toTest.KnownSquadMemberPresenceReader();

            Assert.IsTrue(friends(0) == 2);
            Assert.IsTrue(friends(1) == 0);
            Assert.IsTrue(friends(2) == 0);
            Assert.IsTrue(friends(3) == 0);
            Assert.IsTrue(friends(4) == 1);
            Func <int, bool> clear = toTest.IsClearReader();

            Assert.IsTrue(clear(0) && clear(1) && !clear(2) && clear(3) && !clear(7));
            Func <int, bool> potentials = toTest.PotentialEnemiesReader();

            Assert.IsTrue(potentials(6) && !potentials(1) && potentials(7) && potentials(8) && potentials(5) && !potentials(4) && !potentials(9));
            Func <int, bool> vis = toTest.VisibleToEnemiesReader();

            Assert.IsTrue(vis(1) && vis(2) && !vis(3) && !vis(0) && !vis(7));
            Func <int, bool> noPres = toTest.HasNoKnownPresenceReader();

            Assert.IsTrue(noPres(7) && noPres(5) && !noPres(2));
            Func <int, int> lastE = toTest.LastKnownEnemyPositionReader();

            Assert.IsTrue(lastE(8) == 1 && lastE(5) == 0 && lastE(3) == 0);
            Func <int, int> lastF = toTest.LastKnownFriendlyPositionReader();

            Assert.IsTrue(lastF(6) == 2 && lastF(8) == 0 && lastF(5) == 0 && lastF(3) == 0);
            Func <int, int> takingFire = toTest.TakingFireMagnitudeLevelReader();

            Assert.IsTrue(takingFire(9) == 1 && takingFire(4) == 0 && takingFire(0) == 0);

            // Test edges
            Func <int, int, bool> clearing = toTest.CausingClearEffectReader();

            Assert.IsTrue(clearing(0, 1) && clearing(0, 3) && !clearing(0, 2) && !clearing(2, 1) && clearing(4, 3));
            Func <int, int, bool> causingPotentials = toTest.CausingPotentialEnemiesEffectReader();

            Assert.IsTrue(causingPotentials(5, 1) && causingPotentials(5, 6) && !causingPotentials(2, 1) && causingPotentials(8, 6) && causingPotentials(8, 7));
            Func <int, int, bool> causingVisible = toTest.CausingVisibleToEnemiesEffectReader();

            Assert.IsTrue(causingVisible(2, 1) && !causingVisible(2, 7) && !causingVisible(1, 5));

            Assert.IsTrue(toTest.GetEdge(0, 1).IsCausingClearEffect&& !toTest.GetEdge(0, 1).IsCausingControlledByTeamEffect);
            Assert.IsTrue(toTest.GetEdge(0, 3).IsCausingClearEffect&& toTest.GetEdge(0, 3).IsCausingControlledByTeamEffect);
            Assert.IsTrue(toTest.GetEdge(2, 1).IsCausingVisibleToEnemiesEffect&& toTest.GetEdge(2, 5).IsCausingVisibleToEnemiesEffect);
            Assert.IsTrue(toTest.GetEdge(5, 1).IsCausingPotentialEnemiesEffect&& toTest.GetEdge(8, 6).IsCausingPotentialEnemiesEffect&& toTest.GetEdge(8, 7).IsCausingPotentialEnemiesEffect);
            Assert.IsTrue(toTest.GetEdge(9, 8).IsCausingSourceOfEnemyFireEffect&& toTest.GetEdge(8, 9).IsCausingTakingFireEffect);
            // TODO: 8 - Implement specfic logic to define what happens when you call a node edge read from a node, to itself. I.e. dynamicStateInstance.GetEdge(x, x).friendlies;. Possibly not allowed?
        }
        private void TestModifiedDynamicState(DynamicState toTest)
        {
            // Test node data reads
            Assert.IsTrue(toTest.GetNodeData(0).SquadMemberPresence == 0);  // Should be changed! (Compared to the original)
            Assert.IsTrue(toTest.GetNodeData(0).EnemyPresence == 0);
            Assert.IsTrue(!toTest.GetNodeData(0).IsFriendlyArea);           // Should be changed! (Compared to the original)
            Assert.IsTrue(!toTest.GetNodeData(0).IsClear);                  // Should be changed! (Compared to the original)
            Assert.IsTrue(!toTest.GetNodeData(0).IsControlledByTeam);       // Should be changed! (Compared to the original)
            Assert.IsTrue(!toTest.GetNodeData(1).IsControlledByTeam);
            Assert.IsTrue(!toTest.GetNodeData(1).IsClear);                  // Should be changed! (Compared to the original. Node zero friendlies were previously causing this)
            Assert.IsTrue(toTest.GetNodeData(1).VisibleToEnemies);
            Assert.IsTrue(toTest.GetNodeData(1).PotentialEnemies);          // Should be changed! (Compared to the original). 'Clear' effect caused by node zero friendlies was previously precluding this.
            Assert.IsTrue(toTest.GetNodeData(2).EnemyPresence == 3);
            Assert.IsTrue(toTest.GetNodeData(2).IsEnemyArea);
            Assert.IsTrue(!toTest.GetNodeData(2).IsContestedArea);
            Assert.IsTrue(!toTest.GetNodeData(2).IsClear);
            Assert.IsTrue(toTest.GetNodeData(2).IsControlledByEnemies);
            Assert.IsTrue(toTest.GetNodeData(2).VisibleToEnemies);
            Assert.IsTrue(toTest.GetNodeData(3).IsClear);                   // Node 4 friendlies should still be 'clearing' node 3, despite the absence of node zero friendlies
            Assert.IsTrue(!toTest.GetNodeData(3).IsControlledByTeam);       // Node 3 was previously being controlled by node zero friendlies! Node 4 friendlies do not 'control' this area, only observe it.
            Assert.IsTrue(!toTest.GetNodeData(3).IsControlledByEnemies);
            Assert.IsTrue(!toTest.GetNodeData(4).IsControlledByEnemies);
            Assert.IsTrue(toTest.GetNodeData(4).SquadMemberPresence == 1);
            Assert.IsTrue(toTest.GetNodeData(4).IsFriendlyArea);
            Assert.IsTrue(toTest.GetNodeData(5).TakingFireMagnitudeLevel == 5);
            Assert.IsTrue(toTest.GetNodeData(5).VisibleToEnemies);
            Assert.IsTrue(toTest.GetNodeData(5).PotentialEnemies);
            Assert.IsTrue(toTest.GetNodeData(5).IsClear == false);
            Assert.IsTrue(toTest.GetNodeData(6).PotentialEnemies);
            Assert.IsTrue(toTest.GetNodeData(6).IsEnemyArea == false);
            Assert.IsTrue(toTest.GetNodeData(6).IsControlledByTeam == false);
            Assert.IsTrue(!toTest.GetNodeData(7).IsControlledByTeam);
            Assert.IsTrue(toTest.GetNodeData(7).EnemyPresence == 0);
            Assert.IsTrue(toTest.GetNodeData(7).SquadMemberPresence == 0);
            Assert.IsTrue(toTest.GetNodeData(7).TakingFireMagnitudeLevel == 4);          // Testing the new Danger fact on node seven!

            Assert.IsTrue(!toTest.GetNodeData(0).VisibleToSquad);
            Assert.IsTrue(!toTest.GetNodeData(1).VisibleToSquad);
            Assert.IsTrue(toTest.GetNodeData(3).VisibleToSquad);
            Assert.IsTrue(toTest.GetNodeData(4).VisibleToSquad);
            Assert.IsTrue(!toTest.GetNodeData(2).VisibleToSquad);

            // Do the same tests but using the graph-subset reader functions
            Func <int, bool> visf = toTest.VisibleToSquadReader();

            Assert.IsTrue(!visf(0) && !visf(1) && visf(3) && visf(4) && !visf(5) && !visf(6) && !visf(7) && !visf(2));
            Func <int, int> friends = toTest.KnownSquadMemberPresenceReader();

            Assert.IsTrue(friends(0) == 0);                                 // Should be changed! (Compared to the original)
            Assert.IsTrue(friends(1) == 0);
            Assert.IsTrue(friends(2) == 0);
            Assert.IsTrue(friends(3) == 0);
            Assert.IsTrue(friends(4) == 1);
            Func <int, bool> clear = toTest.IsClearReader();

            Assert.IsTrue(!clear(0) && !clear(1) && !clear(2) && clear(3) && !clear(7));    // Node zero and one are no longer clear
            Func <int, bool> potentials = toTest.PotentialEnemiesReader();

            Assert.IsTrue(potentials(6) && potentials(1) && potentials(7) && !potentials(2) && potentials(5) && potentials(8));     // Node 1 should now have potential enemies
            Func <int, bool> vis = toTest.VisibleToEnemiesReader();

            Assert.IsTrue(vis(1) && vis(2) && !vis(3) && !vis(0) && !vis(7));
            Func <int, int> danger = toTest.TakingFireMagnitudeLevelReader();

            Assert.IsTrue(danger(7) == 4 && danger(5) == 5 && danger(2) == 0 && danger(3) == 0);

            // Test edges
            Func <int, int, bool> clearing = toTest.CausingClearEffectReader();

            Assert.IsTrue(!clearing(0, 1) && !clearing(0, 3) && !clearing(0, 2) && !clearing(2, 1) && clearing(4, 3));      // Node zero no longer clearing 1 or 3
            Func <int, int, bool> causingPotentials = toTest.CausingPotentialEnemiesEffectReader();

            Assert.IsTrue(causingPotentials(5, 1) && causingPotentials(5, 6) && !causingPotentials(2, 1));
            Func <int, int, bool> causingVisible = toTest.CausingVisibleToEnemiesEffectReader();

            Assert.IsTrue(causingVisible(2, 1) && !causingVisible(2, 7) && !causingVisible(1, 5));

            Assert.IsTrue(!toTest.GetEdge(0, 1).IsCausingClearEffect&& !toTest.GetEdge(0, 1).IsCausingControlledByTeamEffect);      // Node zero no longer clearing 1
            Assert.IsTrue(!toTest.GetEdge(0, 3).IsCausingClearEffect&& !toTest.GetEdge(0, 3).IsCausingControlledByTeamEffect);      // Node zero no longer clearing or controlling 3
            Assert.IsTrue(toTest.GetEdge(2, 1).IsCausingVisibleToEnemiesEffect&& toTest.GetEdge(2, 5).IsCausingVisibleToEnemiesEffect);
            Assert.IsTrue(toTest.GetEdge(5, 1).IsCausingPotentialEnemiesEffect&& toTest.GetEdge(8, 6).IsCausingPotentialEnemiesEffect&& toTest.GetEdge(8, 7).IsCausingPotentialEnemiesEffect);
        }