![]() | ![]() | ![]() | Objetos para leer y consultar |
Una orden como "Busca la figura 18 en el manual técnico" es muy difícil de entender para Inform, ya que en la primera parte ("la figura 18") puede aparecer prácticamente cualquier cosa. Incluso su formato depende de la segunda parte. En general el jugador puede intentar las siguientes órdenes:
Consulta <cualquier secuencia de palabras> en <objeto>
Consulta <objeto> sobre <cualquier secuencia de palabras>
Lee sobre <cualquier secuencia de palabras> en <objeto>
Lee <cualquier secuencia de palabras> en <objeto>
Busca <cualquier secuencia de palabras> en <objeto>
Busca en <objeto> sobre <cualquier secuencia de palabras>
Busca en <objeto> <cualquier secuencia de palabras>
Todas ellas generarán la misma acción: <Consultar objeto>. Observa que esta acción tiene un objeto en la variable uno, pero no pone nada en la variable otro. Formalmente, la acción consultar sólo recibe un objeto, que es el libro consultado. El tema de la consulta debe averiguarlo el propio objeto consultado, analizando la cadena <cualquier secuencia de palabras> por sí mismo, ya que el parser no intenta analizar esa parte. Esto deberá hacerlo en su rutina antes. Para facilitar este trabajo, existen las siguientes variables y funciones:
En realidad, el valor que devuelve es un número, que identifica a una palabra de las que el juego tiene en su diccionario (el diccionario del juego se forma automáticamente con todas las palabras que el programador haya puesto entre 'apostrofes' en cualquier lugar del código). Si el jugador ha escrito algo que no estaba en el diccionario (por ejemplo "asdfg"), entonces el valor retornado sería 0. También retorna 0 si se ha alcanzado el final del texto.
Usando las variables y funciones anteriores, el objeto consultado debe ir analizando una a una las palabras usadas por el jugador, y decidir qué respuesta darle. Si la rutina devuelve false, la librería mostrará el mensaje estándar "No encuentras nada interesante.", y si devuelve true la librería no hará nada, como de costumbre.
![]() |
Todo esto es tremendamente tedioso y difícil de programar. Por ello
he desarrollado una librería adicional llamada ETemas que
puedes usar en tus juegos junto con InformATE que te
permite crear una serie de "Temas de consulta", y hace todo
el trabajo de parsing por ti, para identificar el tema que el
jugador intentaba consultar, de forma bastante flexible como para
que el jugador pueda poner variantes y aún así ser comprendido (por
ejemplo: "Busca en la enciclopedia la historia de Oz", "Busca en
enciclopedia Oz", "Busca en enciclopedia historia Oz", etc.
Puedes encontrar más información sobre ETemas en http://www.geocities.com/TimesSquare/Fortress/9939/informate. |
Un ejemplo de cómo hacer esto: un diccionario de símbolos mayas, que podría llevar consigo el jugador de "Ruinas" para interpretar las pequeñas pistas que irá encontrando por el juego.
Object diccionario "Diccionario Maya de Waldeck" objjugador
with nombre 'diccionario' 'libro' 'maya' 'waldeck',
descripcion "Ha sido escrito a partir de las poco fiables
litografías del legendario explorador y narrador ~Conde~
Jean Frederic Maximilian Waldeck (1766??-1875), este libro
contiene lo poco que se sabe de los símbolos usados en el
antiguo dialecto local.",
antes [simbolo;
Consultar:
if (consultar_num_palabras > 2)
print_ret (string) diccionario.ayuda;
np=consultar_desde;
simbolo=SiguientePalabra();
if (consultar_num_palabras > 1)
{
if (simbolo=='el' or 'la')
simbolo=SiguientePalabra(); ! Saltarse 'el'
else print_ret (string) diccionario.ayuda;
}
switch(simbolo)
{
'q1':"(¡Este es el símbolo que has memorizado!)^^
Q1: ~lugar sagrado~.";
'circulo': "Círculo: ~El Sol; también vida, duración de
la vida~.";
! . . .
default: "Ese símbolo no ha sido registrado hasta la
fecha.";
}
],
ayuda "Ponlo así: ~Busca <nombre del símbolo> en el libro.~",
has masculino;
|
Observaciones: este objeto lo hemos puesto dentro de otro llamado objjugador que, como habrás adivinado, es el jugador. Es la forma de que aparezca inicialmente en su inventario. La rutina antes, por primera vez en lo que va de manual, tiene una variable local, llamada simbolo. Para crear variables locales en las rutinas basta ponerlas delante del punto y coma. Esta variable contendrá la palabra que el jugador está intentando consultar, pero es la propia rutina antes la que tiene que ocuparse de averiguar esa palabra. Lo primero que miramos es que el jugador no haya escrito más de dos palabras (aceptaremos por ejemplo "Busca en el libro el circulo", o "Busca en el libro circulo", pero no "Busca en el libro el símbolo del circulo". Si se detecta que consultar_num_palabras es mayor de 2, se imprime una pequeña ayuda y se termina. Si todo va bien, continúa poniendo la variable np igual a consultar_desde y llamando a SiguientePalabra(). Esto devolverá, bien un artículo, bien directamente el nombre del símbolo. Si es un artículo hay que hacer un de nuevo SiguientePalabra() para obtener el nombre del símbolo (si el jugador usó dos palabras pero la primera no era un artículo, se saca el mensaje de ayuda).
Tras esas averiguaciones, simbolo contendrá la palabra de diccionario usada por el jugador. El switch comparará esa palabra con una serie de posibilidades ('q1', 'circulo', etc.) Importante no poner acentos en estas posibilidades (en general, como ya hemos dicho, no deben ponerse acentos en las palabras de diccionario, es decir, todas aquellas encerradas entre apóstrofes en el listado). Si la palabra que usó el jugador no coincide con ninguna de las listadas, se irá al caso default.
Observar cómo hemos puesto el mensaje de ayuda en una propiedad nueva, creada especialmente para este objeto (y cómo para imprimirla hay que poner (string) delante de ella).
EJERCICIO 17 | Programa una biblia en la que el jugador pueda efectuar un comando como "Lee san lucas 23 en la biblia". La Biblia debe entender referencias a los cuatro evangelios. La solución es un poco tediosa, porque hay que tener en cuenta que el jugador puede teclear muchas variantes ("Lee lucas en la biblia", "Lee san lucas en la biblia", "Lee lucas 23 en la biblia") y hay que asegurar que se acepta cualquiera de ellas. Necesitarás usar la función IntentarNumero(np) esta función intenta interpretar como un número la palabra señalada por np. Si lo consigue, devuelve el valor de ese número y si no lo consigue devuelve la cantidad -1000. (Esta función entiende también números "de palabra", como por ejemplo: "Lee san lucas once en la biblia". En este caso sólo comprende números entre "uno" y "veinte"). (Solución) |
![]() ![]() |
La librería estándar define el verbo "Lee objeto" de forma que
provoque la acción Examinar objeto. Si quieres hacer un
objeto que pueda ser examinado o leido, dando diferente resultado en
cada caso, hay que redefinir este verbo. Esto se haría por ejemplo
así (definimos un nuevo atributo legible que habría que dar
a los objetos que pueden ser leídos):
La clave está en las dos últimas líneas, que redefinen el verbo "lee" que venía en la librería, de modo que añaden a la definición original la línea que dice * legible -> Leer; Esta línea significa que si el verbo "lee" se intenta sobre un objeto legible, entonces la acción generada será Leer en vez de examinar (si no es legible se usará la gramática original, por lo que se generaría la acción Examinar). Necesitamos proporcionar la rutina LeerSub que lleve a cabo la acción "por defecto", y hemos decidido que la acción por defecto sea Examinar objeto. La forma de evitar esta acción por defecto es hacer que los objetos capturen la acción Leer en su rutina Antes, que es lo que hace el ejemplo libro_texto.
|
![]() | ![]() | ![]() | Objetos para leer y consultar |