 |  |  | Criaturas vivas y cómo conversar |
Criaturas vivas y cómo conversar
Nuestro recorrido por los diferentes tipos de objeto programados en
InformATE termina con el más complejo de todos: las criaturas vivas.
Pero ve sobre aviso: algunos puntos de esta sección requieren
algunos conocimientos que están en el
capítulo sobre parsing.
Los objetos animados, como un monstruo marino, una tía loca o los
enanitos odiosos, tienen una propiedad llamada vida. La
estructura de esta propiedad (que es una rutina) es totalmente
idéntica a la de las propiedades antes y despues, la
diferencia es que la propiedad vida sólo será llamada por la
librería cuando el jugador intenta una de las siguientes acciones
sobre la criatura:
- Atacar
- El jugador demuestra hostilidad...
- Besar
- ...o todo lo contrario...
- DespertarOtro
- ...o intenta despertarle.
- Lanzar
- El jugador intenta Lanzar uno a esta criatura
 |
Cuidado. La acción que recibe la criatura es Lanzar y no
RecibirLanzamiento como podrías en buena lógica pensar.
En mi opinión esto es un poco confuso, pero he respetado la
nomenclatura original de Graham Nelson.
|
- Dar
- El jugador intenta Dar uno a la criatura.
- Mostrar
- ...o solo le tienta mostrándoselo.
- Preguntar
- El jugador ha preguntado algo a la criatura. Al igual
que si se tratara de un libro, la rutina vida debe usar las
variables consultar_desde y
consultar_num_palabras para averiguar qué es lo que el
jugador ha preguntado (aquí de nuevo resulta útil la librería
ETemas). La variable otro contiene la primera
palabra de la pregunta que no sea un artículo. A veces ésto puede
ser útil.
- Hablar
- El jugador le ha dicho algo a la criatura, usando el
verbo "Habla sobre <cualquier secuencia de palabras> al
enano". Otra vez las variables consultar_desde y
consultar_num_palabras pueden usarse para averiguar qué
le ha dicho. Como en el caso anterior la variable otro
contiene la primera palabra.
- Responder
- Esta acción puede originarse de dos formas
diferentes:
- El jugador ha usado el verbo "Di <cualquier secuencia
de palabras> al enano" (o "Di al enano <cualquier
secuencia de palabras>). También vale usar el verbo "Grita"
o "responde" en vez de "di". En todos estos casos se genera
la acción Responder enano y las variables
consultar_desde y consultar_num_palabras
quedan preparadas para interpretar la secuencia de palabras.
- El jugador ha usado el formato típico para ordenar algo al
enano ("Enano, salta"), pero la orden no ha sido comprendida
por el parser, por ejemplo "Enano, vete a paseo". En este caso
se genera la acción Responder enano y las variables
consultar_desde y consultar_num_palabras
quedan referidas a la orden no comprendida; en el ejemplo
anterior esto implicaría que consultar_desde valdría 3
(ya que la palabra 1 es 'enano' y la palabra 2 es la coma), y
consultar_num_palabras valdría también 3 (ya que la
orden no comprendida tiene 3 palabras).
En este caso, además, la librería habrá intentado interpretar la
primera palabra de la orden como si fuera un número, y el
resultado de su interpretación puede hallarse en la variable
numero_especial. Por ejemplo, el comando "Computador,
123" causará la acción Responder computador y la
variable numero_especial tomaría el valor 123.
 |
Cuidado. Esta acción utiliza las variables uno y
otro en orden inverso a las demás acciones de
conversación. Normalmente la variable uno contiene el
personaje con el que el jugador intenta hablar y la variable
otro contiene la primera palabra de lo que el jugador
intenta decir. En cambio en la acción Responder es al
revés. La primera palabra de la respuesta está en uno
y el personaje al que se responde está en otro.
|
- Orden
- Esta acción se genera si el jugador ha dado una orden a
la criatura (por ejemplo "Enano, salta") y la rutina
Ordenes de esa criatura no ha hecho nada. (La rutina
Ordenes la veremos enseguida).
Si la rutina vida no existe o retorna false, la
librería mostrará un mensaje por defecto adecuado a cada acción (y en
general, no pasará nada). Es evidente que para hacer un personaje
interesante su rutina vida tenderá a ser bastante larga. Por
ejemplo, programemos un sacerdote (muy simple) para el juego
"Ruinas" (NOTA: recuerda que si quieres imprimir el símbolo de
comillas en la pantalla, debes poner el símbolo ~ en el código
fuente):
Object sacerdote "sacerdote momificado" camara
with nombre 'sacerdote' 'momificado',
descripcion
"Con el tiempo se ha disecado, y sus moléculas se
mantienen unidas sólo por la fuerza de su voluntad. Aunque
su idioma sea presumiblemente el maya local, tienes el
curioso presentimiento de que entendería tu lengua.",
inicial "Tras la losa un sacerdote momificado espera de pie,
apenas vivo, imposiblemente venerable.",
vida [;
Responder: "El sacerdote tose, y casi se desintegra.";
Preguntar:
switch(otro)
{
'diccionario', 'libro':
if (diccionario has general)
"~El símbolo del ~pájaro~... muy divertido...~";
else "~¿Un diccionario?¿de veras?~";
'simbolo', 'maya', 'dialecto', 'simbolos':
"~En nuestra cultura los sacerdotes siempre son
cultos.~";
'rey', 'tumba', 'altar', 'sepulcro', 'losa', 'templo':
"~El Rey (¡vida, felicidad, prosperidad!) está
profundamente enterrado en su Sepulcro, donde nunca
entrarás.~";
}
"~Tú mismo debes hallar la respuesta.~";
Hablar: "El sacerdote no tiene interés en tu sórdida vida.";
Atacar, Besar:
remove self;
"El sacerdote se desintegra en un fino polvo hasta que
nada queda, ni un cabello, ni un hueso.";
Lanzar:
move uno to localizacion;
<<Atacar self>>;
Dar, Mostrar:
if (uno == diccionario && diccionario hasnt general)
{
give diccionario general;
"El sacerdote lee un poco del libro, riendo de forma
hueca y rasposa. Al final no puede resistirse y
garabatea una corrección antes de devolvértelo.";
}
"Al sacerdote no le interesan mucho las cosas
terrenales.";
],
has animado;
|
Observa cómo en la rutina vida tratamos las diferentes
acciones antes mencionadas. En concreto mira la entrada para
Preguntar. Gracias a ese código el sacerdote podrá responder
a cosas como "Pregunta al sacerdote por el sepulcro" o "Pregunta
sobre el diccionario al sacerdote", evidentemente esta parte sería
más larga en un juego real, para proporcionar respuestas a muchas
preguntas posibles. Observa también lo que ocurre en la acción
Lanzar, en primer lugar movemos el objeto lanzado a
"localizacion" (el objeto queda tirado en el suelo) y
además causamos la acción Atacar, que hará desaparecer al
sacerdote.
Por supuesto, además de la rutina vida, una criatura tiene
las rutinas antes y despues como cualquier otro
objeto. También pueden tener las rutinas reaccionar_antes y
reaccionar_despues, y es en los PNJ donde resulta más
útiles, por ejemplo:
reaccionar_antes [;
Dejar: if (uno==pieza_del_satelite)
print "~No debió hacer eso, Mr Bond,~ dice Blofeld.^^";
Disparar:
remove pistola;
"En cuanto desenfundas, Blofeld chasquea los dedos y un
imán gigante sustrae el arma de tu mano. Golpea el techo
con un clang. Blofeld acaricia suavemente a su gato.";
];
|
Si Blofeld se mueve de un lugar a otro, estas reglas se mueven con
él. (Nota: La acción Disparar no está en la librería. Se
supone que habrá sido definida en el juego en que está Blofeld).
EJERCICIO 18 |
Programa un psiquiatra barbudo que tiene al jugador bajo observación
y que de vez en cuando murmura ocurrencias como "El sujeto pone el
cono verde en la mesa, interesante." (Solución)
|
Otro ejemplo puede ser la serpiente del juego "Balances", que
demuestra que incluso la rutina vida más diminuta puede ser
adecuada para un animal:
Object serpiente "serpiente de cascabel"
with nombre 'serpiente' 'cascabel',
inicial "Hecha un apretado ovillo, en el borde del abismo, hay
una serpiente de cascabel.",
vida [;
"¡La serpiente sisea enfurecida!";
],
has animado femenino;
|
A veces interesa que las criaturas sean transparentes (es decir, que
pueda verse los objetos que "contienen") y a veces no. Por ejemplo,
considera los dos siguientes ejemplos de objetos animados:
- Un golfillo con algo abultando en el bolsillo de la chaqueta.
- Un guardián que tiene un mazo de llaves colgando del cinturón.
El guardián es transparente, pero el golfillo no. De este
modo el parser impedirá que el jugador pueda referirse a lo que el
golfillo está ocultando, incluso si el jugador ha jugado ya el juego y
sabe lo que hay en el bolsillo y cómo se llama. En cambio podrá
examinar y ser tentado por las llaves del guardián (si bien las llaves
no serán mencionadas en la descripción estándar del guardián, y sería
necesario que el programador escribiera una rutina
descripcion que lo hiciera, suponiendo que sea necesario
mencionar la llave al jugador).
El jugador puede darle una orden a cualquier criatura que encuentre en
el juego usando para ello la forma: "Rana, salta", por ejemplo. Es
decir, en primer lugar iría el nombre de la criatura (o persona) y
seguidamente, tras una coma, la orden que se le da. La orden puede ser
tan compleja como la que se podría dar al propio jugador, es decir,
por ejemplo: "Rey Midas, toca la gran puerta de roble". El parser de
Inform comprenderá la orden y se la "enviará" al Rey (lo cual, por
supuesto, no implica que el Rey vaya a obedecerla). La librería no
tiene forma de ejecutar las acciones que no van destinadas al jugador,
de modo que en este caso todo el trabajo recae en el
programador. Suponiendo que efectivamente quisiéramos que el Rey
llevara a cabo la acción, habría que programar todas las
comprobaciones necesarias "a mano" (es decir, habría que comprobar
que la puerta de roble en cuestión es visible por el Rey, y habría que
enviarle a la puerta el mensaje indicando que va a ser tocada). Lo
único que hace la librería es preparar una variable llamada
actor indicando qué personaje ha de llevar a cabo la acción
(normalmente se trata del jugador).
Así que si el jugador pone algo como "Manolo, vete al sur" se
generará una "orden", que es el equivalente de una acción. La
librería ejecutará la rutina ordenes de Manolo (si Manolo
tiene una). Es esta rutina la que tiene que llevar a cabo la
orden. Como ayuda, recibe en la variable accion la acción
solicitada (##Ir, en el ejemplo) y en las variables
uno y otro los objetos involucrados (obj_s
y NULL en el ejemplo). La rutina ordenes puede tener
una estructura similar a antes, despues o
vida, es decir, una lista de acciones seguidas del código a
ejecutar en cada caso.
Por ejemplo, se podría añadir lo siguiente al sacerdote:
ordenes [;
Ir: "~No debo abandonar el sepulcro.~";
NoComprendido: "~Hablas en acertijos para mí~";
default: "~No es a ti a quien sirvo.~";
],
|
Fíjate que el sacerdote es muy poco colaborador. Ante cualquier orden
emite un mensaje y no hace nada más (por tanto no lleva a cabo la
orden). Si el jugador pone "Sacerdote, sal", el sacerdote dirá que
no debe abandonar el sepulcro; si pone cualquier otro verbo de los que
InformATE comprende (por ejemplo, "Sacerdote, salta.", "Sacerdote,
abre la tumba", "Sacerdote, come la seta"), responderá que no es el
siervo del jugador. Si el jugador usa un verbo no comprendido por el
juego (por ejemplo "Sacerdote, escupe") la respuesta será que hablas
en acertijos.
Incluso si el jugador usa una palabra comprendida por el juego, si
ésta no es un verbo la orden generada será NoComprendido de
todas formas. Así, "Sacerdote, seta", "Sacerdote, tumba" llevarán
a la respuesta "Hablas en acertijos para mí.". También acabaremos en
este mismo punto si el jugador menciona un objeto que no está al
alcance del sacerdote, como "Sacerdote, coge jaula" (suponiendo que
hay una jaula en otro lugar del juego). Más adelante veremos que es
posible distinguir la causa del NoComprendido y responder
adecuadamente.
Si ante la acción NoComprendido la rutina codigo
retornase false, la librería generaría a continuación la
acción Responder, como ya se ha explicado antes. Pero en
nuestro ejemplo, la rutina ordenes siempre retorna
true, por lo que una frase como "Sacerdote, hola", nunca se
convertirá en equivalente de "Di hola al sacerdote".
 |
Algo que hay que tener siempre presente es que la palabra "Si" es
un verbo para la librería, por lo que "Sacerdote, si" se convierte
en una orden con accion igual a Si. En
cambio "Di si al sacerdote" se convierte en una acción
Responder. Esto es un poco fastidioso ya que hay que
programar la respuesta en dos sitios diferentes del personaje.
|
  |
Si no existe la propiedad ordenes (o si esta propiedad
retorna false), la orden se envía a la rutina vida
del PNJ. Se convierte en una acción Orden o bien en una
acción Responder. El primer caso ocurre cuando el verbo
usado es comprendido por Inform (y se almacena en la variable
accion). El segundo caso ocurre cuando el verbo usado no es
comprendido.
Esto se ha hecho así por compatibilidad con antiguas librerías de
Inform, pero se recomienda programar usando la nueva forma, es
decir, usando la propiedad ordenes del PNJ.
|
Para aclarar un poco el pequeño lío anterior, resumimos en una tabla
qué acción se genera según qué verbo haya usado el jugador y en qué
forma lo haya usado. En todos los casos se trata del jugador
hablándole a un PNJ, pero debido a la flexibilidad del parser hay
muchas posibilidades. La columna "rutina" indica qué rutina del
PNJ será llamada en primer lugar para ocuparse de la orden. La
última columna (consulta) indica qué valores tomarían las variables
consultar_desde y consultar_num_palabras en
cada caso.
|
Comando usado | Rutina | accion | uno | otro |
consulta |
|
"Orco, coge el hacha" | ordenes | Coger | hacha |
0 |
|
"Orco, sí" | ordenes | Si | 0 | 0 |
|
"Pide al orco el escudo" | ordenes | Dar | escudo
| jugador |
|
"Orco, payaso" | ordenes | NoComprendido |
'payaso' | orco | 3 | 1 |
|
"di payaso al orco" | vida | Responder | 'payaso'
| orco | 2 | 1 |
|
"responde payaso al orco" | vida | Responder |
'payaso' | orco | 4 | 1 |
|
"orco, hablame de las monedas" | vida | Preguntar |
orco | 'monedas' | 6 | 2 |
|
"pregunta al orco sobre el gran troll" | vida | Preguntar |
orco | 'gran' | 5 | 3 |
|
"pregunta al orco sobre asdfg" | vida | Preguntar |
orco | 0 | 5 | 1 |
|
"hablale al orco sobre el gran troll" | vida | Hablar |
orco | 'gran' | 5 | 3 |
|
|
|
|
La tabla anterior requiere una explicación más detallada en algunas
líneas. Para empezar, recordemos que la orden que se menciona en la
tabla se generará siempre y cuando los objetos involucrados estén al
alcance del orco. Por ejemplo: "orco, coge el hacha" sólo generará
la orden Coger si el hacha está al alcance del orco. En caso
contrario se genera NoComprendido, como ya hemos explicado.
Por otro lado, podemos observar que algunos verbos son convertidos en
acciones un tanto inesperadas. Así, el verbo "Pedir" se convierte en
la acción Dar, por lo que el jugador puede usar
indistintamente la forma "Pide al orco el escudo", o bien "Orco,
dame el escudo" (ambas son equivalentes si el escudo está al alcance,
si no no equivalen ya que la primera genera directamente un error de
parser mientras que la segunda genera la orden
NoComprendido. Otro ejemplo de transformación de orden es
"Orco, hablame de las monedas", que se transforma en la acción
Preguntar y por tanto sería equivalente a "Pregunta al orco
sobre las monedas".
 |
En ambos casos, "orco, dame" y "orco, hablame" hay que estar
avisado de que InformATE separará el verbo en dos trozos y lo que
realmente procesará será: "orco, da -me" y "orco, habla -me"
donde el objeto llamado "-me" es el propio jugador. Hay que tener
esto en cuenta para comprender por qué consultar_desde
vale 6 en el ejemplo "Orco, hablame de las monedas". En efecto, la
palabra 1 es "orco", la palabra 2 es la coma, la palabra 3 es
"habla" la palabra 4 es "-me", la palabra 5 es "de" y
finalmente, en la palabra 6 comienza el tema de la conversación, que
consta de dos palabras (como se refleja en la variable
consultar_num_palabras.
|
En la línea que dice "Pregunta al orco sobre asdfg" se entiende que
"asdfg" es un texto desconocido por el juego (es decir, es un texto
que nunca aparece en el programa escrito entre comillas simples. Si
apareciera así una sola vez, Inform lo agregaría a su diccionario y
pasaría a ser palabra conocida). Al ser desconocida esa palabra, la
variable otro toma el valor 0 (si fuera conocida tomaría como
valor la dirección de diccionario de la palabra, lo que se representa
en el resto de la tabla poniendo la palabra en cuestión entre comillas
simples).
 |
EJERCICIO 19 |
Quizás consideres que tener dos acciones separadas, una para
Responder y otra para Hablar, junto con la forma "orco, tal
cosa", sea complicar demasiado el juego (sobre todo para el
jugador). Piensa cómo se podría programar un comando "habla" y
"responde" de modo que cuando el jugador los intente, el juego
responda "Para hablar con alguien ponlo así: alguien, lo que
sea". (Solución) Nota: para dar con la solución necesitarás saber
cómo funciona la gramática. No obstante puedes aprovechar esta
solución para tus necesidades.
|
|
Existen objetos con los que, pese a que no son seres vivos, es
necesario hablar (como micrófonos, teléfonos, etc). Sería incorrecto
programarlos como animados, ya que no tienen las restantes
características de los seres vivos. En vez de esto, basta con darles
el atributo hablables y proporcionar las rutinas
ordenes y vida para que manejen la conversación.
EJERCICIO 20 |
Escribe un objeto "computador" que comprenda la orden
"Computador, alfa es 20" (o cualquier otro número) y responda
"Asignado el valor 20 a alfa". (Pista: necesitas crear un nuevo
verbo, 'alfa' y manejarlo en la rutina ordenes del
computador). (Solución)
|
 |
El resto de este capítulo se solapa mucho con el
capítulo sobre parsing, y se supone un cierto
conocimiento del parser. De momento puedes saltártelo y volver a
leerlo cuando sepas más.
|
En la rutina ordenes puedes poner el caso
NoComprendido. Este caso es generado por el parser cuando no
ha sido capaz de comprender el comando que se le estaba dando al
personaje. Por ejemplo "Piloto, vuela hacia Aldebarán". La variable
tipoerror contiene un número que indica el error que el
parser habría escrito si la orden hubiese sido para el jugador, (en
vez de para un personaje). Por ejemplo, si contiene el valor
NOVEO_PE el mensaje sería "No veo eso que dices" (en este
caso significaría que el personaje no "ve" el objeto al que se
refiere el jugador en su orden).
 |
Cuando el jugador da una orden a una criatura o a un objeto
hablable, el parser intenta interpretar esta orden usando
la misma gramática que usa para las órdenes dadas al jugador. El
comando es interpretado exactamente de la misma forma que si hubiera
sido dirigido al jugador (con la diferencia de que la variable
actor contiene el personaje a quien fue dada la
orden). Esto suele ser lo más adecuado en muchos casos, pero en
otros podría ser necesario usar una gramática totalmente diferente
al hablar con ciertos personajes u objetos. Por ejemplo, imaginemos
un computador de una nave espacial, llamado Zen. No sería muy normal
darle a Zen órdenes como "Zen, coge la espada", sino que las
órdenes serían más bien de este tipo:
"Zen, pon rumbo a Centauro" "Zen, velocidad estándar 6" "Zen, rastrea órbita 360" "Zen, activa escudo protector" "Zen, prepara los blasters"
Todo esto puede hacerse añadiendo verbos a la gramática (ver el
ejercicio anterior), o con una programación cuidadosa del caso
Responder de la rutina vida del computador. Esto
es difícil y pesado. Especialmente si la mitad de los comandos que
quieres reconocer son ya reconocidos por la gramática normal pero la
otra mitad son nuevos.
Para estos casos, una criatura o un objeto hablable pueden
proporcionar una rutina llamada gramatica. Esta rutina es
llamada una vez que el parser ha detectado que el jugador está
intentando darle una orden a ese objeto. Cuando es llamada, las
variables palabra_verbonum y palabra_verbo ya
han sido inicializadas por el parser de modo que contienen el número
que ocupa el verbo entre las palabras tecleadas por el jugador y la
palabra de diccionario que corresponde a dicho verbo. Por ejemplo,
en el comando "Orac, activa el teleportador" la variable
palabra_verbonum valdría 3 ("Orac" es la 1, la coma es la 2
y "activa" es la 3) y palabra_verbo valdría
'activa'.
La rutina gramatica puede analizar entonces el resto de la
línea y finalmente retornar:
- 0
- (false) El parser sigue en la forma habitual
- 1
- (true) El parser debe suponer que gramatica ya ha
hecho todo el trabajo de parsing y que finalmente ha puesto en
las variables accion, uno y otro los
resultados de su parsing. (Para hacer este parsing puede usar las
funciones SiguientePalabra, IntentarNumero y
DominioNombre.
- 'verbo'
- El parsing no usa la gramática estándar, sino la del
verbo que se le indica aquí (más abajo se explica esto).
- -'verbo'
- Como en el caso anterior, pero además, si no es
capaz a interpretar la orden usando ese verbo, entonces sigue
intentando con los verbos de la gramática estándar.
Además, la rutina gramatica puede intentar hacer una
interpretación parcial de las primeras palabras de la orden,
actualizando la variable palabra_verbonum para indicar
hasta dónde ha llegado su interpretación, y dejar al parser que haga
el resto.
|
 |
EJERCICIO 21 |
Programa un personaje llamado Carlota, que es una niñita que está
jugando al juego de "simón dice". En este juego Carlota tiene
que obedecer los comandos que empiecen por "simón dice", pero
desobedece los demás. Así, si ordenas "Carlota, salta", Carlota
no obedecerá (y en vez de ello, te sacará la lengua), pero si le
dices "Carlota, simón dice salta" sí lo hará.
(NOTA: Para simplificar, haremos que Carlota sólo sepa ejecutar la
orden Saltar, y para las demás responde "Lo haría, pero no sé
como".) (Solución)
|
|
 |
EJERCICIO 22 |
Otra de las reglas que obedece Carlota es que si dices un número,
tendrá que aplaudir tantas veces como el número que has dicho
¿Juegas? (Nota: puedes usar la función
IntentarNumero(lugar) donde lugar es la posición
que ocupa la palabra que esperas que sea un número, dentro de las
tecleadas por el jugador. Si esa palabra es realmente un número,
la función te devuelve un entero cuyo valor es ese número. (Solución)
|
|
 |
EJERCICIO 23 |
Lamentablemente el personaje Dan Dislexic siempre confunde las
palabras "coge" y "deja" (cuando el jugador le ordena un
comando, entiende el otro). Programa este personaje. (Solución)
|
|
 |
Es interesante saber que siempre que el jugador escriba una coma (o
un punto) pegada a otra palabra, el parser la separará. Por esto si
en el diccionario del juego hay una palabra que contenga una coma o
un punto como una de sus letras, nunca encajará con nada de lo que
el jugador escriba. Estas palabras se llaman "palabras
intecleables" y son útiles para generar verbos que el
jugador nunca podrá escribir, pero que pueden generarse desde dentro
del juego (por ejemplo si son retornados por la rutina
gramatica de un objeto). Por ejemplo, para programar un
ordenador que entienda comandos como "computador, alfa es 3",
"computador, beta es ocho", "computador, gamma es 27", etc. se
podría hacer así:
[ Control;
switch(SiguientePalabra())
{ 'alfa': numero_interpretado=1; return 1;
'beta': numero_interpretado=2; return 1;
'gamma': numero_interpretado=3; return 1;
default: return -1;
}
];
Verb 'comp,' * Control 'es' number -> PonerA;
|
Observa que la gramática define un verbo "intecleable" puesto que
contiene una coma, y espera detrás de él un Control, que es
definido por la función Control como una de las palabras
alfa, beta o gamma (si no es ninguna de
estas, retorna -1 lo cual causa que el parser no entienda el comando)
seguido de la palabra 'es' y finalmente un número.
El verbo 'comp,' no puede ser generado por el jugador, pero
puede ser generado por la propiedad gramatica de un objeto,
en nuestro caso el computador, si lo programamos como sigue:
Object computador "computador"
with nombre 'computador' 'ordenador' 'zen',
gramatica [; return 'comp,'; ],
ordenes [;
PonerA:
switch(uno)
{
1: print "~Alfa";
2: print "~Beta";
3: print "~Gamma";
}
" vale ahora ", otro, "~.";
default:
"No computado.";
],
has hablable;
|
Esto puede parecer complicado (y lo es), pero es tremendamente
flexible, como mostrarán los ejercicios siguientes (tómatelos más como
ejemplos que como ejercicios, son muy difíciles).
|
  |
Otro posible uso de las palabras intecleables es crear lo que
podríamos llamar una "acción-falsa falsa". Recuerda que las
"acciones falsas" (fake_action) eran acciones que nunca
serán generadas por el parser (es decir, nunca pueden resultar de
un comando escrito por el jugador) y que además no tienen rutina
AccionSub. Su uso fundamental es para enviarselas
directamente a objetos (como Recibir o
DejarSalir. En algunos casos (muy raros) puedes necesitar
acciones que, al igual que las falsas, nunca puedan ser generadas
por el jugador pero que, a diferencia de las falsas, tengan su
rutina AccionSub. En este caso puedes generar un verbo
intecleable como el siguiente:
Verb 'xxxxx.'
* -> Preparar
* -> Pelar
* -> Cocinar;
|
Puesto que el verbo 'xxxxx.' nunca puede ser escrito por el
jugador, las líneas anteriores solo sirven para crear las acciones
Preparar, Pelar y Cocinar.
|
  |
EJERCICIO 24 |
¿Cómo cambiarías una línea de la gramática de forma que el cambio
se aplique sólo a un personaje concreto? Por ejemplo, supón que el
verbo "examinar" ha de ser extendido, de forma que "examina
pertenencias" genere la acción Inv (inventario), pero
sólo cuando esta orden va dirigida a Dan, de modo que "Dan,
examina pertenencias" se convierta en una acción Inv para
Dan, mientras que "Manolo, examina pertenencias" sea interpretada
en la forma habitual (que sería buscar el objeto llamado
"pertenencias" entre las cosas que hay al alcance de Manolo). (Solución)
|
|
 |
EJERCICIO 25 |
Programa una alarma que entienda los comandos, "alarma, on",
"alarma, off" y "alarma, ocho y media" (el último sería para
fijar la alarma a una hora). (Solución)
|
|
 |
EJERCICIO 26 |
Programa un analizador que escriba un análisis de un objeto dado,
en respuesta a comandos como "analizador, el cuarzo" (el cuarzo
se supone que sería un objeto presente, al alcance del
analizador) (Solución)
|
|
EJERCICIO 27 |
Programa un replicador de objetos, que es capaz de replicar algunas
bebidas exquisitas bajo orden, como por ejemplo "Replicador, brandy
de aldebarán", "Replicador, vino verde de Fomahault". El conjunto
de bebidas que puede suministrar está programado de antemano, no
puede replicar cualquier cosa que al jugador se le ocurra. No es
necesario que realmente sea capaz de crear estos objetos, basta con
que imprima un mensaje como "El replicador hace aparecer una copa
de brandy de aldebarán que bebes ansiosamente" (Solución)
|
  |
EJERCICIO 28 |
Programa un comunicador que se supone en contacto con un
computador central, de modo que el jugador pueda preguntarle al
comunicador dónde está cualquier otro miembro de la tripulación,
mediante una frase como "computador, donde esta el almirante"
(nota: puedes crear un atributo nuevo tripulacion y
dárselo a los personajes que son miembro de la tripulación) (Solución)
|
|
EJERCICIO 29 |
Finalmente, programa a Zen, al formidable computador de vuelo. (Solución) Mira directamente la solución, ya que con un
enunciado tan vago no podrías solucionarlo. Es un ejemplo de un
ordenador que comprende varias ordenes complejas gracias a un verbo
intecleable.
|
Los siguientes ejercicios (o ejemplos) realmente pertenecen más a la
sección sobre el alcance, pero son tan útiles en relación con la
programación de la conversación con criaturas lejanas (vía un
teléfono, por ejemplo) que hemos considerado más oportuno ponerlos
aquí en vez de dejarlo para tan adelante. Observar que en lugar de los
extraños trucos que verás en estos ejercicios puedes usar un atajo
mucho más simple para que el parser comprenda algo como "Manolo,
hablame de las gemas" (suponiendo que Manolo está al otro extremo
del teléfono que tiene el jugador). Simplemente haz que el teléfono
tenga el atributo hablable y que la palabra 'Manolo' se
refiera al teléfono.
Para más detalles sobre cómo "trastear" con el alcance, véase la
sección sobre el alcance. Observar que la variable
razon_alcance siempre contiene el valor
RAZON_HABLAR mientras el parser está tratando de averiguar
con quién intentas hablar. Así que es fácil cambiar qué cosas están al
alcance del jugador de cara a los verbos de conversación, sin afectar
a los otros verbos.
 |
EJERCICIO 30 |
A través de la pantalla principal de la Astronave Enterprise, el
capitán Picard quiere ver a Noslen Maharg y hablar con él. El
famoso tirano está en el planeta Mfroni. Programa esta pantalla
para que la
conversación sea posible. (Solución)
|
|
  |
EJERCICIO 31 |
Pon al jugador en contacto telepático con Marta, quien está en una
habitación sellada en otro lugar lejano, pero tiene el poder de la
telekinesia, es decir, puede darle al jugador objetos cercanos a
Marta (pese a que están separados). El jugador debe ser capaz de
darle ordenes a Marta como: "Marta, mira", "Pregunta a Marta
sobre...", "Di hola a Marta", "Pide a Marta la pelota roja"
(suponiendo que Marta tiene una), o "Marta, dame la pelota roja",
etc. (Solución)
|
|
Zak McKraken - spinf@geocities.com
 |  |  | Criaturas vivas y cómo conversar |