Beispiel #1
0
        /// <summary>
        /// Creates the layout for the random level.
        /// </summary>
        private void Generate()
        {
            Layout = new LevelLayout();

            branchEnds = new HashSet <Vector2Int>();
            seeds      = new HashSet <Vector2Int>();

            Layout.AddRoom(Vector2Int.zero);
            branchEnds.Add(Vector2Int.zero);

            int remainingSeeds = seedCount;

            while (remainingSeeds > 0)
            {
                Vector2Int[] seedCandidateArray = branchEnds.ToArray();

                // There's a slim but real chance that no more valid seedCandidatesExist.
                // If this occurs, we'll have to make some up.
                if (seedCandidateArray.Length == 0)
                {
                    seedCandidateArray = Layout.RoomsWithMissingNeighbors();
                }

                PlantSeed(seedCandidateArray[Random.Range(0, seedCandidateArray.Length)]);

                remainingSeeds--;
            }

            // Now to make all the remaining branch ends have a special purpose.
            List <Vector2Int> pointsOfInterest;            //new List<Vector2Int>(seeds.Union(branchEnds));

            if (branchEnds.Count < 2)
            {
                // Since we have less than two branchEnds (somehow?), we'll include seeds too.
                pointsOfInterest = new List <Vector2Int>(seeds.Union(branchEnds));
            }
            else
            {
                // We have enough branch ends, so we'll just use those.
                pointsOfInterest = new List <Vector2Int>(branchEnds);
            }

            // First, we'll select a room for the entry and exit.
            int randomIndex = Random.Range(0, pointsOfInterest.Count);

            Layout.GetRoom(pointsOfInterest[randomIndex]).Purpose = RoomPurpose.Entry;
            pointsOfInterest.RemoveAt(randomIndex);

            randomIndex = Random.Range(0, pointsOfInterest.Count);
            Layout.GetRoom(pointsOfInterest[randomIndex]).Purpose = RoomPurpose.Exit;
            pointsOfInterest.RemoveAt(randomIndex);

            // Then we'll mark the rest of the rooms of interest as being special.
            foreach (Vector2Int point in pointsOfInterest)
            {
                Layout.GetRoom(point).Purpose = RoomPurpose.Special;
            }


            if (debugGeneration)
            {
                Debug.Log("Branch ends: " + string.Join(", ", branchEnds.Select(x => x.ToString()).ToArray()));
                Debug.Log("Seeds: " + string.Join(", ", seeds.Select(x => x.ToString()).ToArray()));
                Debug.Log(Layout.ToString());
            }
        }
Beispiel #2
0
        /// <summary>
        /// This'll create a branch. It will not cross over itself,
        /// and considers the start point part of itself.
        /// </summary>
        /// <param name="startPoint"></param>
        /// <param name="dir"></param>
        /// <returns>The end point. If length is zero, this is the startPoint.</returns>
        private Vector2Int GrowBranch(Vector2Int startPoint, int length, Direction dir)
        {
            HashSet <Vector2Int> path = new HashSet <Vector2Int>();

            path.Add(startPoint);

            Vector2Int endPoint = startPoint;

            // Only do anything if we're allowed to make at least one thing.
            if (length >= 1)
            {
                endPoint += dir.ToVector();
                Layout.AddRoom(endPoint);
                Layout.ConnectRooms(startPoint, endPoint);
                path.Add(endPoint);

                // Set this to true if we can't grow for any reason.
                bool stuck = false;

                // Subtract one because we start with the start point in there.
                while (path.Count - 1 < length && !stuck)
                {
                    List <Vector2Int> adjacentPoints = LevelLayout.GetAdjacentCoordinates(endPoint).ToList();

                    // We want to choose a direction, but we'll give up if we run out of points.
                    Vector2Int?chosenLocation = null;
                    while (!chosenLocation.HasValue && adjacentPoints.Count > 0)
                    {
                        int randomIndex = Random.Range(0, adjacentPoints.Count);

                        // Basically, if this branch hasn't selected this spot before
                        if (!path.Contains(adjacentPoints[randomIndex]))
                        {
                            chosenLocation = adjacentPoints[randomIndex];
                        }
                        else
                        {
                            adjacentPoints.RemoveAt(randomIndex);
                        }
                    }

                    if (!chosenLocation.HasValue)
                    {
                        stuck = true;
                    }
                    else
                    {
                        Layout.AddRoom(chosenLocation.Value);
                        Layout.ConnectRooms(endPoint, chosenLocation.Value);
                        path.Add(chosenLocation.Value);

                        endPoint = chosenLocation.Value;
                    }
                }                 // while(path.Count -1 < length && !stuck)
            }

            if (debugGeneration)
            {
                Debug.Log("Path taken: " + string.Join(", ", path.Select(x => x.ToString()).ToArray()));
            }

            return(endPoint);
        }