Created
December 28, 2023 11:44
-
-
Save pjmagee/ab5bb8185f838ac13d474ca066015318 to your computer and use it in GitHub Desktop.
My scrappy nodes generator for a text based space rpg
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| void Main() | |
| { | |
| Galaxy galaxyNode = new Galaxy() { Name = "The galaxy", NodeType = NodeType.Galaxy }; | |
| foreach(var regionName in Enumerable.Range(0, 5).Select(x => $"Region {x}")) | |
| { | |
| SpaceRegion spaceNode = new SpaceRegion { Name = regionName, NodeType = NodeType.SpaceRegion }; | |
| foreach (var sectorName in Enumerable.Range(0, 3).Select(x => $"Sector : {x}")) | |
| { | |
| SpaceSector spaceSectorNode = new SpaceSector { Name = sectorName, Parent = spaceNode, NodeType = NodeType.SpaceSector }; | |
| foreach (var starSystemName in Enumerable.Range(0, 3).Select(x => $"System: {x}")) | |
| { | |
| StarSystem starSystemNode = new StarSystem { Name = starSystemName, Parent = spaceSectorNode, NodeType = NodeType.StarSystem }; | |
| foreach(var planetName in Enumerable.Range(0, Random.Shared.Next(10)).Select(x => $"Planet: {x}")) | |
| { | |
| Planet planetNode = new Planet { Name = planetName, Parent = starSystemNode, NodeType = NodeType.Planet }; | |
| foreach(var planetRegionName in Enumerable.Range(0, Random.Shared.Next(10)).Select((i, x) => $"Region: {i}")) | |
| { | |
| PlanetRegion planetRegionNode = new PlanetRegion { Name = planetRegionName, Parent = planetNode, NodeType = NodeType.PlanetRegion }; | |
| foreach (var planetAreaName in Enumerable.Range(0, Random.Shared.Next(10)).Select(x => $"Area: {x}")) | |
| { | |
| NodeType[] areaTypes = [NodeType.Settlement, NodeType.Desert, NodeType.Wasteland, NodeType.Canyon, NodeType.Plains, NodeType.Oasis, NodeType.Graveyard, NodeType.Jungle, NodeType.Savanna, NodeType.Crater]; | |
| var nodeType = areaTypes.OrderBy(x => Random.Shared.Next()).First(); | |
| PlanetArea planetAreaNode = new PlanetArea { Name = nodeType.ToString(), Parent = planetRegionNode, NodeType = NodeType.PlanetArea }; | |
| if (nodeType == NodeType.Settlement) | |
| { | |
| var settlementType = Settlements.OrderBy(x => Random.Shared.Next()).First(); | |
| var settlement = new Settlement { Name = "Settlement Name", Parent = planetAreaNode, NodeType = settlementType }; | |
| if (settlementType == NodeType.City) | |
| { | |
| settlement.AddChild(new Node { Name = "Hospital", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Market", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Cantina", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Starport", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Shuttle", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Government Offices", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Clone Center", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "City Hall", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Garage", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Library", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Jedi Temple", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = FactoryNameGenerator.GenerateFactoryName(), NodeType = NodeType.POI }); | |
| } | |
| else if (settlementType == NodeType.Outpost) | |
| { | |
| settlement.AddChild(new Node { Name = "Small Apartment Block", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Small Shack", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Shuttle", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Clone Center", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Labratory", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = FarmNameGenerator.GenerateFarmName(), NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = FarmNameGenerator.GenerateFarmersMarketName(), NodeType = NodeType.POI }); | |
| } | |
| else if (settlementType == NodeType.Town) | |
| { | |
| settlement.AddChild(new Node { Name = "Shuttle", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Town Hall", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Clone Center", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Small Market", NodeType = NodeType.POI }); | |
| } | |
| else if (settlementType == NodeType.Village) | |
| { | |
| settlement.AddChild(new Node { Name = FarmNameGenerator.GenerateFarmersMarketName(), NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Village hall", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = JunkyardNameGenerator.GenerateJunkyard(), NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Green Houses", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Village Hall", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Low-rise Apartment Block", NodeType = NodeType.POI }); | |
| } | |
| else if (settlementType == NodeType.Settlement) | |
| { | |
| settlement.AddChild(new Node { Name = "Shuttle", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = "Small Market", NodeType = NodeType.POI }); | |
| settlement.AddChild(new Node { Name = FactoryNameGenerator.GenerateFactoryName(), NodeType = NodeType.POI }); | |
| } | |
| planetAreaNode.AddChild(settlement); | |
| } | |
| else if (planetAreaNode.NodeType == NodeType.Desert) | |
| { | |
| planetAreaNode.AddChild(new Node { Name = "Large Cave System", NodeType = NodeType.POI }); | |
| planetAreaNode.AddChild(new Node { Name = "Sand dunes", NodeType = NodeType.POI }); | |
| planetAreaNode.AddChild(new Node { Name = "Sand storm", NodeType = NodeType.POI }); | |
| } | |
| else if (planetAreaNode.NodeType == NodeType.Wasteland) | |
| { | |
| planetAreaNode.AddChild(new Node { Name = "Icy Cavern", NodeType = NodeType.POI }); | |
| } | |
| else if (planetAreaNode.NodeType == NodeType.Canyon) | |
| { | |
| planetAreaNode.AddChild(new Node { Name = "Camp", NodeType = NodeType.POI }); | |
| } | |
| else if (planetAreaNode.NodeType == NodeType.Plains) | |
| { | |
| planetAreaNode.AddChild(new Node { Name = "Abandoned Ranch", NodeType = NodeType.POI }); | |
| planetAreaNode.AddChild(new Node { Name = "Homestead", NodeType = NodeType.POI }); | |
| planetAreaNode.AddChild(new Node { Name = "Temple", NodeType = NodeType.POI }); | |
| } | |
| else if (planetAreaNode.NodeType == NodeType.Oasis) | |
| { | |
| planetAreaNode.AddChild(new Node { Name = "Homestead", NodeType = NodeType.POI }); | |
| planetAreaNode.AddChild(new Node { Name = "Lavish Temple", NodeType = NodeType.POI }); | |
| } | |
| else if (planetAreaNode.NodeType == NodeType.Graveyard) | |
| { | |
| planetAreaNode.AddChild(new Node { Name = "Shack", NodeType = NodeType.POI }); | |
| planetAreaNode.AddChild(new Node { Name = "Cryogen Capsules", NodeType = NodeType.POI }); | |
| planetAreaNode.AddChild(new Node { Name = "Underground Crypts", NodeType = NodeType.POI }); | |
| } | |
| else if (planetAreaNode.NodeType == NodeType.Jungle) | |
| { | |
| planetAreaNode.AddChild(new Node { Name = "Lively ave", NodeType = NodeType.POI }); | |
| } | |
| else if (planetAreaNode.NodeType == NodeType.Savanna) | |
| { | |
| planetAreaNode.AddChild(new Node { Name = "Calm Herbivors", NodeType = NodeType.POI }); | |
| } | |
| else if (planetAreaNode.NodeType == NodeType.Crater) | |
| { | |
| planetAreaNode.AddChild(new Node { Name = "Mining Droids", NodeType = NodeType.POI }); | |
| planetAreaNode.AddChild(new Node { Name = "Excavation", NodeType = NodeType.POI }); | |
| } | |
| else if (planetAreaNode.NodeType == NodeType.Flats) | |
| { | |
| planetAreaNode.AddChild(new Node { Name = "Homestead", NodeType = NodeType.POI }); | |
| planetAreaNode.AddChild(new Node { Name = "Mining Post", NodeType = NodeType.POI }); | |
| } | |
| else if (planetAreaNode.NodeType == NodeType.Forest) | |
| { | |
| planetAreaNode.AddChild(new Node { Name = "Cave", NodeType = NodeType.POI }); | |
| planetAreaNode.AddChild(new Node { Name = "Hidden Cabin", NodeType = NodeType.POI }); | |
| planetAreaNode.AddChild(new Node { Name = "Abandoned Cabin", NodeType = NodeType.POI }); | |
| } | |
| planetRegionNode.AddChild(planetAreaNode); | |
| } | |
| planetNode.AddChild(planetRegionNode); | |
| } | |
| starSystemNode.AddChild(planetNode); | |
| } | |
| spaceSectorNode.AddChild(starSystemNode); | |
| } | |
| spaceNode.AddChild(spaceSectorNode); | |
| } | |
| galaxyNode.AddChild(spaceNode); | |
| } | |
| galaxyNode.GetAllNodes().Where(x => x.NodeType >= NodeType.Planet).Dump(1); | |
| } | |
| public class HasSomething | |
| { | |
| public void Test() | |
| { | |
| var hasHospital = Random.Shared.Next(2) > 0; | |
| var hasTownHall = Random.Shared.Next(2) > 0; | |
| var hasCantina = Random.Shared.Next(2) > 0; | |
| var hasShuttle = Random.Shared.Next(2) > 0; | |
| var hasSchool = Random.Shared.Next(2) > 0; | |
| var hasLibrary = Random.Shared.Next(2) > 0; | |
| var hasShop = Random.Shared.Next(2) > 0; | |
| var hasMarket = Random.Shared.Next(2) > 0; | |
| var hasSpacePort = Random.Shared.Next(2) > 0; | |
| var hasGarage = Random.Shared.Next(2) > 0; | |
| var hasJediTemple = Random.Shared.Next(2) > 0; | |
| var hasArmory = Random.Shared.Next(2) > 0; | |
| var hasGovernmentOffice = Random.Shared.Next(2) > 0; | |
| var hasTrainingFacility = Random.Shared.Next(2) > 0; | |
| var hasAnimalPens = Random.Shared.Next(2) > 0; | |
| var hasResidential = Random.Shared.Next(2) > 0; | |
| var hasMilitary = Random.Shared.Next(2) > 0; | |
| var hasTransportation = Random.Shared.Next(2) > 0; | |
| var hasAgricultural = Random.Shared.Next(2) > 0; | |
| var hasIndustrial = Random.Shared.Next(2) > 0; | |
| } | |
| } | |
| public class WaterNameGenerator | |
| { | |
| private static string[] Adjectives = { "Aquatic", "Blue", "Clear", "Deep", "Fresh", "Glistening", "Hydroelectric", "Hydrophilic", "Hydrophobic", "Hydrothermal", "Icy", "Liquid", "Misty", "Oceanic", "Pristine", "Reflective", "Refreshing", "Saline", "Seabed", "Seaweed", "Shiny", "Stormy", "Tidal", "Turbulent", "Underwater", "Whirlwind", "Wavy" }; | |
| public static string GenerateRiverName() => Adjectives[Random.Shared.Next(Adjectives.Length)] + " River"; | |
| public static string GenerateLakeName() => Adjectives[Random.Shared.Next(Adjectives.Length)] + " Lake"; | |
| } | |
| public class FactoryNameGenerator | |
| { | |
| private static string[] Adjectives = { "Automated", "Busy", "Chemical", "Clean", "Efficient", "Electrical", "Heavy", "Industrial", "Massive", "Mechanical", "Noisy", "Oil", "Powerful", "Robotic", "Smelly", "Smokey", "Steel", "Technological", "Toxic", "Vast" }; | |
| public static string GenerateFactoryName() => Adjectives[Random.Shared.Next(Adjectives.Length)] + " Factory"; | |
| } | |
| public class JunkyardNameGenerator | |
| { | |
| public static string[] Adjectives = { "Abandoned", "Busted", "Crumbling", "Decrepit", "Derelict", "Dilapidated", "Disheveled", "Dismantled", "Fallen", "Grimy", "Grotty", "Neglected", "Old", "Overgrown", "Rundown", "Scrappy", "Shabby", "Tattered", "Torn", "Trashed", "Weathered" }; | |
| public static string GenerateJunkyard() => Adjectives[Random.Shared.Next(Adjectives.Length)] + " Junkyard"; | |
| } | |
| public class FarmNameGenerator | |
| { | |
| private static string[] Adjectives = { "Agricultural", "Blossoming", "Bountiful", "Country", "Fertile", "Flourishing", "Green", "Lively", "Lush", "Natural", "Organic", "Plentiful", "Productive", "Rich", "Rustic", "Scenic", "Secluded", "Spring", "Thriving", "Vibrant", "Wooded" }; | |
| public static string GenerateFarmName() => Adjectives[Random.Shared.Next(Adjectives.Length)] + " Farm"; | |
| public static string GenerateFarmersMarketName() => Adjectives[Random.Shared.Next(Adjectives.Length)] + " Farmers Market"; | |
| } | |
| public enum NodeType | |
| { | |
| // Space | |
| Galaxy, | |
| Space, | |
| SpaceRegion, | |
| SpaceSector, | |
| StarSystem, | |
| SpaceStation, | |
| // Planetary | |
| Planet, | |
| PlanetRegion, | |
| PlanetArea, | |
| // Points of Interest (POI) | |
| POI, | |
| // Landscapes | |
| Desert, | |
| Jungle, | |
| MountainRange, | |
| Crater, | |
| Reefs, | |
| Flats, | |
| Plains, | |
| Oasis, | |
| Canyon, | |
| Forest, | |
| Graveyard, | |
| Wasteland, | |
| Savanna, | |
| // Settlements | |
| Homestead, | |
| Settlement, | |
| City, | |
| Town, | |
| Village, | |
| Outpost, | |
| // Agriculture | |
| Farm, | |
| Fields, | |
| Marsh, | |
| Lagoon, | |
| // Natural Features | |
| Spires, | |
| Ridge, | |
| Rainforest, | |
| Plateau, | |
| Water, | |
| Rural, | |
| Wilderness, | |
| // Ruins and Water Bodies | |
| Ruins, | |
| River, | |
| Lake, | |
| // Default | |
| None | |
| } | |
| public List<NodeType> Settlements = [NodeType.Homestead, NodeType.Settlement, NodeType.City, NodeType.Town, NodeType.Village, NodeType.Outpost]; | |
| public class NPC : IVisitor, IEquatable<NPC> | |
| { | |
| public string Name { get; set; } | |
| public bool Equals(NPC? other) => Name.Equals(other?.Name); | |
| } | |
| public interface IVisitor { } | |
| public interface ITangible { } | |
| public interface INode | |
| { | |
| Guid Id { get; } | |
| string Name { get; } | |
| INode Parent { get; } | |
| HashSet<INode> Siblings { get; } | |
| HashSet<INode> Children { get; } | |
| HashSet<INode> Ancestors { get; } | |
| NodeType NodeType { get; } | |
| } | |
| public class Node : IEquatable<Node>, INode | |
| { | |
| public Guid Id { get; set; } | |
| public string Name { get; set; } | |
| public INode Parent { get; set; } | |
| public HashSet<Node> Siblings { get; set; } | |
| public HashSet<Node> Children { get; set; } | |
| public HashSet<Node> Ancestors { get; set; } | |
| public virtual string[] Adjectives { get; } | |
| public List<IVisitor> Visitors { get; } = new(); | |
| public List<ITangible> Tangibles { get; } = new(); | |
| public virtual bool CanVisit => false; | |
| public string Path | |
| { | |
| get | |
| { | |
| List<string> names = new List<string>() { Name }; | |
| INode current = this.Parent; | |
| while(current != null) | |
| { | |
| names.Add(current.Name); | |
| current = current.Parent; | |
| } | |
| return string.Join(" > ", names.AsEnumerable().Reverse()); | |
| } | |
| } | |
| HashSet<INode> INode.Siblings { get => Siblings.ToHashSet<INode>(); } | |
| HashSet<INode> INode.Children { get => Children.ToHashSet<INode>(); } | |
| HashSet<INode> INode.Ancestors { get => Ancestors.ToHashSet<INode>();} | |
| public NodeType NodeType { get; set; } = NodeType.None; | |
| public Node() | |
| { | |
| Id = Guid.NewGuid(); | |
| Siblings = new HashSet<Node>(); | |
| Children = new HashSet<Node>(); | |
| Ancestors = new HashSet<Node>(); | |
| } | |
| public override string ToString() => Name; | |
| public void AddChild(Node child) | |
| { | |
| child.Parent = this; | |
| Children.Add(child); | |
| UpdateHierarchy(child); | |
| UpdateHierarchy(this); | |
| } | |
| public bool IsNeighbor(Node other) => Ancestors.Intersect(other.Ancestors).Any(); | |
| private void UpdateHierarchy(Node child) | |
| { | |
| child.Siblings = Children.Where(c => c != child).ToHashSet(); | |
| child.Ancestors = Ancestors.Concat(new[] { this }).ToHashSet(); | |
| foreach (var grandchild in child.Children) | |
| { | |
| grandchild.Ancestors = child.Ancestors.Concat(new[] { child }).ToHashSet(); | |
| UpdateHierarchy(grandchild); | |
| } | |
| } | |
| public bool Equals(Node? other) => Id.Equals(other?.Id); | |
| public List<Node> GetAllNodes() | |
| { | |
| var nodes = new List<Node> { this }; | |
| foreach (var child in Children) | |
| { | |
| nodes.AddRange(child.GetAllNodes()); | |
| } | |
| return nodes; | |
| } | |
| } | |
| public class Galaxy : Node { } | |
| public class SpaceRegion : Node {} | |
| public class SpaceSector : Node{ } | |
| public class StarSystem : Node { } | |
| public class Structure : Node { } | |
| public class Planet : Node { } | |
| public class PlanetRegion : Node { } | |
| public class PlanetArea : Node { } | |
| public class Settlement : PlanetArea { } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment