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