Geração aleatória de mapas - estratégias para dispersão / agrupamento de nós aleatórios

10

Estou fazendo um jogo simples de estratégia 4X no espaço, onde cada nó é um ponto de interesse (um planeta, um asteróide e etc.).

Para gerar um mapa aleatoriamente, eu seguiria as etapas abaixo

  1. Decida quantos tipos de nós o mapa terá (talvez, digamos, 5 planetas parecidos com a Terra, 10 planetas estéreis etc.)

  2. Coloque cada tipo de nó no mapa.

Para a etapa 2, gostaria de ter uma distribuição uniforme de cada tipo de nó. Por exemplo, eu começaria colocando todos os planetas semelhantes à Terra. Se eu simplesmente fizer um rand (map.width, map.height) para determinar a posição, posso acabar com todos os planetas semelhantes à Terra agrupados, o que dará vantagem ao jogador que começar nessa área.

Existem métodos, como o uso de diferentes funções gráficas ou de ruído, que podem gerar uma sequência de coordenadas (x, y) espalhadas uma da outra. Da mesma forma, existem maneiras de gerar coordenadas próximas umas das outras?

Extrakun
fonte
1
Marque uma resposta como aceita, seja minha ou de outra pessoa. Obrigado.
Engenheiro de

Respostas:

8

O problema que você está enfrentando é que a seleção aleatória não discrimina, e isso pode significar que não é o ideal para o que você precisa fazer. Mas há pelo menos uma maneira fácil de solucionar isso:

  1. Divida seu espaço em setores (por exemplo, se você tem uma área de 100 por 100 e precisa gerar 100 desses sistemas solares, divida sua área em uma grade de setores de 10 por 10)

  2. Faça um loop em cada setor e repita a etapa 3 (que, por sua vez, repetirá a etapa 4 várias vezes)

  3. Determine aleatoriamente o número de planetas para o sistema solar atual (por exemplo, para um intervalo de 3 a 7 planetas, basta adquirir um número aleatório que varia de 0 a 4 e adicionar 3) no setor atual (se você tiver mais de um sistema solar sistema em um setor, é aqui que você configuraria outro loop)

  4. Atribua aleatoriamente seus planetas no sistema solar atual identificado pelo seu loop (você também pode usar números aleatórios para aumentar as distâncias mínimas entre os planetas); é aqui que você decide os tipos de planetas, que também podem ser determinados aleatoriamente com uma variedade de pesos ou com o método que você preferir

Você também pode definir uma área "fora dos limites" ao redor de cada setor para impedir que planetas de setores vizinhos façam contato direto entre si (apenas no caso de serem efetivamente localizados aleatoriamente lado a lado) ou. ..

Outra solução pode estar no momento de decidir a localização de cada sistema solar e / ou planeta, apenas para executar uma verificação rápida de proximidade com os setores vizinhos e ajustar de acordo (por exemplo, afastar-se da borda por uma distância mínima mais uma distância aleatória )

Randolf Richardson
fonte
De nada! E +1 por postar algum acompanhamento sobre o que resolveu seu problema. =)
Randolf Richardson
8

A melhor maneira de garantir uma distribuição uniforme é tratar cada nó como uma espécie de partícula física. Primeiro, faça uma distribuição aleatória através de um plano xy contínuo (ponto flutuante). Ao aplicar forças de repulsão entre cada par distinto de partículas individuais no avião, você descobrirá que elas se espalham lentamente. Em certo sentido, é como uma resolução de colisão, só que não há contato real para falar. É então simples converter esse plano ("rasterizar") novamente em uma grade indexada por número inteiro. Você pode simplesmente fazer isso a partir de uma grade com índice inteiro, mas pode ser um pouco mais difícil obter as coisas "agradáveis" - isso depende de quão alta é a resolução da sua grade ... quanto maior, melhor , nesse caso.

Obviamente, você também pode aplicar algum tipo de força a partir das bordas do plano quadrado, ou poderá encontrar muitas partículas "lavando-se nas margens". Como alternativa, você pode criar um campo muito maior do que o necessário e tirar uma foto instantânea de uma pequena área disso - isso evita o problema mencionado acima.

Quando você quiser garantir o oposto, ou seja, que o agrupamento não ocorrer, então olhar para a distribuição "padrão" ou "Gaussian". É por isso que os campos estelares gerados aleatoriamente geralmente parecem falsos; eles usam distribuição aleatória pura em vez de um modelo de distribuição mais naturalista.

Engenheiro
fonte
1
Você também pode obter um comportamento de agrupamento a partir do modelo "físico", basta usar um conjunto de regras diferente, possivelmente usando uma mistura de atração e repulsa. As opções são infinitas, basta encontrar o modelo certo.
Aaaaaaaaaaaa
6

Você pode usar um algoritmo simples de distribuição de disco Poisson para obter uma distribuição de "ruído azul". Isso resulta em pontos no plano que são aproximadamente espaçados igualmente um do outro. Isso funciona não apenas no seu exemplo 2D, mas também no 3D, e também em espaços não euclidianos, mas os cálculos podem se tornar rapidamente difíceis de manejar.

A idéia básica desses algoritmos é que você comece com um primeiro ponto "inicial" e depois trabalhe para fora adicionando pontos aleatórios ou pseudo-aleatórios no espaço anular entre as distâncias máximas e mínimas que você gostaria de ter do ponto em diante e eliminando aqueles que estão muito próximos um do outro. Seu algoritmo trabalha para fora dessa maneira, até que a quantidade de pontos necessários seja adicionada (o que fornece uma nuvem de pontos aproximadamente circular) ou o espaço disponível seja preenchido.

Um algoritmo alternativo rápido e elegante para geração de ruído 2D, bem como uma breve discussão sobre suas propriedades, pode ser encontrado em " Uma estrutura de dados espaciais para geração rápida de amostras de disco de Poisson " por Daniel Dunbar e Greg Humphreys, da Universidade da Virgínia.

Martin Sojka
fonte
2
Nunca tinha ouvido falar de distribuições de disco de Poisson - bom link!
tenpn