示例#1
0
        public void DisconnectTest()
        {
            Dungeon a = new Dungeon(10, 1);


            Random rnd      = RandomGenerator.rnd;
            int    i        = rnd.Next(a.bridges.Length);
            string bridgeid = a.bridges[i].id;

            //maak lijst van nodes die allemaal behouden moeten worden
            List <string> keep = new List <string>();

            foreach (Node n in Predicates.reachableNodes(a.startNode))
            {
                if (a.level(n) > a.level(a.bridges[i]) || a.level(n) == 0)
                {
                    keep.Add(n.id);
                }
            }

            keep.Add(a.bridges[i].id);

            a.disconnect(a.bridges[i]);

            foreach (Node n in Predicates.reachableNodes(a.startNode))
            {
                Assert.IsTrue(keep.Contains(n.id));
            }
        }
示例#2
0
        public void MSTest_level()
        {
            Node    node        = new Node();
            Bridge  bridge      = new Bridge("bridge 4");
            Dungeon d           = new Dungeon();
            uint    nodeLevel   = d.level(node);
            uint    bridgeLevel = d.level(bridge);

            Assert.IsTrue(nodeLevel == 0);
            Assert.IsTrue(bridgeLevel == 4);
        }
示例#3
0
        /* Move the pack to an adjacent node. */
        public void move(Node u)
        {
            if (u == location)
            {
                Logger.log("Pack" + id + " doesn't move.");
                return;
            }
            if (!location.neighbors.Contains(u))
            {
                throw new ArgumentException();
            }
            int capacity = (int)(dungeon.M * (dungeon.level(u) + 1));

            // count monsters already in the node:
            foreach (Pack Q in u.packs)
            {
                capacity = capacity - Q.members.Count;
            }
            // capacity now expresses how much space the node has left
            if (members.Count > capacity)
            {
                Logger.log("Pack " + id + " is trying to move to a full node " + u.id + ", but this would cause the node to exceed its capacity. Rejected.");
                return;
            }
            location.packs.Remove(this);
            location = u;
            u.packs.Add(this);
        }
示例#4
0
        public void PopulateDungeon(int monsters, ref int monsterHP, Dungeon dungeon)
        {
            int monstersLeft = monsters;
            int l            = dungeon.zone.Count + 1;

            for (int i = 1; i < l; i++)
            {
                int         rMax             = (int)dungeon.M + 1;
                List <Node> curZone          = dungeon.zone[i];
                int         monstersThisZone = (2 * i * monsters) / (int)((dungeon.difficultyLevel + 2) * (dungeon.difficultyLevel + 1));
                if (monstersThisZone > monstersLeft)
                {
                    monstersThisZone = monstersLeft;
                    monstersLeft     = 0;
                }
                else
                {
                    monstersLeft -= monstersThisZone;
                }
                //if (monstersThisZone > monstersLeft)
                //	monstersThisZone = monstersLeft;
                //monstersLeft -= monstersThisZone;
                int    j        = 1;
                string idPrefix = "Pack-" + i + ".";
                while (monstersThisZone > 0)
                {
                    if (rMax > monstersThisZone)
                    {
                        rMax = monstersThisZone;
                    }
                    int nPack = r.Next(1, rMax);
                    int index = r.Next(curZone.Count);
                    if (curZone[index] == dungeon.exitNode)
                    {
                        continue;                        //not allowed to drop in exitnode, skip
                    }
                    int capacity = (int)(dungeon.M * (dungeon.level(curZone[index]) + 1));
                    // count monsters already in the node:
                    foreach (Pack Q in curZone[index].packs)
                    {
                        capacity = capacity - Q.members.Count;
                    }

                    if (capacity >= nPack)                   //if there is enough space, make and drop new pack
                    {
                        Pack pack = new Pack(idPrefix + j, (uint)nPack);
                        j++;
                        monstersThisZone -= nPack;
                        pack.location     = curZone[index];
                        pack.dungeon      = dungeon;
                        pack.zone         = i;
                        curZone[index].packs.Add(pack);
                        monsterHP += pack.startingHP;
                    }
                }
            }
        }
示例#5
0
        // parameter = visit node
        public void Move(Node move)
        {
            if (move == null)
            {
                throw new ArgumentException();
            }
            Node old_location = this.location;

            if (dungeon.level(old_location) != dungeon.level(move))
            {
                Console.WriteLine("You entered zone: " + dungeon.level(move));
                undo_alert_packs(old_location, move); //checks if it is necessary to undo alert packs (Ralert rule)
                enter_last_zone(move);                //checks if it is really the last zone and apply RendZone rule
            }

            if (move != null && this.location.neighbors.Contains(move))
            {
                this.location.contested = false;
                this.location           = move;
                move.visited            = true;

                //Pick up items.
                foreach (Item potion in this.location.items.ToList())
                {
                    if (potion is HealingPotion)
                    {
                        Console.WriteLine("You found a potion with {0} healing. Added to bag.", (potion as HealingPotion).HPvalue);
                    }
                    else
                    {
                        Console.WriteLine("You found a crystal! Added to bag.");
                    }

                    this.location.items.Remove(potion);
                    this.bag.Add(potion);
                }
                if (this.location.packs.Count > 0)
                {
                    this.location.contested = true;
                    alert_packs(this.location); //(Ralert rule)
                }
            }
            else
            {
                throw new ArgumentException();
            }
        }
示例#6
0
文件: MSTest_Pack.cs 项目: Sd8991/STV
        public void MStest_move_with_insufficient_capacity()
        {
            Dungeon d = new Dungeon(5);
            Pack    p = new Pack("pid", 3);
            Pack    q = new Pack("qid", (d.M * (d.level(d.zone[1][1]) + 1)));

            p.dungeon  = d;
            q.dungeon  = d;
            p.location = d.zone[1][0];
            q.location = d.zone[1][1];
            d.zone[1][0].packs.Add(p);
            d.zone[1][1].packs.Add(q);
            p.move(d.zone[1][1]);
            Assert.IsTrue(p.location == d.zone[1][0]);
        }
示例#7
0
文件: Pack.cs 项目: nii3lsh/STVrogue
        public Node getRandomValidNeighbour(Dungeon d)
        {
            List <Node> candidates = new List <Node>();

            foreach (Node n in this.location.neighbors.ToList())
            {
                if (n.CountCreatures() + this.members.Count < n.Capacity(d) && d.level(n) == d.level(this.location) && n != dungeon.exitNode)
                {
                    candidates.Add(n);
                }
            }
            if (candidates.Count() == 0)
            {
                return(this.location);
            }
            else
            {
                return(candidates.GetRandomItem());
            }
        }
示例#8
0
        public void Level_Simple()
        {
            //tets a simple graph
            Dungeon a = new Dungeon(1, 1);

            a.graph.Clear();
            a.startNode = null;
            a.exitNode  = null;

            Node[] xs = new Node[2];
            //level 1
            xs[0]           = new Node("0");
            xs[0].nodeLevel = 1;
            a.startNode     = xs[0];

            Bridge b1 = new Bridge("2");

            b1.nodeLevel = 1;

            xs[1]           = new Node("1");
            xs[1].nodeLevel = 2;

            b1.connectToNodeOfSameZone(xs[0]);
            b1.connectToNodeOfSameZone(xs[1]);

            a.exitNode = xs[1];

            a.bridges = new Bridge[] { b1 };

            a.dungeon_size = 3;
            a.graph.Add(xs[0]);
            a.graph.Add(b1);
            a.graph.Add(xs[1]);


            //startnode - bridge - exitnode (startnode and bridge are lvl 1 and exitnode lvl 0)
            foreach (Node n in Predicates.reachableNodes(a.startNode))
            {
                Assert.AreEqual(n.nodeLevel, a.level(n));
            }
        }
示例#9
0
文件: Pack.cs 项目: nii3lsh/STVrogue
        /* Move the pack to an adjacent node. */
        public void move(Node u, Node playerlocation = null)
        {
            if (u == location)
            {
                return;
            }
            if (!location.neighbors.Contains(u) || u == null)
            {
                throw new ArgumentException();
            }
            uint capacity = dungeon.M * (dungeon.level(u) + 1);

            if (u.CountCreatures() + this.members.Count() >= capacity)
            {
                Logger.log("Pack " + id + " is trying to move to an already full node " + u.id + ". Rejected.");
                //throw new ArgumentException();
            }
            else if (u == dungeon.exitNode)
            {
                Logger.log("Pack " + id + " is trying to move to the exit node, rejected.");
                // throw new ArgumentException();
            }
            else
            {
                location.packs.Remove(this);
                location = u;
                if (location == playerlocation && members.Count > 0)
                {
                    location.contested = true;
                }
                foreach (Monster m in members.ToList())
                {
                    m.location = u;
                }
                u.packs.Add(this);
            }
        }
示例#10
0
        /* Move the pack to an adjacent node. */
        public void move(Node u)
        {
            if (!location.neighbors.Contains(u))
            {
                throw new ArgumentException();
            }

            // pack can't move to a different zone
            if (location.zoneNumber != u.zoneNumber)
            {
                return;
            }

            int capacity = (int)(dungeon.M * (dungeon.level(u) + 1));

            // count monsters already in the node:
            foreach (Pack Q in u.packs)
            {
                capacity = capacity - Q.members.Count;
            }
            // capacity now expresses how much space the node has left
            if (members.Count > capacity)
            {
                Logger.log(id + " is trying to move to a full node " + u.id + ", but this would cause the node to exceed its capacity. Rejected.");
                return;
            }
            u.packs.Add(this);
            string prevLocation = location.id;

            location.packs.Remove(this);
            location = u;
            foreach (Monster m in members)
            {
                m.location = location;
            }
            Logger.log(id + " moves from " + prevLocation + " to " + location.id + ".");
        }
示例#11
0
        /**
         * Move the pack to an adjacent node.
         * @param name="u" node should be adjacent
         */
        public void Move(Node u)
        {
            if (!location.neighbors.Contains(u))
            {
                throw new ArgumentException();
            }
            int capacity = (int)(dungeon.M * (dungeon.level(u) + 1));             //each zone has a specified capacity

            // count monsters already in the node:
            foreach (Pack Q in location.packs)             //for each pack in the node
            {
                capacity = capacity - Q.members.Count;     //decrease the capacity by number of pack members
            }
            // capacity now expresses how much space the node has left
            if (members.Count > capacity)
            {
                Logger.log("Pack " + id + " is trying to move to a full node " + u.id + ", but this would cause the node to exceed its capacity. Rejected.");
                return;
            }
            //else move is successful
            this.location = u;
            u.packs.Add(this);
            Logger.log("Pack " + id + " moves to the node " + u.id + ". Not rejected.");
        }
示例#12
0
文件: Game.cs 项目: nii3lsh/STVrogue
        public void spawnMonsters(uint numberOfMonsters, uint difficultyLevel)
        {
            Random r = RandomGenerator.rnd;

            List <Node> availableNodes = Predicates.reachableNodes(dungeon.startNode);

            Logger.log("This dungeon consists of " + availableNodes.Count + " nodes.");

            uint   monstersLeft    = numberOfMonsters;
            double monstersinLevel = 0;
            uint   packID          = 0;

            for (uint i = 1; i < difficultyLevel; i++)
            {
                List <Node> availableNodesinLevel = new List <Node>();
                foreach (Node n in availableNodes.ToList())
                {
                    if (dungeon.level(n) == i)
                    {
                        availableNodesinLevel.Add(n);
                    }
                }
                monstersinLevel = Math.Round((2 * i * (double)numberOfMonsters / ((difficultyLevel + 2) * (difficultyLevel + 1))));
                while (monstersinLevel > 0)
                {
                    uint capacityLevel = availableNodesinLevel[0].Capacity(dungeon);
                    foreach (Node nd in availableNodesinLevel.ToList())
                    {
                        int creatureCount = nd.CountCreatures();
                        int space         = (int)capacityLevel - creatureCount;
                        if (space == 0)
                        {
                            availableNodesinLevel.Remove(nd);
                        }
                        if (availableNodesinLevel.Count() == 0)
                        {
                            throw new GameCreationException("Too many monsters, not enough nodes");
                        }

                        int spawnX = r.Next(0, Math.Min(space, (int)monstersinLevel) + 1);
                        if (spawnX == 0)
                        {
                            continue;              //We increase randomness by potentially skipping a node while placing packs
                        }
                        monstersinLevel -= (double)spawnX;
                        monstersLeft    -= (uint)spawnX;
                        Pack pack = new Pack(packID++.ToString(), (uint)spawnX, nd, dungeon);
                        nd.packs.Add(pack);
                        dungeon.alivePacks.Add(pack);
                    }
                    //Console.WriteLine("{0} monsters in level. {1} monsters left", monstersinLevel, monstersLeft);
                }
            }


            List <Node> availableNodesinExit = new List <Node>();

            foreach (Node n in availableNodes.ToList())
            {
                if (dungeon.level(n) == dungeon.level(dungeon.exitNode))
                {
                    availableNodesinExit.Add(n);
                }
            }
            while (monstersLeft > 0)
            {
                uint capacityLevel = dungeon.M * (dungeon.level(availableNodesinExit[0]) + 1);
                foreach (Node nd in availableNodesinExit.ToList())
                {
                    int creatureCount = nd.CountCreatures();
                    int space         = (int)capacityLevel - creatureCount;
                    if (space == 0)
                    {
                        availableNodesinExit.Remove(nd);
                    }
                    if (availableNodesinExit.Count() == 0)
                    {
                        throw new GameCreationException("Too many monsters, not enough nodes");
                    }

                    int spawnX = r.Next(0, Math.Min(space, (int)monstersLeft) + 1);
                    if (spawnX == 0)
                    {
                        continue;
                    }
                    monstersLeft -= (uint)spawnX;
                    Pack pack = new Pack(packID++.ToString(), (uint)spawnX, nd, dungeon);
                    pack.location = nd;
                    nd.packs.Add(pack);
                    dungeon.alivePacks.Add(pack);
                }
                //Console.WriteLine("Spreading monsters in last zone {0} monsters left", monstersLeft);
            }
        }
示例#13
0
        public void Level_Test_Groot()
        {
            //test a bigger graph (figure 1 from project description)
            Dungeon a = new Dungeon(1, 1);

            a.graph.Clear();
            a.startNode = null;
            a.exitNode  = null;

            Node[] xs = new Node[10];
            //startnode
            xs[0]           = new Node("0");
            xs[0].nodeLevel = 1;
            a.startNode     = xs[0];

            xs[1]           = new Node("1");
            xs[1].nodeLevel = 1;

            xs[2]           = new Node("2");
            xs[2].nodeLevel = 1;

            xs[3]           = new Node("3");
            xs[3].nodeLevel = 1;

            xs[4]           = new Node("4");
            xs[4].nodeLevel = 1;

            Bridge b1 = new Bridge("10");

            b1.nodeLevel = 1;

            xs[0].connect(xs[1]);
            xs[0].connect(xs[3]);
            xs[0].connect(xs[2]);

            xs[2].connect(xs[1]);
            xs[2].connect(xs[3]);

            xs[3].connect(xs[4]);

            b1.connectToNodeOfSameZone(xs[1]);
            b1.connectToNodeOfSameZone(xs[2]);

            //level 2
            xs[5]           = new Node("5");
            xs[5].nodeLevel = 2;

            xs[6]           = new Node("6");
            xs[6].nodeLevel = 2;

            b1.connectToNodeOfNextZone(xs[5]);
            b1.connectToNodeOfNextZone(xs[6]);

            Bridge b2 = new Bridge("11");

            b2.nodeLevel = 2;

            xs[5].connect(xs[6]);

            b2.connectToNodeOfSameZone(xs[5]);
            b2.connectToNodeOfSameZone(xs[6]);

            //level 0
            xs[7]           = new Node("7");
            xs[7].nodeLevel = 3;
            b2.connectToNodeOfNextZone(xs[7]);

            xs[8]           = new Node("8");
            xs[8].nodeLevel = 3;
            b2.connectToNodeOfNextZone(xs[8]);

            //exit node
            xs[9]           = new Node("9");
            xs[9].nodeLevel = 3;

            xs[9].connect(xs[7]);
            xs[9].connect(xs[8]);

            a.startNode = xs[0];
            a.exitNode  = xs[9];

            a.bridges = new Bridge[] { b1, b2 };

            for (int i = 0; i < 10; i++)
            {
                a.graph.Add(xs[i]);
            }
            a.graph.Add(b1);
            a.graph.Add(b2);

            a.dungeon_size = 12;

            foreach (Node n in Predicates.reachableNodes(a.startNode))
            {
                Assert.AreEqual(n.nodeLevel, a.level(n));
            }
        }
示例#14
0
        /*Node level should always be 0, Dungeon size is irrelevant so no FsCheck.*/
        public void TestNodeLevel()
        {
            var d = new Dungeon(1, 1);

            Assert.Zero(d.level(new Node()));
        }
示例#15
0
        public void NTest_located_Level()
        {
            Node n1 = new Node("1", 1);

            Assert.Equals(dungeon.level(n1), 1);
        }
示例#16
0
 public uint Capacity(Dungeon d)
 {
     return(d.M * (d.level(this) + 1));
 }
示例#17
0
        // takes a Command and processes it according to the game rules
        private void processPlayerInput(Command userCommand)
        {
            // pick up any item
            if (player.location.items.Count != 0)
            {
                for (int i = player.location.items.Count - 1; i >= 0; i--)
                {
                    Item item = player.location.items[i];
                    player.bag.Add(item);
                    player.location.items.Remove(item);
                }
            }

            // move to node
            if (userCommand.action == Command.Action.Move)
            {
                // old player location not contested anymore
                player.location.isContested = false;

                player.move(userCommand.moveTo);
                // if player left alert zone, reset alert zone
                if (dungeon.alertZone != player.location.zoneNumber)
                {
                    dungeon.alertZone = -1;
                }
            }

            // attack
            if (userCommand.action == Command.Action.Attack)
            {
                playerAttacks(player.location);
                // set alert zone
                if (dungeon.alertZone != dungeon.level(player.location))
                {
                    if (dungeon.alertZone != player.location.zoneNumber)
                    {
                        dungeon.alertZone = player.location.zoneNumber;
                    }
                }
            }

            // flee
            if (userCommand.action == Command.Action.Flee)
            {
                playerFlees(player.location);
                // if player left alert zone, reset alert zone
                if (dungeon.alertZone != player.location.zoneNumber)
                {
                    dungeon.alertZone = -1;
                }
            }

            // use crystal
            if (userCommand.action == Command.Action.UseCrystal)
            {
                Item item = player.bag.Find(i => i is Crystal);
                player.use(item);
                items.Remove(item);
            }

            // use potion
            if (userCommand.action == Command.Action.UsePostion)
            {
                Item item = player.bag.Find(i => i is HealingPotion);
                player.use(item);
                items.Remove(item);
            }

            // leave
            if (userCommand.action == Command.Action.Leave && player.location is Bridge)
            {
                // ((Bridge)player.location).disconnectBridge();
            }
        }
示例#18
0
        /* This creates a player and a random dungeon of the given difficulty level and node-capacity
         * The player is positioned at the dungeon's starting-node.
         * The constructor also randomly seeds monster-packs and items into the dungeon. The total
         * number of monsters are as specified. Monster-packs should be seeded as such that
         * the nodes' capacity are not violated. Furthermore the seeding of the monsters
         * and items should meet the balance requirements stated in the Project Document.
         */
        public Game(uint difficultyLevel, uint nodeCapcityMultiplier, uint numberOfMonsters)
        {
            player  = new Player();
            dungeon = new Dungeon(difficultyLevel, nodeCapcityMultiplier);
            packs   = new List <Pack>();
            items   = new List <Item>();

            // Game should have at least one monster.
            if (numberOfMonsters < 2)
            {
                throw new GameCreationException("Not enough monsters. numberOfMonsters should be >= 2");
            }

            // Check if node multiplier is bigger then 1, else dungeon cannot have any monsters.
            if (nodeCapcityMultiplier <= 0)
            {
                throw new GameCreationException("Invalid nodeCapcityMultiplier must be > 0");
            }

            // Check if dungeon is big enough to hold all the monsters.
            uint maxCapacity = 0;

            dungeon.allNodes.ForEach(node => maxCapacity += nodeCapcityMultiplier * (dungeon.level(node) + 1));
            if (numberOfMonsters > maxCapacity)
            {
                throw new GameCreationException("The number of monsters (" + numberOfMonsters + ") exceed dungeon capacity (" + maxCapacity + ")");
            }
            Logger.log("Creating a game of difficulty level " + difficultyLevel + ", node capacity multiplier "
                       + nodeCapcityMultiplier + ", and " + numberOfMonsters + " monsters.");

            player.dungeon = dungeon;
            // Player should start at the starting node.
            player.location = dungeon.startNode;

            // Get all dungeon bridges.
            List <Node> bridges = new List <Node>(dungeon.bridges);

            // Pretend the start and exit node are also a bridge.
            bridges.Insert(0, dungeon.startNode);
            bridges.Add(dungeon.exitNode);

            // The total hp off all monsters, will later be used to determine the amount of healing potions that can be spawned.
            int totalMonsterHp = 0;
            // Number of packs created.
            int packCount = 0;
            // Number of monsters created.
            int monsterCount = 0;

            // Helper function for pack creation.
            Func <uint, Node, Pack> createPack = new Func <uint, Node, Pack>((numberOfMonstersToCreate, node) =>
            {
                // Create a pack with the number of monsters.
                Pack pack       = new Pack("Pack" + packCount++, numberOfMonstersToCreate);
                pack.dungeon    = dungeon;
                pack.location   = node;
                pack.zoneNumber = pack.location.zoneNumber;
                node.packs.Add(pack);

                monsterCount += (int)numberOfMonstersToCreate;
                pack.members.ForEach(member =>
                {
                    member.pack     = pack;
                    totalMonsterHp += member.HP;
                });
                packs.Add(pack);
                return(pack);
            });

            // Distribute packs/monsters in dungeon.
            for (int level = 0; level <= difficultyLevel; level++)
            {
                // The amount of monster allowed in this zone.
                int monsterPerZone = (int)Math.Floor((2.0 * (level + 1) * numberOfMonsters) / ((difficultyLevel + 2) * (difficultyLevel + 1)));

                // The last level (zone) does not have to follow the formula above and can get the remaining monsters.
                if (level == difficultyLevel)
                {
                    monsterPerZone += ((int)numberOfMonsters - monsterCount) - monsterPerZone;
                }

                // All the nodes in the in this zone. (without the start or exit node).
                List <Node> nodes = Util.getAllNodesBetween(bridges[level], bridges[level + 1]).FindAll(node => node != dungeon.startNode && node != dungeon.exitNode);

                // For each node in level.
                for (int i = 0; i < nodes.Count && monsterPerZone > 0; i++)
                {
                    // The max number of monster that can be on this node.
                    uint nodeCapacityLimit = nodeCapcityMultiplier * (dungeon.level(nodes[i]) + 1);
                    // Subtract the monsters that are already on this node.
                    nodes[i].packs.ForEach(pack => nodeCapacityLimit -= (uint)pack.members.Count);

                    // Take a random number of monster to create for this pack on this node.
                    // But do not exceed the node capacity.
                    uint numberOfMonstersToCreate = (uint)RandomGenerator.rnd.Next((int)(Math.Min(nodeCapacityLimit, monsterPerZone) + 1));

                    // Check if we can still create a pack, we do not wish to create a pack of zero monsters.
                    if (numberOfMonstersToCreate > 0)
                    {
                        // Subtract the amount of monster spawned from the total monster pool.
                        // This pool should reach zero by the end of the zone.
                        monsterPerZone -= (int)numberOfMonstersToCreate;

                        // Put the pack on then node.
                        createPack(numberOfMonstersToCreate, nodes[i]);
                    }
                }

                // Not necessarily all monster should have been created, due to the randomness.
                // So we just distribute the rest of the monster accordingly.
                for (int i = 0; i < nodes.Count && monsterPerZone > 0; i++)
                {
                    // The number of monsters this node can still hold.
                    uint remainingNodeCapacity = nodeCapcityMultiplier * (dungeon.level(nodes[i]) + 1);
                    nodes[i].packs.ForEach(pack => remainingNodeCapacity -= (uint)pack.members.Count);
                    uint numberOfMonstersToCreate = (uint)Math.Min(monsterPerZone, remainingNodeCapacity);

                    // Check if we can still create a pack, we do not wish to create a pack of zero monsters.
                    if (numberOfMonstersToCreate > 0)
                    {
                        monsterPerZone -= (int)numberOfMonstersToCreate;
                        createPack(numberOfMonstersToCreate, nodes[i]);
                    }
                }

                // Monsters for this zone should be exactly zero.
                // If not the zone was to small and the dungeon is invalid.
                if (monsterPerZone != 0)
                {
                    throw new GameCreationException("To many monsters to fit in zone!");
                }
            }

            // Player HP
            player.HP = Math.Min(player.HPbase, (int)(0.8 * totalMonsterHp));

            // All nodes in dungeon without the start and exit node.
            List <Node> allNodes = dungeon.allNodes.FindAll(node => node != dungeon.startNode && node != dungeon.exitNode);

            // HP left to spend is the difference between 80% of the total monster HP and the player HP including all possible potions.
            int hpLeftToSpend = (int)Math.Floor(totalMonsterHp * 0.8) - player.HP;

            // Minus the HP of possible healing potion already in player bag.
            //hpLeftToSpend -= (int)player.bag.OfType<HealingPotion>().Sum(item => item.HPvalue);

            // Generate healing potions.
            for (int i = 0; ; i++)
            {
                HealingPotion potion = new HealingPotion("HP_" + i);
                // Check if the healing potion will not exceed the maximum amount of HP.
                if (hpLeftToSpend - potion.HPvalue >= 0)
                {
                    // Decrease the maximum amount of HP that can still be allocated to healing potions.
                    hpLeftToSpend -= (int)potion.HPvalue;
                    items.Add(potion);
                    // Add potion to random node in dungeon.
                    allNodes[RandomGenerator.rnd.Next(allNodes.Count)].items.Add(potion);
                }
                else
                {
                    break;
                }
            }

            // Generate crystals.
            for (int i = 0; i < allNodes.Count; i++)
            {
                // Each node has 10% chance to spawn a crystal.
                if (RandomGenerator.rnd.Next(10) == 0)
                {
                    Crystal crystal = new Crystal("Cry_" + i);
                    items.Add(crystal);
                    // Add crystal to node.
                    allNodes[i].items.Add(crystal);
                }
            }
        }