CURSO DE HUGO
Lección 2

Pues sí parece que nos volvemos a reunir los tres que seguimos esta sección, que somos: , Raúl y yo mismo. Si te preguntas por qué razón Mr. Álvarez se lee esta sección, te diré que siempre la revisa para comprobar que todo está a su gusto y sobretodo para ver que no me meto con él. Algún día os contaré toda la verdad sobre semejante individuo... De momento me he asegurado de que no vuelva su censura, bajo amenaza de que si volviera a ocurrir un servidor emigraría al Zona Zero o al CAAD.

Bueno, vayamos a lo que nos interesa... En la primera entrega os expliqué los ficheros que debíais bajaros para tener todo lo necesario para Hugo. Para esta ocasión os he preparado una entrega donde veremos los tipos de datos de Hugo y lo básico para escribir en pantalla. En la próximas dos entregas (si aún sigo en SQ) nos meteremos de lleno en los objetos en sí y en las estructuras de control, y así ya estaréis listos para hacer una aventurilla en Hugo.

Primeros pasos

Editad en un fichero (o hacer cut&paste) el siguiente código:

   routine main
   {
       "Hola, este es mi primer programa en Hugo"
       return
   }
En cualquier programa/aventura escrita en Hugo debe haber un main, que es la rutina principal, o sea, lo primero que se ejecuta. Lo que aparece entre comillas ("") es texto que se imprime por pantalla. Como en una aventura de texto se supone que ha de haber mucho texto será algo que usarás mucho. Grabarlo como 'ejemplo1.hug' y compilémoslo con 'hc ejemplo1'. Si lo ejecutáis (he ejemplo1) muy posiblemente no veréis nada de nada, porque en cuanto finaliza el programa sale al DOS borrando toda la pantalla. Hmm, mejor si antes de devolver el control al sistema ponemos una pausa, ¿no os parece?
   routine main
   {
       "Hola, este es mi primer programa en Hugo"
       pause    ! hacemos una pausa antes de salir 
       return
   }
Añadiendo ese pause ahora sí que podemos contemplar el resultado, que no es muy espectacular, pues símplemente aparece un "Hola, este es mi primer programa en Hugo" por pantalla. La única diferencia con el anterior es que ahora no se sale automáticamente, sino que antes tenemos que pulsar una tecla cualquiera.

Fijémonos en ese signo de admiración que aparece a la derecha del pause. No tiene ningún secreto pues no es más que un comentario, puedes poner tantos como y donde quieras, y generalmente se usan para facilitar la comprensión del código. Imagina que has hecho una aventura de 6000 líneas, con cientos de variables y objetos, pero sin ningún comentario. A medida que la estés programando no tendrás problema en recordar para qué diantre sirve tal variable, o para qué haces tal bucle. Pero a medida que pase el tiempo, y a menos que seas un genio, te irás olvidando de todo ello, y para cuando meses depués te la vuelvas a mirar posiblemente te encuentres que no te acuerdas de NADA.

Así que lo mejor es insertar comentarios en el código a medida que este se va escribiendo... Y como a continuación puedes comprobar, los hay de dos tipos, el que ya hemos visto (para una sola línea), y el que también sirve para más de una (entre !\ y \!).

    ! éste es un comentario de una sola línea
    !\ Y éste tiene una,
       dos,
       tres y
       cuatro líneas \!
No sé si te habrás dado cuenta de un pequeño detalle. Parece una insignificancia, una menudencia, pero es muy importante, de veras. Fíjate que en los comentarios hemos puesto vocales con acento, y en cambio, al 'este' del ejemplo1, el que está en "Hola, este es mi primer programa en Hugo", no le puse acento. Why?

La respuesta es que los carácteres especiales que usamos normalmente en español quedan fuera del ASCII de 7 bits que hoy día tenemos que tragar en muchos ámbitos. Imprimir estos es un auténtico coñazo ya que, al igual que pasa en HTML, habrá que hacer cosas raras:

Acento agudo: á, é, í, ó, ú \'a, \'e, \'i, \'o, \'u
Acento grave: à, è, ì, ò, ù \`a, \`e, \`i, \`o, \`u
Eñe\~n
Diéresis: ä, ö, ï, ö, ü, ÿ \:a, \:e, \:i, \:o, \:u, \:y
Otros: ¡, ¿\!, \?

En los comentarios no hay problema con que uséis acentos, ya que Hugo simplemente los ignora. De hecho, también podéis usar acentos en nombres de variables y objetos lo cual le hace ganar unos buenos tantos a este parser. Realmente sí que es una pega lo de imprimir carácteres especiales, pero siempre puedes definir macros en tu procesador de textos y olvidarte de ello, que es precisamente lo que hace el que esto escribe.

Así que si un acento en este quieres ver, esto deberás hacer...

   routine main
   {
       "Hola, \'este es mi primer programa en Hugo"
       pause    ! hacemos una pausa antes de salir 
       return
   }

Más sobre la salida por pantalla

Hugo ofrece muchas facilidades en este sentido. Veamos unas cuantas...

   routine main
   {
       ! ejemplo de descripción larga
       "Frente a ti se alza el edificio de la Convenci\'on. Por lo
        que ves el evento ha despertado bastante inter\'es, a juzgar
        por la gran cantidad de veh\'iculos estacionados en la zona.
        Puedes ver coches de la polic\'ia local, una furgoneta de
        la nacional, adem\'as de \'unidades m\'oviles de radio
        y televisi\'on.\n\nGran cantidad de periodistas se agolpan 
        en la entrada, lugar custodiado por dos polic\'ias armados
        con sendas UZI's."
       pause    ! hacemos una pausa antes de salir 
       return
   }   

Como puedes ver no hay problema con continuar escribiendo en la línea de abajo si no te cabe todo el texto en una sola línea. Esto es muy útil y cómodo. Hay que decir también que al escribir texto de esta forma, siempre se escribe un retorno de carro al final, y a veces esto no es lo que le conviene a uno. Hay entra el punto y coma ';'.

   routine main
   {
       ! ejemplo de descripción larga
       "Uno m\'as uno son ";
       print number (1+1);
       "." 
       pause    ! hacemos una pausa antes de salir 
       return
   }

Si no hubiéramos puesto el primer punto y coma hubiera salida algo como:

   Uno más uno son
   2.

cuando lo que queríamos es que todo se imprimiera en una única línea. Si queremos insertar explícitamente un retorno de carro, en mitad de un texto, usamos '\n' (al igual que en C o en CAOS). Llegados a este punto es interesante realizar un apunte:

       "\!Hola mundo!"
       print "Hello world!"
Entre estas dos instrucciones no hay diferencia a efectos prácticos. Cuando se trata de escribir texto, podemos dejarnos el print sin mayor problema, y así escribimos menos. Lo único es que Hugo guarda todo el texto que no lleva un print delante en un banco de solo-texto (a nivel interno, nosotros ni nos enteramos), que en el caso de que la cosa ande floja de memoria, el engine irá trayendo a cachos, a medida que se vaya necesitando. No tiene mayor importancia.

En cambio ese print en el ejemplo de más arriba, si que es necesario cuando se trata de algo que no va entre comillas, como el (1+1) del ejemplo anterior. Lo del number está para indicarle al parser que queremos que interprete el resultado de la operación como un número, y no como una dirección de memoria o un número hexadecimal, por ejemplo.

Tipos de Datos

Hugo no define tipos de datos para todo, ni tampoco hace una comprobación estricta de tipos. En ese sentido pasa bastante, lo cual no deja de ser una ventaja:

Los booleanos son los flags o banderas que hay en todo parser. Pueden indicar si la lámpara está encendida o apagada, si el jugador ha visto la moneda en el zapato, o si ha movido la palanca. Siempre se refieren a cosas, aspectos del juego, que pueden estar en dos estados diferentes, verdadero y falso, al que le damos el sentido apropiado: tal variable indica si la lámpara está encendida, por ejemplo.

En el próximo capítulo veremos como definir objetos, y las tablas también las veremos más adelante.

Una variable en Hugo puede contener cualquier cosa, desde un número, hasta un booleano o referirse a un objeto. Las variables pueden ser o bien globales o bien locales. Las globales son variables que se pueden acceder desde cualquier punto del programa, mientras que el ámbito de las locales se reduce a un espacio más pequeño, las rutinas, que no son más que particiones que nosotros nos montamos de un programa. El main, por ejemplo, no deja de ser una rutina de estas.

   global dia            ! dia es una variable global

   routine main          ! main es una... routine
   {
       local i           ! i es una variable local 
       pause             ! hacemos una pausa antes de salir 
       return
   }
   
   routine otra_rutina
   {
       local j=5         ! otra variable local (inicializada a 5)
       print number j
   }

En este ejemplo, tenemos dos rutinas, la ya conocida main, y otra que hemos bautizado como otra_rutina. En el main tenemos la variable local i, mientras que en otra_rutina tenemos declarada la j. Debe quedar claro que ni desde main no podemos acceder a j, ni desde otra_rutina podemos hacerlo a i. Pero por otra parte, la variable global dia es accesible desde ambas rutinas, he aquí la diferencia entre locales y globales.

Fíjate que la j la inicializamos a 5, esto quiere decir que cuando otra_rutina se ejecute tendrá un valor inicial de 5. Por otro lado está la i, que como no la inicializamos explícitamente, tendrá asociado un 0 (o false) como valor inicial.

A las globales también se le pueden dar un valor inicial, como veremos en el siguiente ejemplo...

   global dia=6          ! dia es una variable global (inicializada)

   routine main          ! main es una... routine
   {
       local i           ! i es una variable local 
       i=3               ! asignación
       print "'i' y 'dia' suman: "; number (i+dia)
       otra_rutina       ! llamamos a la otra rutina
       pause             ! hacemos una pausa antes de salir 
       return
   }
   
   routine otra_rutina
   {
       local j=5         ! otra variable local (inicializada a 5)
       print "Estoy en otra_rutina, y 'j' vale: "; number j
   }
Si lo ejecutas lo que obtendrás como resultado será lo siguiente:
    'i' y 'dia' suman: 9
    Estoy en otra_rutina, y 'j' vale: 5
Hay dos cosas nuevas en este último ejemplo:
  1. en main se llama a otra_rutina. La invocación es muy sencilla, con el nombre de la misma basta

  2. una asignación i=3 en main. Lo que se hace es dar el valor 3 a la variable i, y así de tener el 0 inicial, pasaría a tener un 3.

Despedida

Pues sí, esto ha sido todo por hoy. En la próxima más, mucho más. Sobretodo intenta prácticar; tanto como puedas, para hacerte lo antes posible con los conceptos básicos explicados en esta entrega. Si alguien tiene dudas, o tiene cualquier cosa que decir, como que que cree que voy demasiado lento/rápido, o que me explico mal o que debería poner más ejemplos, pues no tiene más que pinchar aquí y ponerse en contacto conmigo. Un saludo,

Daniel Cárdenas


[Volver]