public RCT2RideData GenerateWoodenRollerCoaster() { RideData.RCT2RideData coaster = new RideData.RCT2RideData(); //Track Type coaster.TrackType = new RideData.RCT2RideCode(); coaster.TrackType.RideType = RideData.RCT2RideCode.RCT2TrackName.WoodenRollerCoaster6Seater; do { //Track Data coaster.TrackData = GenerateWoodenRollerCoasterTrack(); } while (coaster.TrackData == null); //Ride Features coaster.RideFeatures = new RideData.RCT2RideFeatures(); coaster.RideFeatures.Populate(coaster.TrackData); //Operating Mode coaster.OperatingMode = RideData.RCT2RideData.RCT2OperatingModes.ContinuousCircuit; //Colour Scheme coaster.ColourScheme = new RideData.RCT2VehicleColourScheme(); coaster.ColourScheme.ColourMode = RideData.RCT2VehicleColourScheme.RCT2VehicleColourMode.AllSameColour; List <RideData.RCT2VehicleColourScheme.RCT2Colour> bodyColours = new List <RideData.RCT2VehicleColourScheme.RCT2Colour>(); List <RideData.RCT2VehicleColourScheme.RCT2Colour> trimColours = new List <RideData.RCT2VehicleColourScheme.RCT2Colour>(); List <RideData.RCT2VehicleColourScheme.RCT2Colour> additionalColours = new List <RideData.RCT2VehicleColourScheme.RCT2Colour>(); Random random = new Random(); Array colourValues = Enum.GetValues(typeof(RideData.RCT2VehicleColourScheme.RCT2Colour)); for (int i = 0; i < 32; i++) { bodyColours.Add((RideData.RCT2VehicleColourScheme.RCT2Colour)colourValues.GetValue(random.Next(colourValues.Length))); trimColours.Add((RideData.RCT2VehicleColourScheme.RCT2Colour)colourValues.GetValue(random.Next(colourValues.Length))); additionalColours.Add((RideData.RCT2VehicleColourScheme.RCT2Colour)colourValues.GetValue(random.Next(colourValues.Length))); } coaster.ColourScheme.BodyColours = bodyColours.ToArray(); coaster.ColourScheme.TrimColours = trimColours.ToArray(); coaster.ColourScheme.AdditionalColours = additionalColours.ToArray(); //Entrance Style coaster.EntranceStyle = RideData.RCT2RideData.RCT2EntranceStyle.Plain; //Air Time In Seconds coaster.TrackData.PopulateRideStatistics(); coaster.AirTimeInSeconds = coaster.TrackData.AirTimeInSeconds; //Departure Flags coaster.DepartureFlags = new RideData.RCT2DepartureControlFlags(); coaster.DepartureFlags.UseMinimumTime = true; coaster.DepartureFlags.WaitForFullLoad = true; //Number of Trains coaster.NumberOfTrains = 1; //Number of Cars per Train coaster.NumberOfCarsPerTrain = 2; //Min Wait Time in Seconds coaster.MinWaitTimeInSeconds = 10; //Max Wait Time in Seconds coaster.MaxWaitTimeInSeconds = 60; //Speed of Powered Launch/Number of Go Kart Laps/Max number of people in Maze coaster.SpeedOfPoweredLaunch = 0; coaster.NumberOfGoKartLaps = 0; coaster.MaxNumberOfPeopleMaze = 0; //Max Speed of Ride coaster.MaxSpeedOfRide = coaster.TrackData.MaxSpeed; //Average Speed of Ride coaster.AverageSpeedOfRide = coaster.TrackData.AverageSpeed; //Ride length in metres coaster.RideLengthInMetres = coaster.TrackData.CalculateRideLengthInMeters(); //Pos G Force coaster.PosGForce = coaster.TrackData.MaxPositiveG; //Neg G Force coaster.NegGForce = coaster.TrackData.MaxNegativeG; //Lat G Force coaster.LatGForce = coaster.TrackData.MaxLateralG; //Number of Inversions coaster.NumberOfInversions = coaster.TrackData.NumOfInversions; //Number of Drops coaster.NumberOfDrops = coaster.TrackData.NumOfDrops; //Highest Drop coaster.HighestDrop = coaster.TrackData.HighestDrop; //Excitement Times Ten coaster.ExcitementTimesTen = coaster.TrackData.Excitement * 10; //Intensity Times Ten coaster.IntensityTimesTen = coaster.TrackData.Intensity * 10; //Nausea Times Ten coaster.NauseaTimesTen = coaster.TrackData.Nausea * 10; //Main Track Colour coaster.TrackMainColour = (RideData.RCT2VehicleColourScheme.RCT2Colour)colourValues.GetValue(random.Next(colourValues.Length)); coaster.TrackMainColourAlt1 = (RideData.RCT2VehicleColourScheme.RCT2Colour)colourValues.GetValue(random.Next(colourValues.Length)); coaster.TrackMainColourAlt2 = (RideData.RCT2VehicleColourScheme.RCT2Colour)colourValues.GetValue(random.Next(colourValues.Length)); coaster.TrackMainColourAlt3 = (RideData.RCT2VehicleColourScheme.RCT2Colour)colourValues.GetValue(random.Next(colourValues.Length)); //Additional Track Colour coaster.TrackAdditionalColour = (RideData.RCT2VehicleColourScheme.RCT2Colour)colourValues.GetValue(random.Next(colourValues.Length)); coaster.TrackAdditionalColourAlt1 = (RideData.RCT2VehicleColourScheme.RCT2Colour)colourValues.GetValue(random.Next(colourValues.Length)); coaster.TrackAdditionalColourAlt2 = (RideData.RCT2VehicleColourScheme.RCT2Colour)colourValues.GetValue(random.Next(colourValues.Length)); coaster.TrackAdditionalColourAlt3 = (RideData.RCT2VehicleColourScheme.RCT2Colour)colourValues.GetValue(random.Next(colourValues.Length)); //Support Track Colour coaster.TrackSupportColour = (RideData.RCT2VehicleColourScheme.RCT2Colour)colourValues.GetValue(random.Next(colourValues.Length)); coaster.TrackSupportColourAlt1 = (RideData.RCT2VehicleColourScheme.RCT2Colour)colourValues.GetValue(random.Next(colourValues.Length)); coaster.TrackSupportColourAlt2 = (RideData.RCT2VehicleColourScheme.RCT2Colour)colourValues.GetValue(random.Next(colourValues.Length)); coaster.TrackSupportColourAlt3 = (RideData.RCT2VehicleColourScheme.RCT2Colour)colourValues.GetValue(random.Next(colourValues.Length)); //Is Six Flag Design coaster.IsSixFlagsDesign = false; //DAT File Header //We scum this in the TD6 Parser so it's not needed to be filled yet //TODO coaster.DatFile = new RideData.DATFileHeader(); //DAT File Checksum coaster.DatChecksum = coaster.DatFile.CalculateChecksum(RideData.RCT2RideCode.RideNameVehicleMap[coaster.TrackType.RideType]); //Required Map Space coaster.RequiredMapSpace = coaster.TrackData.CalculateRequiredMapSpace(); //Lift Chain Speed coaster.LiftChainSpeed = 5; //Number of Circuits coaster.NumberOfCircuits = 1; //Check Validity RCT2TrackData.InvalidityCode invalidityResult = coaster.TrackData.CheckValidity(); if (invalidityResult != RCT2TrackData.InvalidityCode.Valid) { Console.WriteLine("Failed Validity Check: " + invalidityResult.ToString()); return(null); } return(coaster); }
private RCT2TrackData GenerateWoodenRollerCoasterTrack() { RCT2TrackData trackData = new RCT2TrackData(); trackData.TrackData = new List <RCT2TrackPiece>(); Random random = new Random(); //Begin Station trackData.TrackData.Add(new RideData.RCT2TrackPiece() { TrackElement = RideData.RCT2TrackElements.RCT2TrackElement.BeginStation, Qualifier = new RideData.RCT2Qualifier() { IsChainLift = false, TrackColourSchemeNumber = 0, TrackRotation = RideData.RCT2Qualifier.RCT2QualifierRotation.Zero, AtTerminalStation = false, StationNumber = 0 } }); //End Station trackData.TrackData.Add(new RideData.RCT2TrackPiece() { TrackElement = RideData.RCT2TrackElements.RCT2TrackElement.EndStation, Qualifier = new RideData.RCT2Qualifier() { IsChainLift = false, TrackColourSchemeNumber = 0, TrackRotation = RideData.RCT2Qualifier.RCT2QualifierRotation.Zero, AtTerminalStation = false, StationNumber = 0 } }); //TODO: Marking valid track pieces as invalid // The prior connection check is failing for (int i = 2; i < length; i++) { List <RCT2TrackElements.RCT2TrackElement> candidates = RCT2TrackElements.FindValidSuccessors(whitelistedTracks, trackData.TrackData[i - 1].TrackElement); bool reselect = false; do { //If we have no candidates left if (candidates.Count <= 0) { return(null); //if (steppedBack) //{ // return null; //} //if (i < 3) //{ // throw new Exception("ERROR: Unable to create Coaster - Index stepped back too far"); //} ////Console.WriteLine("ERROR: No Valid Track Pieces Found, Stepping back and starting again"); //trackData.TrackData.Remove(trackData.TrackData.Last()); //i -= 2; //steppedBack = true; //TODO - Make this a better solution, right now it's a hack to make it work //break; } //Select our successor and remove it from the potential pool RCT2TrackElements.RCT2TrackElement successor = candidates[random.Next(candidates.Count)]; candidates.Remove(successor); RCT2TrackElementProperty property = RCT2TrackElements.TrackElementPropertyMap[successor]; //Console.WriteLine($"\tAttempting Track Piece {successor.ToString()}"); RCT2Qualifier qualifier; //Create our qualifier bit if (property.Displacement.Y > 0) { //TODO: Check if it should be a chain // Perform a lookup to see if previous track was chain lift // Or if our current velocity would be negative/0 // If not possible, do a lookup to see if previous X tracks contained a decline, if not we need one bool chainLift = trackData.TrackData[i - 1].Qualifier.IsChainLift; //If our current velocity would be negative or zero, we need a chain lift qualifier = new RCT2Qualifier() { IsChainLift = true, TrackColourSchemeNumber = 0, TrackRotation = RideData.RCT2Qualifier.RCT2QualifierRotation.Zero, AtTerminalStation = false, StationNumber = 0 }; } else { qualifier = new RCT2Qualifier() { IsChainLift = false, TrackColourSchemeNumber = 0, TrackRotation = RideData.RCT2Qualifier.RCT2QualifierRotation.Zero, AtTerminalStation = false, StationNumber = 0 }; } //Add to track trackData.TrackData.Add(new RCT2TrackPiece() { TrackElement = successor, Qualifier = qualifier }); //If it's invalid RCT2TrackData.InvalidityCode invalidityCode = trackData.CheckValidity(); if (invalidityCode != RCT2TrackData.InvalidityCode.Valid) { //Remove it and try again reselect = true; trackData.TrackData.Remove(trackData.TrackData.Last()); //Console.WriteLine($"\tInvalid Selection, Code: {invalidityCode.ToString()}"); } else { reselect = false; } } while (reselect); //Console.WriteLine($"{trackData.TrackData.Last().TrackElement.ToString()} Selected!"); } //for (int i = 0; i < trackData.TrackData.Count(); i++) //{ // Console.WriteLine("\t" + trackData.TrackData[i].TrackElement.ToString()); //} return(trackData); }
private List <RCT2RideData> Crossover(RCT2RideData parent1, RCT2RideData parent2) { List <RCT2RideData> children = new List <RCT2RideData>(); int crossoverPoint = length; int redoCount = 0; bool redo = false; RCT2TrackData.InvalidityCode parent1Invalidity = parent1.TrackData.CheckValidity(); RCT2TrackData.InvalidityCode parent2Invalidity = parent2.TrackData.CheckValidity(); //Create crossover point if (random.NextDouble() <= crossoverRate) { crossoverPoint = random.Next(length); } do { if (redoCount >= crossoverAttempts) { crossoverPoint = length; } //Add first halves to each child RCT2TrackData child1Track = new RCT2TrackData(); RCT2TrackData child2Track = new RCT2TrackData(); for (int i = 0; i < crossoverPoint; i++) { child1Track.TrackData.Add(parent1.TrackData.TrackData[i]); child2Track.TrackData.Add(parent2.TrackData.TrackData[i]); } //Add second halves to each child for (int i = crossoverPoint; i < parent2.TrackData.TrackData.Count(); i++) { child1Track.TrackData.Add(parent2.TrackData.TrackData[i]); } for (int i = crossoverPoint; i < parent1.TrackData.TrackData.Count(); i++) { child2Track.TrackData.Add(parent1.TrackData.TrackData[i]); } RCT2RideData child1 = new RCT2RideData(parent1); RCT2RideData child2 = new RCT2RideData(parent2); child1.TrackData = child1Track; child2.TrackData = child2Track; //If the created children are invalid, keep trying //Wont cause an infinite loop as we will eventually crossover at point 0 //Which acts as if we never crossed over at all RCT2TrackData.InvalidityCode child1Invalidity = child1.TrackData.CheckValidity(); RCT2TrackData.InvalidityCode child2Invalidity = child2.TrackData.CheckValidity(); if (child1Invalidity != RCT2TrackData.InvalidityCode.Valid || child2Invalidity != RCT2TrackData.InvalidityCode.Valid) { redo = true; redoCount++; crossoverPoint = random.Next(length); } else { redo = false; children.Add(child1); children.Add(child2); if (crossoverPoint != length) { successfulCrossovers++; } } } while (redo); return(children); }