[PC] Ayuda con una función (matrices)

Hola, la verdad que no sabia muy bien como poner el mejor tiutlo posible xDD El tema, estoy haciendo un juegecillo en SDL (si, ya se que es mejor usar opengl en ortho, pero es mas lo primero porque es mas sencillo para un proyecto pequeño como esto, y lo segundo me interesa aprender sdl, opengl ya me la tengo muy vista). Bueno, el juego es tipo el jt´s blocks de yahoo (http://kids.yahoo.com/games/game/jtblocks). Esta el motor mas o menos programado, el problema biene al detectar todos los bloques y romper los iguales. Para guardar los datos del tablero, utilizo una matriz ya que es lo más cómodo. ç

Cuando tu tocas un bloque, se supone que se rompen los bloques que estan en una cruz desde el bloque que tu tocas, y a la vez los bloques que estan en cruz con los que se van a romper. No me explico muy bien asi que lo mejor es que jugeis un poco al juego y veis lo que os quiero decir.

La matriz la tengo de la siguiente manera:
1 = bloques naranjas
2= bloques rojos
3=...

entonces me queda algo como (lo pongo en 8x8):

56237381
15364726
75645332
56473252
35465786
45243163
14354657
15346457

Bueno, el tablero quedaría algo asi, pero un poco mas pensado, ya que eso lo he puesto al azar.

El problema es como puedo detectar cuales se rompen. Lo unico que se me ocurria era detectar la cruz y apartir de hay ir mirando quien rompo pero es imposible, tendria que hacer una condicion para cada posicion.

Espero vuestras ideas.

Gracias y salu2.
Pues no te queda otra que ir haciendolo de manera recursiva (rompo un bloque, miro la cruz, rompo bloque y miro la cruz de los que toquen) o guardas una lista con los bloques contiguos, de manera que si rompes uno de la lista, se rompan todos, pero me da que seria aun mas follon (ya que no siempre se rompera el primero de la lista, asi que te tocaria recorrer toooda la lista)

Porque no lo quieres hacer con lo de la cruz? creo que seria lo mejor.
darix escribió:Pues no te queda otra que ir haciendolo de manera recursiva (rompo un bloque, miro la cruz, rompo bloque y miro la cruz de los que toquen) o guardas una lista con los bloques contiguos, de manera que si rompes uno de la lista, se rompan todos, pero me da que seria aun mas follon (ya que no siempre se rompera el primero de la lista, asi que te tocaria recorrer toooda la lista)

Porque no lo quieres hacer con lo de la cruz? creo que seria lo mejor.

Al principio lo hice, y cuando prove vi que comprobaba la cruz, vale, me dava por ejemplo que los cuatro eran del mismo color, hay tenia que hacer la cruz al primero, si dava que si tenia que hacer la cruz al que le hice la cruz, etc... algo imposible vamos.

salu2
Haces una función recursiva que compruebe los valores en las casillas de alrededor de la casilla que le hayas pasado a la función por parámetros

Si una de las comprobaciones da resultado, borras la casilla del tablero y añades la casilla que haya dado positivo en una lista.

Despues de comprobar todas las casillas de alrededor, compruebas si existe alguna casilla en el array, si existe, la borras del array y llamas a la función de nuevo con esa casilla

Punto y final
judelco escribió:Haces una función recursiva que compruebe los valores en las casillas de alrededor de la casilla que le hayas pasado a la función por parámetros

Si una de las comprobaciones da resultado, borras la casilla del tablero y añades la casilla que haya dado positivo en una lista.

Despues de comprobar todas las casillas de alrededor, compruebas si existe alguna casilla en el array, si existe, la borras del array y llamas a la función de nuevo con esa casilla

Punto y final


Ya te he dicho por msn que ya probe con las funciones recursivas, aun así voy a volver a probar aver...

Salu2
Yo es que no veo el juego, asi que no se como es, pero exactamente que quieres, poner un 0 donde ya no hay bloque?

void eliminarBloque(int x, int y, int color)
{
if( ( x < 0) || (x > MAX_X) || (y < 0) || (y > MAX_Y) ) return;

if(matrix[x,y] == color)
{
matrix[x,y] = 0;
eliminarBloque(x-1,y,color);
eliminarBloque(x+1,y,color);
eliminarBloque(x,y-1,color);
eliminarBloque(x,y+1,color);
}

}

Algo asi no te iria bien? Hecho rapido y corriendo
darix escribió:Yo es que no veo el juego, asi que no se como es, pero exactamente que quieres, poner un 0 donde ya no hay bloque?

void eliminarBloque(int x, int y, int color)
{
if( ( x < 0) || (x > MAX_X) || (y < 0) || (y > MAX_Y) ) return;

if(matrix[x,y] == color)
{
matrix[x,y] = 0;
eliminarBloque(x-1,y,color);
eliminarBloque(x+1,y,color);
eliminarBloque(x,y-1,color);
eliminarBloque(x,y-1,color);
}

}

Algo asi no te iria bien? Hecho rapido y corriendo


No, yo lo ke necesito es lo siguiente:

Toco un bloque, detecto los contiguos de ese color. Una vez detectado detecto los contiguos de los detectados. Asi acabo detectando todos los bloques que estan contiguos. Eliminarlos es lo facil, tengo una funcion que me devuelve quien es en la matriz el bloque que quiero y le pongo un 0, y el resto del programa se encarga el solo de mover la matriz entera para acer que los bloques caigan y esas cosas, lo jodido es detectar a quien elimino.

Me parece que lo de la función recursiva es lo mejor, lo e programado, aver cuando compilo, que el proyecto lo tengo de hace mucho y ahora mismo no tengo sdl instalado en el portatil con windows y el cabron no me conecta a internet, el otro portatil no tiene ni sdk y el sobremesa tiene linux y es un follón ponerme ahora a manipular el proyecto en linux. De todas formas dad ideas, ya prove con las funciones recursivas una vez y nanai, asi que no me inspira mucha confianza -.-

salu2
Ya te digo que el codigo lo que hace es poner un 0 si le has dado a la matriz y a todos los que sean contiguos de ella. Asi que adaptarlo no deberia ser muy dificil, pero no entiendo como lo tienes montado :p

Pero vamos, que yo programe lo mismo que tu estas diciendo (por lo que entiendo) con un codigo similar a este de manera recursiva.
Se puede hacer de forma iterativa pero te puedes volver loco. Como te han dicho recorrer los bloques contiguos de manera recursiva es la solución lógica, ademas de que es la que conceptualmente mas se parece a lo que pretendes hacer (Compruebo mis bloques de alrededor, despues los de alrededor de los que estén a mi alrededor, etc...).
He echo lo que decis, con varias modificaciones mas que nada porque sino borraba el mismo bloque varias veces etc... funciona a medias. Me explico:

-compruebo el bloque de arriba, llamo a la misma funcion recursiva

- compruebo otro bloque, llamo a la misma funcion recursiva

- compruebo otro bloque, llamo a la misma funcion recursiva

- compruebo otro bloque, llamo a la misma funcion recursiva

Compilo, voy a tocar un bloque, pum, se me cierra la aplicacion, yo wtf???

Hago la siguiente prueba:

- compruebo un bloque, llamo a la misma funcion recursiva

- compruebo otro bloque, NO llamo a la funcion

- compruebo otro bloque, llamo a la misma funcion recursiva

- compruebo otro bloque, NO llamo a la funcion

Y fufa pero la mitad obiamente, solo comprueba dos lados, si hago que compruebe mas peta. No se que coño puede ser, porque si vuelvo a poner un 0 a la matriz no pasaria nada, y si vuelvo a borrar el sprite tampoco, porque nos es que lo borre, realmente para borrar lo que haces es dejar de dibujarlo. Voy a seguir trasteando aver...

salu2
Te lo he dejado bastante claro en el post que escribí antes. No haces exactamente lo que dice

Ademas, tu problema de crasheo es que entra en un bucle infinito ya que si comprueba un bloque de la izq por ejemplo, entra en la fucnion para el bloque de la izquierda, que al comprobar el de la derecha, entra en el, que al comprobar el de la izquierda... así sucesivamente.

NO tienes que llamar a la funcion en cada comprobacion, sino ir añadiendo a una lista los bloques que den positivo.

Lee bien Imagen
He echo lo que me a dicho judelco y a funcionado [+risas]

Muchas gracias a todos por la ayuda. A todo esto, si a alguien se le ocurre como hacer ay los niveles seria dios. He pensado en lo siguiente:

Hay x fichas de cada color, mediante random, las reparto por el tablero. Despues compruebo. Si hay mas de x fichas que se pueden romper juntas, empiezo el juego, si no llega a un mínimo rehago el nivel hasta que haya un minimo de fichas rompibles. No se ni cual es el nombre original del juego, asi que no puedo buscar mucha info sobre si los niveles teoricamente se tienen que poder resolver sin que sobren fichas etc... yo creo que va mas al azar.

Salu2 y gracias
Sobre lo de los mapas, pues simple, genera el nivel a la inversa, es decir, empiezas con unos bloques unidos del mismo color, luego (random todo, claro) metes por medio separando a esos bloques otra ristra de otro color, luego repites el proceso todas las veces que sean necesarias hasta rellenar todo el tablero

Suena fácil, pero conlleva muchos controles.
12 respuestas