Socorrito - Parece que los bucles se superponen

Started by Danielo515, April 18, 2010, 01:08:35 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Danielo515

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]

Danielo515


Drumpi

No he analizado el código pero:
a) si matafilas sólo sirve para hacer un análisis o unas operaciones que no usan gráficos ¿por qué no usas una función en lugar de un proceso? además, congela al padre hasta que termina.
b) hay un frame(300) en medio del código, creo (ya digo, no he leido el código) que lo pusiste para debug y ahora te sobra ¿no? porque dentro de un bucle, y con el 300 se va a estar ejecutando durante 24 frames.
Siento no ser de más ayuda, pero el tiempo me apremia :S
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

Danielo515

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.

Danielo515

¿A alguien se le ocurre como puedo implementar un sistema de control que sea bueno para manejar, al menos, tres piezas?

Gracias.