Ejemplo n.º 1
0
    private Sphere[] GenerateRandomSpheres()
    {
        var spheres = new Sphere[SphereAmount];

        for (int i = 0; i < SphereAmount; i++)
        {
            var radius     = 0f;
            var position   = Vector3.zero;
            var isMetal    = _random.NextDouble() < 0.5;
            var isEmitting = _random.NextDouble() < 0.2;
            var color      = GenerateRandomColor();

            if (!GeneratePosition(spheres, out position, out radius))
            {
                break;
            }

            spheres[i] = new Sphere()
            {
                Position   = position,
                Radius     = radius,
                Color      = color,
                Specular   = isMetal ? color : Vector3.one * 0.04f,
                Smoothness = NextFloat(),
                Emission   = isEmitting ? color : Vector3.zero
            };
        }

        return(spheres);
    }
Ejemplo n.º 2
0
        public static Vector2 insideUnitCircle(this System.Random self)
        {
            float radius = (float)self.NextDouble();
            float angle  = (float)self.NextDouble() * Mathf.PI * 2;

            return(new Vector2(Mathf.Cos(angle) * radius, Mathf.Sin(angle) * radius));
        }
Ejemplo n.º 3
0
    void SurvivalSelection()
    {
        ResetAllChildren();
        //Survival selection!
        Generation += 1;

        // n = calc how many children to remove from pop (always even)
        // remove n worst members of the pop
        // let's go with quarter pop removal
        var quarterPop = Population.Count / 4;

        for (int i = quarterPop * 3; i < Population.Count; i++)
        {
            PlayerAI tempPlayer = Population[i];
            DiscardedChildren.Enqueue(tempPlayer);
        }
        Population.RemoveRange(quarterPop * 3, quarterPop);


        List <PlayerAI> tempChildren = new List <PlayerAI>();

        // select parents from the remaining pool and make n children
        for (int i = 0; i < quarterPop / 2; i++)
        {
            PlayerAI[] parents  = TournamentSelection(Population, Population.Count / 2);
            PlayerAI[] children = Crossover(parents);

            foreach (var child in children)
            {
                // should we mutate?
                if (random.NextDouble() <= MutationRate)
                {
                    child.Chromosome = Mutation(child.Chromosome);
                }
                child.fitness = Fitness(child);

                // removed children get replaced with the new children
                tempChildren.Add(child);
            }
        }

        foreach (var child in tempChildren)
        {
            Population.Add(child);
        }
        Population = Population.OrderByDescending(p => p.fitness).ToList();

        GameState = GAMESTATE.RUNNING;
        //Done with Survival Selection
        foreach (var child in Population)
        {
            child.StartPlayerAI();
        }
    }
Ejemplo n.º 4
0
        //https://gist.github.com/tansey/1444070
        private static double SampleGaussian(System.Random random, double mean, double stddev)
        {
            // The method requires sampling from a uniform random of (0,1]
            // but Random.NextDouble() returns a sample of [0,1).
            double x1 = 1 - random.NextDouble();
            double x2 = 1 - random.NextDouble();

            double y1 = Math.Sqrt(-2.0 * Math.Log(x1)) * Math.Cos(2.0 * Math.PI * x2);

            return(y1 * stddev + mean);
        }
        private void AddTree(Coordinates position)
        {
            var treeEntityId  = GenerateId();
            var spawnRotation = (uint)Mathf.CeilToInt((float)rand.NextDouble() * 360);

            snapshotEntities.Add(treeEntityId, EntityTemplateFactory.CreateTreeTemplate(position, spawnRotation));
        }
Ejemplo n.º 6
0
        public void OnTriggerEnter(Collider thingICollidedWith)
        {
            if (thingICollidedWith.transform.root == playersVehicle.transform)
            {
                Health health = Traverse.Create(playeractor).Field("h").GetValue() as Health;
                if (health.currentHealth > 10)
                {
                    playeractor.health.Damage(birdDamage, new Vector3(0, 0, 0), Health.DamageTypes.Impact, birdActor, "Bird Strike");
                }

                Debug.Log("Bird Strike!!");
                squawk.Play();
                BaseFailure   fail   = getRandomFailure();
                System.Random rand   = new System.Random();
                double        chance = rand.NextDouble();

                if (fail.failureName.Contains("Engine Failure") && chance <= engineFailureRate)
                {
                    fail.runFailure();
                }
                else
                {
                    Debug.Log($"Is {chance} <= {fail.failureRate * failureRateMultiplier}?");
                    if (chance <= fail.failureRate * failureRateMultiplier)
                    {
                        Debug.Log($"Triggering failure {fail.failureName}");
                        fail.runFailure(null, true);
                    }
                }
            }
        }
Ejemplo n.º 7
0
    /// <summary>
    /// Fill the chunk with trees
    /// </summary>
    /// <param name="chunkData"></param>
    /// <param name="pos"></param>
    /// <param name="parent"></param>
    private void CreateTrees(Vector2 pos, Transform parent, ChunkData chunkData)
    {
        Debug.Log("Creating trees");
        System.Random randSeed = new System.Random((int)pos.x * 11200 + (int)pos.y);

        float simplex = _noise.GetSimplex((int)pos.x * .8f, (int)pos.y * .8f);

        if (simplex > 0)
        {
            simplex *= 2f;

            int treeCount = Mathf.FloorToInt((float)randSeed.NextDouble() * (chunkSize - 1) * simplex);

            for (int i = 0; i < treeCount; i++)
            {
                int xPos = (int)(randSeed.NextDouble() * (chunkSize - 2)) + 1 + (int)pos.x;
                int zPos = (int)(randSeed.NextDouble() * (chunkSize - 2)) + 1 + (int)pos.y;

                int y = 200;

                var randTree = Random.Range(0, propManager.TreesForInWorld.Count);

                var tree = Instantiate(propManager.TreesForInWorld[randTree].PropPrefab, new Vector3(xPos, y, zPos),
                                       Quaternion.Euler(PickRandomRotation()));

                RaycastHit hit;

                if (Physics.Raycast(tree.transform.position, tree.transform.TransformDirection(Vector3.down), out hit,
                                    10000))
                {
                    var trans = tree.transform;
                    trans.position = hit.point;
                    var randomRotation = Random.Range(0, 360);
                    trans.rotation = Quaternion.Euler(trans.rotation.x, randomRotation,
                                                      trans.rotation.z);
                    tree.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);

                    // if(tree.transform.rotation)

                    SaveObjectOnChunk(tree, randTree, chunkData, false);

                    tree.transform.SetParent(parent);
                }
            }
        }
        CreateBuildings(pos, parent, chunkData);
    }
Ejemplo n.º 8
0
        public static T GetRandom <T>(this List <T> vals) where T : IRandom
        {
            var total = 0f;

            var probs = new float[vals.Count];


            for (var i = 0; i < probs.Length; i++)
            {
                probs[i] = vals[i].returnChance;
                total   += probs[i];
            }


            var randomPoint = (float)_r.NextDouble() * total;


            for (var i = 0; i < probs.Length; i++)
            {
                if (randomPoint < probs[i])
                {
                    return(vals[i]);
                }
                randomPoint -= probs[i];
            }

            return(vals[0]);
        }
Ejemplo n.º 9
0
    // Taken From: https://answers.unity.com/questions/486626/how-can-i-shuffle-alist.html
    void FisherYatesCardDeckShuffle()
    {
        System.Random _random = new System.Random();
        GameObject    card;
        int           n = deck.Count;

        for (int i = 0; i < n; i++)
        {
            int r = i + (int)(_random.NextDouble() * (n - i));
            card    = deck[r];
            deck[r] = deck[i];
            deck[i] = card;
        }
    }
Ejemplo n.º 10
0
        public static T GetRandomElementByChance <T>(this IList <T> list) where T : IRandomChance
        {
            var total = 0.0f;
            var probs = new float[list.Count];

            for (int i = 0; i < probs.Length; i++)
            {
                probs[i] = list[i].GetChance;
                total   += probs[i];
            }

            var randomPoint = (float)_random.NextDouble() * total;

            for (int i = 0; i < probs.Length; i++)
            {
                if (randomPoint < probs[i])
                {
                    return(list[i]);
                }
                randomPoint -= probs[i];
            }

            return(list.GetRandomElement());
        }
Ejemplo n.º 11
0
    void RollNext()
    {
        _nextIndex = _pieceRng.Next(0, Templates.GetLength(0));
        _repeated.Add(_nextIndex);
        _nextRotation  = _rotationRng.Next(0, 4);
        _nextTranspose = _rotationRng.NextDouble() >= 0.5f;

        _repeated.Add(_nextIndex);
        if (_repeated.Distinct().ToList().Count > 1)
        {
            _repeated.Clear();
        }
        else if (_repeated.Count >= 3)
        {
            RollNext();
        }
    }
Ejemplo n.º 12
0
    public void Next()
    {
        float rand = (float)random.NextDouble();

        var availableTransitions = transitions[currentState];

        foreach (var trans in availableTransitions)
        {
            if (rand < trans.Probability)
            {
                currentState = trans.TargetState;
                break;
            }

            rand -= trans.Probability;
        }
    }
Ejemplo n.º 13
0
    void FixedUpdate()
    {
        timer += Time.deltaTime;

        if (rotate && !tookPicture)
        {
            transform.rotation = Quaternion.Euler(0f, 0f, maxRotation * Mathf.Sin(Time.time) + originalRotation);
        }

        if (timer > lockOnTimeout && !tookPicture)
        {
            timer -= lockOnTimeout;

            var lockedOn = rand.NextDouble() <= GetChanceToLockOn();

            if (lockedOn)
            {
                var isInCone = CheckIfPlayerInCone();
                var canSee   = CanSeePlayer();

                if (canSee && isInCone)
                {
                    TakePhotoOfPlayer(true);
                }
            }
        }
        else if (tookPicture)
        {
            restartTimer += Time.deltaTime;
        }

        if (restartTimer >= 2)
        {
            restartTimer = 0;
            tookPicture  = false;
            timer        = 0;

            if (moveTowardsPlayer != null)
            {
                moveTowardsPlayer.moving = true;
            }
        }
    }
Ejemplo n.º 14
0
    public void Initialise()
    {
        List <int> structure = new List <int>()
        {
            28,
            24,
            24,
            4
        };

        values        = new float[structure.Count][];
        desiredValues = new float[structure.Count][];
        biases        = new float[structure.Count][];
        biasesSmudge  = new float[structure.Count][];
        weights       = new float[structure.Count - 1][][];
        weightsSmudge = new float[structure.Count - 1][][];
        for (var i = 0; i < structure.Count; i++)
        {
            values[i]        = new float[structure[i]];
            desiredValues[i] = new float[structure[i]];
            biases[i]        = new float[structure[i]];
            biasesSmudge[i]  = new float[structure[i]];
        }
        for (var i = 0; i < structure.Count - 1; i++)
        {
            weights[i]       = new float[values[i + 1].Length][];
            weightsSmudge[i] = new float[values[i + 1].Length][];
            for (var j = 0; j < weights[i].Length; j++)
            {
                weights[i][j]       = new float[values[i].Length];
                weightsSmudge[i][j] = new float[values[i].Length];
                for (var k = 0; k < weights[i][j].Length; k++)
                {
                    weights[i][j][k] = (float)Random.NextDouble() * Mathf.Sqrt(2f / weights[i][j].Length);
                }
            }
        }
        inputs = new float [28];
    }
Ejemplo n.º 15
0
    void Step()
    {
        for (int x = 0; x < cellsAmmount.x; ++x)
        {
            for (int y = 0; y < cellsAmmount.y; ++y)
            {
                int aliveNeighbours = CountAliveNeighbours(x, y);

                Cell c = board[x, y];
                if (!c.Alive && aliveNeighbours == 3)
                {
                    calcCells[x, y] = true;
                }
                else if (c.Alive && (aliveNeighbours < 2 || aliveNeighbours > 3))
                {
                    calcCells[x, y] = false;
                }
                else
                {
                    calcCells[x, y] =
                        (c.Alive)
                                                        ? c.Alive
                                                        : ((rnd.NextDouble() < cellRandomSpawnProbability)
                                                                ? true
                                                                : false);
                }
            }
        }

        for (int x = 0; x < cellsAmmount.x; ++x)
        {
            for (int y = 0; y < cellsAmmount.y; ++y)
            {
                board[x, y].Alive = calcCells[x, y];
            }
        }
    }
Ejemplo n.º 16
0
    // Mitchell's best candidate
    private float getNextLeafAngle(List <Tuple <int, float> > existing, System.Random random)
    {
        float bestCandidate = 0;
        float bestDistance  = 0;

        for (int i = 0; i < 10; i++)
        {
            float candidate = 360 * (float)random.NextDouble();

            // Take the first candidate if it's the first leaf
            if (existing.Count == 0)
            {
                bestCandidate = candidate;
                break;
            }

            // Get distance to nearest leaf
            float distance = 0;
            foreach (Tuple <int, float> l in existing)
            {
                float d = Mathf.Abs(candidate - l.Item2);
                // Debug.Log("d: " + d);
                if (distance == 0 || d < distance)
                {
                    distance = d;
                }
            }
            // Debug.Log(candidate + ", " + distance + ", " + bestDistance);
            if (distance > bestDistance)
            {
                bestCandidate = candidate;
                bestDistance  = distance;
            }
        }

        return(bestCandidate);
    }
Ejemplo n.º 17
0
    public double Next()
    {
        double fac, rsq, v1, v2;

        if (iset == 0)
        {
            do
            {
                v1  = 2.0 * r1.NextDouble() - 1.0;
                v2  = 2.0 * r2.NextDouble() - 1.0;
                rsq = v1 * v1 + v2 * v2;
            } while (rsq >= 1.0 || rsq == 0.0);

            fac  = System.Math.Sqrt(-2.0 * System.Math.Log(rsq) / rsq);
            gset = v1 * fac;
            iset = 1;
            return(v2 * fac);
        }
        else
        {
            iset = 0;
            return(gset);
        }
    }
Ejemplo n.º 18
0
    //TODO: could be recursive
    //TODO: improve running time
    private IEnumerator GenerateAreaFromPoint(Tile startTile, Area a)
    {
        //Debug.Log("generating in thread");

        yield return(null);

        //Using system random to be threadsafe
        var rnd = new System.Random();

        //Mark Tile as examined
        startTile.Examined     = true;
        startTile.ForestChance = 0f;

        var growthChance = 0.02f;

        var increase = growthChance * 2;

        startTile.Type = TileType.Ground;

        movableTiles.Add(startTile);
        immovableTiles.Remove(startTile);
        a.MovablePositions.Add(startTile);

        //last ring = areamiddle;
        List <Tile> lastRing = new List <Tile>()
        {
            startTile
        };

        int rings = 0;

        //while (!last.all forest chance == 100)
        while (rings < AreaSize / 2 && lastRing.Any(t => t.ForestChance < 1f))
        {
            rings++;

            List <Tile> nextRing = new List <Tile>(lastRing.Count * 2);

            //Increase growthchance
            growthChance += increase;

            //for last
            //    .selectnighbours.where not examined
            foreach (var tile in lastRing)
            {
                var ns = GetNeightbours(tile, false, false);


                foreach (var n in ns)
                {
                    //neighbour.forestChance = last.forestchance + Rnd < (growth chance + last.forestchance)
                    //mark examined
                    n.Examined     = true;
                    n.ForestChance = tile.ForestChance + rnd.NextDouble() < (growthChance + tile.ForestChance) ? growthChance : 0;

                    n.Type = rnd.NextDouble() <= n.ForestChance ? TileType.Forest : TileType.Ground;

                    n.Hidable = n.Type == TileType.Forest;

                    if (n.Type == TileType.Ground)
                    {
                        movableTiles.Add(n);
                        immovableTiles.Remove(n);
                        nextRing.Add(n);
                        a.MovablePositions.Add(n);
                    }
                }
            }

            lastRing = nextRing;
        }

        //Debug.Log("finshings area in "+ rings + " rings");

        areasExpanding--;
        //Debug.Log("Finishing area gen in thread");
    }
Ejemplo n.º 19
0
 public static float NextFloat(this System.Random random)
 {
     return((float)random.NextDouble());
 }
Ejemplo n.º 20
0
    public List <Point> GeneratePoints(int amount, double maxX, double maxY, GenerationType generationType)
    {
        MaxX = maxX;
        MaxY = maxY;

        var point0 = new Point(0, 0);
        var point1 = new Point(0, MaxY);
        var point2 = new Point(MaxX, MaxY);
        var point3 = new Point(MaxX, 0);

        var points = new List <Point>(amount + 1)
        {
            point0, point1, point2, point3
        };

        tri1 = new Triangle(point0, point1, point2);
        tri2 = new Triangle(point0, point2, point3);

        border = new List <Triangle>()
        {
            tri1, tri2
        };

        var random = new System.Random();

        switch (generationType)
        {
        case GenerationType.Guassian:
            for (int i = 0; i < amount - 4; i++)
            {
                var pointXG = Math.Abs(random.NextGaussian(0, 0.3f) * MaxX);
                var pointYG = Math.Abs(random.NextGaussian(0, 0.3f) * MaxY);

                points.Add(new Point(pointXG, pointYG));
            }

            break;

        case GenerationType.Random:
            for (int i = 0; i < amount - 4; i++)
            {
                var pointX = random.NextDouble() * MaxX;
                var pointY = random.NextDouble() * MaxY;
                points.Add(new Point(pointX, pointY));
            }

            break;

        case GenerationType.Circle:
            for (int i = 0; i < amount - 4; i++)
            {
                var point = random.InCircleGetPoint(1500);
                points.Add(point);
            }

            break;

        default:
            throw new ArgumentOutOfRangeException(nameof(generationType), generationType, null);
        }

        return(points);
    }
Ejemplo n.º 21
0
 public static int GetRandomRange(this Vector2 value, System.Random random)
 {
     return(Mathf.RoundToInt((float)(value.x + random.NextDouble() * (value.y - value.x))));
 }
Ejemplo n.º 22
0
 private float RandomRange(float min, float max) => Mathf.Lerp(min, max, (float)_random.NextDouble());
Ejemplo n.º 23
0
 public static float range(this System.Random self, float min, float max)
 {
     return((float)(self.NextDouble() * (max - min) + min));
 }
Ejemplo n.º 24
0
		/** Returns randomly selected points on the specified nodes with each point being separated by \a clearanceRadius from each other.
		 * Selecting points ON the nodes only works for TriangleMeshNode (used by Recast Graph and Navmesh Graph) and GridNode (used by GridGraph).
		 * For other node types, only the positions of the nodes will be used.
		 * 
		 * clearanceRadius will be reduced if no valid points can be found.
		 */
		public static List<Vector3> GetPointsOnNodes (List<GraphNode> nodes, int count, float clearanceRadius = 0) {
			
			if (nodes == null) throw new ArgumentNullException ("nodes");
			if (nodes.Count == 0) throw new ArgumentException ("no nodes passed");
			
			var rnd = new System.Random();
			
			var pts = ListPool<Vector3>.Claim(count);
			
			// Square
			clearanceRadius *= clearanceRadius;
			
			if (nodes[0] is TriangleMeshNode || nodes[0] is GridNode) {
				//Assume all nodes are triangle nodes or grid nodes
				
				var accs = ListPool<float>.Claim(nodes.Count);
					
				float tot = 0;
				
				for (var i=0;i<nodes.Count;i++) {
					var tnode = nodes[i] as TriangleMeshNode;
					if (tnode != null) {
						float a = Math.Abs(Polygon.TriangleArea(tnode.GetVertex(0), tnode.GetVertex(1), tnode.GetVertex(2)));
						tot += a;
						accs.Add (tot);
					}
					 else {
						var gnode = nodes[i] as GridNode;
						
						if (gnode != null) {
							var gg = GridNode.GetGridGraph (gnode.GraphIndex);
							var a = gg.nodeSize*gg.nodeSize;
							tot += a;
							accs.Add (tot);
						} else {
							accs.Add(tot);
						}
					}
				}
				
				for (var i=0;i<count;i++) {
					
					//Pick point
					var testCount = 0;
					var testLimit = 10;
					var worked = false;
					
					while (!worked) {
						worked = true;
						
						//If no valid points can be found, progressively lower the clearance radius until such a point is found
						if (testCount >= testLimit) {
							clearanceRadius *= 0.8f;
							testLimit += 10;
							if (testLimit > 100) clearanceRadius = 0;
						}
					
						var tg = (float)rnd.NextDouble()*tot;
						var v = accs.BinarySearch(tg);
						if (v < 0) v = ~v;
						
						if (v >= nodes.Count) {
							// This shouldn't happen, due to NextDouble being smaller than 1... but I don't trust floating point arithmetic.
							worked = false;
							continue;
						}
						
						var node = nodes[v] as TriangleMeshNode;
						
						Vector3 p;
						
						if (node != null) {
							// Find a random point inside the triangle
							float v1;
							float v2;
							do {
								v1 = (float)rnd.NextDouble();
								v2 = (float)rnd.NextDouble();
							} while (v1+v2 > 1);
							
							p = ((Vector3)(node.GetVertex(1)-node.GetVertex(0)))*v1 + ((Vector3)(node.GetVertex(2)-node.GetVertex(0)))*v2 + (Vector3)node.GetVertex(0);
						} else {
							var gnode = nodes[v] as GridNode;
							
							if (gnode != null) {
								var gg = GridNode.GetGridGraph (gnode.GraphIndex);
								
								var v1 = (float)rnd.NextDouble();
								var v2 = (float)rnd.NextDouble();
								p = (Vector3)gnode.position + new Vector3(v1 - 0.5f, 0, v2 - 0.5f) * gg.nodeSize;
							} else
							{
								//Point nodes have no area, so we break directly instead
								pts.Add ((Vector3)nodes[v].position);
								break;
							}
						}
						
						// Test if it is some distance away from the other points
						if (clearanceRadius > 0) {
							for (var j=0;j<pts.Count;j++) {
								if ((pts[j]-p).sqrMagnitude < clearanceRadius) {
									worked = false;
									break;
								}
							}
						}
						
						if (worked) {
							pts.Add (p);
							break;
						} else {
							testCount++;
						}
					}
				}
				
				ListPool<float>.Release(accs);
				
			} else {
				for (var i=0;i<count;i++) {
					pts.Add ((Vector3)nodes[rnd.Next (nodes.Count)].position);
				}
			}
			
			return pts;
		}
Ejemplo n.º 25
0
 int RandomRange(int _min, int _max)
 {
     return((int)(rand.NextDouble() * (_max - _min) - 0.001f) + _min);
 }
Ejemplo n.º 26
0
 public double GetRandomNumber(double minimum, double maximum)
 {
     return(RANDOM.NextDouble() * (maximum - minimum) + minimum);
 }
Ejemplo n.º 27
0
    public override void Generate()
    {
        cleanUp();
        RandomiseValues();

        float segmentLength       = 0.45f;
        float segments            = Mathf.FloorToInt(length / segmentLength);
        float scaledSegmentLength = length / segments;

        Vector3 lastSegmentPos = Vector3.zero;
        float   segmentAngle   = 0;

        for (int i = 0; i < segments; i++)
        {
            float   y   = lastSegmentPos.y + scaledSegmentLength * Mathf.Cos(segmentAngle * Mathf.Deg2Rad);
            float   x   = Mathf.Pow(curveAmount * y, 2);
            Vector3 pos = new Vector3(x, y);
            segmentAngle = Vector3.Angle(Vector3.up, pos - lastSegmentPos);

            GameObject segment = Instantiate(i < segments - 1 ? trunkSegment : trunkSegmentTop, lastSegmentPos, Quaternion.Euler(0, 0, -segmentAngle));
            segment.transform.localScale = new Vector3(trunkWidth, scaledSegmentLength / segmentLength, trunkWidth);
            segment.transform.SetParent(componentContainer, false);

            lastSegmentPos = pos;
        }

        leavesContainer.transform.localPosition = lastSegmentPos;
        leavesContainer.transform.localRotation = Quaternion.Euler(0, 0, -segmentAngle + 60 * curveAmount);

        float leavesScale = Mathf.Clamp(0.5f + length / 3, 0.5f, 2f);

        leavesContainer.transform.localScale = Vector3.one * leavesScale;

        System.Random random = new System.Random(seed);

        // Create random amount of leaves (fewer small leaves than big leaves)
        float bigLeavesAmount     = (4 + 6 * (float)random.NextDouble()) * leafDensity;
        float smallLeavesAmount   = (4 + 6 * (float)random.NextDouble()) * leafDensity * 0.66f;
        float leavesAmountCurrent = 0;
        int   coconutCount        = Mathf.Clamp(random.Next(0, (int)(4 * leafDensity)), 0, 6);

        // <leaf size, angle>
        List <Tuple <int, float> > leaves      = new List <Tuple <int, float> >();
        List <Tuple <int, float> > smallLeaves = new List <Tuple <int, float> >();
        List <Tuple <int, float> > coconuts    = new List <Tuple <int, float> >();

        while (leavesAmountCurrent < bigLeavesAmount)
        {
            int leaf = random.Next(0, leafObjects.Length);
            leavesAmountCurrent += leaf + 1;
            leaves.Add(new Tuple <int, float>(leaf, getNextLeafAngle(leaves, random)));
        }

        leavesAmountCurrent = 0;
        while (leavesAmountCurrent < smallLeavesAmount)
        {
            int leaf = random.Next(0, leafObjects.Length - 1); // Don't use biggest leaf object for small leaves
            leavesAmountCurrent += leaf + 1;
            smallLeaves.Add(new Tuple <int, float>(leaf, getNextLeafAngle(smallLeaves, random)));
        }

        foreach (Tuple <int, float> leaf in leaves)
        {
            GameObject leafObject = Instantiate(leafObjects[leaf.Item1], Vector3.zero, Quaternion.identity);
            leafObject.transform.SetParent(leavesContainer, false);
            float xRot = -10 + 20 * (float)random.NextDouble();
            leafObject.transform.localRotation = Quaternion.Euler(new Vector3(xRot, leaf.Item2, 0));
            leafObject.transform.Translate(leafObject.transform.forward * -0.05f, Space.World);
        }

        foreach (Tuple <int, float> leaf in smallLeaves)
        {
            GameObject leafObject = Instantiate(leafObjects[leaf.Item1], Vector3.zero, Quaternion.identity);
            leafObject.transform.SetParent(leavesContainer, false);
            float xRot = -20 + 15 * (float)random.NextDouble();
            leafObject.transform.localRotation = Quaternion.Euler(new Vector3(xRot, leaf.Item2, 0));
            leafObject.transform.Translate(leafObject.transform.forward * -0.1f, Space.World);
            leafObject.GetComponent <Renderer>().sharedMaterial = smallLeafMaterial;
            leafObject.transform.localScale *= 0.5f;
        }

        for (int i = 0; i < coconutCount; i++)
        {
            float angle = getNextLeafAngle(coconuts, random);
            coconuts.Add(new Tuple <int, float>(0, angle));

            GameObject coconut = Instantiate(coconutObject, Vector3.zero, Quaternion.identity);
            coconut.transform.SetParent(leavesContainer, false);
            coconut.transform.localRotation = Quaternion.Euler(new Vector3(-35f, angle, 0));
            coconut.transform.Translate(Vector3.forward * 0.15f + Vector3.up * -0.2f);
            coconut.transform.localScale = Vector3.one * (0.7f + 0.6f * (float)random.NextDouble());
        }
    }