share

Creación de Sigilos con QB64

Sigilos

Un sigilo es un glifo pictórico que oculta una declaración o deseo. Os dejo un esquema de como se construyen a partir de un cuadrado mágico y siguiendo una grafía regular.

El proceso sería el siguiente:

  1. Se formula un deseo. Por ejemplo «GANAR LOTERÍA»
  2. Se quitan los espacios y las letras repetidas: «GANRLOTEI»
  3. Las Y las transformamos en I y las Ñ en N.
  4. Se construye el cuadrado mágico de 5 x 5 con las letras del alfabeto español. Como el alfabeto español tiene 27 caracteres metemos la I con la Y , y la N con la Ñ; por similitud. Así cuadra.
  5. Empezamos por la primera letra, En este caso la G y vamos trazando líneas rectas para unir todas las letras, escogiendo como punto de unión el centro de las celdillas de los cuadrados mágicos, según se observa en la imagen.
  6. Una vez hecho el primero, lo aprendemos de memoria y aprendemos a dibujarlo sin ayuda del cuadrado mágico.
  7. Luego lo dibujamos en todos los sitios que queramos. Se supone que estos sigilos hay que «cargarlos» mágicamente y que su efectividad radica en los procesos mentales que ocurren cuando tenemos la atención fijada en su construcción dentro del cuadrado mágico.

QB64

Bien, nosotros nos vamos a ocupar de construir una aplicación que dibuje estos sigilos en la pantalla del ordenador. Y para esto ¿qué necesito?.

Pues obviamente, un lenguaje de programación que sea capaz de acceder a la pantalla gráfica. Es decir que tenga funciones para operar a nivel del píxel y capaz de dibujar formas geométricas. Al menos, las mas elementales: líneas, círculos, rectángulos, etc.

Prácticamente todos los lenguajes son capaces de acceder a la pantalla gráfica. Pero el que yo uso mas habitualmente: VBA para Access, Oh sorpresa, no accede a la pantalla gráfica, salvo si se instalan ciertas librerías, que estuve mirando y no había una documentación clara para hacerlo rápido. Simplemente decían: «instálense las librerías» (ya, pero como) y «utilícense las funciones» (si, si pero al menos un ejemplo ¿no?).

Luego estuve mirando los lenguajes modernillos tipo C# o JAVA y tres cuartos de lo mismo. Te remiten a interminables librerías. Es decir, al final hay que hacer un arco de iglesia para trazar unos simples segmentos.

Y he aquí que apareció QB64, quick basic de 64 bits. Un lenguaje de los de antes, pero modernizado. Y lo que yo buscaba, una colección muy amplia de funciones que hacen todo lo que yo quería y muchas mas cosas. Y sin librerías ni nada. Simplemente forman parte del lenguaje.

Además tiene integración con Visual Studio Code, y lo que es mejor, es un compilador! a la antigua. Que genera archivos EXE stand alone totalmente autónomos.

Una joya. Así que me dispuse a instalarlo y probarlo. Primera sorpresa. No hace falta instalación.

El compilador se puede descargar aquí. Y viene ya con un IDE anticuado pero muy funcional. La sintaxis del lenguaje se puede consultar aquí.

Y ésta es la página de GitHub de QB64. En ésta web hay una buena entrada sobre QB64.

Instalación de QB64

Pues otra grata sorpresa de QB64. No necesita instalación. Simplemente descargamos el lenguaje que viene en este zip:

qb64_dev_2022-09-08-07-14-00_47f5044_win-x64.7z

Si lo abrimos observaremos que trae una carpeta que se llama qb64. Es tan simple como descomprimir esa carpeta en el lugar que queramos. Por comodidad y mejor funcionamiento yo la he puesto colgando de C:

C:\qb64

Pero podéis ponerla donde queráis. Eso sí, hay que modificar la variable del sistema: PATH, para añadir la nueva carpeta. Eso se hace abriendo el panel de control:

Pulsamos Sistema y seguridad:

Pulsamos Sistema, y dentro de sistema, Configuración Avanzada del Sistema:

Pulsamos Variables de entorno:

Y dentro de variables de entorno nos posicionamos en: Path y pulsamos editar:

Después pulsamos «nueva» y añadimos: c:\qb64

Salimos grabando y ya tenemos operativa la nueva variable de entorno.

Bueno, pues con esto estaría la instalación del lenguaje. Como habéis visto ni 5 minutos. Se tarda mas en explicarlo que en hacerlo.

Manera de programar en QB64

Nuevamente, simplicidad extrema. Abrimos una carpeta en cualquier sitio y vamos metiendo ahí todos los archivos relacionados con el proyecto. En mi caso, por simplicidad y por tenerlo todo en un mismo sitio, he abierto la carpeta: SIGILOS en:

C:\qb64\SIGILOS

para compilar el programa de forma rápida, he creado un archivo:

e.bat

que contiene:

cls
del /Q sigilos.exe
qb64 -c sigilos.bas -o C:\qb64\sigilos\sigilos.exe
C:\qb64\sigilos\sigilos.exe

Como podéis ver lo que hace es compilar el código fuente y ejecutar el EXE.

El código fuente de QB64 son archivos de texto acabados en .BAS

Para editar esos archivos de texto, se puede usar cualquier editor, pero como somos programadores profesionales lo suyo es usar el Visual Studio Code. A ver, existe una extensión de VSCode para QB64, que me ha funcionado bien en Windows 11, pero Windows 10 no ha habido manera. Esa extensión se puede descargar aquí. Si alguien consigue que funcione en Windows 10, que me explique como.

Bueno, pues ya tenemos el compilador instalado, el entorno de programación configurado (Visual Studio Code), y ahora simplemente arrancamos el VSCode:

En el VSCode ya tengo cargada la carpeta de trabajo:

C:\qb64\SIGILOS

Que ya contiene el fichero de código fuente que ejecuta el programa:

C:\qb64\SIGILOS\sigilos.bas

En el apéndice final se puede ver ese código fuente, que aún lo estoy puliendo pero que ya funciona en lo que debe hacer el programa que es dibujar los sigilos. Faltan toda bastantes detalles, sobre todo de adorno.

La manera de trabajar es la siguiente:

  1. Abro VSCode y voy programando la aplicación en el código fuente.
  2. Cuando quiero probar como va mi trabajo y ejecutar la aplicación, lo que hago es abrir un terminal MSDOS.

Y desde este terminal ejecuto:

e.bat

Como veis se reproduce exactamente el sigilo pedido. A la aplicación le faltan cosas, pero lo principal lo hace que era lo que quería mostrar.

Código fuente de SIGILOS

‘———————-
‘- SIGILOS –
‘———————-

 

CLS

 

REM $NOPREFIX
CONST YELLOW = _RGB32(255, 255, 0)
CONST BLUE = _RGB32(0, 255, 255)
CONST MAGENTA = _RGB32(255, 0, 255)
CONST RED = _RGB32(127, 0, 0)
CONST BRIGHTRED = _RGB32(255, 0, 0)
CONST GREEN = _RGB32(0, 127, 0)
CONST BRIGHTGREEN = _RGB32(0, 255, 0)
CONST TRUE=-1
CONST FALSE=0

 

SCREEN _NEWIMAGE(1024, 800, 32)

 

REM  PRINT «LINE (69, 89)-(640, 480), _RGB32(255, 255, 0)»

 

DIM SHARED CASILLA
DIM SHARED OFFSET
DIM SHARED PUNTOS(25,2)
DIM SHARED LETRAS(25) AS STRING
REM DIM DESEO AS STRING

 

P = _LOADIMAGE(«c:\qb64\SIGILOS\CRIPTA1.JPG»)
_PUTIMAGE (0, 481), P

 

CASILLA=96
OFFSET=(CASILLA/2)+2
CALL CARGA_LETRAS
CALL CARGA_PUNTOS
CALL PINTA_CUADRICULA
CALL PINTA_SIGILO
LOCATE 40, 34
PRINT «PRESS A KEY»;
SLEEP
CLS

 

SUB PINTA_SIGILO
    DESEO$=»ADELGZR»
    FOR I=1 TO LEN(DESEO$)
        LETRA_ORIGEN$=MID$(DESEO$,I,1)
        LETRA_DESTINO$=MID$(DESEO$,I+1,1)

 

        SELECT CASE LETRA_ORIGEN$
            CASE «A»
                X_INICIO=PUNTOS(1,1)
                Y_INICIO=PUNTOS(1,2)
            CASE «B»
                X_INICIO=PUNTOS(2,1)
                Y_INICIO=PUNTOS(2,2)
            CASE «C»
                X_INICIO=PUNTOS(3,1)
                Y_INICIO=PUNTOS(3,2)
            CASE «D»
                X_INICIO=PUNTOS(4,1)
                Y_INICIO=PUNTOS(4,2)
            CASE «E»
                X_INICIO=PUNTOS(5,1)
                Y_INICIO=PUNTOS(5,2)
            CASE «F»
                X_INICIO=PUNTOS(6,1)
                Y_INICIO=PUNTOS(6,2)
            CASE «G»
                X_INICIO=PUNTOS(7,1)
                Y_INICIO=PUNTOS(7,2)
            CASE «H»
                X_INICIO=PUNTOS(8,1)
                Y_INICIO=PUNTOS(8,2)
            CASE «I»
                X_INICIO=PUNTOS(9,1)
                Y_INICIO=PUNTOS(9,2)
            CASE «J»
                X_INICIO=PUNTOS(10,1)
                Y_INICIO=PUNTOS(10,2)
            CASE «K»
                X_INICIO=PUNTOS(11,1)
                Y_INICIO=PUNTOS(11,2)
            CASE «L»
                X_INICIO=PUNTOS(12,1)
                Y_INICIO=PUNTOS(12,2)
            CASE «M»
                X_INICIO=PUNTOS(13,1)
                Y_INICIO=PUNTOS(13,2)
            CASE «N»
                X_INICIO=PUNTOS(14,1)
                Y_INICIO=PUNTOS(14,2)
            CASE «O»
                X_INICIO=PUNTOS(15,1)
                Y_INICIO=PUNTOS(15,2)
            CASE «P»
                X_INICIO=PUNTOS(16,1)
                Y_INICIO=PUNTOS(16,2)
            CASE «Q»
                X_INICIO=PUNTOS(17,1)
                Y_INICIO=PUNTOS(17,2)
            CASE «R»
                X_INICIO=PUNTOS(18,1)
                Y_INICIO=PUNTOS(18,2)
            CASE «S»
                X_INICIO=PUNTOS(19,1)
                Y_INICIO=PUNTOS(19,2)
            CASE «T»
                X_INICIO=PUNTOS(20,1)
                Y_INICIO=PUNTOS(20,2)
            CASE «U»
                X_INICIO=PUNTOS(21,1)
                Y_INICIO=PUNTOS(21,2)
            CASE «V»
                X_INICIO=PUNTOS(22,1)
                Y_INICIO=PUNTOS(22,2)
            CASE «W»
                X_INICIO=PUNTOS(23,1)
                Y_INICIO=PUNTOS(23,2)
            CASE «X»
                X_INICIO=PUNTOS(24,1)
                Y_INICIO=PUNTOS(24,2)
            CASE «Z»
                X_INICIO=PUNTOS(25,1)
                Y_INICIO=PUNTOS(25,2)
        END SELECT

 

        SELECT CASE LETRA_DESTINO$
            CASE «A»
                X_FINAL=PUNTOS(1,1)
                Y_FINAL=PUNTOS(1,2)
            CASE «B»
                X_FINAL=PUNTOS(2,1)
                Y_FINAL=PUNTOS(2,2)
            CASE «C»
                X_FINAL=PUNTOS(3,1)
                Y_FINAL=PUNTOS(3,2)
            CASE «D»
                X_FINAL=PUNTOS(4,1)
                Y_FINAL=PUNTOS(4,2)
            CASE «E»
                X_FINAL=PUNTOS(5,1)
                Y_FINAL=PUNTOS(5,2)
            CASE «F»
                X_FINAL=PUNTOS(6,1)
                Y_FINAL=PUNTOS(6,2)
            CASE «G»
                X_FINAL=PUNTOS(7,1)
                Y_FINAL=PUNTOS(7,2)
            CASE «H»
                X_FINAL=PUNTOS(8,1)
                Y_FINAL=PUNTOS(8,2)
            CASE «I»
                X_FINAL=PUNTOS(9,1)
                Y_FINAL=PUNTOS(9,2)
            CASE «J»
                X_FINAL=PUNTOS(10,1)
                Y_FINAL=PUNTOS(10,2)
            CASE «K»
                X_FINAL=PUNTOS(11,1)
                Y_FINAL=PUNTOS(11,2)
            CASE «L»
                X_FINAL=PUNTOS(12,1)
                Y_FINAL=PUNTOS(12,2)
            CASE «M»
                X_FINAL=PUNTOS(13,1)
                Y_FINAL=PUNTOS(13,2)
            CASE «N»
                X_FINAL=PUNTOS(14,1)
                Y_FINAL=PUNTOS(14,2)
            CASE «O»
                X_FINAL=PUNTOS(15,1)
                Y_FINAL=PUNTOS(15,2)
            CASE «P»
                X_FINAL=PUNTOS(16,1)
                Y_FINAL=PUNTOS(16,2)
            CASE «Q»
                X_FINAL=PUNTOS(17,1)
                Y_FINAL=PUNTOS(17,2)
            CASE «R»
                X_FINAL=PUNTOS(18,1)
                Y_FINAL=PUNTOS(18,2)
            CASE «S»
                X_FINAL=PUNTOS(19,1)
                Y_FINAL=PUNTOS(19,2)
            CASE «T»
                X_FINAL=PUNTOS(20,1)
                Y_FINAL=PUNTOS(20,2)
            CASE «U»
                X_FINAL=PUNTOS(21,1)
                Y_FINAL=PUNTOS(21,2)
            CASE «V»
                X_FINAL=PUNTOS(22,1)
                Y_FINAL=PUNTOS(22,2)
            CASE «W»
                X_FINAL=PUNTOS(23,1)
                Y_FINAL=PUNTOS(23,2)
            CASE «X»
                X_FINAL=PUNTOS(24,1)
                Y_FINAL=PUNTOS(24,2)
            CASE «Z»
                X_FINAL=PUNTOS(25,1)
                Y_FINAL=PUNTOS(25,2)
        END SELECT

 

        LINE (X_INICIO, Y_INICIO)-(X_FINAL, Y_FINAL), BRIGHTGREEN

 

    NEXT I
END SUB

 

SUB CARGA_PUNTOS
    INCREMENTO=0
    FOR I=1 TO 25
        IF INCREMENTO=5 THEN
            INCREMENTO=0
        END IF
        PUNTOS(I,1)=OFFSET+CASILLA*INCREMENTO
        INCREMENTO=INCREMENTO+1
    NEXT I
    FOR I=1 TO 25
       
        SELECT CASE I
            CASE 1 TO 5 : INCREMENTO=0
            CASE 6 TO 10 : INCREMENTO=1
            CASE 11 TO 15 : INCREMENTO=2
            CASE 16 TO 20 : INCREMENTO=3
            CASE 21 TO 25 : INCREMENTO=4
        END SELECT
        IF INCREMENTO=5 THEN
            INCREMENTO=0
        END IF
        PUNTOS(I,2)=OFFSET+CASILLA*INCREMENTO
       
    NEXT I
END SUB

 

SUB PINTA_CUADRICULA
    FOR I=1 TO 25
        PSET(PUNTOS(I,1),PUNTOS(I,2)), YELLOW
    NEXT I

 

    LINE (0, 0)-(CASILLA*5,CASILLA*5 ), RED, B
    LINE (0, 96)-(480,96), RED
    LINE (0, 96*2)-(480,96*2), RED
    LINE (0, 96*3)-(480,96*3), RED
    LINE (0, 96*4)-(480,96*4), RED
    LINE (96, 0)-(96,480), RED
    LINE (96*2, 0)-(96*2,480), RED
    LINE (96*3, 0)-(96*3,480), RED
    LINE (96*4, 0)-(96*4,480), RED
   

 

END SUB

 

SUB CARGA_LETRAS
    LETRAS(1)=»A»
    LETRAS(2)=»B»
    LETRAS(3)=»C»
    LETRAS(4)=»D»
    LETRAS(5)=»E»
    LETRAS(6)=»F»
    LETRAS(7)=»G»
    LETRAS(8)=»H»
    LETRAS(9)=»I»
    LETRAS(10)=»J»
    LETRAS(11)=»K»
    LETRAS(12)=»L»
    LETRAS(13)=»M»
    LETRAS(14)=»N»
    LETRAS(15)=»O»
    LETRAS(16)=»P»
    LETRAS(17)=»Q»
    LETRAS(18)=»R»
    LETRAS(19)=»S»
    LETRAS(20)=»T»
    LETRAS(21)=»U»
    LETRAS(22)=»V»
    LETRAS(23)=»W»
    LETRAS(24)=»X»
    LETRAS(25)=»Z»

 

    LOCATE 2,2
    PRINT LETRAS(1)
    LOCATE 1,14
    PRINT LETRAS(2)
    LOCATE 1,27
    PRINT LETRAS(3)
    LOCATE 1,40
    PRINT LETRAS(4)
    LOCATE 1,53
    PRINT LETRAS(5)

 

    LOCATE 7,1
    PRINT LETRAS(6)
    LOCATE 7,14
    PRINT LETRAS(7)
    LOCATE 7,27
    PRINT LETRAS(8)
    LOCATE 7,40
    PRINT LETRAS(9)
    LOCATE 7,53
    PRINT LETRAS(10)

 

    LOCATE 13,1
    PRINT LETRAS(11)
    LOCATE 13,14
    PRINT LETRAS(12)
    LOCATE 13,27
    PRINT LETRAS(13)
    LOCATE 13,40
    PRINT LETRAS(14)
    LOCATE 13,53
    PRINT LETRAS(15)
   

 

    LOCATE 19,1
    PRINT LETRAS(16)
    LOCATE 19,14
    PRINT LETRAS(17)
    LOCATE 19,27
    PRINT LETRAS(18)
    LOCATE 19,40
    PRINT LETRAS(19)
    LOCATE 19,53
    PRINT LETRAS(20)

 

    LOCATE 25,1
    PRINT LETRAS(21)
    LOCATE 25,14
    PRINT LETRAS(22)
    LOCATE 25,27
    PRINT LETRAS(23)
    LOCATE 25,40
    PRINT LETRAS(24)
    LOCATE 25,53
    PRINT LETRAS(25)

 

END SUB