![]() |
![]() |
![]() |
Entendiendo Inform (y olvidando PAWS) |
Tenemos bastantes rompecabezas en nuestro mini-juego, y esto va a involucrar muchas cosas nuevas: definir objetos, definir los comportamientos de esos objetos, etc... Para comprender realmente cómo se hacen estas cosas en InformATE es necesario conocer antes su filosofía, que es diferente en muchas cosas a la de PAWS. Por ello iremos muy despacio en el primer rompecabezas, y ya correremos más en los siguientes.
El primer rompecabezas que vamos a implementar será la puerta
secreta.
De momento, vamos a quitar la conexión que había entre la
escalera y
la mazmorra. Vamos, edita tu fichero y borra la línea que dice w_to
Mazmorra
dentro del objeto EscaleraCaracol2
.
¿Ya lo has hecho?
Compila el juego y juegalo de nuevo. Verás como ya no se puede
ir al
oeste desde la escalera. Sin embargo, sí que se podría
aún ir al este
desde la Mazmorra (¡si hubiera alguna forma de entrar en la
mazmorra!), puesto que no hemos borrado esa salida. Inform, al igual
que PAWS, permite conexiones asimétricas o ilógicas.
![]() |
Vamos a hacer un poco de
trampa. Durante la fase de programación y pruebas puede resultar
útil tener ciertos "superpoderes", que te permitan teleportarte
y hacer otras maravillas dentro del juego. Muchos de estos
"superpoderes" están activados por defecto en nuestro juego.
Arranca el juego y escribe "VERSION", aparecerá el título
del juego, y después información sobre la versión
del juego y de la librería. ¿Aparecen las letras SD al
final de esta línea? Si es así, tenemos los superpoderes
(en realidad, esto indica que está activado el "modo Debug"). En
la versión final del juego esto deberá estar desactivado,
más adelante diremos cómo desactivarlo.
Uno de los superpoderes es el de teletransportación. Para usarlo necesitas conocer el número de la localidad a la que vas a teletransportarte (¡como en el MUD!). Este es un número que Inform asigna a cada objeto del juego y que normalmente el programador no conoce. Podemos averiguarlo con el comando XLISTA, el cual nos mostrará todos los objetos del juego, y al lado de cada localidad, entre paréntesis, su número secreto. En nuestro juego saldrá algo como esto:
Aqui puedes ver que, además de las localidades del juego, hay dos objetos misteriosos. Uno llamado "Oscuridad" (con el número 20) y otro llamado "a ti mismo" (sin número). La Oscuridad es un lugar ficticio que existe en todo juego Inform, al que vas a parar tan pronto como te quedes a oscuras. "A ti mismo" es el jugador. ¡Ya te había dicho
que el jugador es un
objeto más! Además, fíjate que esa línea
aparece un poco metida hacia
la derecha, justo debajo de la línea que dice "Puerta
Principal", lo
que significa que en este momento, el objeto jugador está dentro
del
objeto Además hemos obtenido información sobre los
números de las diferentes
localidades, con lo que ya podemos teleportarnos a cualquiera de
ellas. ¡Incluso a la Mazmorra a pesar de que no tenía
entrada posible!
Para ello basta poner el comando Comprueba, una vez teleportado, que puedes salir de la mazmorra si te mueves al este (irás a parar a la escalera de caracol), pero no puedes volver a entrar en la mazmorra yendo hacia el oeste, pues habiamos borrado esa conexión. |
Lo que queremos ahora es que la conexión de entrada a la Mazmorra reaparezca mágicamente cuando el jugador intente EMPUJAR la antorcha, y desaparezca de nuevo cuando intente TIRAR DE la antorcha.
Para ello tenemos que crear el objeto antorcha. Esto es otra importantísima diferencia entre Inform y PAWS. En PAWS el jugador podía referirse a cosas que en realidad no existían como objetos dentro del juego (eran meros NOMBRES, pero no objetos). En Inform esto no es posible. Cualquier cosa a la que el jugador deba referirse, ha de ser un objeto.
Para comprender por qué, es necesario entrar a explicar con un poco de detalle las diferencias entre el parser de PAWS y el parser de Inform.
El parser de PAWS era muy sencillo, ya que lo único que hacía era comparar cada palabra de las que el jugador ha escrito con las palabras que el juego había definido en su vocabulario, tras lo cual asignaba una categoría diferente a cada una de estas palabras, ignorando sin más las no reconocidas. De este modo, al final del parsing se tenían en ciertas banderas:
A partir de aquí, el resto del trabajo correspondía al juego, que debía comparar el verbo usado por el jugador con cada posible verbo del juego, una vez encontrado, debía comparar el nombre usado por el jugador con cada posible nombre del juego, y una vez localizado, debía averiguar si ese nombre tenía sentido en la situación actual del jugador. Así, por ejemplo, ante la frase TIRA DE LA ANTORCHA, el parser simplemente se limita a decirnos que Verbo=TIRA, preposicion=DE, Nombre1=ANTORCHA. El programador debía hacer una serie de comprobaciones de este estilo:
Si Verbo es TIRA y Nombre1 es ANTORCHA Entonces: Si el jugador esta en la escalera de caracol .... .... Instrucciones para abrir la puerta secreta .... Si no mostrar el mensaje ``No veo ninguna antorcha aqui'' |
En Inform, la mayor parte de estas comprobaciones las hace la librería. El programador debe escribir tan solo la parte que correspondería a las instrucciones para abrir la puerta secreta.
Pero antes de explicar cómo hace la librería para interpretar la frase, remarquemos dos conceptos clave de Inform: ACCIONES y OBJETOS. Estos conceptos marcan toda la diferencia entre Inform y los parsers tipo PAWS. Mientras no comprendas estos conceptos, no entenderás Inform. Repíte estas dos palabras todas las noches hasta quedar dormido, ACCIONES y OBJETOS, hasta que logres olvidarte de "verbos y nombres".
![]() |
El jugador escribe VERBOS en sus FRASES. Sin embargo, lo que el juego recibe son ACCIONES. El Parser se ocupa de transformar FRASES en ACCIONES. |
Un mismo verbo puede dar lugar a diferentes acciones, según la frase en que aparece. Fíjate: TIRA LA PIEDRA, TIRA DE LA ANTORCHA, TIRA LA PIEDRA CONTRA EL ESPEJO. El mismo verbo "TIRA", tiene significados bien distintos. En el primer caso significa algo como "dejar caer", mientras que en el segundo es más bien "dar un tirón" y en el tercero es "lanzar" o "arrojar".
El concepto de accion, pues, no es más que el
significado de un
verbo. El cometido del parser de Inform es analizar frases y
convertirlas en acciones, es decir, extraer el significado de
la frase. En la primera frase, "TIRA LA PIEDRA", la acción que
genera el parser es Drop (o sea Dejar)
, en la segunda frase "TIRA DE
LA
ANTORCHA" la acción que genera el parser es Pull (o sea Tirar)
,
y en la
tercera frase "TIRA LA PIEDRA CONTRA EL ESPEJO", la acción
generada
es ThrowAt (o sea Lanzar)
.
Es muy importante no confundir los verbos con las acciones. En los
tres ejemplos anteriores el verbo ha sido el mismo "TIRAR", pero las
acciones generadas han sido diferentes. Y la inversa también es
cierta, hay muchos verbos diferentes que darán lugar a la misma
acción. Así, la acción Drop
puede
ser generada por frases bien
distintas: "DEJA LA PIEDRA", "SUELTA LA PIEDRA", "TIRA LA
PIEDRA". Y la acción ThrowAt
también puede
ser generada por
diferentes frases: "LANZA LA PIEDRA", "ARROJA LA PIEDRA", "TIRA
LA PIEDRA CONTRA LA PARED".
![]() |
En PAWS el parser no intentaba
"comprender" la frase, en Inform sí, y una vez comprendida, da
lugar a una ACCION.
En PAWS existían verbos sinónimos, en Inform lo que ocurre es que muchas frases distintas pueden dar lugar a la misma ACCION. Podría decirse que en Inform hay "frases sinónimas". |
¿En qué se basa el parser para decidir que "TIRA DE LA
ANTORCHA"
tiene distinto significado que "TIRA LA PIEDRA"? No se conforma con
examinar el verbo, sino que tiene que leer la frase completa para
tratar de extraer un significado. En este ejemplo, el parser ha sido
instruido para que, ante una frase que use TIRA seguida de la palabra
DE, seguida de un nombre de objeto, la acción que genere sea Pull
.
Si, en cambio, la frase es simplemente TIRA seguida de un nombre de
objeto (sin el DE), la acción será Drop
.
Finalmente, si la frase
tiene la estructura TIRA <nombre de objeto> CONTRA
<nombre de
objeto>, entonces la acción será ThrowAt
.
Esta información de qué acción debe generar
para cada posible
estructura de frase, no está incrustada dentro del parser de
forma que
sea imposible cambiarla. ¡Todo lo contrario! Se halla definida en
un
fichero aparte (SpanishG.h
) y es bastante sencillo
cambiarla, de
modo que si tu lo prefieres, puedes hacer que TIRA PIEDRA genere la
acción ThrowAt
en lugar de Drop
.
Por supuesto también es posible crear nuevas acciones, y
asignarlas a
nuevas estructuras de frase. Así, puedes crear la acción Ayuda
(que
no existe por defecto en la librería), y hacer que esta
acción se
genere ante las frases "AYUDA", "SOCORRO", "HELP". No obstante,
la definición acciones y frases nuevas se dejará para
más adelante.
![]() |
La librería Inform ya
trae predefinidas un montón de frases y las
correspondientes acciones para cada caso. Es importante que conozcas
qué acciones se generan para cada verbo, ya que como programador
tú te
las verás únicamente con las acciones, y no con los
verbos. Puedes consultar una guía rápida en InfoLib
at your fingertips.
Más adelante daremos un truco para saber qué acciones se generan ante cada posible frase, de modo que no necesites saber eso de memoria. |
La otra palabra clave que debes comprender es la del objeto, ya que:
![]() |
Las acciones actúan
sobre los objetos.
En PAWS, se programaban "tablas de respuestas" que indicaban qué responder para cada verbo, ante cada posible nombre. En inform en cambio los programas van "dentro" de los propios objetos, e indican qué debe responder ese objeto ante cada posible acción que se intente sobre él. Las acciones que el objeto no contemple, serán manejadas de forma automática por la librería. |
Basta de teoría. Programemos de una vez el objeto antorcha
para ver
qué ocurre con él. Añade el siguiente
código en tu juego. Puedes
escribirlo en cualquier punto después del objeto EscaleraCaracol2
,
incluso podría ir al final del fichero. Sin embargo es buena
idea
ponerlo justo detrás de la EscaleraCaracol2
, ya
que de ese modo los
lugares y los objetos que hay en ellos quedan juntos en el
código.
Object antorcha "antorcha" EscaleraCaracol2 with name 'antorcha', has female; |
Fijate en la estructura de un objeto, en realidad es casi idéntica a la estructura de una localidad:
Object
indica que va a comenzar
la definición de un objeto. Esta definición
terminará cuando aparezca un punto y coma (el cual aparece tras
la palabra female
). Objeto1
, Objeto2
,
etc.. Pero admitirás que resulta mucho más lógico
llamarlo antorcha
. Este nombre nunca lo verá el
jugador (y no puede contener acentos ni eñes, ni coincidir con
el nombre interno de ningún otro objeto del juego) EscaleraCaracol2
. Este otro
objeto será el "recipiente" que contiene a la antorcha. Si es
una localidad, esto significará que la antorcha está en
esa localidad. with
que da inicio a la lista de
propiedades, al igual que en las localidades. name
es la propiedad que indica
qué nombres puede usar el jugador para referirse a este objeto.
En este caso particular, el nombre por el que el jugador se referirá será seguramente 'antorcha', pero este es el lugar donde podríamos poner más sinónimos (como por ejemplo 'tea'). Si quieres poner sinónimos, irían separados por espacios:
with name 'antorcha' 'tea', |
![]() |
Los nombres que pongas en
la propiedad name deben ir entre comillas simples
(apóstrofes). Todas estas palabras las va recopilando Inform a
medida que compila tu programa y las va metiendo en el Diccionario del
juego.
Inform no tiene una sección donde se le indique el vocabulario del juego, sino que él mismo lo va construyendo a medida que va encontrando palabras entre comillas simples como las anteriores. En estas palabras puedes poner acentos o eñes,
pero se recomienda que no las pongas. Piensa que los juegos
Inform pueden ser ejecutados en muchos ordenadores diferentes, algunos
de los cuales ni siquiera tienen eñe en su teclado. Si pones en
el |
name
. Más adelante
le daremos más. has
. female
. Algunos objetos
pueden llevar también el atributo pluralname
(por ejemplo "gafas"). Si el género es masculino, puedes optar por poner el
atributo male
o no ponerlo (Inform presupone
atributo male
si no se pone).
Aquí tienes el
código fuente del programa
que incluye la antorcha, compílalo y tendrás la
versión lista para jugar. Vamos a hacer
muchos experimentos con esta antorcha, de modo que te aconsejo que
sigas las explicaciones con el juego funcionando. Si pones VERSION en
este juego precompilado, observarás que al final ya no aparecen
las
letras SD
, sino sólamente D
. La
letra D
indica que aún estamos
en "modo debug" y por tanto seguimos disponiendo de
superpoderes. La letra S
indicaba además
otro modo especial
que no interesa para estas pruebas, y que es mejor desactivar. Para
lograr desactivar el modo S
, dejando activado el modo D
,
debes
usar la siguiente orden al compilar:
INFORM-631 -D -~S torre3.inf |
>xlista Oscuridad (20) (Library Extensions) (24) Puerta Principal (26) a ti mismo Dormitorio (27) Escalera de caracol (28) Mazmorra (29) Escalera de caracol (30) una antorcha Alto de la torre (32) |
¿Has visto? la antorcha está en la localidad
número 30, la escalera de
caracol. Vamos a teleportarnos allí. Puedes usar como antes el
verbo
XIR 30
, pero ahora que la localidad contiene un objeto,
puedes usar
otra forma más cómoda: IRDONDE ANTORCHA
, lo
cual te teletransportará a la
habitación en la que esté el objeto que tiene 'antorcha'
en su
name
.
> IRDONDE ANTORCHA Escalera de caracol Los desgastados peldaños de piedra resbalan en ocasiones. A mitad de la escalera una antorcha en la pared impide que la oscuridad sea completa. Puedes ver una antorcha. |
Efectivamente, el mensaje "puedes ver una antorcha" nos ratifica que está en el lugar correcto. Realmente ese mensaje sobraba, puesto que la descripción de la localidad ya había mencionado la antorcha. Esto es muy fácil de corregir y después veremos cómo. Por el momento vamos a realizar algunas acciones sobre la antorcha.
![]() |
¡Y este es un truco
imprescindible! Otro de los superpoderes de que disponemos en modo
"Debug" es el poder ver las acciones que genera el parser
ante cada posible frase que tecleamos. Para ello pon:
Y ahora intenta diferentes verbos sobre la antorcha, para averiguar qué acción genera cada uno. Como hemos dicho, el programador necesita conocer siempre las acciones generadas, pues la programación del juego ocurre en torno a las acciones (y no a los verbos como en PAWS). |
Comprobemos que todo lo que os había contado antes sobre el verbo "TIRAR" es cierto, intentando las diferentes formas de este verbo y comprobando cómo cada una da lugar a una acción diferente:
>tirar antorcha [ Action Drop with noun 31 (antorcha) ] Para dejar la antorcha deberías tenerla. |
El mensaje entre corchetes ha aparecido porque hemos puesto antes
ACCIONES
. El mensaje que aparece a continuación es
la respuesta
estándar cuando intentamos dejar un objeto que no tenemos.
¿Qué
significa el mensaje "[ Action Drop
with noun
31
(antorcha) ]"?
En Inform casi todas las acciones recaen sobre algún objeto,
aunque
hay algunas excepciones (por ejemplo Jump
, Sing
, Pray
son
acciones que no necesitan objeto, mientras que Take
, Drop
etc
son acciones que siempre han de ir referidas a un objeto: el objeto
que se coge o se deja). Incluso en algunos casos se involucran dos
objetos (como en la acción Insert
que requiere el
objeto que se está
metiendo y el objeto dentro del cual se está metiendo).
El parser, después de analizar la frase y tras haber determinado el objeto (u objetos) sobre los que la acción tiene lugar, deja preparadas tres variables:
action
: esta variable contiene la acción que
se ha generado noun
: esta variable contiene el primer objeto
relacionado con esa acción second
: esta variable contiene el segundo objeto
relacionado con esa acción
![]() |
En cierta manera, es algo análogo al verbo, el nombre1 y el nombre2 de PAWS, solo que en Inform no se trata de palabras, sino de acciones y objetos. El parser siempre intentará relacionar las palabras con los objetos del juego, y si no puede, causará un mensaje de error. |
Volvamos a lo que ha dicho el juego: "[ Action Drop
with noun
31
(antorcha) ]" Su significado debe de estar más claro ahora. La
acción generada es Drop
(aunque el verbo usado ha
sido "TIRA"), y
el objeto sobre el que recae la acción (lo que Inform llama
"noun")
es el objeto número 31 (que es la antorcha como nos aclara
después
entre paréntesis). El número de objeto no es importante
para nosotros,
es un número interno que Inform asocia a cada objeto. [Jeje,
date
cuenta que ahora que sabemos el número de la antorcha
podríamos
teleportarnos a su interior con XIR 31
¿qué
crees que pasará?]
![]() |
Otro detalle
importantísimo. Si el parser no es capaz de asociar la frase del
jugador con un objeto válido en las cercanías, el parser
se detiene con un error y la acción no llega a generarse.
Esto se comprueba fácilmente en el juego. Ve al piso inferior (donde la antorcha ya no es visible) e intenta de nuevo poner "Tira antorcha". Veamos qué ocurre:
No aparece ningún mensaje entre corchetes indicando la acción ¡porque no ha llegado a generarse ninguna acción! El comando ha sido abortado porque no se ha encontrado el objeto sobre el cual se supone que debería actuarse. Esto es otra diferencia fundamental con PAWS, en donde el parser no intentaba asociar los nombres con los objetos, sino que se limitaba a dejarlos en una variable. Esto permitía que el juego pudiera reaccionar a nombres de cosas, sin que esas cosas existieran en realidad. En Inform esto no es posible. Cualquier cosa a la que el jugador deba referirse, debe ser un objeto del juego. |
Sigamos experimentando con las acciones, viendo qué entiende el parser ante diferentes comandos:
>salta [ Action Jump ] Saltas en el sitio, sin ningún resultado. |
Fíjate cómo en este caso la acción que se
genera no lleva objeto
asociado (no se menciona el valor de noun
). ¿Y si
intentamos del
mismo modo poner "DEJA" sin más palabras?
>deja ¿Qué quieres dejar? |
No se ha generado la acción Drop
, porque el
parser detecta que este
es un comando incompleto. El parser ha sido instruído para que
sepa
que detrás del verbo DEJA debe ir siempre el nombre de un
objeto. Como
le falta esto, la acción ni siquiera es iniciada. (NOTA: Si al principio
del código no se declarara la constante MANUAL_PRONOUNS, el paser trataria de
deducir el objeto de forma implicita, 'adivinando' que se trata de la antorcha.)
Volvamos al piso de arriba e intentemos algunas acciones más sobre la antorcha.
>coge antorcha [ Action Take with noun 31 (antorcha) ] Cogida. |
Vaya. ¿Podemos coger la antorcha? Esto no debería ser
asi, el jugador
no debería poder llevarsela. Lo que ha ocurrido es que, dado que
aún
no hemos programado nada en el objeto antorcha
, la
librería ejecuta
las acciones por defecto. Y por defecto, la librería permite
coger
cualquier objeto que se halle al alcance del jugador. Veremos
después
cómo impedirlo.
Podríamos seguir experimentando, pero te dejaré que lo hagas tú mismo. Intenta diferentes verbos sobre la antorcha. Prueba cosas absurdas, intenta abrirla, cerrarla, romperla, quemarla, olerla, lanzarla al suelo, empujarla, tirar de ella, girarla, moverla. Verás que Inform comprende todas esas frases y las convierte en diferentes acciones (o a veces en la misma, en particular fíjate en la acción que se genera para MOVER ANTORCHA).
Ahora pasemos a algo más interesante. Vamos a programar la antorcha para que "reaccione" ante ciertas acciones, evitando así que se ejecute la acción por defecto para esos casos.
>empuja antorcha [ Action Push with noun 31 (antorcha) ] No ocurre nada, aparentemente. >examina antorcha [ Action Examine with noun 31 (antorcha) ] No observas nada especial en la antorcha. >tira de la antorcha [ Action Pull with noun 31 (antorcha) ] No ocurre nada, aparentemente. >mueve la antorcha [ Action Push with noun 31 (antorcha) ] No ocurre nada, aparentemente. >gira la antorcha [ Action Turn with noun 31 (antorcha) ] No ocurre nada, aparentemente. |
Bueno, hemos averiguado que hay al menos tres acciones que
deberíamos
tener en cuenta en nuestro juego: Push (Empujar)
, Pull
(Tirar)
y Turn (Girar)
(fíjate
que el verbo MOVER produce también la acción Push
,
esto es porque
en el fichero SpanishG.h
se ha definido así,
aunque puede
cambiarse. La asignación de verbos a acciones es programable).
Por otra parte Examine (Examinar)
debería dar un mensaje
un poco más
descriptivo. Todo esto implica programar la antorcha.
![]() |
En PAWS las respuestas a los
verbos se codificaban en el proceso llamado "tabla de respuestas". En
Inform, en cambio, se codifican en cada objeto.
Cada objeto lleva "incrustadas" las respuestas ante las posibles acciones. |
Cuando el parser recibe una frase como "EMPUJA ANTORCHA", da los siguientes pasos:
name
de cada objeto con la
palabra "antorcha". action
toma el valor Push (o
sea Empujar)
,
y la variable noun
toma el valor 31 (que representa al
objeto antorcha
en nuestro juego). Push
con noun
=antorcha
.
Cualquier objeto puede abortar la acción. Enseguida explicaremos
cómo tiene lugar este "aviso" y cómo un objeto puede
abortar la acción. Esto es útil, por ejemplo, para lograr
que un PSI (Personaje Pseudo-Inteligente) cercano impida ciertas acciones (recuerda que un PSI es un
objeto para Inform) antorcha
de que el
jugador acaba de realizar la acción Push
sobre
ella. La antorcha
debería tener preparada una
respuesta para este caso. antorcha
tiene preparada respuesta, se
ocupará ella misma de continuar la acción. Aquí
tiene lugar la programación de lo que ocurre al empujar la
antorcha (la aparición de la salida oeste). La librería
ya no hará nada más con respecto a esta acción. Es
algo así como si la antorcha hiciera un DONE. Push
por defecto. La acción
Push
por defecto se
limita a escribir "No ocurre nada, aparentemente" (el mensaje
también puede ser redefinido) Push
, en particular, no
hace nada más, puesto que no se ha cambiado el estado del juego.
Todos los objetos permanecen exactamente igual a como estaban antes.
Sin embargo otras acciones sí que cambian el juego. Por ejemplo Take
(o sea Coger)
o Drop
cambia de sitio algunos objetos. En este tipo de
acciones, la librería "avisa" de nuevo al objeto en
cuestión de que la acción Take
o Drop
ha finalizado con éxito, por si el objeto quiere hacer algo,
antes de que la librería imprima finalmente un mensaje indicador
del éxito de la acción (como "Cogido", o "Dejado"). Esta forma de funcionar, aunque puede parecer complicada al principio, te libera en realidad de un montón de trabajo. Tu programa no tiene que ocuparse de verificar en qué localidad estás para decidir qué responder (como era habitual en PAWS), ya que ha sido el parser el que ha averiguado previamente si la antorcha está ahí o no.
Por tanto, resumamos otra vez el mecanismo:
![]() |
El parser determina si la
frase tiene sentido, y asocia a la frase una action y un
objeto sobre el que recae la acción (siempre que haya un objeto
de ese nombre cerca).
Seguidamente la librería "avisa" a los objetos de que la acción tendrá lugar y si los objetos "no dicen nada", la librería llevará a cabo la acción por defecto. |
¿Cómo "avisa" la librería a los objetos? Para
que un objeto pueda
ser "avisado" por la librería cuando una acción tiene
lugar, el
objeto debe proporcionar una rutina llamada react_before
(entonces la librería le "avisará" de todas las acciones
que tienen
lugar en la proximidad de ese objeto, aunque la acción no vaya
referida a él), o bien una rutina llamada before
(entonces la
librería le "avisará" sólo de las acciones que
recaen sobre él, y no
las que recaerían sobre otros objetos).
Olvidemos de momento la propiedad react_before
y
centrémonos en
la propiedad llamada before
. Esta propiedad se llama
así como un
recordatorio de que se activa antes de que la librería
intente
realizar la acción por defecto.
La propiedad before
es en realidad una "rutina
incrustada en el
objeto". ¿Recuerdas que antes hablábamos de "rutinas
libres", como
la rutina Initialise
? Ha llegado el momento de hablar de
"rutinas
incrustadas en los objetos".
Una rutina "incrustada en un objeto" es similar a una rutina libre
en varios aspectos: se delimita mediante [
y ]
,
tiene una lista de
variables locales y también una lista de instrucciones. Las
principales diferencias son las siguientes:
[
,
sino antes de él. Por ejemplo:
Object antorcha "antorcha" EscaleraCaracol2 with name 'antorcha', saludo [; print "Hey, soy una antorcha!^"; ], has female; |
Hemos añadido tres líneas a la antigua antorcha. En
ellas, hemos
programado una rutina incrustada, llamada saludo
.
Fíjate como el
nombre de la rutina va antes del [
. Después del [
iría la lista de
variables locales, que está vacía en este caso,
y un punto y
coma. A continuación, la lista de instrucciones que componen la
rutina. En este caso sólo hay una instrucción que es
print
. Finalmente, el ]
indica el final de
la rutina. Es necesario
poner una coma detrás de este ]
porque todo lo
anterior era en
realidad una propiedad del objeto antorcha
, y las
propiedades van
separadas por comas. El resto del objeto es como antes.
¿Qué conseguimos añadiéndole una "rutina incrustada"? En realidad nada. Si juegas de nuevo con esta antorcha modificada, verás que el juego es exactamente el mismo. La antorcha tiene una rutina nueva, pero esta rutina no es utilizada por el juego. Podrías utilizar la rutina si, en otra rutina, pones lo siguiente:
antorcha.saludo(); |
Esto es lo que se denomina una llamada a rutina incrustada. Como ves, las llamadas a rutinas incrustadas se forman poniendo, en primer lugar, el objeto del que forman parte, después un punto y detrás el nombre de la rutina. Finalmente, son necesarios los paréntesis (a veces dentro de estos paréntesis puede ir información extra, que se le envía a la rutina, y es copiada en sus variables locales, pero no en este caso puesto que la rutina no tiene variables locales).
Cuando el juego llega a una instrucción como la anterior,
buscará el
objeto antorcha
(no importa en qué lugar del juego
esté, en este caso
no es necesario que esté cerca del jugador), y buscará
dentro del
objeto antorcha
una propiedad llamada saludo
.
Si esta propiedad no
existiera, se produciría un error durante la ejecución
del juego. Si
existe, entonces se ejecutarán las instrucciones que hay dentro
de la
rutina (en nuestro ejemplo, el print
que imprime el
saludo), y
cuando se encuentre una instrucción return
, o bien
cuando se llega
al final de la rutina ]
, el juego continuará por
la instrucción
siguiente a la llamada.
En cierta forma, todo esto es similar a ejecutar un proceso PAWS, pero en este caso los procesos están incrustados dentro de los objetos, y no se identifican por un número, sino por una pareja de nombres: el nombre del objeto y el nombre del proceso.
Bien, pero el caso es que nuestro juego no tiene ninguna
instrucción
que llame a antorcha.saludo
y por eso el mensaje nunca
será impreso.
Sin embargo, si en lugar de saludo
hubieramos llamado
a la rutina before
, el mensaje aparecería cada vez que se
intentara hacer algo
con la antorcha, ya que la librería se ocupa de llamar a
antorcha.before
cada vez que detecta una acción con noun
=antorcha
. ¡Pruébalo! (tienes
una versión modificada y lista
para pruebas aquí
Si ejecutas esta versión, e intentas cosas con la antorcha,
verás que
el mensaje "Hey, soy una antorcha!^" aparece delante de cada
respuesta de la librería. O sea, que la rutina before
es ejecutada
antes que la acción de la librería, no obstante no
impide que la acción por defecto tenga lugar.
Para impedir que la acción por defecto tenga lugar, la rutina before
tiene que ejecutar la instrucción rtrue
(que viene
a ser como el
DONE del PAWS). rtrue
significa "retorna VERDAD"; podemos
imaginar
que la librería le pregunta a la antorcha "¿verdad que ya
te ocupas
tú de realizar la acción?". Si la antorcha
responde "VERDAD",
entonces la librería ya no ejecutará la acción por
defecto. Pero si la
antorcha
responde "MENTIRA" (rfalse
), o no
responde nada, la
librería seguirá adelante con la acción por
defecto.
¿Qué pasará por tanto si cambiamos la antorcha a esto otro?
Object antorcha "antorcha" EscaleraCaracol2 with name 'antorcha', before [; print "¡Dejame en paz!^"; rtrue; ], has female; |
¡El jugador recibirá la respuesta "Dejame en paz" ante cada posible acción que intente sobre la antorcha! Y además la acción no será realizada. En particular, el jugador no podrá coger la antorcha. Todas las acciones fracasarán con el mismo mensaje.
![]() |
![]() |
![]() |
Entendiendo Inform (y olvidando PAWS) |