Esempio n. 1
0
    public void MissionGraphTestSimplePasses()
    {
        System.Console.WriteLine("Hello from unit test!");
        MissionGraph G = new MissionGraph();

        Assert.IsTrue(1 == 0);
    }
        public void TestMissionGraphsWithLargeSizesHaveConsistentVertices()
        {
            MissionGraph g1 = new MissionGraph(0, 10, 1000);

            g1.CompleteProduction();
            checkConsistency(g1);

            MissionGraph g2 = new MissionGraph(1, 15, 1000);

            g2.CompleteProduction();
            checkConsistency(g2);

            MissionGraph g3 = new MissionGraph(2, 20, 1000);

            g3.CompleteProduction();
            checkConsistency(g3);

            MissionGraph g4 = new MissionGraph(3, 25, 1000);

            g4.CompleteProduction();
            checkConsistency(g4);

            MissionGraph g5 = new MissionGraph(4, 30, 1000);

            g5.CompleteProduction();
            checkConsistency(g5);
        }
        public void TestMissionGraphWithAnyBudgetHasNoNonterminalsWhenProductionCompletes()
        {
            MissionGraph g1 = new MissionGraph(0, 10, 1000);

            g1.CompleteProduction();
            Assert.IsTrue(g1.NonterminalCount == 0);

            MissionGraph g2 = new MissionGraph(1, 10, 1000);

            g2.CompleteProduction();
            Assert.IsTrue(g2.NonterminalCount == 0);

            MissionGraph g3 = new MissionGraph(2, 10, 1000);

            g3.CompleteProduction();
            Assert.IsTrue(g3.NonterminalCount == 0);

            MissionGraph g4 = new MissionGraph(5, 10, 1000);

            g4.CompleteProduction();
            Assert.IsTrue(g4.NonterminalCount == 0);

            MissionGraph g5 = new MissionGraph(15, 50, 1000);

            g5.CompleteProduction();
            Assert.IsTrue(g5.NonterminalCount == 0);
        }
        public void TestMissionGraphMeetsSizeBudget()
        {
            MissionGraph g1 = new MissionGraph(0, 10, 1000);

            g1.CompleteProduction();
            int g1SizeSum = 0;

            foreach (Vertex v in g1)
            {
                g1SizeSum += v.Size;
            }
            Assert.AreEqual(10, g1SizeSum);

            MissionGraph g2 = new MissionGraph(1, 15, 1000);

            g2.CompleteProduction();
            int g2SizeSum = 0;

            foreach (Vertex v in g2)
            {
                g2SizeSum += v.Size;
            }
            Assert.AreEqual(15, g2SizeSum);

            MissionGraph g3 = new MissionGraph(2, 20, 1000);

            g3.CompleteProduction();
            int g3SizeSum = 0;

            foreach (Vertex v in g3)
            {
                g3SizeSum += v.Size;
            }
            Assert.AreEqual(20, g3SizeSum);


            MissionGraph g4 = new MissionGraph(1, 50, 1000);

            g4.CompleteProduction();
            int g4SizeSum = 0;

            foreach (Vertex v in g4)
            {
                g4SizeSum += v.Size;
            }
            Assert.AreEqual(50, g4SizeSum);

            MissionGraph g5 = new MissionGraph(10, 100, 1000);

            g5.CompleteProduction();
            int g5SizeSum = 0;

            foreach (Vertex v in g5)
            {
                g5SizeSum += v.Size;
            }
            Assert.AreEqual(100, g5SizeSum);
        }
        public void TestConstructedMissionGraphHasRootVertex()
        {
            MissionGraph g = new MissionGraph();

            System.Diagnostics.Trace.WriteLine("You can see output from statements like this in the test explorer --> this test --> output");
            Assert.IsNotNull(g);
            Assert.IsTrue(g.Count == 1);
            Assert.IsTrue(g.NonterminalCount == 1);
        }
 private void checkConsistency(MissionGraph g)
 {
     foreach (Vertex v in g)
     {
         foreach (Vertex forward in v.ForwardAdj)
         {
             Assert.IsTrue(forward.BackAdj.Contains(v));
         }
         foreach (Vertex backward in v.BackAdj)
         {
             Assert.IsTrue(backward.ForwardAdj.Contains(v));
         }
     }
 }
        public void TestMissionGraphWith0ObstaclesCreatesEntranceNodeExitInOneProduction()
        {
            MissionGraph g = new MissionGraph(0, 10, 1000);

            g.ApplyProduction();
            Assert.IsTrue(g.NonterminalCount == 1);
            Assert.IsTrue(g.TerminalCount == 2);
            bool entranceFound = false;
            bool exitFound     = false;
            bool nodeFound     = false;

            foreach (Vertex v in g)
            {
                // entrance points to node
                if (v.Name.Equals("entrance"))
                {
                    entranceFound = true;


                    // nothing points into entrance
                    Assert.IsTrue(v.BackAdj.Count == 0);
                    Assert.IsTrue(v.ForwardAdj.Count == 1);

                    IEnumerator <Vertex> enumer = v.ForwardAdj.GetEnumerator();
                    enumer.MoveNext();
                    Vertex second = enumer.Current;
                    // Second node is a node, and points back to entrance.
                    Assert.IsTrue(second.Name.Equals("node"));
                    Assert.IsTrue(second.BackAdj.Contains(v));
                }
                else if (v.Name.Equals("exit"))
                {
                    exitFound = true;

                    // exit points forward to nothing
                    Assert.IsTrue(v.ForwardAdj.Count == 0);
                    Assert.IsTrue(v.BackAdj.Count == 1);

                    IEnumerator <Vertex> enumer = v.BackAdj.GetEnumerator();
                    enumer.MoveNext();
                    Vertex second = enumer.Current;
                    // Second node is a node, and points back to entrance.
                    Assert.IsTrue(second.Name.Equals("node"));
                    Assert.IsTrue(second.ForwardAdj.Contains(v));
                }
                else if (v.Name.Equals("node"))
                {
                    nodeFound = true;

                    // middle node points forward to one thing, and backward
                    // to another thing.
                    Assert.IsTrue(v.ForwardAdj.Count == 1);
                    Assert.IsTrue(v.BackAdj.Count == 1);


                    // first node is an entrance, and points back to node.
                    IEnumerator <Vertex> enumer = v.BackAdj.GetEnumerator();
                    enumer.MoveNext();
                    Vertex first = enumer.Current;

                    Assert.IsTrue(first.Name.Equals("entrance"));
                    Assert.IsTrue(first.ForwardAdj.Contains(v));

                    // Second node is a node, and points back to entrance.
                    IEnumerator <Vertex> enumer1 = v.ForwardAdj.GetEnumerator();
                    enumer1.MoveNext();
                    Vertex last = enumer1.Current;

                    Assert.IsTrue(last.Name.Equals("exit"));
                    Assert.IsTrue(last.BackAdj.Contains(v));
                }
                // There should only be these types of nodes in this particular missiongraph...
                else
                {
                    Assert.IsTrue(false);
                }
            }
            Assert.IsTrue(nodeFound && exitFound && entranceFound);
        }
        public void TestMissionGraphWith1ObstacleCreatesOneKeyLockPuzzle()
        {
            MissionGraph g = new MissionGraph(1, 10, 1000);

            g.CompleteProduction();
            //Modelled after the tests above.

            Assert.IsTrue(g.NonterminalCount == 0);
            Assert.IsTrue(g.TerminalCount == 6);
            bool entranceFound = false;
            bool exitFound     = false;
            int  spaceCount    = 0;
            bool keyFound      = false;
            bool doorFound     = false;

            foreach (Vertex v in g)
            {
                Assert.IsTrue(v.IsTerminal);
                Assert.AreNotEqual(v.Name, "node");
                // entrance points to node
                if (v.Name.Equals("entrance"))
                {
                    entranceFound = true;


                    // nothing points into entrance
                    Assert.IsTrue(v.BackAdj.Count == 0);
                    Assert.IsTrue(v.ForwardAdj.Count == 1);

                    IEnumerator <Vertex> enumer = v.ForwardAdj.GetEnumerator();
                    enumer.MoveNext();
                    Vertex second = enumer.Current;
                    // Second node is a node, and points back to entrance.
                    Assert.IsTrue(second.Name.Equals("space"));
                    Assert.IsTrue(second.BackAdj.Contains(v));
                }
                else if (v.Name.Equals("exit"))
                {
                    exitFound = true;

                    // exit points forward to nothing
                    Assert.IsTrue(v.ForwardAdj.Count == 0);
                    Assert.IsTrue(v.BackAdj.Count == 1);

                    IEnumerator <Vertex> enumer = v.BackAdj.GetEnumerator();
                    enumer.MoveNext();

                    Vertex second = enumer.Current;
                    // Second node is a node, and points back to entrance.
                    System.Diagnostics.Trace.WriteLine(second.Name);
                    Assert.IsTrue(second.Name.Equals("door"));
                    Assert.IsTrue(second.ForwardAdj.Contains(v));
                }
                else if (v.Name.Equals("space"))
                {
                    spaceCount += 1;
                    // Don't know which space this is,
                    // so we'll just check the structure for consistency.
                    // The assertions made by the other types of vertices
                    // ensure that this graph has the correct structure for
                    // this obstacle budget.

                    foreach (Vertex forward in v.ForwardAdj)
                    {
                        Assert.IsTrue(forward.BackAdj.Contains(v));
                    }
                    foreach (Vertex backward in v.BackAdj)
                    {
                        Assert.IsTrue(backward.ForwardAdj.Contains(v));
                    }
                }
                else if (v.Name.Equals("key"))
                {
                    keyFound = true;
                    // The key in the 1 obstacle missiongraph has no edges out of it, only into it from a space.
                    Assert.AreEqual(v.ForwardAdj.Count, 0);
                    Assert.AreEqual(v.BackAdj.Count, 1);

                    IEnumerator <Vertex> enumer = v.BackAdj.GetEnumerator();
                    enumer.MoveNext();
                    Vertex back = enumer.Current;
                    Assert.IsTrue(back.Name.Equals("space"));
                    Assert.IsTrue(back.ForwardAdj.Contains(v));
                }
                // the door in the 1 obstacle missiongraph has an edge into it from a space and an edge out of it
                // into the exit
                else if (v.Name.Equals("door"))
                {
                    doorFound = true;
                    // The key in the 1 obstacle missiongraph has no edges out of it, only into it from a space.
                    Assert.AreEqual(v.ForwardAdj.Count, 1);
                    Assert.AreEqual(v.BackAdj.Count, 1);

                    IEnumerator <Vertex> enumer = v.BackAdj.GetEnumerator();
                    enumer.MoveNext();
                    Vertex back = enumer.Current;
                    Assert.IsTrue(back.Name.Equals("space"));
                    Assert.IsTrue(back.ForwardAdj.Contains(v));

                    IEnumerator <Vertex> forwardEnum = v.ForwardAdj.GetEnumerator();
                    forwardEnum.MoveNext();
                    Vertex forward = forwardEnum.Current;
                    Assert.IsTrue(forward.Name.Equals("exit"));
                    Assert.IsTrue(forward.BackAdj.Contains(v));
                }
                // There should only be these types of nodes in this particular missiongraph...
                else
                {
                    Assert.IsTrue(false);
                }
            }
            Assert.AreEqual(spaceCount, 2);
            Assert.IsTrue(entranceFound);
            Assert.IsTrue(exitFound);
            Assert.IsTrue(keyFound);
            Assert.IsTrue(doorFound);
        }
        public void TestMissionGraphWith0ObstaclesCreatesSimpleMaze()
        {
            MissionGraph g = new MissionGraph(0, 10, 1000);

            g.CompleteProduction();
            // modelled after the above test - we'll assert some things we know
            // about what a missiongraph with these parameters should yield.

            // it should have a three long maze - an entrance, a space, and an exit.
            // the only difference between the above with a single reduction performed
            // and this with as many reductions as possible performed should be
            // the change from the center node above to a space. Because the
            // obstacle budget of this missiongraph is 0 it should generate no key/door puzzles.

            Assert.IsTrue(g.NonterminalCount == 0);
            Assert.IsTrue(g.TerminalCount == 3);
            bool entranceFound = false;
            bool exitFound     = false;
            bool spaceFound    = false;

            foreach (Vertex v in g)
            {
                Assert.IsTrue(v.IsTerminal);
                // entrance points to node
                if (v.Name.Equals("entrance"))
                {
                    entranceFound = true;
                    // nothing points into entrance
                    Assert.IsTrue(v.BackAdj.Count == 0);
                    Assert.IsTrue(v.ForwardAdj.Count == 1);

                    IEnumerator <Vertex> enumer = v.ForwardAdj.GetEnumerator();
                    enumer.MoveNext();
                    Vertex second = enumer.Current;
                    // Second node is a node, and points back to entrance.
                    Assert.IsTrue(second.Name.Equals("space"));
                    Assert.IsTrue(second.BackAdj.Contains(v));
                }
                else if (v.Name.Equals("exit"))
                {
                    exitFound = true;

                    // exit points forward to nothing
                    Assert.IsTrue(v.ForwardAdj.Count == 0);
                    Assert.IsTrue(v.BackAdj.Count == 1);

                    IEnumerator <Vertex> enumer = v.BackAdj.GetEnumerator();
                    enumer.MoveNext();
                    Vertex second = enumer.Current;
                    // Second node is a node, and points back to entrance.
                    Assert.IsTrue(second.Name.Equals("space"));
                    Assert.IsTrue(second.ForwardAdj.Contains(v));
                }
                else if (v.Name.Equals("space"))
                {
                    spaceFound = true;

                    // middle node points forward to one thing, and backward
                    // to another thing.
                    Assert.IsTrue(v.ForwardAdj.Count == 1);
                    Assert.IsTrue(v.BackAdj.Count == 1);


                    // first node is an entrance, and points back to node.
                    IEnumerator <Vertex> enumer = v.BackAdj.GetEnumerator();
                    enumer.MoveNext();
                    Vertex first = enumer.Current;

                    Assert.IsTrue(first.Name.Equals("entrance"));
                    Assert.IsTrue(first.ForwardAdj.Contains(v));

                    // Second node is a node, and points back to entrance.
                    IEnumerator <Vertex> enumer1 = v.ForwardAdj.GetEnumerator();
                    enumer1.MoveNext();

                    Vertex last = enumer1.Current;
                    Assert.IsTrue(last.Name.Equals("exit"));
                    Assert.IsTrue(last.BackAdj.Contains(v));
                }
                // There should only be these types of nodes in this particular missiongraph...
                else
                {
                    Assert.IsTrue(false);
                }
            }
            Assert.IsTrue(spaceFound && exitFound && entranceFound);
        }
Esempio n. 10
0
    // Use this for initialization
    void Start()
    {
        if (SpaceBudget <= 2)
        {
            throw new System.ArgumentException("Space Budget must be at least 3.");
        }
        if (ObstacleBudget < 0)
        {
            throw new System.ArgumentException("ObstacleBudget must be positive.");
        }
        g = new MissionGraph(ObstacleBudget, SpaceBudget);
        g.CompleteProduction();

        // So, for now, due to lack of time, I'm going to make some assumptions
        // specific to this grammar to create the space. This makes it easier to write
        // this bit of code but makes it harder in the future to change the missiongraph grammar
        // But I can remove this stuff if I chose to change the grammar in the future
        // and make more scalable code here.
        // So this is fine for now.

        // Here, in assertion form, are the assumptions I make about a graph
        // produced by the current grammar
        foreach (Vertex v in g)
        {
            // Spaces can only have four vertices conneted to them
            if (v.Name.Equals("space"))
            {
                Debug.Assert(v.BackAdj.Count + v.ForwardAdj.Count <= 4);
            }

            // Nothing leads into an entrance, and an entrance leads into one vertex
            else if (v.Name.Equals("entrance"))
            {
                Debug.Assert(v.ForwardAdj.Count == 1 && v.BackAdj.Count == 0);
            }
            // Only one vertex leads into an exit, and an exit leads into nothing
            else if (v.Name.Equals("exit"))
            {
                Debug.Assert(v.ForwardAdj.Count == 0 && v.BackAdj.Count == 1);
            }
            // Only one vertex leads into a key room and a key room leads nowhere
            else if (v.Name.Equals("key"))
            {
                Debug.Assert(v.ForwardAdj.Count == 0 && v.BackAdj.Count == 1);
            }
            // Exactly one vertex enters a door and exactly one vertex leads out of a door.
            else if (v.Name.Equals("door"))
            {
                Debug.Assert(v.ForwardAdj.Count == 1 && v.BackAdj.Count == 1);
            }
        }
        // I actually don't mind this that much even though it looks janky as f**k.
        // One of the ways we discussed to deal with bad results of generation is
        // constraint checking - generate some stuff and make sure it follows the rules.
        // While this constraint checking could be prevented with a more sophisticated
        // space assigning algorithm, I'm worried such an algorithm might become slower
        // than using an unsophisticated algorithm willing to say "oh no, I've made a horrible mistake,
        // let's try again."

        // If I wanted to go down that route because maybe at some point in the future when I'm trying to generate very large
        // levels because I have more kinds of things to fill the space with, the first place I'd try is to
        // teach the algorithm to select directions in a better way than random selection. That's ultimately what causes
        // the problems, and doing something like, for example, trying to find the deepest branch of a tree and allocate it
        // a direction to grow in, might solve many issues here.


        // But for now this works okay.

        // It seems like the reasonable maximum number of obstacles for the current (as of 8/8) grammar is 13.

        // But nobody wants a maze that big anyway I think the realistic maximum is like 6.
        int attempts = 1;

        while (attempts < AttemptsBeforeTimeout)
        {
            try
            {
                AssignVerticesSpace();
                break;
            }
            catch (System.Exception)
            {
                attempts++;
                int seed = Random.Range(int.MinValue, int.MaxValue);
                Random.InitState(seed);
            }
        }
        if (attempts == AttemptsBeforeTimeout)
        {
            throw new System.Exception("Error! World not successfully generated after " + attempts + " attempts, exiting.");
        }
        //Debug.Log("Success after " + attempts + " attempts to generate");

        foreach (Vertex v in g)
        {
            MissionTerminal t = Instantiate(terminalType(v.Name), new Vector3(0, 0, 0), Quaternion.identity);

            t.Build(v);
        }
        ResetPlayerPosition();
    }