/// <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()); } }
/// <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); }