Para analizar correctamente las órdenes introducidas por el jugador, AGE necesita identificar los verbos que se utilizan en los juegos, distinguiéndolos de palabras que no sean verbos. Esto es necesario por dos motivos:
En la gran mayoría de los casos, el programador de aventuras no se tiene por qué preocupar de estas cuestiones, dado que AGE cuenta con una lista de verbos que le permiten distinguir las palabras que pueden ser verbos de las que no lo son. Sin embargo, en algunos casos específicos puede ser útil manipular esta lista de verbos:
En esta sección veremos cómo se puede consultar la lista de verbos de AGE, así como editarla para una aventura concreta si nos encontramos en uno de estos casos.
La lista de verbos por defecto de AGE se puede ver accediendo a la opción “Ver lista de verbos” que se encuentra en el menú “Herramientas” de PUCK. Nótese que esta ventana de PUCK no permite modificar la lista, sino sólo verla a efectos informativos. En ella podemos comprobar, por ejemplo, si falta algún verbo que necesitemos, para así añadirlo a la aventura mediante código BeanShell.
Utilizando esta opción, podremos comprobar que las entradas de la lista de verbos contienen dos formas verbales: una es un imperativo o primera persona, y la otra es el infinitivo al que corresponde. El motivo es que AGE puede comprender órdenes tanto en infinitivo como en imperativo o primera persona, y (como se vio en la sección sobre métodos de análisis de la entrada) lo hace convirtiendo todas esas formas al infinitivo. La lista de verbos es lo que usa AGE para hacer dicha conversión.
Por este motivo, si añadimos un nuevo verbo a la lista, deberíamos añadir dos entradas: una que indique cómo pasar de imperativo a infinitivo, y otra que indique cómo pasar de primera persona a infinitivo.
Para añadir un verbo a la lista de verbos de nuestro mundo, podemos utilizar el siguiente código BeanShell:
world.getLanguage().addVerbEntry("enladrilla","enladrillar"); //formas imperativo e infinitivo world.getLanguage().addVerbEntry("enladrillo","enladrillar"); //formas primera persona e infinitivo
El método getLanguage()
de la clase World
nos proporciona un objeto de la clase NaturalLanguage
que representa el idioma en el que acepta órdenes el mundo, y que contiene métodos que trabajan con ese idioma como es en este caso el método addVerbEntry()
para añadir formas verbales.
Las dos líneas del ejemplo actúan como si se añadieran dos filas a la tabla que hemos visto más arriba: una diciendo que “enladrilla” es el imperativo del verbo “enladrillar”, y otra diciendo que “enladrillo” es su primera persona (en realidad AGE no distingue entre imperativos y primeras personas, simplemente le estamos diciendo que ambas son formas verbales aceptadas para el verbo “enladrillar”. La propia forma “enladrillar”, al aparecer como infinitivo, también será aceptada automáticamente).
Nótese que el verbo se añadirá de forma dinámica al ejecutarse el código BeanShell, así que no se verá en la ventana de PUCK de la lista de verbos, que muestra siempre la lista que hay por defecto al comenzar el juego.
Para quitar un verbo de la lista de verbos, se utiliza un método removeVerbEntry()
que hace lo opuesto al método addVerbEntry()
:
world.getLanguage().removeVerbEntry("enladrilla","enladrillar"); //formas imperativo e infinitivo world.getLanguage().removeVerbEntry("enladrillo","enladrillar"); //formas primera persona e infinitivo
Las ejecuciones de removeVerbEntry()
del este ejemplo quitarán los verbos añadidos por las ejecuciones de addVerbEntry()
del ejemplo anterior. Por supuesto, mediante este método también se pueden quitar de la aventura verbos que no hayamos añadido nosotros, sino que estén en la lista por defecto que muestra PUCK.
NOTA: En opinión del creador de AGE, el contenido de esta subsección no es necesario, y de hecho no debería utilizarse nunca porque no se gana nada con ello y en cambio sí hay posibilidades de perder o degradar funcionalidad. Sin embargo, se incluye en esta documentación por completitud, dado que es funcionalidad que existe y que algunos autores han utilizado.
Por defecto, todos los verbos de la lista pueden ser “adivinados” por AGE en el modo “second chance” descrito en la sección de métodos de análisis de la entrada. Sin embargo, AGE también proporciona la opción de desactivar este modo para todos los verbos o para algún verbo en concreto.
Desactivar el modo “second chance” para todos los verbos no está recomendado bajo ningún concepto, dado que es un componente fundamental para que AGE analice correctamente las órdenes del jugador. Sin embargo, en alguna ocasión podría interesar a algunos autores desactivar este modo para algún verbo concreto. En particular, puede interesar desactivarlo para verbos intransitivos que tengamos definidos de manera que se ignore toda palabra que se teclee después del verbo. Por ejemplo, si hemos definido un verbo “estornudar” con el parseCommand del jugador de esta manera:
String parseCommand( String verb , String args ) { if ( equals(verb,"estornudar") ) { self.write("Estornudas con fuerza.\n"); end(); } }
Este verbo nos aceptaría entradas como:
> estornudar Estornudas con fuerza. > estornudar Pepito Estornudas con fuerza. > estornudar con muchísimo cuidado de no despertar a Juan Estornudas con fuerza. > estornudar adfaifjadf Estornudas con fuerza.
Pero si utilizáramos una oración compuesta en la que la segunda orden no tuviese un verbo reconocido ni una palabra que se le pareciese, como
> estornudar y asdfadf
Veríamos como salida
Estornudas con fuerza. Estornudas con fuerza.
debido a que después del primer estornudo, al procesarse la orden “asdfadf”, salta el modo “second chance” y adivina el verbo “estornudar” (la oración se interpretaría como dos órdenes: “estornudar” y “estornudar asdfadf”).
Una situación así nunca se dará en una partida real, sino sólo en sesiones de testing dirigidas específicamente a abusar del parser. Sin embargo, algún autor podría querer evitarla. Esto se hace quitando el verbo “estornudar” de la lista de verbos “adivinables” con el modo “second chance”, de la siguiente manera:
world.getLanguage().setUnguessable("estornudar");
Nótese que en este método setUnguessable
sólo hace falta especificar el verbo en infinitivo para desactivar el modo “second chance” con ese verbo.
También cabe destacar que si hubiésemos programado el verbo “estornudar” para que sólo funcionase si se introduce con argumentos, el modo “second chance” nunca tendría efecto con este verbo aunque no utilizásemos setUnguessable()
:
String parseCommand( String verb , String args ) { if ( equals(verb,"estornudar") && equals(args,"") ) { self.write("Estornudas con fuerza.\n"); end(); } }
En el ejemplo de arriba, esto haría que “estornudar asdfadf” no respondiese:
> estornudar y asdfadf Estornudas con fuerza. No entiendo...
Más en general, los siguientes métodos de la clase NaturalLanguage
manipulan la lista de verbos que son adivinables y no adivinables con el modo “second chance”:
/*clase NaturalLanguage*/ void setAllGuessable ( )
Activa el modo “second chance” para todos los verbos. Éste es el comportamiento por defecto de AGE.
/*clase NaturalLanguage*/ void setAllUnguessable ( )
Desactiva el modo “second chance” para todos los verbos. Se recomienda no llamar a este método nunca, salvo tal vez en el caso especial en el que se quiera degradar a propósito la funcionalidad de análisis de AGE (tal vez para simular la respuesta de algún sistema retro).
/*clase NaturalLanguage*/ void setGuessable ( String verb )
Desactiva el modo “second chance” para el verbo verb
.
/*clase NaturalLanguage*/ void setUnguessable ( String verb )
Activa el modo “second chance” para el verbo verb
.