¿Q'aecho esto? (II)

Por... Melitón Rodríguez

Cachis la mar, ya me ha vuelto a enrrollar de mala manera el JAPS para que le haga esta sección... Pues la va a hacer su... ¿Cómo dices? 15... Bueno si es por éso, pero que conste que no lo hago por dinero, ¿Eh?

Esta vez vamos a hacer que el mensaje del otro día se imprima en la pantalla una serie de veces. Para eso vamos a usar las banderas cardinales y los bucles. Veamos que es cada cosa:

  1. Las banderas cardinales son exactamente igual que las banderas del PAWS. Sirven para contener valores numéricos. La única diferencia es que en vez de haber 256 de ellas hay 500 (de la 0 a la 499).
  2. Los bucles son una 'estructura' que permite ejecutar repetidamente una serie de condactos. Hay bucles MIENTRAS (que hacen que los condactos de su interior se ejecuten mientras se cumpla una condición) y bucles HASTA (que hacen que los condactos de su interior se ejecuten hasta que se cumple una condición).

Para el ejemplo necesitaremos contar el número de veces que escribimos el mensaje en pantalla; para eso usaremos una bandera y comprobaremos si hemos llegado al valor deseado. Usaremos un nuevo condacto:

IGQ bandera valor

Se trata de una condición que será VERDADERA si el contenido de la bandera coincide con el valor. Usaremos un bucle HASTA: pondremos una bandera a cero y cada vez que imprimamos un mensaje le sumaremos uno, hasta que llegue a un valor dado. La estructura de un bucle de estos sería:

HASTA (condición) {cosas a hacer repetidamente}

También usaremos el condacto:

COPI valor bandera

que pone el valor en la bandera. Y el condacto:

INC valor bandera

que suma valor a la bandera.

El programa se parece bastante al que hicimos la vez anterior:

        \MEN 0
        \0 ""Mi sicólogo es un gilipollas!!""

        \BLO
        BLOQUE [0] Insulto()
        {
                COPI 0 1;        /: En la bandera uno ponemos un cero :/
                HASTA (IGQ 1 20) /: 20 veces :/
                    {
                    MENSAJE 0 0;
                    INC 1 1;
                    }
        }

        Veamos lo que se ha hecho: Primero con el COPI 0 1; ponemos el valor

cero en la bandera 1. Repetiremos lo de dentro del bucle hasta que la bandera 1 valga 20. Dentro del bucle imprimimos el mensaje y sumamos 1 a la bandera 1. ¿Lo entiendes? Pues si no lo entiendes, te puedo concertar una cita con mi sicólogo.

Vamos a hacer uso ahora de una directiva del compilador. ¿Qué diablos es una directiva del compilador? Una directiva del compilador es todo aquello que no genera nada en la base de datos compilada (.AVT) pero que ayuda en la creación del programa. O sea, es algo que hace algo pero que no hace nada, está claro como el agua, ¿no?. La directiva que vamos a usar es la directiva 'define' La directiva 'define' permite asociar un valor a un símbolo (exactamente igual que el 'define' de C o las constantes simbólicas del nuevo SINTAC, por cierto que es un copión el JSJ este, vamos si yo fuese el autor del CAECHO? no sé le diría un par... bueno, bueno, vale JAPS ya me callo, ¡Jolín!. Donde se ha quedado la libertad de expresión en este país!?.) La sintaxis de uso sería:

#define símbolo valor;

Veamos un ejemplo: es bastante típico que en un programa haya una serie de valores 'clave', en nuestro caso el número de veces que se escribe el mensaje. Para que sea fácil de comprender y de mantener el programa, es bastante útil que esos valores estén todos presentes al principio del listado y todos juntos; de forma que si se quiere cambiar el comportamiento del programa baste con cambiar el principio. En nuestro caso sería:

        #define NumeroDeVeces 20;

        \MEN 0
        \0 ""Mi sicólogo es un gilipollas!!!""

        \BLO
        BLOQUE [0] Insulto()
        {
                COPI 0 1;        /: En la bandera uno ponemos un cero :/
                HASTA (IGQ 1 NumeroDeVeces) /: 20 veces :/
                    {
                    MENSAJE 0 0;
                    INC 1 1;
                    }
        }

Ahora vamos a hacer una virguería que me parece que mi sicólogo aún no se ha dado por enterado. Vamos a escribir los mensajes pero en diagonal. Para ello usaremos dos nuevos condactos:

LIMPANT

borra la pantalla (como el cls del DOS o el BASIC) y

MOVXY x y

este condacto hace que lo siguiente que se vaya a imprimir se ponga en las coordenadas x e y. La coordenada x puede variar de 1 a 80 y la y de 1 a 24. Usaremos también el modo de direccionamiento indirecto. CAECHO? tiene muchos modos de direccionamiento, que iremos viendo poco a poco, y que sirve para un acceso rápido y fácil de muchos tipos de información. Hoy vamos a ver el indirecto. El concepto es muy simple, si escribimos

[n]

estaremos escribiendo 'el contenido de la bandera cardinal n', o sea [0] es el contenido de la bandera 0, [200] es el contenido de la bandera 200, etc...

Nos servirá para hacer:

MOVXY [1] [1];

que coloca el cursor (donde se va a escribir) en la columna que indique el contenido de la bandera 1, y la fila que indique la misma bandera. Con esto el programa queda como:

        #define NumeroDeVeces 20;

        \MEN 0
        \0 ""Mi sicólogo es un gilipollas!!!""

        \BLO
        BLOQUE [0] Insulto()
        {
                LIMPANT;        /: Borra la pantalla :/
                COPI 0 1;       /: En la bandera uno ponemos un cero :/
                HASTA (IGQ 1 NumeroDeVeces) /: 20 veces :/
                    {
                    MENSAJE 0 0;
                    INC 2 1;
                    MOVXY [1] [1];
                    DEC 1 1;
                    }
        }

Básicamente lo que hacemos es aprovechar que la bandera contendrá los valores de 0 a 19, para ir poniendo en (1,1)....(20,20) los mensajes. Vease cada vez incrementamos en 2 la bandera 1 y luego la decrementamos. Eso es para que los MOVXY vayan un valor por delante del contador (por que las coordenadas van de 1 a 24 y no de 0 a 23).

Veamos otro uso de la indirección y de paso veamos una demostración del uso de varias tablas de mensajes en CAECHO?. Ahora vamos a poner delante de cada HOLA, un mensaje que indica cuál es, para ello abrimos otra tabla de mensajes y usamos de nuevo el contenido de la bandera 1 para escoger cuál es el correspondiente (por razones de espacio sólo imprimiremos cinco mensajes esta vez, además que mi sicólogo está empezando a cabrearse y me está amenazando con quitarme toda la colección del CAAD y yo le tengo mucho cariño al monstruo que me devoró la cabeza en el número cero):

        #define NumeroDeVeces 5;

        \MEN 0
        \0 "" INSULTO: 'Mi sicólogo es un gilipollas!!!'.""
        \1 ""ESTE ES EL ""

        \MEN 1
        \0 ""PRIMER""
        \1 ""SEGUNDO""
        \2 ""TERCER""
        \3 ""CUARTO""
        \4 ""QUINTO""

        \BLO
        BLOQUE [0] Insulto()
        {
                LIMPANT;        /: Borra la pantalla :/
                COPI 0 1;       /: En la bandera uno ponemos un cero :/
                HASTA (IGQ 1 NumeroDeVeces) /: 20 veces :/
                    {
                    MEN 0 1;
                    MEN 1 [1];
                    MENSAJE 0 0;
                    INC 2 1;
                    MOVXY [1] [1];
                    DEC 1 1;
                    }
        }

El condacto MEN es como el condacto MENSAJE pero no pasa a la siguiente linea tras poner en pantalla el mensaje (equivale MEN al MES del PAWS y MENSAJE al MESSAGE del PAWS).

Vamos a hacer otra cosa con los bucles ahora, mientras intento convencer a mi sicólogo de que debe devolverme los CAAD. Vamos a imprimir unas ristras de asteriscos para ver como puede meterse un bucle dentro de otro. (Además escribir asteríscos es una de las terapias que usa mi sicólogo con los internos, será gilipollas!) En pantalla vamos a poner:

        0
        1 *
        2 **
        3 ***
        4 ****
        5 *****
Para hacer todo esto vamos a usar algunos condactos nuevos:

ESC n

pone en pantalla el valor 'n'. O sea, un ESC 1 pondrá un uno en pantalla y un ESC [1] pondrá el contenido de la bandera 1 en pantalla.

ESCCAR n

pondrá el caracter cuyo código ASCII sea n en pantalla. Así un ESCCAR 32 pondrá un espacio y un ESCCAR "*" pondrá un asterisco.

NL

hace que se escriba en la siguiente línea (como un printf("\n") de C. O un NEWLINE del DAAD o del SINTAC ).

Tenemos que llevar dos contadores, uno para el número de ristra de asteriscos que hemos puesto y otro para el número de asteriscos dentro de cada ristra. Usaremos las bandera 1 y 2 respectivamente. El programa quedaría así:

        #define NumRistras 5;

        \BLO
        BLOQUE [0] Ristras()
        {
                COPI 0 1; /: Poner a cero el contador de ristras :/
                HASTA (IGQ 1 NumRistras)
                    {
                    COPI 0 2;  /: Poner a cero el contador de asteriscos :/
                    ESC [1];   /: Poner el número de asteríscos :/
                    ESCCAR 32; /: Y un espacio :/
                    HASTA (IGQ 2 [1])
                       {
                       ESCCAR "*";  /: Pongo asterisco :/
                       INC 1 2;     /: Incremento el contador :/
                       }
                    INC 1 1; /: Incrementa contador de ristras :/
                    NL; /: Nueva línea :/
                    }
        }

Creo que por hoy ha sido suficiente. Hagamos un breve repaso de todos los condactos que hemos utilizado:

IGQ bandera valor: comprueba si la bandera contiene el valor.

MEN tabla mensaje: escribe un mensaje de una tabla de mensajes.

MENSAJE tabla mensaje: equivale a:

MEN tabla mensaje; NL;

COPI valor bandera: pone el valor en la bandera.

INC valor bandera: suma el valor al contenido de la bandera.

DEC valor bandera: resta el valor al contenido de la bandera.

LIMPANT: borra la pantalla.

MOVXY x y: pone el cursor de impresión en la posición (x,y).

ESC valor: pone el valor en la pantalla.

ESCCAR códigoASCII: pone un caracter en pantalla.

NL: pasa a la siguiente línea de la pantalla.

Bueno nada más, espero encontrar otro pardillo que haga esto por mí para el próximo CAAD. Yo no tengo muchas ganas de hacer nada, yo creo que es por culpa de las pastillas verdes que me hacen tomar; claro que mi última novia me dijo antes de dar el portazo que en realidad lo que pasaba es que era un asqueroso holgazán. Algún día de estos me acercaré a la biblioteca a buscar que significa 'holgazán', pero es que está tan lejos, en el piso de arriba; si incluso hay que subir la escalera!