Beispiel #1
0
        public Battle(BattleParams param, Navmesh navmesh, LuaEnv luaEnv)
        {
            this.rid  = param.id;
            this.data = ModelFactory.GetBattleData(Utils.GetIDFromRID(this.rid));

            this._luaEnv        = luaEnv;
            this._context       = new UpdateContext();
            this._entityManager = new EntityManager(this);
            this._buffManager   = new BuffManager(this);
            this._random        = new ConsistentRandom(param.rndSeed);
            this._pathManager   = new NavMeshProxy();
            this._timer0        = new TimeScheduler();
            this._pathManager.Create(navmesh);

            if (!string.IsNullOrEmpty(this.data.script))
            {
                this._script = new Script(this, this._luaEnv, this.data.script);
                this._script.Call(Script.S_ON_BATTLE_INITIALIZED);
            }

            this.CreatePlayers(param);

            foreach (KeyValuePair <string, BattleData.Structure> kv in this.data.structures)
            {
                BattleData.Structure def = this.data.structures[kv.Key];
                this.CreateBio(def.id, def.pos, def.dir, def.team);
            }

            foreach (KeyValuePair <string, BattleData.Neutral> kv in this.data.neutrals)
            {
                BattleData.Neutral def = this.data.neutrals[kv.Key];
                this.CreateBio(def.id, def.pos, def.dir, def.team);
            }
        }
    /// <summary>
    /// Build connections inside maze frame using hunt and kill algorithm.
    /// </summary>
    /// <param name="mazeFrame">Maze frame object.</param>
    /// <param name="huntAfterSegmentLength">Enter hunting mode after segment has grown to this length in world units,
    /// defaults to unlimited (uses smalles Scale value.</param>
    /// <param name="huntProbability">Probability of starting hunt when it arrives, defaults to 0.50.</param>
    protected void BuildMazeFrameUsingHuntAndKill(ref MazeFrame mazeFrame, float huntAfterSegmentLength = float.PositiveInfinity, float huntProbability = 0.50f)
    {
        if (mazeRandGen == null)
        {
            mazeRandGen = new ConsistentRandom();
        }
        if (randGen == null)
        {
            randGen = new ConsistentRandom();
        }

        // Build maze using hunt and kill

        /* 1) Make the initial node the current node and mark it as visited
         * 2) While there are unvisited nodes
         *      1) If the current node has any neighbours which have not been visited
         *          1) Choose randomly one of the unvisited neighbours
         *          2) Remove the wall between the current node and the chosen node
         *          3) Make the chosen node the current node and mark it as visited and add to targets
         *      2) Find random unvisited node next to visited node
         *          1) Make it the current node and mark it as visited and add to targets
         */

        // Check start/end node active status
        if (!mazeFrame.StartNode.IsActive || !mazeFrame.EndNode.IsActive)
        {
            throw new System.Exception("Start/end nodes are required to be active.");
        }

        // Set storage of visit flags and create list for hunt to target
        int nNodesVisited = 0;
        Dictionary <string, bool> isVisited = new Dictionary <string, bool>(mazeFrame.Nodes.Count);

        foreach (MazeNode nd in mazeFrame.Nodes)
        {
            if (nd.IsActive)
            {
                isVisited.Add(nd.Identifier, false);
            }
            else
            {
                isVisited.Add(nd.Identifier, true); nNodesVisited++;
            }
        }
        List <MazeNode> targets = new List <MazeNode>(Mathf.RoundToInt(mazeFrame.Nodes.Count / 2f)); // half of full maze should be more than enough

        // Ignore nodes without neighbors
        foreach (MazeNode nd in mazeFrame.Nodes)
        {
            if (nd.AllNeighbors.Count == 0)
            {
                isVisited[nd.Identifier] = true; nNodesVisited++;
            }
        }

        // Determine huntAfterNConnections
        int huntAfterNConnections = Mathf.RoundToInt(huntAfterSegmentLength / Scale.ComponentMin());

        //Initialize near startNode
        MazeNode currentNode = mazeFrame.StartNode;

        isVisited[currentNode.Identifier] = true;
        nNodesVisited++;
        targets.Add(currentNode);
        int count            = 0;
        int nConnectionsMade = 0;

        while (nNodesVisited < mazeFrame.Nodes.Count)
        {
            // See if there are unvisited neighbors
            List <MazeNode> unvisitedNeighbors = new List <MazeNode>();
            foreach (MazeNode nb in currentNode.AllNeighbors)
            {
                if (!isVisited[nb.Identifier])
                {
                    unvisitedNeighbors.Add(nb);
                }
            }

            if (nConnectionsMade >= huntAfterNConnections)
            {
                if (mazeRandGen.NextDouble() < huntProbability)
                {
                    nConnectionsMade = 0;
                }
            }
            if (unvisitedNeighbors.Count > 0 && nConnectionsMade < huntAfterNConnections)
            {
                // Select random neighbor (2)
                MazeNode selNode = unvisitedNeighbors[mazeRandGen.Next(unvisitedNeighbors.Count)];
                // Add as connected neighbor to current node object(3) and vice versa
                currentNode.AddConnectionByReference(selNode);
                // Switch to new node(4) and record visit
                currentNode = selNode;
                isVisited[currentNode.Identifier] = true;
                nNodesVisited++;
                targets.Add(currentNode);
                nConnectionsMade++;
            }
            else
            {
                // Find random unvisited node neighboring a visited node
                List <int> targetInd = new List <int>(targets.Count);
                for (int i = 0; i < targets.Count; i++)
                {
                    targetInd.Insert(i, i);
                }
                bool             found           = false;
                Stack <MazeNode> targetsToRemove = new Stack <MazeNode>();
                int huntCount = 0;
                while (!found)
                {
                    // sample a random target node
                    int      randInd    = targetInd[mazeRandGen.Next(targetInd.Count)];
                    MazeNode currTarget = targets[randInd];
                    // See if target has unvisited neighbors
                    unvisitedNeighbors = new List <MazeNode>();
                    foreach (MazeNode nb in currTarget.AllNeighbors)
                    {
                        if (!isVisited[nb.Identifier])
                        {
                            unvisitedNeighbors.Add(nb);
                        }
                    }
                    // if it has no unvisited neighors, remove target from list and go again, otherwise, pick random unvisited neighbor
                    if (unvisitedNeighbors.Count == 0)
                    {
                        targetInd.Remove(randInd);
                        targetsToRemove.Push(currTarget);
                    }
                    else
                    {
                        // Select random neighbor and set as currentNode
                        currentNode = currTarget;
                        found       = true;
                    }
                    // Reset connections counter
                    nConnectionsMade = 0;

                    // Safety check
                    huntCount++;
                    if (huntCount > targets.Count)
                    {
                        throw new System.Exception("Hunt did not terminate correctly.");
                    }
                }
                // Remove nodes from targets that had no unvisisted neigbors
                while (targetsToRemove.Count > 0)
                {
                    targets.Remove(targetsToRemove.Pop());
                }
            }

            // Safety check
            count++;
            if (targets.Count == 0 || count > Mathf.Pow(mazeFrame.Nodes.Count, 2))
            {
                throw new System.Exception("Hunt and kill loop did not terminate correctly.");
            }
        }

        // Sanity check
        foreach (MazeNode nb in mazeFrame.Nodes)
        {
            if (!isVisited[nb.Identifier])
            {
                throw new System.Exception("Hunt and kill loop did not terminate correctly.");
            }
        }
    }
    /// <summary>
    /// /// Build connections inside maze frame using recursive backtracking algorithm.
    /// </summary>
    /// <param name="mazeFrame">Maze frame object.</param>
    protected void BuildMazeFrameUsingRecursiveBacktracking(ref MazeFrame mazeFrame)
    {
        if (mazeRandGen == null)
        {
            mazeRandGen = new ConsistentRandom();
        }
        if (randGen == null)
        {
            randGen = new ConsistentRandom();
        }

        // Build maze using recursive backtracking
        // From wikipedia:

        /* 1) Make the initial node the current node and mark it as visited
         * 2) While there are unvisited nodes
         *      1) If the current node has any neighbours which have not been visited
         *          1) Choose randomly one of the unvisited neighbours
         *          2) Push the current node to the stack
         *          3) Remove the wall between the current node and the chosen node
         *          4) Make the chosen node the current node and mark it as visited
         *      2) Else if stack is not empty
         *          1) Pop a node from the stack
         *          2) Make it the current node
         */

        // Check start/end node active status
        if (!mazeFrame.StartNode.IsActive || !mazeFrame.EndNode.IsActive)
        {
            throw new System.Exception("Start/end nodes are required to be active.");
        }

        // Set storage of visit flags and create stack for visisted nodes
        int nNodesVisited = 0;
        Dictionary <string, bool> isVisited = new Dictionary <string, bool>(mazeFrame.Nodes.Count);

        foreach (MazeNode nd in mazeFrame.Nodes)
        {
            if (nd.IsActive)
            {
                isVisited.Add(nd.Identifier, false);
            }
            else
            {
                isVisited.Add(nd.Identifier, true); nNodesVisited++;
            }
        }
        Stack <MazeNode> nodeTrack = new Stack <MazeNode>(mazeFrame.Nodes.Count); // FIXME does preallocating help performance here?

        // Ignore nodes without neighbors
        foreach (MazeNode nd in mazeFrame.Nodes)
        {
            if (nd.AllNeighbors.Count == 0)
            {
                isVisited[nd.Identifier] = true; nNodesVisited++;
            }
        }

        //Initialize near startNode
        MazeNode currentNode = mazeFrame.StartNode;

        isVisited[currentNode.Identifier] = true;
        nNodesVisited++;
        while (nNodesVisited < mazeFrame.Nodes.Count)
        {
            // See if there are unvisited neighbors
            List <MazeNode> unvisitedNeighbors = new List <MazeNode>();
            foreach (MazeNode nb in currentNode.AllNeighbors)
            {
                if (!isVisited[nb.Identifier])
                {
                    unvisitedNeighbors.Add(nb);
                }
            }

            if (unvisitedNeighbors.Count != 0)
            {
                // Add current node to stack (1)
                nodeTrack.Push(currentNode);
                // Select random neighbor (2)
                //MazeNode selNode = RandomlySelectNodeWithBiasTowardsForwards(currentNode, unvisitedNeighbors);
                //Node selNode = RandomlySelectNodeWithBiasTowardsNode(currentNode, unvisitedNeighbors, endNode.AllNeighbors[0], 2,mazeRandGen);
                MazeNode selNode = unvisitedNeighbors[mazeRandGen.Next(unvisitedNeighbors.Count)];
                // Add as connected neighbor to current node object(3) and vice versa
                currentNode.AddConnectionByReference(selNode);
                // Switch to new node(4) and record visit
                currentNode = selNode;
                isVisited[currentNode.Identifier] = true;
                nNodesVisited++;
            }
            else if ((unvisitedNeighbors.Count == 0) && (nodeTrack.Count != 0))
            {
                currentNode = nodeTrack.Pop();
            }

            // Safety check
            if ((nodeTrack.Count == 0) && (nNodesVisited > mazeFrame.Nodes.Count))
            {
                throw new System.Exception("Recursive backtracking loop did not terminate correctly.");
            }
        }

        // Sanity check
        foreach (MazeNode nb in mazeFrame.Nodes)
        {
            if (isVisited[nb.Identifier] == false)
            {
                throw new System.Exception("Recursive backtracking loop did not terminate correctly.");
            }
        }
    }
Beispiel #4
0
    private IEnumerator BuildNewMaze()
    {
        float mazeFrameElementsBuilt = 0;

        mazeFrameMeshesArePresent = false;
        // Initialize maze creator
        MazeFrameCreator mazeFrameCreator = null;

        switch (mazeShape)
        {
        case 0:
        {
            mazeFrameCreator = new MazeFrameCreatorSquare3D(mazeSize, nQuadrants)
            {
                Scale = mazeScale, Jitter = mazeJitter
            }; break;
        }

        case 1:
        {
            mazeFrameCreator = new MazeFrameCreatorMeshIcosahedron(nDivisions, nQuadrants)
            {
                Scale = mazeScale, Jitter = mazeJitter
            }; break;
        }
        }
        // Set random seed selector
        System.Random randGen = new ConsistentRandom();
        // Randomize order of difficulties
        int[] randomQuadrantIndices = Utilities.RandomIndices(nQuadrants);
        // Generate maze!
        if (nQuadrants != 0 && nQuadrants != difficulties.Length)
        {
            throw new System.ArgumentException("When using quadrants, nQuadrants and nDifficulties should be equal.");
        }
        List <MazeFrame> singleMazeFrames = new List <MazeFrame>(difficulties.Length);

        for (int iDifficulty = 0; iDifficulty < difficulties.Length; iDifficulty++)
        {
            List <MazeFrame> singleFrameSections = new List <MazeFrame>(nSections);
            for (int iSections = 0; iSections < nSections; iSections++)
            {
                // Create sections
                int quadrantInd;
                //if (nQuadrants != 0) { quadrantInd = iDifficulty; }
                if (nQuadrants != 0)
                {
                    quadrantInd = randomQuadrantIndices[iDifficulty];
                }
                else
                {
                    quadrantInd = 0;
                }
                MazeFrame currSection    = null;
                int       currDifficulty = difficulties[iDifficulty];
                int       currSeedInd    = randGen.Next(seedData[quadrantInd].seeds[currDifficulty].Length);
                mazeFrameCreator.RandomSeed = seedData[quadrantInd].seeds[currDifficulty][currSeedInd];
                //mazeFrameCreator.RandomSeed = seedData[quadrantInd].seeds[iDifficulty][iSections];
                if (nQuadrants == 0)
                {
                    currSection = mazeFrameCreator.GenerateMaze();
                }
                else
                {
                    currSection = mazeFrameCreator.GenerateEmptyMazeFrame();
                    mazeFrameCreator.GenerateMaze(ref currSection, quadrantInd);
                    currSection.SetOnShortestPath(currSection.Quadrants[quadrantInd], 0); // HACKY
                }
                //currSection.KeepOnlyShortestPathConnections();
                //currSection.AddPathSegments();
                // DEBUG
                if (nQuadrants != 0)
                {
                    Debug.Log(currSection.GetNIntersectionsOnPath()[0] + "  " + currSection.GetDifficulty(quadrantInd)[0] + " - " + seedData[quadrantInd].difficulties[currDifficulty][currSeedInd]);
                }
                else
                {
                    Debug.Log(currSection.GetNIntersectionsOnPath()[0] + "  " + currSection.GetDifficulty()[0]);
                }
                // DEBUG
                singleFrameSections.Add(currSection);
                mazeFrameElementsBuilt++;
                LevelBuiltProgressPercentage = (mazeFrameElementsBuilt / (difficulties.Length * nSections)) / 2;
                yield return(null);
            }
            MazeFrame currSingleFrame;
            if (singleFrameSections.Count > 1)
            { //MazeFrame currSingleFrame = MazeFrame.Concatenate(singleFrameSections, mazeFrameCreator.Scale, mazeDirection);
                currSingleFrame = MazeFrame.CombineShrink(singleFrameSections, shrinkFactor);
            }
            else
            {
                currSingleFrame = singleFrameSections[0];
            }
            currSingleFrame.AddOffsetStartNode(Vector3.Scale(mazeDirection, mazeScale) * startOffsetFactor, true);
            currSingleFrame.AddOffsetEndNode(Vector3.Scale(mazeDirection, mazeScale) * endOffsetFactor, true);
            for (int iInc = 0; iInc < iDifficulty; iInc++)
            {
                currSingleFrame.IncrementShortestPathIndices();
            }
            singleMazeFrames.Add(currSingleFrame);
        }
        if (singleMazeFrames.Count > 1)
        {
            mazeFrame = MazeFrame.Merge(singleMazeFrames);
        }
        else
        {
            mazeFrame = singleMazeFrames[0];
        }
        //mazeFrame.ConnectUnconnectedNodes();
        mazeFrame.AddPathSegments();
        yield return(null);

        // Populate maze and get return splines and maze objects
        mazePopulator.PopulateWithSplineFittedBars(mazeFrame, ref mazeFrameSplines, ref mazeObjects, objectScaling);
        //mazePopulator.PopulateWithSplineFittedCylinders(mazeFrame, ref mazeFrameSplines, ref mazeObjects, objectScaling);

        // Wait till population is complete
        while (!mazeFrameMeshesArePresent)
        {
            if (mazePopulator.MazeObjectsPlaced == mazeFrameSplines.SplineSegments.Count)
            {
                mazeFrameMeshesArePresent = true;
            }
            yield return(null);
        }

        // Create and Initialize gravity frame
        gravityFrameController = new GravityFrameController(mazeFrame, mazeFrameSplines, gravJunctionDistFactor, gravPlaneWidth);
        yield return(null);


        // Place others
        PlacePlayerAndCamera();
        PlaceEndPortal();
        PlaceCubeOfDeath();
        PlaceMindWarpTriggers();
    }
    /// <summary>
    /// Find random integer in list with integer-specific probability specified by <paramref name="weightsArray"/>.
    /// </summary>
    /// <returns>Random integer from list.</returns>
    /// <param name="intArray">Array of integers to get random integer from.</param>
    /// <param name="weightsArray">Weights specifying integer-specific probability (can be bigger than 1) </param>
    public static int GetRandomIntWeightedProbability(int[] intArray, float[] weightsArray, ConsistentRandom randGen)
    {
        // Find random integer using integer-specific weights

        // check inputs
        if (intArray.Length != weightsArray.Length)
        {
            throw new System.ArgumentException("Input arrays should be of equal length.");
        }

        // Rescale weights
        float sum = 0;

        for (int i = 0; i < weightsArray.Length; i++)
        {
            sum = sum + weightsArray[i];
        }
        for (int i = 0; i < weightsArray.Length; i++)
        {
            weightsArray[i] = weightsArray[i] / sum;
        }
        if (Mathf.Approximately(sum, 0))
        {
            throw new System.ArgumentException("Sum of weights cannot be zero.");
        }

        // Find index using above probabilities
        float p   = (float)randGen.NextDouble();
        int   ind = -1;

        for (int i = 0; i < weightsArray.Length; i++)
        {
            p = p - weightsArray[i];
            if (p <= 0)
            {
                ind = i;
                break;
            }
        }
        if (ind == -1)
        {
            throw new System.Exception("Weighted probability selection failed.");
        }
        return(ind);

        //// DEBUG
        //string str = "";
        //for (int i = 0; i < weightsArray.Length; i++) { str = str + "-" + weightsArray[i]; }
        //Debug.Log(str);
        //// DEBUG
    }
    private IEnumerator CreateMazesFromSeeds()
    {
        // Parse difficulty
        float[,] difficultyBounds = new float[nDifficulties, 2];
        float difficultyStartPad = difficultyLimits[0];
        float difficultyEndPad   = 1 - difficultyLimits[1];
        float diffRange          = 1 - (difficultyStartPad + difficultyEndPad);
        float currDiffSize       = difficultySize * diffRange;
        float diffSpacing        = (diffRange - (nDifficulties * currDiffSize)) / (nDifficulties - 1);

        if (diffSpacing < 0)
        {
            throw new System.Exception("Overlapping difficulties.");
        }
        for (int i = 0; i < (nDifficulties); i++)
        {
            difficultyBounds[i, 0] = difficultyStartPad + (currDiffSize + diffSpacing) * i;
            difficultyBounds[i, 1] = difficultyBounds[i, 0] + currDiffSize;
        }
        string boundsDisp = difficultyBounds[0, 0] + ">x<=" + difficultyBounds[0, 1];

        for (int i = 1; i < nDifficulties; i++)
        {
            boundsDisp = boundsDisp + " | " + difficultyBounds[i, 0] + ">x<=" + difficultyBounds[i, 1];
        }
        Debug.Log(boundsDisp);

        //seedList[0] = new List<int>(nMazes); // difficulty <=.20
        //seedList[0] = new List<int>(nMazes); // difficulty >.20 <=.40
        //seedList[0] = new List<int>(nMazes); // difficulty >.40 <=.60
        //seedList[0] = new List<int>(nMazes); // difficulty >.60 <=80
        //seedList[0] = new List<int>(nMazes); // difficulty >.80 <=1

        // Set random seed
        int mainRandomSeed = System.Environment.TickCount;
        ConsistentRandom mainRandomGenenerator = new ConsistentRandom(mainRandomSeed);

        // Setup maze creators
        MazeFrameCreator mazeFrameCreator = null;

        switch (mazeShape)
        {
        case 0: { mazeFrameCreator = new MazeFrameCreatorSquare3D(mazeSize, nQuadrants); break; }

        case 1: { mazeFrameCreator = new MazeFrameCreatorMeshIcosahedron(divisions, nQuadrants); break; }
        }
        mazeFrameCreator.Scale = mazeScale; // Used in hunt and kill for determining  when to hunt

        // Create level from new seeds
        int ittMax = 1;

        if (nQuadrants != 0)
        {
            ittMax = nQuadrants;
        }
        for (int iQuadrant = 0; iQuadrant < ittMax; iQuadrant++)
        {
            // Setup seed/difficulty list
            List <List <int> > seedList = new List <List <int> >(nDifficulties);
            for (int i = 0; i < nDifficulties; i++)
            {
                seedList.Add(new List <int>(nMazes));
            }
            List <List <float> > difficultyList = new List <List <float> >(nDifficulties);
            for (int i = 0; i < nDifficulties; i++)
            {
                difficultyList.Add(new List <float>(nMazes));
            }

            bool done  = false;
            int  count = 0;
            while (!done)
            {
                // set new seed
                int mazeSeed = mainRandomGenenerator.Next();
                mazeFrameCreator.RandomSeed = mazeSeed;
                // get maze
                MazeFrame mazeFrame = mazeFrameCreator.GenerateEmptyMazeFrame();
                if (nQuadrants != 0)
                {
                    mazeFrame.SetActiveQuadrant(iQuadrant);
                }
                mazeFrameCreator.GenerateMaze(ref mazeFrame);
                // Save according to difficulty
                float difficulty;
                if (nQuadrants == 0)
                {
                    difficulty = mazeFrame.GetDifficulty()[0];
                }
                else
                {
                    difficulty = mazeFrame.GetDifficulty(iQuadrant)[0];
                }
                for (int i = 0; i < nDifficulties; i++)
                {
                    if (difficulty > difficultyBounds[i, 0] && difficulty <= difficultyBounds[i, 1] && seedList[i].Count < nMazes)
                    {
                        seedList[i].Add(mazeSeed);
                        difficultyList[i].Add(difficulty);
                    }
                }

                // Check end condition
                done = true;
                for (int i = 0; i < nDifficulties; i++)
                {
                    done = done && seedList[i].Count == nMazes;
                }

                // safety check
                count++;
                if (count == count * 100)
                {
                    throw new System.Exception("Something went wrong.");
                }

                // Display progress
                string disp;
                if (nQuadrants == 0)
                {
                    disp = count + ": " + seedList[0].Count;
                }
                else
                {
                    disp = "quadrant" + (iQuadrant + 1) + "of" + nQuadrants + " | " + count + ": " + seedList[0].Count;
                }
                for (int i = 1; i < nDifficulties; i++)
                {
                    disp = disp + ", " + seedList[i].Count;
                }
                Debug.Log(disp + "  | d = " + difficulty.ToString("0.0000"));

                // Yield
                WaitForSecondsRealtime wait = null;
                if (wait == null)
                {
                    wait = new WaitForSecondsRealtime(0.0001f);
                }
                if ((count % 10) == 0)
                {
                    yield return(wait);
                }
            }

            // Convert to SeedData object
            if (nDifficulties == 5)
            {
                seedData = new SeedData(seedList[0].ToArray(), seedList[1].ToArray(), seedList[2].ToArray(), seedList[3].ToArray(), seedList[4].ToArray(),
                                        difficultyList[0].ToArray(), difficultyList[1].ToArray(), difficultyList[2].ToArray(), difficultyList[3].ToArray(), difficultyList[4].ToArray(),
                                        mazeSize, mazeFrameCreator.GetType().FullName);
            }
            else if (nDifficulties == 4)
            {// Convert to SeedData object
                seedData = new SeedData(seedList[0].ToArray(), seedList[1].ToArray(), seedList[2].ToArray(), seedList[3].ToArray(),
                                        difficultyList[0].ToArray(), difficultyList[1].ToArray(), difficultyList[2].ToArray(), difficultyList[3].ToArray(),
                                        mazeSize, mazeFrameCreator.GetType().FullName);
            }
            else if (nDifficulties == 3)
            {// Convert to SeedData object
                seedData = new SeedData(seedList[0].ToArray(), seedList[1].ToArray(), seedList[2].ToArray(),
                                        difficultyList[0].ToArray(), difficultyList[1].ToArray(), difficultyList[2].ToArray(),
                                        mazeSize, mazeFrameCreator.GetType().FullName);
            }
            else if (nDifficulties == 2)
            {// Convert to SeedData object
                seedData = new SeedData(seedList[0].ToArray(), seedList[1].ToArray(),
                                        difficultyList[0].ToArray(), difficultyList[1].ToArray(),
                                        mazeSize, mazeFrameCreator.GetType().FullName);
            }
            else
            {
                throw new System.Exception("Requested nDifficulty not implemented due to the stupid save part.");
            }

            // Save to disk
            string creatorName = "";
            string filePath;
            switch (mazeShape)
            {
            case 0: { creatorName = mazeFrameCreator.GetType().FullName + "-" + mazeSize.ToString() + "-" + mazeScale.ToString(); break; }

            case 1: { creatorName = mazeFrameCreator.GetType().FullName + "-" + divisions.ToString() + "-" + mazeScale.ToString(); break; }
            }
            if (nQuadrants != 0)
            {
                filePath = filePathBase + "-" + creatorName + "-" + "quadrant" + (iQuadrant + 1) + "of" + nQuadrants + ".json";
            }
            else
            {
                filePath = filePathBase + "-" + creatorName + ".json";
            }
            SeedDataController.SaveSeedData(seedData, filePath);
        }
        Debug.Log("Done!");
        Debug.Break();

#if UNITY_EDITOR
        UnityEditor.EditorApplication.isPlaying = false;
#endif
    }