- Home /
Randomly place a specific number of objects?
I am trying to fill a space game area with stars (currently just small spheres) and asteroids (currently just medium spheres). The stars are randomly placed with the System.Random function and a string seed. I want the seed to always place the stars and asteroids in the exact same spot each time. I have this part working with the System.Random(string seed) functionality.
The stars have a density limit set by a random number as well (always the same density value based on the same seed). But I want exactly 100 asteroids randomly placed. Is there a code efficient way to place exactly 100 asteroids but in random locations?
int[,] CalcStars(int seed) {
// Using the existing seeded random numbers, place the
// exact same number of starts for this seed every time
System.Random rng = new System.Random (seed);
int[,] stars = new int[100, 100];
for (int x = 0; x < 100; x++) {
for (int y = 0; y < 100; y++) {
string rand = rng.Next ().ToString ();
stars [x, y] = int.Parse(rand.Substring(rand.Length - 1)) < currentSector.starDensity ? 1 : 0;
}
}
return stars;
}
public void DrawStars(GameObject starObject){
// Just cycle through the int[,] stars and every time I find a 1,
// I place a small sphere prefab
int starCount = 0;
for (int x = 0; x < 100; x++) {
for (int y = 0; y < 100; y++) {
if (currentSector.stars [x, y] == 1) {
GameObject star = (GameObject)Instantiate(starObject,new Vector3((x-50)*20,0,(y-50)*20),transform.rotation,transform);
starCount++;
}
}
}
Debug.Log (starCount);
}
int[,] CalcAsteroids() {
// 100x100 is my int[,] - I then multiply it by 20 to essential make
// this 2000x2000 when I actually place the objects
// This also allows me to space them out away from each other
int[,] asteroids = new int[100, 100];
for (int x = 0; x < 100; x++) {
for (int y = 0; y < 100; y++) {
// Place exactly 100 asteroids in the int[,] asteroids
// No more, no less, maintaining a fairly random distribution
// I don't want it to stop at 100 placed otherwise only the
// first part of the map will contain asteroids
// I need to ensure all asteroids are placed, and they aren't all in one area
}
}
return asteroids;
}
I have just looked into "Shuffling" an array - however this would not be based on a seed, thus every time it loads this space sector, the asteroids would be in different spots. So in addition to my question posted - I need to ensure the placement of the 100 asteroids is random by based on the same seed as the stars are generated by (or the Next() of the System.Random).
Answer by seandolan · Apr 10, 2018 at 02:26 PM
I got it to work to some degree with a loop of 0 to 99 and my checking 5 times that the entry doesn't exist already. This is the code:
int[,] CalcAsteroids(int seed) {
System.Random rng = new System.Random (seed);
int[,] asteroids = new int[100, 100];
for (int x = 0; x < 100; x++) {
for (int y = 0; y < 100; y++) {
asteroids [x, y] = 0;
}
}
for (int i = 0; i < 100; i++) {
int sampleX = rng.Next (0, 100);
int sampleY = rng.Next (0, 100);
if (asteroids [sampleX, sampleY] == 0) {
asteroids [sampleX, sampleY] = 1;
} else {
sampleX = rng.Next (0, 100);
sampleY = rng.Next (0, 100);
if (asteroids [sampleX, sampleY] == 0) {
asteroids [sampleX, sampleY] = 1;
} else {
sampleX = rng.Next (0, 100);
sampleY = rng.Next (0, 100);
if (asteroids [sampleX, sampleY] == 0) {
asteroids [sampleX, sampleY] = 1;
} else {
sampleX = rng.Next (0, 100);
sampleY = rng.Next (0, 100);
if (asteroids [sampleX, sampleY] == 0) {
asteroids [sampleX, sampleY] = 1;
} else {
sampleX = rng.Next (0, 100);
sampleY = rng.Next (0, 100);
if (asteroids [sampleX, sampleY] == 0) {
asteroids [sampleX, sampleY] = 1;
}
}
}
}
}
}
return asteroids;
}
I'm not 100% sure what you're trying to accomplish with the 2-dimensional array, but wouldn't be a simple loop that creates a random Vector and spawns a star at that point be enough? For Example:
Random rng = new Random(seed);
int starCount = 100;
float width = 100f;
float height = 100f;
float depth = 50f;
for(int i=0; i<starCount;i++){
Vector3 spawnpos = Vector3.zero;
spawnpos.x = rng.Range(-width/2,width/2);
spawnpos.y = rng.Range(-height/2,height/2);
spawnpos.z = rng.Range(-depth/2,depth/2);
Instantiate(starObject,spawnpos,transform.rotation,transform);
}
That might create overlaps of the asteroids. Al all of my solar systems are generated off of a seed, I need to make sure I am not overlapping any. I can also reference where the asteroids are positioned for my map at a later time. I do appreciate your input. I only wish I could implement your more efficient method of creation but I need the location data easily accessible for other game functionality.