public SpecialistPool(SeededRandom seededRandom, List <SpecialistConfiguration> allowedSpecialists) { foreach (SpecialistConfiguration specConfig in allowedSpecialists) { AddSpecialistToPool(specConfig); } // Create the specialist hire order. // This algorithm will create 3 seperate lists of the allowed specialists. // The lists are then randomized in place, to ensure one full cycle of all allowed specialists is offered before a second is offered. // All three lists are appended together. // This results in 3 specialists of each type in the pool while preventing two of the same specialist getting offered before another player has seen it once. _specialistHireOrder .AddRange(_specialistPool.Keys.ToList().OrderBy(it => seededRandom.NextRand(0, 1000))); _specialistHireOrder .AddRange(_specialistPool.Keys.ToList().OrderBy(it => seededRandom.NextRand(0, 1000))); _specialistHireOrder .AddRange(_specialistPool.Keys.ToList().OrderBy(it => seededRandom.NextRand(0, 1000))); }
public void SameSeedTest() { int seed = 1; SeededRandom rand1 = new SeededRandom(seed); SeededRandom rand2 = new SeededRandom(seed); for (int i = 0; i < 1000; i++) { Assert.AreEqual(rand1.NextDouble(), rand2.NextDouble()); } for (int i = 0; i < 1000; i++) { Assert.AreEqual(rand1.NextRand(0, 10), rand2.NextRand(0, 10)); } for (int i = 0; i < 1000; i++) { Assert.AreEqual(rand1.NextDouble(), rand2.NextDouble()); Assert.AreEqual(rand1.NextRand(0, 10), rand2.NextRand(0, 10)); } }
/// <summary> /// Translates a given set of outposts by a set amount, duplicating the outposts at a different coordinate location. /// Result from this function is a newly generated set of outposts offset by the specified translation. /// </summary> /// <param name="outposts">A list of outposts to translate</param> /// <param name="translation">The translation to apply</param> /// <returns>A list of translated outposts</returns> private List <Outpost> TranslateOutposts(List <Outpost> outposts, RftVector translation) { // Generate a random rotation of 0/90/180/270 so the map doesn't appear to be tiled. double rotation = _randomGenerator.NextRand(0, 3) * Math.PI / 2; // List to store the newly translated outposts List <Outpost> translatedOutposts = new List <Outpost>(); // Loop through the original outposts. foreach (Outpost outpost in outposts) { // Get original outpost location RftVector position = outpost.GetComponent <PositionManager>().GetPositionAt(new GameTick(0)); // New vector for the copied location RftVector newPosition = new RftVector(RftVector.Map, position.X, position.Y); // Undo the rotation and apply a new rotation. // https://stackoverflow.com/questions/620745/c-rotating-a-vector-around-a-certain-point double cs = Math.Cos(rotation); double sn = Math.Sin(rotation); double translatedX = position.X; double translatedY = position.Y; double resultX = translatedX * cs - translatedY * sn; double resultY = translatedY * cs - translatedX * sn; resultX += _mapConfiguration.MaximumOutpostDistance; resultY += _mapConfiguration.MaximumOutpostDistance; newPosition.X = (float)resultX; newPosition.Y = (float)resultY; // Apply the translation to offset the outpost. newPosition += translation; // Add a new outpost to the translated outposts list Outpost newOutpost = CreateOutpost(newPosition, outpost.GetOutpostType()); newOutpost.GetComponent <DrillerCarrier>().SetOwner(outpost.GetComponent <DrillerCarrier>().GetOwner()); newOutpost.GetComponent <IdentityManager>().SetName(_nameGenerator.GetRandomName()); translatedOutposts.Add(newOutpost); } // Return the translated outposts. return(translatedOutposts); }
/// <summary> /// Translates a given set of outposts by a set amount, duplicating the outposts at a different coordinate location. /// Result from this function is a newly generated set of outposts offset by the specified translation. /// </summary> /// <param name="outposts">A list of outposts to translate</param> /// <param name="translation">The translation to apply</param> /// <returns>A list of translated outposts</returns> private List <Outpost> TranslateOutposts(List <Outpost> outposts, RftVector translation) { // Generate a random rotation of 0/90/180/270 so the map doesn't appear to be tiled. double rotation = RandomGenerator.NextRand(0, 3) * Math.PI / 2; // List to store the newly translated outposts List <Outpost> translatedOutposts = new List <Outpost>(); // Loop through the original outposts. foreach (Outpost outpost in outposts) { // Get original outpost location RftVector position = outpost.GetCurrentPosition(); // New vector for the copied location RftVector newPosition = new RftVector(RftVector.Map, position.X, position.Y); // Undo the rotation and apply a new rotation. // https://stackoverflow.com/questions/620745/c-rotating-a-vector-around-a-certain-point double cs = Math.Cos(rotation); double sn = Math.Sin(rotation); double translatedX = position.X; double translatedY = position.Y; double resultX = translatedX * cs - translatedY * sn; double resultY = translatedY * cs - translatedX * sn; resultX += this.MaxSeedDistance; resultY += this.MaxSeedDistance; newPosition.X = (float)resultX; newPosition.Y = (float)resultY; // Apply the translation to offset the outpost. newPosition += translation; // Add a new outpost to the translated outposts list translatedOutposts.Add(new Outpost(newPosition, outpost.GetOwner(), outpost.GetOutpostType())); } // Return the translated outposts. return(translatedOutposts); }
/// <summary> /// Generates a random outpost name for an outpost /// </summary> /// <returns>The random outpost name</returns> public string GetRandomName() { // If there are pre-generated outposts to be selected from, // Choose one of them. if (_outpostNames.Count > 0) { int selection = seeder.NextRand(0, _outpostNames.Count - 1); string name = _outpostNames[selection]; _outpostNames.Remove(name); _selectedNames.Add(name); return(name); } // If there are some derived names to pick from, select them if (_fallbackNames.Count > 0) { int selection = seeder.NextRand(0, _fallbackNames.Count - 1); string name = _fallbackNames[selection]; _fallbackNames.Remove(name); _selectedNames.Add(name); return(name); } // Otherwise, generate a random shuffled string // Try 10 scrambles before giving up. int scrambleCounter = 0; while (scrambleCounter < 10) { // Pick a random name from the list of names. int randomName = seeder.NextRand(0, _selectedNames.Count - 1); // Shuffle the letters in the outpost name. string shuffled = this._shuffleString(_selectedNames[randomName]); if (!_selectedNames.Contains(shuffled)) { _selectedNames.Add(shuffled); return(shuffled); } scrambleCounter++; } // As a final measure, if a string couldn't be derived, generate a random name. const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; string generated = new string(Enumerable.Repeat(chars, 8) .Select(s => s[seeder.NextRand(0, s.Length)]).ToArray()); return(this._capitolizeFirstLetter(generated)); }