Esempio n. 1
0
        public void MSTest_disconnect_not_connected_nodes()
        {
            Node node1 = new Node();
            Node node2 = new Node();

            node1.disconnect(node2);
        }
Esempio n. 2
0
        public void MSTest_disconnect_nodes()
        {
            Node baseNode = new Node();
            Node nbNode   = new Node();

            baseNode.neighbors.Add(nbNode);
            baseNode.neighbors.Add(baseNode);
            baseNode.disconnect(nbNode);
            Assert.IsFalse(baseNode.neighbors.Contains(nbNode));
            Assert.IsFalse(nbNode.neighbors.Contains(baseNode));
        }
Esempio n. 3
0
        /*Tuple contains the remaining connections from the bridge,
        *  the amount of nodes, and the total amount of connections.*/
        private Tuple <int, int, int> makeSection(Node start, int startc, ref int level)
        {
            Bridge b      = new Bridge(level.ToString());
            Bridge bstart = start as Bridge;

            if (startc == 1) //can only be directly connected to a bridge
            {
                level++;
                b.connectToNodeOfSameZone(start);
                if (bstart != null)
                {
                    bstart.connectToNodeOfNextZone(b);
                    bstart.disconnect(b);
                }
                if (level > difficultyLevel + 1)
                {
                    exitNode = new Node(b);
                }
                else
                {
                    bridges[level - 2] = b;
                }
                return(Tuple.Create(rng.Next(1, 4), 1, 1));
            }
            HashSet <int> open       = new HashSet <int>();
            List <Node>   nodes      = new List <Node>();
            List <int>    conns      = new List <int>();
            int           totalConns = 0;

            open.Add(0);
            nodes.Add(start);
            conns.Add(startc);
            int index;

            while (open.Count > 1 || open.Contains(0))
            {
                Node n = new Node();
                index = nodes.Count;
                open.Add(index);
                nodes.Add(n);
                conns.Add(rng.Next(1, 5));
                for (int i = 0; i < index; i++)
                {
                    if (open.Contains(i) && conns.Sum() > open.Count)
                    {
                        totalConns++;
                        nodes[i].connect(n);
                        conns[i]--;
                        if (conns[i] == 0)
                        {
                            open.Remove(i);
                        }
                        conns[index]--;
                        if (conns[index] == 0)
                        {
                            open.Remove(index);
                            break;
                        }
                    }
                }
            }
            if (bstart != null)
            {
                bstart.toNodes = bstart.neighbors.Except(bstart.fromNodes).ToList();
            }
            index = open.Single();
            foreach (Node nd in shortestpath(start, nodes[index])
                     .Where(m => m == nodes[index] || p.isBridge(start, nodes[index], m)))
            {
                level++;
                if (level > difficultyLevel + 1)
                {
                    exitNode    = nd;
                    exitNode.id = "exit";
                    break;
                }
                else
                {
                    var nb = nd.neighbors;
                    while (nb.Count > 0)
                    {
                        Node m = nb[0];
                        m.disconnect(nd);
                        if (p.isReachable(start, m))
                        {
                            b.connectToNodeOfSameZone(m);
                        }
                        else
                        {
                            b.connectToNodeOfNextZone(m);
                        }
                    }
                    bridges[level - 2] = b;
                    b = new Bridge(level.ToString());
                }
            }
            return(Tuple.Create(conns[index], nodes.Count - 1, totalConns));
        }
Esempio n. 4
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));
                }
            }
        }
Esempio n. 5
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);
            }
        }