Você poderia usar um algoritmo que verifica perto de blocos e varia a probabilidade dependendo do que existe - mas acho que é em grande parte a abordagem errada.
O que você deseja observar são os tipos de ruído fractal - nesse caso, ruído perlin ou simplex. Se você gerar ruído, obterá valores de -1 a 1.
http://en.wikipedia.org/wiki/Perlin_noise
Em seguida, você pode ajustar o nível da água definindo o limiar do que faz a água. Para os outros blocos, você pode executar um segundo conjunto de ruído para alternar entre rochas e grama. (dessa forma, você pode ter grandes manchas de água, mas pequenos pedaços de pedra).
getTerrain(x,y) {
if(perlin_noise(x,y) > 0) {
if(perlin_noise(x * scale,y * scale) > 0) {
return rock
} else {
return dirt
}
} else {
return water
}
Como acho que o método de varredura e arremesso é excessivamente complicado e não muito robusto e escalonável, vou sugerir outro método que gostei:
Coloque uma grade em seu mapa, dividindo o mapa em quadrados grandes.
Gere um número aleatório em cada interseção (entre 0 e 1 funcionará para suas porcentagens)
Subdivida cortando cada quadrado em 4 quadrados pares - siga as linhas antigas e, onde você encontrar as linhas de subdivisão, gere um número aleatório entre os 2 pontos adjacentes, da mesma forma que para o centro da cruz, gere um ponto que fique entre os mais altos e valores mais baixos.
Enxague e repita. Você obterá a aleatoriedade inicial no primeiro passe, mas os últimos passes darão alguma uniformidade. Desculpe pelos números psuedo-random:
0-------5 0---3---5 0-1-3-4-5 011233455
| | | | | | | | | | 012344555
| | | | | 0-2-4-6-5 002445665
| | | | | | | | | | 123445666
| | 2---5---7 2-4-5-7-7 234455777
| | | | | | | | | | 233455688
| | | | | 2-3-5-5-9 223455589
| | | | | | | | | | 233455589
2-------9 2---4---9 2-4-4-5-9 234445579
Isso funciona ainda melhor para triângulos, porque você não tem a barra cruzada perdida ao subdividir.
Obviamente, o melhor resultado absoluto virá da combinação desses métodos - camada após camada, algumas técnicas fornecerão grandes massas terrestres, outras darão impressionantes cavernas, outras funcionarão em colinas e outras funcionarão em sistemas de água.
O ruído é uma boa solução, como já foi mencionado. Outra opção é fazer uma segunda passagem nos dados para movê-los para o layout desejado. O Gaussian Blur é uma das muitas maneiras pelas quais você pode conseguir isso. Fazer um passe com isso deve gerar blobs "redondos" de cada tipo.
Não importa qual método você use, porém, uma coisa importante a ter em mente é armazenar os resultados do processo em um novo local. Se você modificar o mapa, as partes que você já processou começarão a afetar o algoritmo e você terá alguns padrões estranhos.
fonte
Uma maneira relativamente simples de fazer isso seria criar um número de núcleos em posições aleatórias. Desenhe o diagrama Voronoi desses pontos. Atribua um elemento a cada região do resultado.
Isso resulta em algo bastante feio e mecânico. Enlamear um pouco as fronteiras e você estará em boa forma.
Se você estiver gerando um mapa grande, poderá fazer isso em dois níveis. Crie seu diagrama inicial de Voronoi usando, digamos, 20 núcleos e chame cada região resultante de nação. Crie outro diagrama usando 400 núcleos e chame cada região resultante de vicaria.
Todos os vicariatos totalmente contidos em uma nação terão o elemento da nação. As vicarias parcialmente contidas em duas ou mais nações tomarão aleatoriamente um dos elementos de suas nações anexas.
Este post merece uma foto, mas estou com preguiça de fornecer uma.
fonte
O Polygonal Map Generator seria uma boa leitura para criar mapas com diferentes 'zonas', o que também proporcionaria mapas melhor formados. É baseado em diagramas de voronoi, mas acho que seria um bom começo para isso.
fonte
você pode fazer isso usando este método:
fonte