Abril 19, 2018, 05:32:53 AM Ultima modificación: Abril 19, 2018, 05:38:04 AM por getnoff
Buenas, tengo un problema que no sé como resolver, aquí voy:

Estoy creando un juego de mesa que es en un tablero hexagonal y se van poniendo fichas (tipo damas chinas, hex) y el juego se basa en la conexión de las fichas, un jugador con blancas y otro con negras y van poniendo una ficha por turno; bueno mi problema es que no se me ocurre qué algoritmo usar para detectar anillos... con esto me refiero a que las fichas hacen una formación de un anillo, acá unos ejemplos.


O sea que encierren un área dentro teniendo al menos una casilla dentro, pero no sé como detectar cuando pasa eso.
Como dato adicional, cada casilla le he asignado string de coordenadas para identificarlas, y cambia de estado según está vacía u ocupada por una ficha, también he creado una lista con las coordenadas de las fichas que van conectándose, uso la función instance_nearest para detectar las 6 casillas alrededor si hay fichas conectadas, ....

A bote pronto, se me ocurre usar collision_circle con varios radios, y que te vaya devolviendo el número de instancias que va colisionando. A partir de ahí las filtras por color.

No creo que eso sea suficiente, ya que mi problema no es que no pueda detectar las instancias con fichas de cierto color, sino que no logro detectar cuando encierran un área dentro... los anillos pueden tener cualquier forma con tal que se cierren, e incluso dentro pueden tener fichas de cualquier color.

El tablero se podría guardar en un array 2D, para evitar guardar las coordenadas como strings.
Los anillos se podrían detectar de esta forma, pero revisando 6 celdas adyacentes en lugar de 4.
https://stackoverflow.com/questions/30903506/detecting-closed-loop-in-a-2d-array-pattern

#4 Abril 21, 2018, 03:31:05 AM Ultima modificación: Abril 21, 2018, 12:30:06 PM por getnoff
gracias clamud por el link, eso es lo que busco... aunque cuesta mucho entender el código estando en otro lenguaje de programación, ¿por favor me guías un poco en que consiste?

Edito: leyendo ese post vi que mencionan el algoritmo Flood Fill y analizándolo me dio una idea, debo mirar las casillas de adentro y chequear las adyacentes con un ciclo, y las fichas blancas actuan como tapones, en ese ciclo si hay camino libre al borde del tablero entonces no hay anillo desde esa casilla, de lo contrario hay anillo... ya estoy viendo que funciona, lo probaré ;D

Creo que "flood fill" es la solución. Estuve probando el ejemplo de Stack Overflow y detecta loops aunque no existan ceros dentro del loop, entonces no sirve para lo que necesitas.

Después encontré esta alternativa
https://www.geeksforgeeks.org/find-number-of-islands/
que utiliza el algoritmo DFS para encontrar todas las celdas adyacentes. El problema es que DFS es recursivo y he leído que GMS tiene un límite reducido de niveles de recursión, por lo que no es muy seguro.

Para evitar la recursión se puede usar BFS
https://es.wikipedia.org/wiki/B%C3%BAsqueda_en_anchura

Con esa información logré hacer un programa que asigna colores aleatorios a islas de 0's separadas por barreras de 1's. El editable está adjunto.

Para que funcione como lo necesitas debes agregar más posiciones de celdas adyacentes y verificar que las islas no tocan la orilla del tablero.

#6 Abril 23, 2018, 01:31:17 AM Ultima modificación: Abril 27, 2018, 11:23:53 AM por getnoff
Muchas gracias, el ejemplo está muy bueno, nada más que estoy usando gm 8.0 por lo que tuve que instalar el 8.1 y manualmente convertirlo a .gmk pero no importa me tomé el trabajo y funciona perfecto. Con esto ya tengo material suficiente para implementar lo que necesito (quizás me toque rehacer varias cosas porque no tengo el tablero a base de arrays, pero lo lograré)

Edito: ya lo he logrado, agradezco mucho la ayuda.