예제 #1
0
    public void AddOreVein(byte[,] undergroundValue, byte toValue, int N, float fracOfDomainsWithOre, string snakeOrCircle)
    {
        // Frac is "this fraction of domains have this resource"
        // Use that to figure out how many ore deposits to have
        float prob = 0;
        float p, nk;
        float n = 0;

        while (prob < fracOfDomainsWithOre)
        {
            p    = Mathf.PI * 100 * 100 / N / N;
            n    = n + 1;
            prob = 0;
            for (int k = 1; k < Mathf.Min(n, 4); k++)
            {
                nk   = MyFactorial((int)n) / (MyFactorial(k) * MyFactorial((int)n - k));
                prob = prob + nk * Mathf.Pow(p, k) * Mathf.Pow(1 - p, n - k);
            }
            if (n > 20)
            {
                break;
            }
        }
        //Debug.Log("number of veins selected as " + n.ToString() + " with probability of being in a domain of >" + prob.ToString());
        int numberOfVeins = Mathf.RoundToInt(n);
        // Generate either a snaking ore or a circle of ore
        float branchProbability;
        int   travelLength;

        if (snakeOrCircle == "snake") // Snake
        {
            branchProbability = 0.01F;
            travelLength      = 150;
            // .01, 100-> ~108 ores
            // ***.01, 150-> ~225 ores ***
            // .01, 200-> ~400 ores
            // .01, 300-> ~1300 ores
            // .01, 400-> ~3300 ores
            // .02, 100-> ~200 ores
            // .02, 200-> ~1560 ores
            // .03, 100-> ~375 ores
        }
        else   // Circle
        {
            branchProbability = 0.1F;
            travelLength      = 25;
            // .05, 50-> ~135 ores per
            // .08, 25-> ~92 ores per
            // .08, 50-> ~230 ores per
            // ***.10, 25-> ~100 ores per***
        }

        // Generate this many veins
        for (int i = 0; i < numberOfVeins; i++)
        {
            GenerateOreVeins.CreateVein(new Vector2Int(UnityEngine.Random.Range(0, N - 1), UnityEngine.Random.Range(0, N - 1)),
                                        PoissonRandomGenerator.GetPoisson(travelLength), undergroundValue, toValue, branchProbability, N);
        }
    }
예제 #2
0
    public static void PropogateVein(Vector2Int ij, int travelLength, Vector2 aimDir, byte[,] undergroundValue, byte toValue,
                                     float branchProbability, int N, Stack <Vector2Int> ijValues, Stack <int> lenValues)
    {
        int   ind = 0;
        float roll;
        float xChance = Mathf.Abs(aimDir.x) / (Mathf.Abs(aimDir.x) + Mathf.Abs(aimDir.y));

        xChance = Mathf.Min(xChance, 0.9F);
        xChance = Mathf.Max(xChance, 0.1F);
        Vector2Int moveVec = new Vector2Int();

        while (ind < travelLength)
        {
            ind++;
            // Set this tile to be the ore value
            undergroundValue[ij.x, ij.y] = toValue;

            // Roll for x or y based on the main direction of motion
            roll      = Random.Range(0F, 1F);
            moveVec.x = 0; moveVec.y = 0;
            if (roll <= xChance) // Choose to go in the x direction
            {
                moveVec.x = (int)Mathf.Sign(aimDir.x);
            }
            else // Choose to go in the y direction
            {
                moveVec.y = (int)Mathf.Sign(aimDir.y);
            }

            // Roll for right or wrong direction
            roll = Random.Range(0F, 1F);
            if (roll < 0.2) // Wrong direction
            {
                moveVec.x = -moveVec.x;
                moveVec.y = -moveVec.y;
            }

            // Travel
            ij = ij + moveVec;
            // Enforce bounds
            if (ij.x < 0)
            {
                break;
            }
            if (ij.x == N - 1)
            {
                break;
            }
            if (ij.y < 0)
            {
                break;
            }
            if (ij.y == N - 1)
            {
                break;
            }

            // Check if this vein branches
            float randVal = Random.Range(0F, 1F);
            //Debug.Log("Rolled " + randVal.ToString() + ", branch prob " + branchProbability.ToString());
            if (randVal < branchProbability)
            {
                // Generate a new length
                int newLength;
                if (travelLength > 1000)
                {
                    newLength = travelLength;
                }
                else
                {
                    newLength = PoissonRandomGenerator.GetPoisson(travelLength - ind);
                }
                if (newLength <= 2)
                {
                    continue;
                }
                //Debug.Log("New Branch of length " + newLength.ToString());
                // Branch the vein
                ijValues.Push(ij);
                lenValues.Push(newLength);
            }
        }
    }