Generación aleatoria de mapas: estrategias para dispersar / agrupar nodos aleatorios


10

Estoy haciendo un simple juego de estrategia 4X en el espacio donde cada nodo es un punto de interés (un planeta, un asteroide, etc.).

Para generar un mapa al azar, seguiría los pasos a continuación

  1. Decida cuántos tipos de cada nodo tendrá el mapa (quizás, digamos, 5 planetas similares a la Tierra, 10 planetas estériles, etc.)

  2. Coloque cada tipo de nodo en el mapa.

Para el paso 2, me gustaría tener una distribución uniforme de cada tipo de nodo. Entonces, por ejemplo, comenzaría colocando todos los planetas similares a la Tierra. Si simplemente hago un rand (map.width, map.height) para determinar la posición, puedo terminar agrupando todos los planetas similares a la Tierra, lo que dará ventaja al jugador que comienza en esa área.

¿Existen métodos, como el uso de diferentes funciones gráficas o funciones de ruido, que podrían generar una secuencia de coordenadas (x, y) que se extienden entre sí? Del mismo modo, ¿hay alguna forma de generar coordenadas cercanas entre sí?


1
Marque una respuesta como aceptada, ya sea mía o de otra persona. Gracias.
Ingeniero

Respuestas:


8

El problema que enfrenta es que la selección aleatoria no discrimina, y eso puede significar que es un ajuste menos que ideal para lo que necesita hacer. Pero, hay al menos una forma fácil de solucionar esto:

  1. Divida su espacio en sectores (por ejemplo, si tiene un área de 100 por 100 y necesita generar 100 de estos sistemas solares, luego divida su área en una cuadrícula de sectores de 10 por 10)

  2. Recorra cada sector y repita el paso 3 (que, a su vez, repetirá el paso 4 varias veces)

  3. Determine aleatoriamente el número de planetas para el sistema solar actual (por ejemplo, para un rango de 3 a 7 planetas, solo adquiera un número aleatorio que varíe de 0 a 4 y agregue 3) en el Sector actual (si tiene más de un solar sistema en un sector, aquí es donde configuraría otro bucle)

  4. Asigna aleatoriamente tus planetas dentro del Sistema Solar actual identificado por tu circuito (también puedes usar números aleatorios para aumentar las distancias mínimas entre los planetas); aquí es donde decidirías los tipos de planetas, que también podrían determinarse aleatoriamente con una variedad de pesos o cualquier método que prefieras usar

También es posible que desee definir un área "fuera de los límites" alrededor del borde de cada sector para evitar que los planetas de los sectores vecinos entren en contacto directo entre sí (en caso de que se ubicaran de forma aleatoria de manera efectiva uno al lado del otro), o. ..

Otra solución podría estar en el punto de decidir la ubicación de cada sistema solar y / o de cada planeta, simplemente ejecutar una verificación de proximidad rápida contra sectores vecinos y ajustar en consecuencia (por ejemplo, alejarse del borde una distancia mínima más una distancia aleatoria )


¡De nada! Y +1 por publicar un seguimiento sobre lo que resolvió su problema. =)
Randolf Richardson el

8

La mejor manera de garantizar una distribución uniforme es tratar cada nodo como una especie de partícula física. Primero haga una distribución aleatoria a través de un plano xy continuo (punto flotante). Al aplicar fuerzas de repulsión entre cada par distinto de partículas individuales en el avión, encontrará que se separan lentamente. En cierto sentido, es como la resolución de colisión, solo que no hay contacto real para hablar. Entonces es simple convertir ese plano ("rasterizarlo") de nuevo en una cuadrícula indexada con enteros. Para comenzar, simplemente puede hacer esto desde una cuadrícula indexada con enteros, pero puede ser un poco más difícil hacer las cosas "agradables"; esto depende de qué tan alta sea la resolución de su cuadrícula ... cuanto más alta, mejor , en este caso.

Obviamente, es posible que también desee aplicar algún tipo de fuerza desde los bordes del plano cuadrado, o bien puede encontrar muchas partículas "lavando en las costas". Alternativamente, puede crear un campo mucho más grande de lo que necesita, luego tomar una instantánea de un área pequeña de eso, esto evita el problema antes mencionado.

Cuando quieres asegurarte lo contrario, es decir, esa agrupación no se producen, a continuación, buscar en la distribución "estándar" o "gaussiana". Es por eso que los campos estelares generados aleatoriamente a menudo parecen falsos; usan distribución aleatoria pura en lugar de un modelo de distribución más naturalista.


1
También puede obtener un comportamiento de agrupación del modelo de "física", solo tendrá que usar un conjunto de reglas diferente, posiblemente usando una combinación de atracción y repulsión. Las opciones son infinitas, todo lo que hay que hacer es encontrar el modelo correcto.
aaaaaaaaaaaa

6

Puede usar un algoritmo de distribución de disco de Poisson simple para obtener una distribución de "ruido azul". Esto da como resultado puntos en el plano que están más o menos espaciados por igual entre sí. Esto funciona no solo en su ejemplo 2D sino también en 3D, y también en espacios no euclidianos, pero los cálculos pueden volverse difíciles de manejar rápidamente.

La idea básica de esos algoritmos es que comience con un primer punto "inicial", luego trabaje hacia afuera agregando puntos aleatorios o pseudoaleatorios en el anillo entre las distancias máxima y mínima que le gustaría tener desde el punto en adelante y elimine los que yacen demasiado cerca el uno del otro. Su algoritmo luego funciona hacia afuera de tal manera, hasta que se agrega la cantidad de puntos necesarios (lo que le da una nube de puntos aproximadamente circular), o se llena el espacio disponible.

Se puede encontrar un algoritmo alternativo rápido y elegante para la generación de dicho ruido 2D, así como una breve discusión sobre sus propiedades, en " Una estructura de datos espaciales para la generación rápida de muestras de disco de Poisson " por Daniel Dunbar y Greg Humphreys de la Universidad de Virginia


2
Nunca había oído hablar de distribuciones de disco Poisson - ¡buen enlace!
Tenpn
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.