Exemplo n.º 1
0
        public void MSTest_shortestpath()
        {
            Node node1 = new Node("1_1");
            Node node2 = new Node("1_2");
            Node node3 = new Node("1_3");
            Node node4 = new Node("1_4");
            Node node5 = new Node("1_5");

            node2.connect(node1);
            node2.connect(node3);
            node4.connect(node1);
            node4.connect(node5);
            node5.connect(node3);
            Dungeon d = new Dungeon();

            d.zone    = new Dictionary <int, List <Node> >();
            d.zone[1] = new List <Node>();
            d.zone[1].Add(node1);
            d.zone[1].Add(node2);
            d.zone[1].Add(node3);
            d.zone[1].Add(node4);
            d.zone[1].Add(node5);

            List <Node> sp         = d.shortestpath(node1, node3);
            List <Node> expectedSp = new List <Node>();

            expectedSp.Add(node2);
            expectedSp.Add(node3);
            Assert.IsTrue(sp.Count == 2);
            Assert.IsTrue(sp[0] == expectedSp[0]);
            Assert.IsTrue(sp[1] == expectedSp[1]);
        }
Exemplo n.º 2
0
        public void NTest_check_fullyConnected_notConnected()
        {
            Node n1 = new Node("" + 0, 1);
            Node n2 = new Node("" + 1, 1);
            Node n3 = new Node("" + 2, 1);
            Node n4 = new Node("" + 3, 1);
            Node n5 = new Node("" + 4, 1);

            n1.connect(n2);
            n1.connect(n3);
            n1.connect(n4);
            n1.connect(n5);
            Assert.IsTrue(n1.isFullyConnected());
        }
Exemplo n.º 3
0
        public void randomConnection(Node thisNode, Node[] toNodes)
        {
            int l = toNodes.Length;

            if (l == 0)
            {
                return;                 // no nodes to connect to (this is a valid situation)
            }
            if (thisNode.neighbors.Count >= maxConnectivity)
            {
                return;                // thisNode is not allowed to have more neigbours
            }
            int index = 0;

            index = r.Next(l - 1);
            if (toNodes[index] == thisNode)
            {
                return;
            }
            if (toNodes[index].neighbors.Count >= maxConnectivity)
            {
                return;
            }
            if (!thisNode.neighbors.Contains(toNodes[index]))
            {
                thisNode.connect(toNodes[index]);
            }
        }
Exemplo n.º 4
0
        public void MSTest_combat_pack_not_flees_does_attack_dies()
        {
            Game game = new Game();

            game.dungeon = new Dungeon();
            Utils.RandomGenerator.initializeWithSeed(0);
            Random r = Utils.RandomGenerator.rnd;

            game.player = new Player();
            Pack pack = new Pack("pack", 1);

            pack.members[0].HP = 7;
            pack.startingHP    = 7;
            Node fightNode   = new Node(0);
            Node retreatNode = new Node(0);

            game.player.location = fightNode;
            game.player.dungeon  = game.dungeon;
            game.dungeon.zone.Add(1, new List <Node>());
            pack.location = game.player.location;
            game.dungeon.zone[1].Add(fightNode);
            game.dungeon.zone[1].Add(retreatNode);
            game.player.zone = 1;
            fightNode.packs.Add(pack);
            fightNode.connect(retreatNode);
            while (fightNode.contested(game.player))
            {
                game.update(new AttackCommand(pack.members[0].id));
            }
            Assert.IsTrue(!fightNode.contested(game.player));
            Assert.IsTrue(fightNode.packs.Count == 0);
            Assert.IsTrue(game.player.KillPoint == 1);
        }
Exemplo n.º 5
0
        /* To disconnect a bridge from the rest of the zone the bridge is in. */
        public void disconnect(Bridge b)
        {
            Logger.log("Disconnecting the bridge " + b.id + " from its zone.");

            Node newStart = new Node(b.id);

            newStart.neighbors = b.neighbors;
            newStart.nodeLevel = b.nodeLevel;

            Node[] allNodes = new Node[b.neighbors.Count];

            b.neighbors.CopyTo(allNodes);

            foreach (Node n in allNodes.ToList())
            {
                if (b.toNodes.Contains(n))
                {
                    newStart.connect(n);
                }

                n.disconnect(b);
            }

            startNode = newStart;
        }
Exemplo n.º 6
0
        public void NTest_shortestpath()
        {
            List <Node> nodes = new List <Node>();
            Node        n1, n2;
            Node        startNode = new Node("" + 0, 1);

            nodes.Add(startNode);
            for (int i = 1; i <= 10; i++)
            {
                Node newNode = new Node("" + (i), 1);
                nodes.Add(newNode);
            }
            for (int i = 1; i <= 3; i++)
            {
                startNode.connect(nodes.ElementAt(i));
            }
            for (int i = 3; i < 9; i++)
            {
                n1 = nodes.ElementAt(i + 1);
                n2 = nodes.ElementAt(i + 2);
                nodes.ElementAt(i).connect(n1);
                nodes.ElementAt(i).connect(n2);
            }
            List <Node> listToCheck = new List <Node>();
            List <Node> pathToCheck = new List <Node>();

            pathToCheck.Add(nodes.ElementAt(3));
            listToCheck.Add(nodes.ElementAt(3));
            for (int i = 4; i <= 10; i++)
            {
                listToCheck.Add(nodes.ElementAt(i));
                i++;
            }
            Assert.AreSame(listToCheck, dungeon.shortestpath(nodes.ElementAt(3), nodes.ElementAt(10)));
        }
Exemplo n.º 7
0
        public void NTest_check_allReachable()
        {
            List <Node> nodes = new List <Node>();
            Node        n1, n2;
            Node        startNode = new Node("" + 10, 1);

            nodes.Add(startNode);
            for (int i = 1; i <= 10; i++)
            {
                Node newNode = new Node("" + (10 + i), 1);
                nodes.Add(newNode);
            }
            for (int i = 1; i <= 3; i++)
            {
                startNode.connect(nodes.ElementAt(i));
            }
            for (int i = 3; i < 9; i++)
            {
                n1 = nodes.ElementAt(i + 1);
                n2 = nodes.ElementAt(i + 2);
                nodes.ElementAt(i).connect(n1);
                nodes.ElementAt(i).connect(n2);
            }
            Assert.IsTrue(dungeon.allReachable(nodes, startNode));
        }
Exemplo n.º 8
0
        public void DungeonIsValidTest_2()
        {
            Dungeon a = new Dungeon(1, 1);

            a.dungeon_size = a.graph.Count;
            a.graph.Clear();

            Node u = new Node();

            a.graph.Add(u);
            Assert.AreEqual(false, a.dungeon_is_ok());

            Node v = new Node();
            Node w = new Node();
            Node x = new Node();

            u.id = ("" + 0);
            v.id = ("" + 1);
            w.id = ("" + 2);
            x.id = ("" + 3);

            a.graph.Add(v);
            a.graph.Add(w);
            a.graph.Add(x);

            u.connect(v);
            v.connect(w);
            w.connect(x);
            a.startNode    = u;
            a.exitNode     = x;
            a.dungeon_size = a.graph.Count;
            Assert.AreEqual(false, a.dungeon_is_ok());
        }
Exemplo n.º 9
0
        public Node[] genSubPath(int n, Node entryNode, Node endNode, int idMod, int lvl)
        {
            Node[] path = new Node[n];
            path[0] = new Node(lvl + "_" + idMod);
            for (int i = 1; i < n; i++)
            {
                path[i] = new Node(lvl + "_" + (2 * (i) + idMod));
                path[i].connect(path[i - 1]);
            }

            if (entryNode.GetType() == typeof(Bridge))
            {
                connectBridge((entryNode as Bridge), path[0], false);
            }
            else
            {
                entryNode.connect(path[0]);
            }

            if (endNode.GetType() == typeof(Bridge))
            {
                connectBridge((endNode as Bridge), path[n - 1], true);
            }
            else
            {
                endNode.connect(path[n - 1]);
            }
            return(path);
        }
Exemplo n.º 10
0
        public void MSTest_connect_nodes()
        {
            Node baseNode = new Node("baseNode");
            Node nbNode   = new Node("nbNode");

            baseNode.connect(nbNode);
            Assert.IsTrue(baseNode.neighbors.Contains(nbNode));
            Assert.IsTrue(nbNode.neighbors.Contains(baseNode));
        }
Exemplo n.º 11
0
        // To create a consistent dummy dungeon to test Pack movement on
        public Dungeon(uint M)
        {
            this.M = M;
            Node N0 = new Node("1_0");
            Node N1 = new Node("1_1");
            Node N2 = new Node("1_2");
            Node N3 = new Node("1_3");

            N0.connect(N1);
            N0.connect(N2);
            N1.connect(N2);
            List <Node> nodes = new List <Node>();

            nodes.Add(N0);
            nodes.Add(N1);
            nodes.Add(N2);
            nodes.Add(N3);
            zone = new Dictionary <int, List <Node> >();
            zone.Add(1, nodes);
        }
Exemplo n.º 12
0
        public void MSTest_RandomConnection_connect_multiple_node_graph()
        {
            Node node1 = new Node();
            Node node2 = new Node();
            Node node3 = new Node();

            node2.connect(node1);
            node2.connect(node3);
            Node[] graph = new Node[3];
            graph[0] = node1;
            graph[1] = node2;
            graph[2] = node3;
            Node    testnode = new Node("test");
            Dungeon d        = new Dungeon();

            d.randomConnection(testnode, graph);
            Assert.IsTrue(testnode.neighbors.Count == 1);
            Node result = testnode.neighbors[0];

            Assert.IsTrue(result.neighbors.Contains(testnode));
        }
Exemplo n.º 13
0
        public void Crystal_Use_OnNode()
        {
            Node N0 = new Node("N0");
            Node N1 = new Node("N1");
            Node N2 = new Node("N2");
            Node N3 = new Node("N3");

            N1.connect(N0);
            N1.connect(N2);
            N1.connect(N3);
            N3.connect(N2);
            Predicates  utils       = new Predicates();
            List <Node> mockDungeon = utils.reachableNodes(N1);

            player.dungeon  = new Dungeon(1, 1);
            player.location = N1;
            Crystal crystal = new Crystal("crystal1");

            player.bag.Add(crystal);
            player.use(crystal);

            Assert.IsTrue(crystal.used);
            Assert.IsFalse(player.bag.Contains(crystal));
            Assert.IsTrue(player.accelerated);
            Assert.IsTrue(mockDungeon.Contains(N0));

            Assert.IsNull(player.name);
            Assert.AreEqual(0, player.HP);
            Assert.AreEqual(5u, player.AttackRating);
            Assert.AreEqual(100, player.HPbase);
            Assert.AreEqual(0u, player.KillPoint);

            foreach (Node node in mockDungeon)
            {
                Console.WriteLine(node.id);
            }
        }
Exemplo n.º 14
0
        public void MSTest_pack_moveTowards()
        {
            Pack    pack    = new Pack("Highlander", 1);
            Dungeon dungeon = new Dungeon(2, 2);
            Node    node    = new Node("node1");
            Node    node2   = new Node("node2");
            Node    node3   = new Node("node3");
            Node    node4   = new Node("node4");
            Node    node5   = new Node("node5");
            Node    node6   = new Node("node6");

            node.connect(node2);
            node2.connect(node3);
            node3.connect(node4);
            node.connect(node5);
            node5.connect(node2);
            node6.connect(node);
            pack.location = node;
            pack.dungeon  = dungeon;
            node.packs.Add(pack);

            pack.moveTowards(node4);
            Assert.AreEqual(pack.location, node2);
        }
Exemplo n.º 15
0
        public void MSTest_RandomConnection_thisnode_max_neighbors()
        {
            Node maxConnectionNode = new Node("maxConnectionNode");

            Node[] graph     = new Node[5];
            Node   graphnode = new Node();

            graph[4] = graphnode;
            for (int i = 0; i < 4; i++)
            {
                Node neighbor = new Node("neighbor " + i);
                maxConnectionNode.connect(neighbor);
            }
            Dungeon d = new Dungeon();

            d.randomConnection(maxConnectionNode, graph);
            Assert.IsTrue(maxConnectionNode.neighbors.Count == 4);
        }
Exemplo n.º 16
0
        public void MSTest_MoveCommand()
        {
            Node n1   = new Node("n1");
            Node n2   = new Node("n2");
            Item item = new Item("test");

            n2.items.Add(item);
            n1.connect(n2);
            Command moveCom = new MoveCommand(0);
            //Assert.IsTrue(moveCom.ToString() == "move to " + n2.id);
            Player player = new Player();

            player.location = n1;
            moveCom.ExecuteCommand(player);
            Assert.IsTrue(player.location == n2);
            Assert.IsTrue(player.bag.Contains(item));
            Assert.IsFalse(n2.items.Contains(item));
        }
Exemplo n.º 17
0
        public void MSTest_fight_flee()
        {
            Node   node   = new Node();
            Node   node2  = new Node();
            Player player = new Player();
            Pack   pack   = new Pack("packo", 4);

            node.connect(node2);

            player.location = node;
            node.packs.Add(pack);
            pack.location = node;

            player.AddNextCommand(0);
            //node.fight(player);
            Assert.AreNotEqual(player.location, node);
            Assert.AreEqual(player.location, node2);
        }
Exemplo n.º 18
0
        public void ShortestPathTest()
        {
            Dungeon a = new Dungeon(1, 1);

            a.graph.Clear();
            //Build a dungeon
            Node u = new Node();
            Node v = new Node();
            Node w = new Node();
            Node x = new Node();

            u.id = ("" + 0);
            v.id = ("" + 1);
            w.id = ("" + 2);
            x.id = ("" + 3);

            // 0 --> 1 --> 2
            u.connect(v);
            v.connect(w);

            a.graph.Add(u);
            a.graph.Add(v);
            a.graph.Add(w);
            a.graph.Add(x);

            a.dungeon_size = a.graph.Count;
            // u --> v = 2 (Min path size)
            List <Node> result = Predicates.shortestpath(u, v, a.dungeon_size);

            Assert.AreEqual(Predicates.find_all_paths_extract_shortest(u, v, a.dungeon_size), result.Count);
            // u --> w = 3 (path size)
            result = Predicates.shortestpath(u, w, a.dungeon_size);
            Assert.AreEqual(Predicates.find_all_paths_extract_shortest(u, w, a.dungeon_size), result.Count);
            // u --> x = 0 (not possible)
            result = Predicates.shortestpath(u, x, a.dungeon_size);
            Assert.AreEqual(Predicates.find_all_paths_extract_shortest(u, x, a.dungeon_size), result.Count);
        }
Exemplo n.º 19
0
        public void DungeonIsValidTest_1()
        {
            Dungeon a = new Dungeon(10, 1);

            a.graph.Clear();

            Node u = new Node();
            Node v = new Node();
            Node w = new Node();
            Node x = new Node();
            Node y = new Node();
            Node z = new Node();

            u.id = ("" + 0);
            v.id = ("" + 1);
            w.id = ("" + 2);
            x.id = ("" + 3);
            y.id = ("" + 4);
            z.id = ("" + 5);

            // 0 --> 1 --> 2
            u.connect(v);
            v.connect(w);

            a.graph.Add(u);
            a.graph.Add(v);
            a.graph.Add(w);
            a.graph.Add(x);
            a.graph.Add(y);
            a.graph.Add(z);

            a.dungeon_size = a.graph.Count;
            bool result = a.dungeon_is_ok();

            Assert.AreEqual(true, result);

            a.graph.Add(y);
            u.connect(w);
            u.connect(x);
            u.connect(y);
            u.connect(z);

            a.dungeon_size = a.graph.Count;
            result         = a.dungeon_is_ok();
            Assert.AreEqual(false, result);

            //clean
            a.graph.Clear();
            u.neighbors.Clear();
            v.neighbors.Clear();
            w.neighbors.Clear();
            x.neighbors.Clear();
            y.neighbors.Clear();
            z.neighbors.Clear();

            u.connect(v);
            u.connect(w);
            u.connect(x);
            u.connect(y);

            v.connect(u);
            v.connect(w);
            v.connect(x);
            v.connect(y);

            w.connect(u);
            w.connect(v);
            w.connect(x);
            w.connect(y);

            x.connect(u);
            x.connect(w);
            x.connect(v);
            x.connect(y);

            y.connect(u);
            y.connect(w);
            y.connect(x);
            y.connect(v);

            a.graph.Add(u);
            a.graph.Add(v);
            a.graph.Add(w);
            a.graph.Add(x);
            a.graph.Add(y);

            a.dungeon_size = a.graph.Count;
            result         = a.dungeon_is_ok();
            Assert.AreEqual(false, result);
        }
Exemplo n.º 20
0
        public void CreateLevel(Node startNode, Node endNode)
        {
            // The number of nodes in this level.
            // There is no specification on the minimum or maximum nodes per level, so a number between 1 and 3 included seems adequate.
            // Note: that there is a minimum implied number of nodes per level of 1. This is because a dungeon must be at least
            // 3 nodes long (including the exit and entry node).
            int numberOfFirstPathNodes  = RandomGenerator.rnd.Next(1, 4);
            int numberOfSecondPathNodes = RandomGenerator.rnd.Next(1, 4);

            // To ensue that there are no bridges within a level, 2 separate paths are created from entry to exit node.
            // Note: that these paths are not necessarily of the same length.
            List <Node> firstPath  = new List <Node>(numberOfFirstPathNodes);
            List <Node> secondPath = new List <Node>(numberOfSecondPathNodes);

            // Populate the lists with nodes.
            for (int i = 0; i < Math.Max(numberOfFirstPathNodes, numberOfSecondPathNodes); i++)
            {
                // Create first path.
                if (i < numberOfFirstPathNodes)
                {
                    Node newNode = new Node("n" + nodeNumber++);
                    allNodes.Add(newNode);

                    newNode.hint      = Node.DrawingHint.Top;
                    newNode.drawIndex = i;
                    // Check if a previous node exists.
                    if (i > 0)
                    {
                        // Connect the new node to the previous node to ensure a valid path.
                        newNode.connect(firstPath[i - 1]);
                    }
                    firstPath.Add(newNode);
                }

                // Create second path.
                if (i < numberOfSecondPathNodes)
                {
                    Node newNode = new Node("n" + nodeNumber++);
                    allNodes.Add(newNode);
                    newNode.hint      = Node.DrawingHint.Bottom;
                    newNode.drawIndex = i;
                    // Check if a previous node exists.
                    if (i > 0)
                    {
                        // Connect the new node to the previous node to ensure a valid path.
                        newNode.connect(secondPath[i - 1]);
                    }
                    secondPath.Add(newNode);
                }
            }

            // Connect the start node of the level to first generated node for each path.
            // If the starting node is a bride then all newly generated nodes are next zone nodes.
            if (startNode is Bridge)
            {
                ((Bridge)(startNode)).connectToNodeOfNextZone(firstPath.First());
                ((Bridge)(startNode)).connectToNodeOfNextZone(secondPath.First());
            }
            // If it's not a bridge we can just connect to it.
            else
            {
                startNode.connect(firstPath.First());
                startNode.connect(secondPath.First());
            }

            // Connect the end node of the level to last generated node for each path.
            // If the end node is a bride then all newly generated nodes are same zone nodes.
            if (endNode is Bridge)
            {
                ((Bridge)(endNode)).connectToNodeOfSameZone(firstPath.Last());
                ((Bridge)(endNode)).connectToNodeOfSameZone(secondPath.Last());
            }
            // If it's not a bridge we can just connect to it.
            else
            {
                endNode.connect(firstPath.Last());
                endNode.connect(secondPath.Last());
            }


            // Total list of nodes, containing the two paths.
            List <Node> nodes = new List <Node>();

            nodes.AddRange(firstPath);
            nodes.AddRange(secondPath);

            // Calculate the total number of neighbors.
            // This is the total amount of neighbors already made.
            int totalNumberOfNeighbors = startNode.neighbors.Count + endNode.neighbors.Count;

            nodes.ForEach(node => totalNumberOfNeighbors += node.neighbors.Count);
            // Calculate the total allowed number of neighbors.
            // The total allowed number of neighbors is the number of nodes + 2 (because the exit and entry node) times 3 (the avg allowed number of neighbors).
            int allowedNumberOfNeigbors = 3 * (nodes.Count + 2);

            // The number of extra connections between nodes.
            // This is the allowed number of neighbors minus the number of neighbor we already have.
            // The amount is then divided by 2 because a connection adds 2 neighbors.
            // Note: that there is a implicit floor() here because we cannot add a fractional amount of connections.
            int numberOfExtraConnections = (allowedNumberOfNeigbors - totalNumberOfNeighbors) / 2;

            // Create extra set of connections.
            for (int i = 0; i < numberOfExtraConnections; i++)
            {
                // Pick 2 nodes at random.
                Node firstNode  = nodes[RandomGenerator.rnd.Next(nodes.Count)];
                Node secondNode = nodes[RandomGenerator.rnd.Next(nodes.Count)];

                // The following conditions must be met to create connection:
                if (firstNode != secondNode &&                   // Not the same nodes, because we cannot add ourself as neighbor.
                    firstNode.neighbors.Count < 4 &&             // Node must not already have 4 neighbors.
                    secondNode.neighbors.Count < 4 &&            // Other node must not already have 4 neighbors.
                    !firstNode.neighbors.Contains(secondNode) && // We may not already be neighbors with other node.
                    !secondNode.neighbors.Contains(firstNode)    // Other node may not be already neighbors with us (this is implied, but just for completeness).
                    )
                {
                    firstNode.connect(secondNode);
                }
            }

            // Create 0 to 3 death end paths to add some complexity.
            int numberOfExtraNodes = RandomGenerator.rnd.Next(4);

            for (int i = 0; i < numberOfExtraNodes; i++)
            {
                // Pick a nodes at random.
                Node node = nodes[RandomGenerator.rnd.Next(nodes.Count)];
                // Node must not already have 4 neighbors.
                // Note: that adding a death end path only creates a single extra connection and thus never exceeds the avg note connection of 3.
                if (node.neighbors.Count < 4)
                {
                    Node newNode = new Node("n" + nodeNumber++);
                    allNodes.Add(newNode);
                    newNode.hint = Node.DrawingHint.Dangling;
                    node.connect(newNode);
                }
            }
        }
Exemplo n.º 21
0
        /* Generates Random graph for dungeon class, uses const max_size, magicshuffle_number and regular dungeon options. */
        public void genGraph()
        {
            int cnt = 0;

            //Generate all zones:
            for (int i = 0; i < (difficultyLevel + 1); i++)
            {
                int  rSize    = RandomGenerator.rnd.Next(2, max_size); //random size for current zone
                Node tmpStart = new Node();                            //startpoint of current zone (exitpoint of last zone)
                Node tmpExit  = new Node();                            //exitpoint of current zone, bridge or exitnode.
                if (i == 0)                                            //first zone.
                {
                    startNode         = new Node("0");
                    startNode.visited = true;
                    graph.Add(startNode);
                    tmpStart = startNode;
                    Bridge b = new Bridge("" + (rSize - 1));
                    graph.Add(b);
                    bridges[i] = b;
                    tmpExit    = b;
                }
                else if (i < difficultyLevel)                       //not first not last zone.
                {
                    tmpStart = bridges[i - 1];
                    Bridge b = new Bridge("" + (rSize + cnt - 1));
                    graph.Add(b);
                    tmpExit    = b;
                    bridges[i] = b;
                }
                else if (i == difficultyLevel)                      //last zone.
                {
                    tmpStart = bridges[i - 1];
                    exitNode = new Node("" + (rSize + cnt - 1));
                    graph.Add(exitNode);
                    tmpExit = exitNode;
                }
                Node[] nodeArray = new Node[rSize];
                nodeArray[0]         = tmpStart;
                nodeArray[rSize - 1] = tmpExit;
                for (int j = 1; j < (rSize - 1); j++)   //we now know how big and what the tmp start/exit is.
                {
                    Node n = new Node("" + (cnt + j));  //build nodes
                    graph.Add(n);
                    nodeArray[j] = n;
                }
                bool once    = false;
                int  shuffle = 0;

                //TODO remove node array only use shuffle array.
                Node[] shuffleArray = new Node[rSize - 2];              //nodes we want to shuffle
                Array.Copy(nodeArray, 1, shuffleArray, 0, rSize - 2);

                //Build zone until correct
                while ((Predicates.countNumberOfBridges(tmpStart, tmpExit) != 0) || !once)
                {                                                                     //connect and shuffle the nodes random:
                    shuffle_connect(shuffleArray, (rSize - 2), magic_shuffle_number); //MSN should be 1. but incase somebody want to change it..
                    tmpExit.neighbors.Clear();

                    if (i > 0)
                    {
                        foreach (Node x in bridges[i - 1].toNodes.ToList())
                        {
                            tmpStart.disconnect(x);
                            tmpStart.neighbors.Remove(x);
                        }
                        bridges[i - 1].toNodes.Clear();
                    }
                    else
                    {
                        tmpStart.neighbors.Clear();
                    }

                    int a = Utils.RandomGenerator.rnd.Next(1, rSize);
                    int b = a;
                    if (rSize != 2)
                    {
                        while (b == a)
                        {
                            b = Utils.RandomGenerator.rnd.Next(1, rSize);
                        }
                    }
                    tmpStart.connect(nodeArray[a]);
                    nodeArray[a].connect(tmpStart);
                    tmpStart.connect(nodeArray[b]);
                    nodeArray[b].connect(tmpStart);

                    if (i > 0)
                    {
                        bridges[i - 1].connectToNodeOfNextZone(nodeArray[a]);
                        bridges[i - 1].connectToNodeOfNextZone(nodeArray[b]);
                    }
                    if (nodeArray[a].id == tmpExit.id || nodeArray[b].id == tmpExit.id)
                    {
                        a = Utils.RandomGenerator.rnd.Next(1, rSize - 1);
                        if (i < difficultyLevel)
                        {
                            bridges[i].connectToNodeOfSameZone(nodeArray[a]);
                        }
                        tmpExit.connect(nodeArray[a]);
                        nodeArray[a].connect(tmpExit);
                    }
                    else
                    {
                        a = Utils.RandomGenerator.rnd.Next(1, rSize - 1);
                        b = a;
                        while (b == a)
                        {
                            b = Utils.RandomGenerator.rnd.Next(1, rSize - 1);
                        }

                        if (i < difficultyLevel)
                        {
                            bridges[i].connectToNodeOfSameZone(nodeArray[a]);
                            bridges[i].connectToNodeOfSameZone(nodeArray[b]);
                        }
                        tmpExit.connect(nodeArray[a]);
                        nodeArray[a].connect(tmpExit);
                        tmpExit.connect(nodeArray[b]);
                        nodeArray[b].connect(tmpExit);
                    }
                    once = true;
                    //Console.WriteLine("shuffle: " + shuffle);
                    shuffle++;
                }
                // if (i == 0) cnt++;
                double t   = 0;
                double avg = 0;
                for (int h = 0; h < rSize; h++)
                {
                    double n = (double)nodeArray[h].neighbors.Count;
                    t = t + n;
                }
                avg = avg + ((double)t / (double)rSize);
                Logger.log("zone " + i + " avg: " + avg);
                cnt = cnt + (rSize - 1);
            }
        }
Exemplo n.º 22
0
        /* To create a new dungeon with the specified difficult level and capacity multiplier */
        //TO-DO: check average connectivity predicate
        //TO-DO: improve the algorithm for building connections between nodes in the same zone
        public Dungeon(uint level, uint nodeCapacityMultiplier, Random random)
        {
            Logger.log("Creating a dungeon of difficulty level " + level + ", node capacity multiplier " + nodeCapacityMultiplier + ".");
            difficultyLevel = level;               //assign dungeon difficulty level
            bridges         = new List <Bridge>(); //List of bridges initialized
            predicates      = new Predicates();
            zones           = new List <Zone>();   //initialize the zones
            M = nodeCapacityMultiplier;            //initialize node capacity multiğlier
            int numberOfNodesInZone = 0;
            int connected           = 0;

            //every node is named with its zone number followed by its number in a zone (nodeId = preId+lastId)
            string preId, lastId, nodeId = "";

            startNode = new Node("" + 10, 1);                       //start node id is set
            Logger.log("Set startNode Id: 10");
            for (int i = 1; i < level + 1; i++)                     //i signifies zone level, for each zone
            {
                Zone newZone = new Zone(i, nodeCapacityMultiplier); //create a new zone
                zones.Add(newZone);                                 //add it in dungeon.zones list
                Logger.log("Creating level " + i);

                preId = "" + i;                          // preId is zone level
                numberOfNodesInZone = random.Next(2, 5); //randomly decide between 2-4 nodes in a zone
                                                         //if you change number of nodes can be in a zone, be careful with the dependent statements below
                Logger.log("Number of nodes in zone " + i + " is " + numberOfNodesInZone);

                for (int j = 1; j <= numberOfNodesInZone; j++) //for each node in a zone
                {                                              //create and add nodes to the list nodesInZone
                    lastId = "" + j;
                    nodeId = preId + lastId;                   //merge preId and lastId to create nodeId
                    Node newNode = new Node(nodeId, i);        //create node
                    Logger.log("Created node with id " + nodeId);
                    newZone.nodesInZone.Add(newNode);          //add node to the list
                }

                //zone's nodesInZone list stores every node in this zone
                int  numberOfNodesToConnect;                                          // temp variable to decide how many nodes to connect for startNode or for bridges
                Node zoneFirstNode;                                                   //holds start node or starting bridge for the zone
                                                                                      //(starting bridge for a zone is the bridge which is connecting it to the previous zone)

                if (i == 1)                                                           //for the first level
                {                                                                     // connect start node to some nodes in the zone
                    zoneFirstNode          = startNode;
                    numberOfNodesToConnect = random.Next(1, numberOfNodesInZone + 1); //randomly decide btw 1-4 nodes
                    //rnd operation is exclusive for the max number, numberofNodesInZone can be 4 at most, thus it is safe this way
                    Logger.log("Connecting startNode to " + numberOfNodesToConnect + " nodes in the zone ");
                    for (int j = 0; j < numberOfNodesToConnect; j++)                 //for each nodes to connect
                    {                                                                //connect them with the start node
                        int nodeIndex = random.Next(0, numberOfNodesInZone);         //randomly get node index to connect
                        while (startNode.alreadyConnected(newZone.nodesInZone.ElementAt(nodeIndex)))
                        {                                                            //if the chosen node is already connected
                            nodeIndex = random.Next(0, numberOfNodesInZone);         //choose a new one
                        }
                        startNode.connect(newZone.nodesInZone.ElementAt(nodeIndex)); //connect start node with that node
                        Logger.log("Connected to node " + newZone.nodesInZone.ElementAt(j).id);
                    }
                }
                else
                {                                                            //connect bridge to some nodes in the next zone
                    Bridge startBridge = bridges.ElementAt(i - 2);           //bridge is already created in previous loop
                    zoneFirstNode = (Node)startBridge;
                    int maxConnect = 4 - startBridge.neighbors.Count;        //maximum number of connections that bridge can make

                    if (numberOfNodesInZone < maxConnect)                    //maximum number of connections are constrained by
                    {
                        maxConnect = numberOfNodesInZone;                    //number of zones in the zone
                    }
                    numberOfNodesToConnect = random.Next(1, maxConnect + 1); //Decide how many connections it should make
                    Logger.log("Connecting bridge " + startBridge.id + " to " + numberOfNodesToConnect + " nodes in the next zone ");
                    for (int j = 0; j < numberOfNodesToConnect; j++)
                    {                                                        //connect them with the bridge node
                        int nodeIndex = random.Next(0, numberOfNodesInZone); //randomly decide the node index
                        while (startBridge.alreadyConnected(newZone.nodesInZone.ElementAt(nodeIndex)))
                        {
                            nodeIndex = random.Next(0, numberOfNodesInZone);
                        }
                        startBridge.connectToNodeOfNextZone(newZone.nodesInZone.ElementAt(nodeIndex)); //connect bridge with the next zone
                        Logger.log("Connected to node " + newZone.nodesInZone.ElementAt(j).id);
                    }
                }
                Logger.log("Connecting nodes in the same zone");

                //connect nodes in the same zone
                //TO-DO improve the algorithm
                //Currently it exits the algorithm once every node is accessible from the starting node of the zone
                while (!allReachable(newZone.nodesInZone, zoneFirstNode))                         //while there exists not reachable nodes
                {
                    Node n1 = newZone.nodesInZone.ElementAt(random.Next(0, numberOfNodesInZone)); //randomly choose node1
                    while (n1.isFullyConnected())                                                 //if it is fully connected node
                    {
                        n1 = newZone.nodesInZone.ElementAt(random.Next(0, numberOfNodesInZone));  //choose another one
                    }
                    Node n2 = newZone.nodesInZone.ElementAt(random.Next(0, numberOfNodesInZone)); //randomly select node2
                    while (n2.isFullyConnected() || n2.id == n1.id || n2.alreadyConnected(n1))    //make sure it is not fully connected, not same as node1, not already connected with node1
                    {
                        n2 = newZone.nodesInZone.ElementAt(random.Next(0, numberOfNodesInZone));
                    }
                    n1.connect(n2);
                    Logger.log("Nodes " + n1.id + " " + n2.id + " are connected");
                }


                List <Node> listOfNotFullNodes = new List <Node>(); //get list of not fully connected nodes in the zone to consider connections

                for (int j = 0; j < newZone.nodesInZone.Count; j++)
                {
                    Node nd = newZone.nodesInZone.ElementAt(j);
                    if (!nd.isFullyConnected())
                    {
                        listOfNotFullNodes.Add(nd);
                    }
                }
                Logger.log("Creating list of not full nodes, number of not full nodes " + listOfNotFullNodes.Count);

                //Connect last node to the zone, either a bridge or the exit node
                int min = 1;
                int max;
                if (i == level)
                { // last zone
                  //connect exit node

                    lastId   = "" + (numberOfNodesInZone + 1);
                    nodeId   = preId + lastId;      //create id of the exit node
                    exitNode = new Node(nodeId, i); //create exit node
                    Logger.log("Last zone is finished, exit node id is set to " + nodeId);
                    max = 4;                        //max number of connections that node can have

                    if (listOfNotFullNodes.Count < 4)
                    {
                        max = listOfNotFullNodes.Count;                    //can make at most listOfNotFullNodes.Count number of connections
                    }
                    numberOfNodesToConnect = random.Next(min, max + 1);    //randomly decide number of nodes to connect

                    for (int j = 0; j < numberOfNodesToConnect; j++)       //connect exit node to that number of nodes
                    {
                        exitNode.connect(listOfNotFullNodes.ElementAt(j)); //can be randomized
                        Logger.log("Connected to node " + listOfNotFullNodes.ElementAt(j).id);
                    }
                }
                else
                { //connect to end bridge
                  //a bridge can be connected to at minimum 1 and at maximum 3 nodes
                    lastId = "" + (numberOfNodesInZone + 1);
                    nodeId = preId + lastId;                  //create bridge id
                    Bridge endBridge = new Bridge(nodeId, i); //create the bridge
                    bridges.Add(endBridge);                   //add it to bridges list to access it in the next loop iteration
                    Logger.log("A new bridge is created with id " + nodeId);

                    max = 3; //since a bridge should already have at least 1 connection to the other zone
                    //max number of connections it can make can not be more than 3

                    if (listOfNotFullNodes.Count < 3)
                    {
                        max = listOfNotFullNodes.Count;                                     //can make at most listOfNotFullNodes.Count number of connections
                    }
                    numberOfNodesToConnect = random.Next(min, max + 1);                     //decide number of nodes to connect

                    for (int j = 0; j < numberOfNodesToConnect; j++)                        //connect it to that number of nodes
                    {
                        endBridge.connectToNodeOfSameZone(listOfNotFullNodes.ElementAt(j)); //not randomized
                        Logger.log("Connected to node " + listOfNotFullNodes.ElementAt(j).id);
                    }
                    //end bridge is also connected
                }

                //Ensure the average connectivity
                if (i == 1)
                {
                    Node n1, n2;
                    connected = startNode.neighbors.Count;
                    for (int j = 0; j < numberOfNodesInZone; j++)
                    {
                        connected += newZone.nodesInZone.ElementAt(j).neighbors.Count;
                    }
                    while (Convert.ToDouble(connected / (numberOfNodesInZone + 1)) > 3)
                    {
                        n1 = newZone.nodesInZone.ElementAt(random.Next(0, numberOfNodesInZone));
                        while (n1.neighbors.Count <= 1)
                        {
                            n1 = newZone.nodesInZone.ElementAt(random.Next(0, numberOfNodesInZone));
                        }
                        n2 = newZone.nodesInZone.ElementAt(random.Next(0, numberOfNodesInZone));
                        while (n2.neighbors.Count <= 1 || n2.id == n1.id || !n2.alreadyConnected(n1))
                        {
                            n2 = newZone.nodesInZone.ElementAt(random.Next(0, numberOfNodesInZone));
                        }
                        n1.disconnect(n2);
                        Logger.log("Nodes " + n1.id + " " + n2.id + " are disconnected");
                        connected -= 2;
                    }
                }
                else if (i == level)
                {
                    Node n1, n2;
                    connected  = exitNode.neighbors.Count;
                    connected += bridges.ElementAt(i - 2).neighbors.Count;
                    for (int j = 0; j < numberOfNodesInZone; j++)
                    {
                        connected += newZone.nodesInZone.ElementAt(j).neighbors.Count;
                    }
                    while (Convert.ToDouble(connected / (numberOfNodesInZone + 2)) > 3)
                    {
                        n1 = newZone.nodesInZone.ElementAt(random.Next(0, numberOfNodesInZone));
                        while (n1.neighbors.Count <= 1)
                        {
                            n1 = newZone.nodesInZone.ElementAt(random.Next(0, numberOfNodesInZone));
                        }
                        n2 = newZone.nodesInZone.ElementAt(random.Next(0, numberOfNodesInZone));
                        while (n2.neighbors.Count <= 1 || n2.id == n1.id || !n2.alreadyConnected(n1))
                        {
                            n2 = newZone.nodesInZone.ElementAt(random.Next(0, numberOfNodesInZone));
                        }
                        n1.disconnect(n2);
                        Logger.log("Nodes " + n1.id + " " + n2.id + " are disconnected");
                        connected -= 2;
                    }
                }
                else
                {
                    Node n1, n2;
                    connected = bridges.ElementAt(i - 2).neighbors.Count;
                    for (int j = 0; j < numberOfNodesInZone; j++)
                    {
                        connected += newZone.nodesInZone.ElementAt(j).neighbors.Count;
                    }
                    while (Convert.ToDouble(connected / (numberOfNodesInZone + 1)) > 3)
                    {
                        n1 = newZone.nodesInZone.ElementAt(random.Next(0, numberOfNodesInZone));
                        while (n1.neighbors.Count <= 1)
                        {
                            n1 = newZone.nodesInZone.ElementAt(random.Next(0, numberOfNodesInZone));
                        }
                        n2 = newZone.nodesInZone.ElementAt(random.Next(0, numberOfNodesInZone));
                        while (n2.neighbors.Count <= 1 || n2.id == n1.id || !n2.alreadyConnected(n1))
                        {
                            n2 = newZone.nodesInZone.ElementAt(random.Next(0, numberOfNodesInZone));
                        }
                        n1.disconnect(n2);
                        Logger.log("Nodes " + n1.id + " " + n2.id + " are disconnected");
                        connected -= 2;
                    }
                }


                //pass to next zone
                Logger.log("Passing to next zone");
            }


            //Add startnode, bridges and endnode
            foreach (Zone z in zones)
            {
                if (z.id == 1)               //first zone, add start node
                {
                    z.nodesInZone.Add(startNode);
                }
                else if (z.id == level)                  //last zone, add end node
                {
                    z.nodesInZone.Add(exitNode);
                }

                if (z.id != level)                         //in middle zones, add their bridges
                {
                    z.nodesInZone.Add(bridges.ElementAt(z.id - 1));
                }
            }
        }