Luz y oscuridadEl modelo del mundoObjetos para leer y consultarCriaturas vivas y cómo conversar

Criaturas vivas y cómo conversar

La vida en InformATE

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
(Esp) 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:
  1. 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.
  2. 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:

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).

Dando órdenes

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.

Las diferentes formas de establecer conversación

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".

(Esp) 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

Luz y oscuridadEl modelo del mundoObjetos para leer y consultarCriaturas vivas y cómo conversar