Пример #1
0
        /// <summary>
        /// Generate the dungeon graph and layout
        /// </summary>
        /// <param name="totalTrials">number of trials used if any of the graph or map generation fails</param>
        /// <param name="graphTrials">number of trials to generate graph before consider it a fail</param>
        /// <param name="mapTrials">number of trials to generate the layout before consider it a fail</param>
        /// <returns>the generated graph and layout</returns>
        public static DungeonResult GenerateDungeon(int totalTrials  = 100, int graphTrials = 100, int mapTrials      = 100,
                                                    int recipeLength = 1, Random randomGen  = null, string recipeName = "graphRecipe")
        {
            Graph resultGraph = null;

            LayoutGrammar.Map resultMap = null;

            for (int i = 0; i < totalTrials; i++)
            {
                var       grammarPath = "FloorGeneration/";
                Generator mg          = CreateGenerator(grammarPath, randomGen);
                for (int j = 0; j < graphTrials; j++)
                {
                    TextAsset graphStartAsset  = Resources.Load <TextAsset>(grammarPath + "graphStart");
                    TextAsset graphRecipeAsset = Resources.Load <TextAsset>(grammarPath + recipeName);
                    const int numNodes         = 4;
                    resultGraph = mg.GenerateDungeonFromString(graphStartAsset.text, graphRecipeAsset.text, numNodes,
                                                               recipeLength);

                    if (resultGraph != null && Helper.CheckIsSolvable(resultGraph, resultGraph.nodes[0]))
                    {
                        break;
                    }

                    resultGraph = null;
                }

                if (resultGraph == null)
                {
                    continue;
                }

                LayoutGrammar.Generator lg = new LayoutGrammar.Generator(randomGen);
                for (int j = 0; j < mapTrials; j++)
                {
                    resultMap = lg.GenerateDungeon(resultGraph);
                    if (resultMap != null && Helper.CheckIsSolvable(resultMap.Get2DMap(), resultMap.GetCell(0)))
                    {
                        break;
                    }

                    resultMap = null;
                }

                if (resultMap == null)
                {
                    continue;
                }

                break;
            }

            return(new DungeonResult(resultGraph, resultMap));
        }
Пример #2
0
        /// <summary>
        /// Generate the dungeon graph and layout
        /// </summary>
        /// <param name="totalTrials">number of trials used if any of the graph or map generation fails</param>
        /// <param name="graphTrials">number of trials to generate graph before consider it a fail</param>
        /// <param name="mapTrials">number of trials to generate the layout before consider it a fail</param>
        /// <returns>the generated graph and layout</returns>
        static DungeonResult generateDungeon(int totalTrials = 100, int graphTrials = 100, int mapTrials = 100)
        {
            MissionGraph.Graph resultGraph = null;
            LayoutGrammar.Map  resultMap   = null;

            for (int i = 0; i < totalTrials; i++)
            {
                MissionGraph.Generator mg = new MissionGraph.Generator(new Random());
                mg.loadPatterns("grammar/");
                for (int j = 0; j < graphTrials; j++)
                {
                    resultGraph = mg.GenerateDungeon("graphStart.txt", "graphRecipe.txt");
                    if (resultGraph != null && Helper.checkIsSolvable(resultGraph, resultGraph.nodes[0]))
                    {
                        break;
                    }
                    else
                    {
                        resultGraph = null;
                    }
                }
                if (resultGraph == null)
                {
                    continue;
                }

                LayoutGrammar.Generator lg = new LayoutGrammar.Generator(new Random());
                for (int j = 0; j < mapTrials; j++)
                {
                    resultMap = lg.generateDungeon(resultGraph);
                    if (resultMap != null && Helper.checkIsSolvable(resultMap.get2DMap(), resultMap.getCell(0)))
                    {
                        break;
                    }
                    else
                    {
                        resultMap = null;
                    }
                }
                if (resultMap == null)
                {
                    continue;
                }
                break;
            }
            return(new DungeonResult(resultGraph, resultMap));
        }
Пример #3
0
 /// <summary>
 /// A structure to hold both the mission graph and layout
 /// </summary>
 /// <param name="missionGraph">the generated mission graph</param>
 /// <param name="layoutMap">the level layout</param>
 public DungeonResult(Graph missionGraph, LayoutGrammar.Map layoutMap)
 {
     this.missionGraph = missionGraph;
     this.layoutMap    = layoutMap;
 }
Пример #4
0
        /// <summary>
        /// Generate a map layout that correspond to the input mission graph
        /// </summary>
        /// <param name="graph">the mission graph that need to be mapped to a 2D layout</param>
        /// <returns>a 2D layout of the mission graph</returns>
        public Map generateDungeon(MissionGraph.Graph graph)
        {
            Map result = new Map(this.random);

            result.initializeCell(graph.nodes[0]);
            #region  make initial dungeon
            List <MissionGraph.Node>            open      = new List <MissionGraph.Node>();
            Dictionary <MissionGraph.Node, int> parentIDs = new Dictionary <MissionGraph.Node, int>();
            foreach (MissionGraph.Node child in graph.nodes[0].getChildren())
            {
                open.Add(child);
                parentIDs.Add(child, 0);
            }
            HashSet <MissionGraph.Node> nodes = new HashSet <MissionGraph.Node>();
            nodes.Add(graph.nodes[0]);
            while (open.Count > 0)
            {
                MissionGraph.Node current = open[0];
                open.RemoveAt(0);
                if (nodes.Contains(current))
                {
                    continue;
                }
                nodes.Add(current);
                if (!result.addCell(current, parentIDs[current]))
                {
                    return(null);
                }
                foreach (MissionGraph.Node child in current.getChildren())
                {
                    if (!parentIDs.ContainsKey(child))
                    {
                        if (current.type == MissionGraph.NodeType.Lock ||
                            current.type == MissionGraph.NodeType.Puzzle)
                        {
                            parentIDs.Add(child, current.id);
                        }
                        else
                        {
                            parentIDs.Add(child, parentIDs[current]);
                        }
                    }
                    open.Add(child);
                }
            }
            #endregion

            #region make lever connections
            open.Clear();
            nodes.Clear();
            open.Add(graph.nodes[0]);
            while (open.Count > 0)
            {
                MissionGraph.Node current = open[0];
                open.RemoveAt(0);
                if (nodes.Contains(current))
                {
                    continue;
                }
                nodes.Add(current);
                foreach (MissionGraph.Node child in current.getChildren())
                {
                    Cell from = result.getCell(current.id);
                    Cell to   = result.getCell(child.id);
                    if (current.type == MissionGraph.NodeType.Lever)
                    {
                        if (!result.makeConnection(from, to, nodes.Count * nodes.Count))
                        {
                            return(null);
                        }
                    }
                    open.Add(child);
                }
            }
            #endregion
            return(result);
        }