Tengo un mapa simple basado en cuadrícula compuesto de habitaciones, como este (A = entrada, B = salida):
0 1 2 3 ######### 0 # B # ##### ######### 1 # ### # ######### 2 # # # # # # 3 # # # ######### 4 # ### # ######### 5 ### A # ### # 6 ### # #########
Y estoy atrapado tratando de hacer un algoritmo adecuado para crear un camino de puertas entre las habitaciones, de tal manera que el jugador tenga que explorar la mayor parte del mapa antes de encontrar la salida.
En otras palabras, estoy tratando de encontrar el camino más largo posible de A a B .
(Soy consciente de que este problema se puede resolver con gráficos acíclicos; sin embargo, en este caso puede haber ciclos).
EDITAR: Otro ejemplo en el que las habitaciones se conectan mediante un relleno y la salida se elige como la habitación más alejada de la entrada:
0 1 2 3 ######### 0 # B # # # # - ##### 1 # | # # ### # # 2 ### # # ### - # - ### 3 # | ### # - ####### 4 #A | # # # # # 5 # # # # # # 6 # # # #########
Tenga en cuenta que la ruta a la salida no es la ruta más larga posible.
path-finding
roguelikes
Usuario no encontrado
fuente
fuente
Respuestas:
Creo que vas por esto de la manera incorrecta. La ruta máxima en un gráfico con ciclos está técnicamente indefinida porque es infinita si el ciclo se encuentra entre el inicio y el final. Probablemente hay formas inteligentes de extender / restringir la definición de ruta máxima, pero no creo que sea el mejor enfoque aquí.
No está intentando modelar un camino largo real (por ejemplo, un robot que intenta explorar la mayor cantidad de área posible en un mapa). Solo estás tratando de hacer que el jugador explore muchas habitaciones.
Entonces, aprovecha la posibilidad de que el jugador encuentre la salida proporcional al porcentaje del mapa explorado hasta ahora . Digamos que hay X habitaciones en un nivel, y el personaje jugador ha explorado Y. La próxima vez que el personaje ingrese a una habitación, coloque la salida allí con probabilidad f (Y, X). Un ejemplo trivial de f podría ser (Y * Y) / (X * X), por ejemplo, para 10 habitaciones, hay un 100% de posibilidades de que salga en la última habitación, un 81% de posibilidades de que esté en la penúltima habitación, y solo un 1% de probabilidad de que esté en la primera habitación.
Puedes ajustar la ecuación como quieras para que el juego se sienta bien, y tal vez incluso darle al jugador algunas habilidades para que sea más probable que genere. La parte clave es, no generar la salida hasta que el personaje realmente entre en la habitación. Este método también es inmune al conocimiento del jugador sobre el algoritmo de generación de mazmorras; incluso si el jugador tiene patrones de movimiento extraños como el salto del caballero en NetHack o teletransportación, tendrá que explorar más habitaciones para encontrar la salida.
Si debe generar estáticamente la salida, puede usar la misma idea con un personaje virtual. Imagine un relleno de inundación a partir de la posición del personaje, moviéndose una vez la celda en cada iteración. La última habitación que se llena es la habitación a la que pertenece la salida (de hecho, la última celda que se llena es la celda donde está más alejado del jugador). Sin embargo, en este caso, el jugador tiene más información sobre la salida, si está a la izquierda, probablemente a la derecha, y si puede teletransportarse, en realidad puede llegar más rápido que una caminata aleatoria normal.
Finalmente, acabo de terminar un roguelike donde la salida se generó en el otro lado del mapa del personaje del jugador, y luego deambulé al azar. Algunos elementos en la mazmorra lo hicieron visible en el mapa, a expensas de tener hambre más rápido. No hice ningún análisis, pero definitivamente sentí que tenía que explorar más del mapa para encontrarlo, y le dio a los niveles una sensación única.
fuente
Una alternativa posible sería crear un árbol de expansión (¿máximo?) Utilizando Prim / Kruskal (para eliminar ciclos) y aplicar un algoritmo tradicional de ruta más larga en el árbol de expansión.
Sin embargo, me preocupa que el algoritmo de árbol de expansión tenderá a crear ramas sin salida, lo que obligará al jugador a retroceder constantemente.
EDITAR: resultado de usar un algoritmo basado en Kruskal y colocar la salida al final de la rama más larga:
fuente
Aquí hay algo para jugar:
Quitaría puertas al azar a lo largo del camino, de lo contrario terminas con 1 puerta en la salida y toneladas de puertas al comienzo.
Creo que esto no es
O(n^2)
tan bueno para mapas grandes.fuente
2 publicaciones de desbordamiento de pila similares a esta: ruta más larga del gráfico , referencia de la misma publicación .
fuente
Creo que ya tiene excelentes respuestas, pero aquí está mi solución teórica de $ 0.02 al problema.
Lo que desea NO es el camino más largo, sino el camino más corto más largo. Desea la habitación más alejada, dado que está considerando el camino más corto hacia la habitación. Esto probablemente suene confuso, pero es muy fácil de calcular.
Calcular una ruta más larga real (no tomará demasiado tiempo para decir 10 habitaciones) no funcionará porque no puede hacer que el jugador tome esa ruta más larga. Por lo tanto, poner la entrada y la salida en las dos habitaciones más alejadas es la mejor opción. Para encontrar esto, calcule la habitación más alejada de una habitación aleatoria. Luego, desde esa habitación, encuentra la habitación más alejada. Esto se llama encontrar el diámetro de un gráfico, por favor Google.
fuente