private Tuple <List <Tuple <int, int, int, decimal> >, int> GetWorldObstaclePositions( WorldObstacleConfig config, decimal seed, int modular, int generateCount, int?offsetx = null, int?offsety = null) { var values = new List <Tuple <int, int, int, decimal> >(); var multiplier = config.Multiplier; var xs = seed; var ys = seed; var constX = config.ConstX; var constY = config.ConstY; var quadPosIndicator = 1; for (var i = 0; i < generateCount; i++) { /* Get the size of each node as the first character of the previous nodes x and y coordinates combined. */ var s = Convert.ToInt32( Convert.ToDecimal(Math.Abs(xs).ToString(CultureInfo.InvariantCulture)[0] + "" + Math.Abs(ys).ToString(CultureInfo.InvariantCulture)[0]) * config.NodeSizeMultiplier); /* Calculate random seeded value for x */ xs = xs * multiplier % modular + constX; /* Calculate random seeded value for y */ ys = ys * multiplier % modular + constY; SetPositionWithMultiplier(xs, ys, quadPosIndicator, out int x, out int y); SetQuadPosIndicator(ref quadPosIndicator); /* Calculate distance to center point of the circle (0,0). */ var d = vectorCalculatorService.GetDistanceBetween( new Position { X = x, Y = y }, new Position { X = 0, Y = 0 }); /* Only add items within the circle radius. */ if (d <= modular) { if (offsetx.HasValue && offsety.HasValue) { x += offsetx.Value; y += offsety.Value; } values.Add(new Tuple <int, int, int, decimal>(x, y, s, d)); } var repeatingValues = values.GroupBy(v => v.Item1).Where(vg => vg.Count() > config.RepeatingValuesLimit).Count(); /* Check if duplicate pattern exists, then start over with new seed. */ if (repeatingValues > config.RepeatingValuesLimit) { i = 0; seed = xs = ys = offsetx.HasValue || seed < config.MaxSeed ? seed + 1 : seed * -1; values = new List <Tuple <int, int, int, decimal> >(); } } return(new Tuple <List <Tuple <int, int, int, decimal> >, int>(values, Convert.ToInt32(seed))); }
private Tuple <List <GameObject>, int> GenerateWorldObstacles( List <GameObject> gameObjects, WorldObstacleConfig config, GameObjectType gameObjectType, int obstacleSeed) { /* Configurables */ Tuple <List <Tuple <int, int, int, decimal> >, int> obstaclePositions = GetWorldObstaclePositions( config, obstacleSeed, config.Modular, config.GenerateCount); var result = new Tuple <List <GameObject>, int>(new List <GameObject>(), obstaclePositions.Item2); var maxCount = Math.Min(obstaclePositions.Item1.Count, config.MaxCount); var startingPositions = GetPlayerStartingPositions().Select(p => new GameObject { Position = p }).ToList(); /* * These item counts are merely the total number of obstacle nodes that have been generated, which will most likely not be a set amount. * We can control the number of nodes that are actually added in the world with config instead to ensure we know exactly how many need to be added. * Thoughts? */ for (var i = 0; i < maxCount; i++) { Tuple <int, int, int, decimal> value = obstaclePositions.Item1[i]; Tuple <List <Tuple <int, int, int, decimal> >, int> obstacleNodePositions = GetWorldObstaclePositions( config, value.Item1, config.SubModular, config.GenerateSubCount, value.Item1, value.Item2); var maxSubCount = Math.Min(obstacleNodePositions.Item1.Count, config.MaxSubCount); for (var j = 0; j < maxSubCount; j++) { Tuple <int, int, int, decimal> subValue = obstacleNodePositions.Item1[j]; var position = new Position { X = subValue.Item1, Y = subValue.Item2 }; var obstacleNode = CreateObjectAtPosition(Guid.NewGuid(), position, gameObjectType, subValue.Item3); var noObjectsInRange = CheckNoObjectsInRange( obstacleNode, startingPositions, config.MinDistanceFromPlayers + obstacleNode.Size); if (noObjectsInRange) { result.Item1.Add(obstacleNode); gameObjects.Add(obstacleNode); } } } return(result); }