lihuencarranza / algo3-TP

1 stars 0 forks source link

obtener botones desde gridpane #9

Closed lihuencarranza closed 1 year ago

lihuencarranza commented 1 year ago

Holaa, tengo una consulta que tiene que ver con las bombas y los numeros. Voy al caso mas simple, cuando toco una bomba se pierde el juego y se muestran todas las bombas. Yo se la ubicaciones de todas las bombas porque hice una lista pero no se como acceder en la vista desde el gridPane para personalizar los botones. En el código pueden buscar en View.java "#9" para encontrar el problema.

smaraggi commented 1 year ago

Hola Liz. Vi que abriste y cerraste otro hilo, entiendo que encontraste vos misma la solución. Te felicito, porque esa es la vida misma del desarrollador.

Yendo a esta consulta.

_"En el código pueden buscar en View.java "#9" para encontrar el problema."_

Si bien explicás muy bien el problema, esta frase suena un poco general. No obstante, como conocemos todos el buscaminas y, como dije, explicás bien el problema, podemos manejarnos.

Para acceder a los "nodos" de un grid pane encontré este ejemplo en internet:

https://stackoverflow.com/questions/20825935/javafx-get-node-by-row-and-column

De todas formas, ¿no te parecería mejor guardar en una matriz todas las referencias a los botones? De esa manera podrías accederlos directamente para cambiarles el estilo o hacer lo que necesites. La clase View podría beneficiarse de mantener una estructura de datos así. La podrías generar cuando creas la grilla, en el método "setsGrid", a la vez que los asignás al grid, los guardas en la matriz de botones de View (lista de listas, como ya sabés el tamaño de antemano podés usar arrays reservando el espacio que vas a necesitar, que sería más adecuado).

lihuencarranza commented 1 year ago

Gracias, tenía esa idea pero me surgió la consulta para cuando clickeo una caja vacía ya que es entendible hacer una lista de cajas con bombas pero de cada caja vacía es un monton. Necesito saber eso para que cuando la clickeo, se clickeenn las adyacentes. Ahora pienso cómo implementarlo.

smaraggi commented 1 year ago

Perfecto, si, entiendo lo que decís de haber jugado al solitario, que cuando clickeás una que no tiene bombas adyacentes, esta abra todas las cajas alrededor que no tengan bombas. Si te sirve el consejo, la recursividad podría ser una buena idea para este caso, pero pensalo vos.

Por ejemplo, en seudocódigo (muy seudo, esto es para comunicar la idea, no para compilarlo!!), podría hacerse algo como esto...

bool bomba() { return this.content == 'bomba'; // seudocódigo... }

int bombasAdyacentes() { // recorre las cajas adyacentes y se fija cuantas bombas hay alrededor, verificando condiciones de borde para cuando la caja está en el borde (superior, inferior, izquierdo, derecho) ver los vecinos sin salirse del mapa }

abrirCaja(){

if (bomba()) {boom(); } // explota

else if (this.bombasAdyacentes() > 0) { mostrarContenido(this.bombasAdyacentes()) } // muestra el número de bombas adyacentes

else if (this.bombasAdyacentes == 0) {for (caja in cajasVecinas) do: caja.abrirCaja() } // abre recursivamente cajas alrededor mientras el nro. de bombas sea cero, fijate de verificar que la caja haya sido abierta antes o no, aunque si la abrís dos veces podría no ser problema }

lihuencarranza commented 1 year ago

Bueno la parte de minas/bombas la solucioné ya que la cantidad es fija pero con las cajas vacías no. Hice esta función recursiva pero no funciona bien. image El primer if es la condicion de corte, si tiene una bandera no se puede clickear (esto es para las siguientes coordenadas que sean invocadas). Luego se crea un boton clickeado y si tiene un numero le agrego su imagen correspondiente y la devuelvo. Si no tiene numero llama recursivamente a los adyacentes pero eso no funciona porque entra en un loop infinito.

smaraggi commented 1 year ago

Hola, claro, entra en un loop infinito porque siempre se van generando nuevas llamadas entre casillas aledañas. Para hacer eso lo que se hace es marcar las casillas ya visitadas y no entrar de nuevo si ya están "marcadas". Podrías agregar una lista, por ejemplo, de casillas visitadas, y si la casilla ij ya se encuentra en la lista, no le llamás al método; si no está en la lista, la agregás a la lista y le llamás al método. Así se van a ir agotando las casillas visitadas sin generar nuevas llamadas infinitamente.

No fui en todos los detalles en mi explicación porque era la idea general nomás, y luego siempre ustedes son los que implementan. Siempre la recursión tiene que tener bien implementada la condición de corte y de no generación de nuevas llamadas sin control.

lihuencarranza commented 1 year ago

Claro, gracias. Además estaba accediendo a campos que no me pertenecían porque si tocaba por ejemplo coordenadas 0, 0 y entraba en las llamadas, entraba en valores -1, -1. ahi le sume el cambio pero sigue entrando en el loop infinito. Por ahora estoy haciendo que se cliqueen solo las vacías pero no las de numeros porque paso a paso. Estoy usando el debugger de IntelliJ. Y lo que sucede es que una vez clickeada la primera caja vacía llamo a una adyacente. Si la caja estaba en el 0, 0, la primera adyacente sería la -1,-1 pero como está fuera de la matríz puse una condición para que no entre, Aun así, aparece la excepcion y no entiendo porqué.

image

Separé los if para que no acceda a campos si todavía no chequeó que sean válidos pero entra igual en la excepcion.

lihuencarranza commented 1 year ago

Estoy modificando esto, ya encontré errores. Si sale todo bien cicerro el issue.

lihuencarranza commented 1 year ago

El problema estaba bastante gráfico. Los elementos de la matriz son del 0 al 9 y yo estaba permitiendo el 10.