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