Estoy escribiendo un juego por turnos que tiene algunos elementos de simulación. Una tarea en la que estoy colgado actualmente es encontrar el camino. Lo que quiero hacer es mover cada turno un aventurero de IA una ficha más cerca de su objetivo usando su x, y actual y su objetivo x, y.
Al tratar de resolver esto por mí mismo, puedo determinar 4 direcciones sin problema usando
dx = currentX - targetY
dy = currentY - targetY
pero no estoy seguro de cómo determinar cuál de las 6 direcciones es en realidad la ruta "mejor" o "más corta".
Por ejemplo, en la forma en que está configurada actualmente, uso East, West, NE, NW, SE, SW pero para llegar a la casilla NE me muevo hacia el este y luego hacia el NW en lugar de solo mover hacia el NW.
Espero que esto no haya sido todo divagado. Incluso un enlace o dos para comenzar sería bueno. La mayor parte de la información que he encontrado está en dibujar las cuadrículas y asimilar el extraño sistema de coordenadas necesario.
fuente
Respuestas:
Algunas respuestas!
El sistema de coordenadas que he visto con mayor frecuencia para el recorrido basado en hexágono es uno en el que el jugador puede moverse en todas las direcciones normales de NSEW, así como NW y SE. Luego, solo representa cada fila con un desplazamiento de medio cuadrado. Como ejemplo, la ubicación (2,7) se considera adyacente a (1,7), (3,7), (2,6), (2,8), y las extrañas: (1,6) y (3,8). Mientras tanto, si suponemos que (2,7) se representa en el centro de la pantalla, (2,6) se representará hacia arriba y hacia la derecha, (2,8) se representará hacia abajo y hacia abajo -la izquierda, (1,7) y (3,7) lo colocarán a la izquierda y derecha respectivamente, y (1,6) y (3,8) se colocarán arriba a la izquierda y abajo a la derecha respectivamente.
Un diagrama de lo que quiero decir:
Si lo está haciendo de esta manera, encontrar el camino directo más corto no es difícil: recorra la distancia máxima NW / SE que pueda sin sobrepasar su objetivo a lo largo de un eje cardinal, luego viaje directamente a lo largo de ese eje hasta el objetivo.
Pero, por supuesto, eso te llevará directamente a través de montañas u otro terreno intransitable. Para responder una pregunta que aún no ha formulado: El algoritmo de búsqueda A * es un enfoque común y razonablemente bueno para encontrar rutas. Manejará no solo diseños extraños que no sean de cuadrícula, sino que felizmente se enfrentará a obstáculos e incluso a terrenos obstruidos / lentos.
fuente
Acabo de publicar una biblioteca de utilidades de cuadrícula hexadecimal en CodePlex.com aquí: https://hexgridutilities.codeplex.com/ La biblioteca incluye la búsqueda de rutas (usando A- * a la Eric Lippert) e incluye utilidades para la conversión automática entre cordones irregulares (denominados Usuario) y coordenadas no irregulares (denominados canónicos). El algoritmo de búsqueda de ruta permite que el costo del paso para cada nodo varíe tanto con el hexágono de entrada como con el lado hexagonal atravesado (aunque el ejemplo proporcionado es más simple). Además, se proporciona un campo de visión elevado mediante la proyección de sombras, [editar: palabras eliminadas].
Aquí hay una muestra de código que se convierte fácilmente entre tres sistemas de coordenadas de cuadrícula hexadecimal:
IntMatrix2D e IntVector2D son implementaciones enteras [editar: homogéneas] de affine2D Graphics Vector y Matrix. La división final por 2 en las aplicaciones de vector es volver a normalizar los vectores; esto podría estar oculto en la implementación de IntMatrix2D, pero la razón del séptimo argumento para los constructores de IntMatrix2D es menos obvia. Tenga en cuenta el almacenamiento en caché combinado y la evaluación diferida de las formulaciones no actuales.
Estas matrices son para el caso:
La biblioteca de códigos mencionada anteriormente proporciona un mecanismo igualmente elegante para la selección hexadecimal (es decir, identificar el hexadecimal seleccionado con un clic del mouse).
En coordenadas canónicas, los 6 vectores de dirección cardinales son (1,0), (0,1), (1,1) y sus inversas para todos los hexágonos, sin la asimetría de las coordenadas irregulares.
fuente
public IntVector2D Normalize() { if (Z==1) return this; else { var x = (X >= 0) ? X : X - Z; var y = (Y >= 0) ? Y : Y - Z; return new IntVector2D(x/Z, y/Z); } }
Este es un problema resuelto, con mucha literatura para respaldarlo. El mejor recurso que conozco es en Red Blob Games: https://www.redblobgames.com/grids/hexagons/ .
En resumen, la razón más probable es que comenzó con un sistema de coordenadas incorrecto. Usar un sistema de coordenadas Cube que implementa el algoritmo A * es bastante simple. Ver demostración en vivo en el enlace de arriba.
Si realmente desea utilizar algún otro sistema, realice la conversión ay desde cuando sea necesario.
fuente