Si, señoras y señor, por algún motivo, que puede que sea un problema del say, o puede que no, la salida se me superpone, y claro, me da un error.
Si correis este código, de un juego de bloques corriente, vereis que cuando ya debería haber acabado el proceso, vuelve a retomar un bucle que ya debería estar acabado y por consiguiente, me da un error perro.
Bueno, ya he solucionado el problema anterior con una chapuzero apaño, el problema es que ahora, al intentar reconocer las horizontales, lo hace mal, y las verticales directamente se sale del programa sin dar siquiera un error, ninguno....
Al final esto va a ser un log de versiones, je je je. Bueno, acabo de solucionar los problemas anteriores, ahora estoy trabajando en otro que me trae de cabeza, la salida (el say) lo da bien, el problema viene cuando se llama al segundo matafilas.
La idea es que un matafilas, liquida a los bloques que deba, vacia sus casillas, y llama al siguiente matafilas, pero no se como hacerlo para darle tiempo al siguiente matafilas para que las piezas se coloquen antes de que el analice. El problema actual, es que, el matafilas liquida las piezas, y antes de que las superiores puedan ocupar los huecos que quedan libres, el otro matafilas analiza la situación, y claro, no encuentra nada hasta la siguiente iteración, en la que ya se han colocado las piezas.
¿se solucionará con un frame?
Probadlo, y vereis....
[code language="bennu"]
#define _verde rgb(20,255,20)
#define _rojo rgb(255,20,20)
#define _azul rgb(20,20,255)
PROGRAM bloques;
INCLUDE "DLL\import.prg"; //Incluye las DLL necesarias para que todo funcione
const
_bloque=20;
x_screen=300;
y_screen=400;
true_x_screen=600;
true_y_screen=480;
_filas=y_screen/_bloque;
_columnas=x_screen/_bloque;
_desp_x=50;
GLOBAL
espacios[_filas][_columnas];
IDS[_filas][_columnas];
activo=false;
vel=50;
matadores=0;
local
int i,j;
BEGIN
set_mode(true_x_screen,true_y_screen,32,MODE_WINDOW); //Resolución de pantalla a 800x600 píxel, 32 bits de color y en modo ventana
from y=1 to _filas;
from x=0 to _columnas;
write_var(0,(x*_bloque)+_desp_x,y*_bloque,4,espacios[y]
- );
end
end
set_text_color(rgb(10,10,255));
write(0,_desp_x-20,2,4,"0");
from y=1 to _filas;
write(0,_desp_x-20,y*_bloque,4,y);
end
loop
if(!activo and matadores<=0)
pieza(rand(1,2));
activo=true;
end
if(key(_esc))exit();end
frame;
end
END
Process matafilas()
private
matados=false;
ini=0;
int w=0;
fin=0;
v_ini=0; //este va a corresponder con la columna, puesto que la fila ya sabemos cual es
v_fin=0;
int n;
begin
matadores++;
/*graph=new_map(10,10,32);
map_clear(0,graph,rgb(rand(0,255),rand(0,255),rand(0,255)));
x=rand(10,x_screen);
y=rand(10,y_screen);*/
for(i=0;i<=_filas and not matados;i++)
//say("Buscando piezas en horizontal...");
for(j=0; j<_columnas and fin-ini<1; j++) //de este bucle sale en cuanto encuentre más de 2 piezas iguales seguidas
if(espacios[j]==espacios[j+1] and espacios[j]!=0)
ini=j;
for(n=j+1;n<_columnas and espacios[n]==espacios[n+1];n++)
fin=n+1;
j=n+1;
say(i+"ini "+ini+" fin "+fin);
end
end
end
//say("Buscando piezas en vertical...");
for(j=0; j<_columnas and v_fin-i<1; j++)
//empieza en ini para ver si es un combo de L o algo así, si antes no hubiera encontrado nada en fila ini seria 0
if(espacios[j]==espacios[i+1][j] and espacios[j]!=0)
v_ini=j; //esto marca en que columna estamos
for(n=i+1;n<_filas and espacios[n][j]==espacios[n+1][j];n++)
v_fin=n+1;
say(i+"v_ini "+v_ini+" fin "+v_fin);
end
end
end
/*Ahora, si se ha encontrado algo, tanto en horizontal como en vertical, se procederá a liquidarlo*/
if(fin-ini>1 or v_fin-i>1) //el v_fin se calcula con la i porque es la que nos indica la fila, que es el inicio de la verticalidad
from w=1 to 8;
say("Flaseando fila horizontal "+i+" boque "+ini+"-"+fin);
for(j=ini; j<=fin and fin-ini>1;j++)
say("bloque "+i+"-"+j);
if(w%2==0)
ids[j].flags=4;
else
ids[j].flags=2;
end
end
for(j=i;j<=v_fin and v_fin-i>1;j++)
say("Flaseando fila vertical "+i+" bloque_v "+i+"-"+v_fin);
if(w%2==0)
ids[j][v_ini].flags=4;
else
ids[j][v_ini].flags=2;
end
end
frame(300);
end
/*Ahora mata a todas las piezas...*/
say("Se van a matar piezas en horizontal si hubiera...");
for(j=ini;j<=fin and fin-ini>1;j++) //en horizontal
say("Matando "+i+"-"+j);
matados=true;
signal(IDS[j],s_kill);
espacios[j]=0;
end
say("Se van a matar piezas en vertical si hubiera...");
for(j=i;j<=v_fin and v_fin-i>1;j++)//y en vertical*/
say("Matando "+j+"-"+v_ini);
matados=true;
signal(IDS[j][v_ini],s_kill);
espacios[j][v_ini]=0;
end
v_fin=0;
v_ini=0;
ini=0;
fin=0;
//say("llamando de nuevo al matafilas");
//matafilas();//si ha matado a alguien, se llama a sí mismo para volver a buscar si hiciera falta
end
END
if(!matados)//si no ha matado bloques, no hay nada más que mirar, pasa a la siguiente pieza
say("El matafilas actual no encontró nada, se autoriza la siguiente ficha");
activo=false;
else//si no, se requiere una revisión de los bloques, y se llama de nuevo a sí mismo
say("llamando a otro matafilas");
frame;
matafilas();
end
matadores--;
end
/*********************matafilas*********************************/
/*********************bloques*********************************/
process pieza(color)
private
int fila=0;
int col=0;
float semi_fila=0;
begin
col=rand(1,_columnas-1);
pieza_d(rand(1,2),col+1);
y=0;
graph=cubo(color);
repeat
/*durante el repeat el bloque va actualizando sus valores de fila
y columna a la para que va bajando, el orden de las sentencias es importante*
*/
espacios[fila][col]=0;
semi_fila+=(float)vel/100;
fila=semi_fila; /*Es importante que esto esté aquí para que la comprobación sea correcta
de lo contrario, primero comprobamos, y luego nos movemos, pero la comprobación
se realizó en la fila superior, con lo cual, errores, errores */
if(key(_left) and col>0 and espacios[fila][col-1]==0 )
col--;
elsif(key(_right) and col<_columnas and espacios[fila][col+1]==0)
col++;
end
espacios[fila][col]=color;
y=fila*_bloque;
x=(col*_bloque)+_desp_x;
frame;
until(espacios[fila+1][col]!=0 or y>=y_screen)
/*al llegar al final, fila y col son las posiciones del array definitivas del bloque*/
espacios[fila][col]=color;
ids[fila][col]=id;
matafilas();
loop
if(fila<_filas and espacios[fila+1][col]==0) //si el hueco de abajo está libre
y+=_bloque; //baja
espacios[fila+1][col]=color; //marca la casilla en cuestión de su color
IDS[fila+1][col]=id; //marca la casilla en cuestión con su id
espacios[fila][col]=0;//deja vacia su casilla
IDS[fila][col]=0;
fila=fila+1; // y actualiza su valor de fila
end
frame;
end
end
process pieza_d(color,col)
private
int fila=0;
float semi_fila=0;
begin
y=0;
graph=cubo(color);
repeat
/*durante el repeat el bloque va actualizando sus valores de fila
y columna a la para que va bajando, el orden de las sentencias es importante*
*/
semi_fila+=(float)vel/100;
fila=semi_fila; /*Es importante que esto esté aquí para que la comprobación sea correcta
de lo contrario, primero comprobamos, y luego nos movemos, pero la comprobación
se realizó en la fila superior, con lo cual, errores, errores */
if(key(_left) and col>0 and espacios[fila][col-1]==0 )
col--;
elsif(key(_right) and col<_columnas and espacios[fila][col+1]==0)
col++;
end
y=fila*_bloque;
x=(col*_bloque)+_desp_x;
frame;
until(espacios[fila+1][col]!=0 or y>=y_screen)
/*al llegar al final, fila y col son las posiciones del array definitivas del bloque*/
espacios[fila][col]=color;
ids[fila][col]=id;
loop
if(fila<_filas and espacios[fila+1][col]==0) //si el hueco de abajo está libre
y+=_bloque; //baja
espacios[fila+1][col]=color; //marca la casilla en cuestión de su color
IDS[fila+1][col]=id; //marca la casilla en cuestión con su id
espacios[fila][col]=0;//deja vacia su casilla
IDS[fila][col]=0;
fila=fila+1; // y actualiza su valor de fila
end
frame;
end
end
Function int cubo(color)
private
dword colores[4];
begin
colores[1]=_rojo;
colores[2]=_verde;
colores[3]=_azul;
graph=new_map(_bloque,_bloque,32);
drawing_map(0,graph);
drawing_color(colores[color]);
map_clear(0,graph,rgb(250,200,20));
draw_box(1,1,_bloque-1,_bloque-1);
return graph;
end
[/code]
Y aqui el import
[code language="bennu"]import "mod_video";
import "mod_proc";
import "mod_map";
import "mod_key";
import "mod_text";
import "mod_rand";
import "mod_draw";
import "mod_say";
[/code]
Gracias Drumpi por tu tiempo.
En un principio me plantee lo que dices de hacerlo en una función (aunque no estaba seguro de que congelara al padre, lo intuia), pero tal como tengo planteado ahora el código, sí que hace operaciones gráficas.
El frame(300) es para darle un poco de cadencia al parpadeo, me imagino que es la peor forma de hacerlo, pero funciona.
Probé lo que dije, de ponerle un frame antes de llamar al siguiente matafilas (para un segundo análisis) pero me parece chapucero, pues a veces las piezas pueden tardar más de un frame en acomodarse.
Gracias.
¿A alguien se le ocurre como puedo implementar un sistema de control que sea bueno para manejar, al menos, tres piezas?
Gracias.