Cómo se interpretan los verbosDescripciones y parsingCómo se interpretan los nombresNombres en plural para objetos repetidos

Nombres en plural para objetos repetidos

Un problema importante y difícil para los parsers de juegos conversacionales, es el manejo de una colección de, digamos, diez monedas de oro, permitiendo al jugador que pueda usar cada moneda de forma independiente de las otras, a la vez que las reúne en un grupo para las descripciones o los inventarios. Esto es relativamente sencillo en Inform, y sólo en algunos casos excepcionalmente complejos necesitarás programar código.

Hay dos problemas que solucionar: primero, el juego debe ser capaz de hablarle al jugador usando plurales, y segundo, viceversea.

El juego usa plurales

Vamos con el primer punto, el juego habla al jugador, y debe usar plurales para agrupar objetos iguales:

Class  MonedaOro
  with nombre 'moneda' 'oro',
       nombre_corto "moneda de oro",
       plural "monedas de oro",
has femenino;

(de forma análoga se definirían las clases MonedaPlata y MonedaBronce). Creemos ahora una bolsa que contiene seis monedas de tipos variados:

Object bolsa "bolsa"
 with  nombre 'bolsa',
has femenino recipiente abrible abierta;
MonedaOro ->;
MonedaOro ->;
MonedaOro ->;
MonedaPlata ->;    
MonedaPlata ->;    
MonedaBronce ->;    

Si el jugador mira en la bolsa, verá:

 >mira en la bolsa
 En la bolsa ves tres monedas de oro, dos monedas de plata y una moneda de
 bronce.

Como vemos, la librería agrupa automáticamente los objetos que son iguales. ¿Cómo sabe la librería que las tres monedas de oro son iguales entre sí, pero no son iguales a la moneda de plata, por ejemplo? Dicho de otro modo ¿qué regla sigue para agrupar objetos en los listados?. La librería no mira que sean de la misma clase, sino que tengan el mismo nombre. Sólo agrupara cosas si:

  1. Tienen la propiedad plural.
  2. Son "indistinguibles" para el jugador.

El hecho de ser "indistinguible" para el jugador consiste en tener exactamente las mismas palabras para referirse a ellas (tanto en la propiedad nombre como en nombre_f, nombre_m, nombre_mp, nombre_fp y adjetivos). No tienen por qué aparecer en el mismo orden, pero si tienen exactamente las mismas palabras, se considerarán objetos indistinguibles, puesto que no hay nada que el jugador pueda escribir que le permita referirse unívocamente a uno de esos objetos.

(!) En realidad, la librería es más lista. Los objetos que son agrupados dependen ligeramente del contexto en el cual la lista está siendo imprsa. Cuando escribe una lista con detalles que especifican qué objetos dan luz, por ejemplo (como en los inventarios), no juntará dos objetos si uno da luz pero el otro no. Lo mismo con objetos cuyos contenidos son visibles, o que pueden llevarse puestos.

(!)(!) La cosa se complica si los objetos tienen una rutina parse_nombre, ya que en este caso la librería no puede usar las propiedades nombre, adjetivos, etc, para averiguar si son o no indistinguibles. Lo que hace la librería es: si las rutinas parse_nombre de los objetos son diferentes, decide que los objetos son diferentes también. Sin embargo, si tienen la misma rutina parse_nombre (lo que ocurrirá si ambos objetos la han heredado de una misma clase base), entonces la librería no puede saber de ninguna forma si son indistinguibles o no (y observa que pueden serlo, ya que tal vez la rutina parse_nombre use un atributo, como encendido para permitir distinguir uno de otro).

En este caso a la librería no le queda más remedio que preguntarle al objeto si es indistinguible o no. Lo hace en la forma siguiente:

  1. Una variable global llamada accion_parser, es inicializada con el valor ##ElMismo
  2. Dos variables globales llamadas parser_uno y parser_dos son inicializadas con los objetos que se están considerando (y para los que hay que decidir si son idénticos o no)
  3. Se llama a la rutina parse_nombre del primer objeto (el almacenado en parser_uno). Si esta rutina retorna:
    -1
    Los objetos se consideran "indistinguibles".
    -2
    Los objetos se consideran diferentes.
    otro
    Ante cualquier otro valor, la librería comparará las propiedades nombre, nombre_f, etc... para decidir si son indistinguibles o no, como si el objeto no tuveria parse_nombre.

##ElMismo, como puedes ver por el ## que lleva delante, es una acción. Sin embargo es una acción que el jugador nunca podrá causar, porque no está asociada a ningún verbo. Es lo que Inform llama fake action, o "acción falsa".

(!)(!) Podría ser útil a veces proporcionar la propiedad parse_nombre sólo para acelerar el proceso de agrupación y separación de objetos. Si tienes 30 monedas de oro, el parser tendrá que trabajar mucho comparando todos sus nombres, pero tú puedes hacer la decisión mucho mas rápida.

El jugador usa plurales

Veamos ahora la problemática que aparece cuando queremos que el jugador pueda referirse a cada objeto de forma individual (COGE MONEDA DE ORO), o de forma colectiva (COGE TRES MONEDAS DE ORO). La cosa se complica aún más si todos los objetos son similares, pero no idénticos, y queremos permitir que el jugador pueda referirse a grupos de ellos. Por ejemplo, imagina un conjunto de coronas de diferentes colores. Querríamos que el parser reconociera:

> DEJA TODAS LA CORONAS EXCEPTO LA VERDE
> DEJA LAS OTRAS TRES CORONAS

Si ponemos la palabra 'coronas' en la lista de nombre del objeto, no funcionaría correctamente, porque el parser tomaría 'coronas' como una palabra válida para referirse a una sola corona. Lo que querríamos es que el parser entienda que la palabra 'corona' se refiere solo a una, pero la palabra 'coronas' se refiere a más de una.

Lo que hay que hacer es poner la palabra 'coronas//p' en la lista de nombre del objeto. El //p señala que la palabra de diccionario coronas es una palabra plural, y que cuando el jugador la usa, se está refiriendo a más de un objeto. (Observa que, por ejemplo, no habría que poner //p en la palabra 'gafas', si quieres que esta palabra sea aplicable a un solo objeto, en lugar de esto lo que tienes que hacer es poner el atributo nombreplural en el objeto, para que la librería ponga correctamente el artículo unas o las delante).

La clase MonedaOro debería definirse así:

Class MonedaOro
 with nombre 'moneda' 'oro' 'monedas//p',
      nombre_corto "moneda de oro",
      plural "monedas de oro",
has femenino;

y ahora el juego permitirá la orden "COGE MONEDAS", y el parser entenderá "coger todos los objetos al alcance que tengan 'monedas//p' dentro de su nombre".

(!)(!) La pega del método anterior, es que la palabra "monedas" está marcada como //p en todo el juego, y no sólo en ese objeto. Imagina que tienes otro objeto que necesite la palabra "monedas" en su nombre, pero no como un plural (por ejemplo, un objeto llamado "maquina falsificadora de monedas").

Hay una forma más complicada de lograr el mismo efecto que con //p, pero sin afectar a otros objetos. Para ello debe usarse la rutina parse_nombre del objeto, de una forma especial. No sólo tiene que reconocer si lo que ha escrito el jugador se refiere a este objeto, sino que también debe decirle a la librería si el jugador ha usado una palabra que debe ser considerada un plural. Para hacer esto, la rutina parse_nombre funcionará como siempre, pero pondrá en la variable global accion_parser el valor ##HalladoPlural (que es otra "acción falsa"). Así, por ejemplo, para las monedas:

Class MonedaOro
 with parse_nombre [ i j;
        for (::) {
          j=SiguientePalabra();
          if (j=='moneda' or self.nombre) i++;
          else {
            if (j=='monedas') {
               accion_parser=##HalladoPlural;
               i++;
            } else return i;
          }
        }
      ],
has femenino;

Este código supone que los objetos derivados de esta clase, definirán sólo una palabra en su propiedad nombre (que sería el metal de que está hecho la moneda).

(?) EJERCICIO 64  Escribe una clase para objetos "curriculum", de modo que si el jugador intenta referirse a varios usando "curriculums", aparezca el mensaje "Lo dejaré pasar por esta vez, pero el plural de curriculum es curricula".
(Solución)


Zak McKraken - spinf@geocities.com

Cómo se interpretan los verbosDescripciones y parsingCómo se interpretan los nombresNombres en plural para objetos repetidos
1