Consigue un anillo de fichas en una cuadrícula hexagonal

17

Gracias a esta publicación: fichas hexagonales y encontrar a sus vecinos adyacentes , puedo recoger fichas adyacentes a una ficha determinada. Pero estoy bastante atascado en un algoritmo que me da solo un "anillo" de mosaicos especificados por un desplazamiento. El algoritmo dado en esa publicación de desbordamiento de pila no se preocupa exactamente por el orden en que recoge los mosaicos.

Sé que con cada desplazamiento se agregan 6 fichas.

  • El desplazamiento 1 te da 6 fichas (las primeras fichas adyacentes).
  • Offset 2 te da 12.
  • Offset 3 te da 18, etc.

Hay un crecimiento constante de 6 con cada desplazamiento. Así que supongo que debería haber una regla que se adapte a estas compensaciones. No puedo entender exactamente esto. ¿Nadie?

Sidar
fuente

Respuestas:

23

Un anillo hexagonal con el radio de N consta de 6 líneas rectas, cada una con una longitud N; vea mi ejemplo extremadamente crudo a continuación :) Para N = 2:

ingrese la descripción de la imagen aquí

Las flechas cubren 2 hexes cada una.

Supongo que tiene algunas funciones que le dan el mosaico vecino en una dirección específica, como norte (), sureste (), etc. Así que su algoritmo, en pseudocódigo, debería ser algo como esto:

var point = startingPoint.north(N)
for i = 0..N-1:
    result.add(point)
    point = point.southeast(1);
for i = 0..N-1:
    result.add(point)
    point = point.south(1);
for i = 0..N-1:
    result.add(point)
    point = point.southwest(1);
for i = 0..N-1:
    result.add(point)
    point = point.northwest(1);
for i = 0..N-1:
    result.add(point)
    point = point.north(1);
for i = 0..N-1:
    result.add(point)
    point = point.northeast(1);

Tenga en cuenta que esto también debería funcionar para casos extremos N = 1, que devuelve 6 mosaicos, y N = 0 que devuelve un conjunto vacío.

Sé que el código no es perfecto :) Hay algo de redundancia aquí. En mis proyectos que usan mapas en mosaico regularmente (hexagonales o de otro tipo), generalmente tengo una "Dirección" de enumeración, que me permite hacer esto más suavemente:

var point = startingPoint.inDir(N, Direction.North)
var dir = Direction.SouthEast.
for d = 0..Direction.count():
    for i = 0..N-1:
        result.add(point)
        point = point.inDir(1, dir);
    dir = nextDirection(dir);
Liosan
fuente
Esto debería empujarme en la dirección correcta. ¡Gracias!
Sidar
2
Tenga en cuenta que el ejemplo de código agregará puntos duplicados para los primeros cinco segmentos. Sin embargo, es una buena respuesta.
MichaelHouse
@ Byte56 Sí, pensé. ¡Pero al menos veo la conexión entre los cambios de dirección!
Sidar
1
@ Byte56 ¿En serio? Hm. Traté de evitar ese ... 0..N-1 da 0..1 para N = 2, entonces eso es i = 0 e i = 1, que son 2 valores. 2 valores de cada vez 6 direcciones son 12 fichas, como debería ser ...?
Liosan
No Tienes razón. Dado que cada bucle agrega un punto del último bucle, me equivoqué por uno para los bucles, mi error. Es un algoritmo inteligente.
MichaelHouse
2

He encontrado que este artículo es una muy buena referencia para los algoritmos de cuadrícula hexagonal, y su sección sobre "Distancias" proporciona un método para determinar el número de pasos entre dos mosaicos. Si convierte sus coordenadas axiales (xy) en coordenadas de cubo (xyz), la distancia siempre es igual a la mayor de las compensaciones de coordenadas entre las dos teselas, o max (| dx |, | dy |, | dz |).

Una búsqueda exhaustiva de la cuadrícula completa para las fichas a la distancia deseada es O(norte2) con las dimensiones de la cuadrícula, pero es una implementación simple que funciona bien para cuadrículas pequeñas.

ingrese la descripción de la imagen aquí

KPM
fuente