Gerar aleatoriamente blocos em um mapa plano
Estou tentando gerar blocos aleatoriamente em um mapa plano e fazê-lo para que eles não se sobreponham. Eu fiz uma matriz (matriz c #) do tamanho do mapa (500x500), os blocos têm uma escala entre 1 e 5. O código funciona, mas se um bloco gerado se sobrepõe a outro, ele é destruído e não é regenerado em outro lugar.
Apenas cerca de 80 dos 1000 blocos que tento gerar não se sobrepõem a outro bloco.
Aqui está uma foto do mapa com cerca de 80 blocos gerados, os quadrados verdes são blocos
void generateElement(int ratio, int minScale, int maxScale, GameObject g) {
bool elementFound = false;
for (int i = 0; i < ratio * generationDefault; i++) {
GameObject el;
// Randomly generate block size and position
int size = Random.Range(minScale, maxScale + 1);
int x = Random.Range(0, mapSizex + 1 - size);
int y = Random.Range(0, mapSizey + 1 - size);
// Check if there is already an element
for (int j = x; j < x + size; j++)
for (int k = y; k < y + size; k++)
if (map[j][k] != null)
elementFound = true;
if (elementFound)
continue;
else {
el = (GameObject)Instantiate(g, new Vector3(x + (float)size / 2, (float)size / 2, y + (float)size / 2), Quaternion.Euler(0, 0, 0));
el.transform.localScale *= size;
}
// Create element on map array
for (int j = x; j < x + size; j++)
for (int k = y; k < y + size; k++)
if (map[j][k] == null) {
map[j][k] = el.GetComponent<ObjectInterface>();
}
}
}
Pensei em 3 possíveis correções
Eu devo definir o tamanho do bloco, dependendo do lugar que ele tem.Eu deveria usar outro algoritmo de randomização.Eu não estou fazendo isso certo.Qual você acha que é a melhor ideia?
ATUALIZAR
Eu consegui o código funcionando muito melhor. Agora, eu tento instanciar os blocos várias vezes, se necessário (máximo de 5 por enquanto) e corrigi os bugs. Se já existem muitos elementos no mapa, eles nem sempre são instanciados e é isso que eu queria, apenas preciso encontrar a quantidade certa de vezes que ele tentará instanciar o bloco.
Tentei instanciar 1280 elementos em um mapa de 500x500. Leva apenas cerca de 1,5 segundo e instancia 1278/1280 blocos (99,843%).
void generateElement(int ratio, int minScale, int maxScale, GameObject g) {
bool elementFound = false;
int cnt = 0;
// Generate every block
for (int i = 0; i < ratio * generationDefault; i++) {
GameObject el = null;
// Randomly generate block size and position
int size, x, y, tryCnt = 0;
// Try maximum 5 times to generate the block
do {
elementFound = false;
// Randomly set block size and position
size = Random.Range(minScale, maxScale + 1);
x = Random.Range(0, mapSizex + 1 - size);
y = Random.Range(0, mapSizey + 1 - size);
// Check if there is already an element
for (int j = x; j < x + size; j++)
for (int k = y; k < y + size; k++)
if (map[j][k] != null)
elementFound = true;
tryCnt++;
} while (elementFound && tryCnt < 5);
if (tryCnt >= 5 && elementFound) continue;
// Instantiate the block
el = (GameObject)Instantiate(g, new Vector3(x + (float)size / 2, (float)size / 2, y + (float)size / 2), Quaternion.Euler(0, 0, 0));
el.transform.localScale *= size;
// Create element on map array
for (int j = x; j < x + size; j++)
for (int k = y; k < y + size; k++)
if (map[j][k] == null) {
map[j][k] = el.GetComponent<ObjectInterface>();
}
cnt++;
}
print("Instantiated " + cnt + "/" + ratio * generationDefault);
}