domingo, 7 de diciembre de 2014

TUTORIAL DE DAAD - Parte 2

Antes de empezar con la segunda parte comentar que en la primera se a mejorado la explicación de como generar la versión de spectrum y se han modificado los textos de las localidades para que incluyan acentos, en la parte de mensajes doy mas detalles sobre eso.

Ademas he incluido un archivo tal como quedaria al final del primer tutorial.


Diagnostico (DEBUG)

Realmente no hay mucha información sobre cómo realizar un depurado de la aventura con el CAAD, veremos las opciones que aparecen en el manual y las que se usan de ejemplo en el codigo fuente de ejemplo de Los templos sagrados.


Por un lado el compilador admite el modificador “-d”, entre otras cosas define el simbolo DEBUG, si esto lo juntamos con las opciones de preprocesador, podemos añadir temporalmente partes del archivo SCE, por ejemplo para tener una palabra “mágica” que nos cambie de localidad, para poder salir fácilmente de un laberinto, que nos de objetos o ajuste banderas, por si queremos depurar una parte del final de la aventura, y no queremos jugarla entera hasta llegar a ese punto, etc, etc…

Por otro lado, existen unos interpretes con la opción de debug, en el caso del español serian INTSD.EXE e INTSDM.EXE, que en caso de aparecer errores en el programa, aparecerá en la parte de arriba de la pantalla información sobre el error.

Procesos y Respuestas

Las tablas de procesos son el núcleo principal de la programación del juego, y es donde definiremos los PSI, las trampas, y cualquier otra función del juego que no sea el simple movimiento y/o coger/dejar objetos.

Estas están formadas por entradas, cada entrada comienza con una linea que indica un verbo y un nombre (o el símbolo comodín "_") y un condact (una orden en el lenguaje de DAAD), seguida de mas lineas con condacts hasta la siguiente linea con verbo y nombre.

Si el verbo y nombre coinciden con los que se están evaluando sacados de la linea de ordenes, se ejecutara dicha entrada.

En paws el ciclo de juego es controlado internamente, una vez se acaba la frase, se vuelve a pedir otra, se ejecutan ciertas tablas de procesos en determinadas ocasiones, etc...

Toda esta preprogramacion en el DAAD no existe, de echo al arrancar el juego se ejecuta la tabla de procesos 0, y si se sale de dicha tabla, se finalizaría el juego.

La principal y mas importante diferencia entre DAAD y PAWS es que en paws la pareja VERBO-NOMBRE solo se comprobaba en la tabla de respuestas, mientras que las tablas de procesos se ejecutaban siempre, usando el verbo-nombre a modo de comentario.
En DAAD siempre se evalua el verbo-nombre, por lo que aquellos procesos que siempre se tienen que evaluar, deben utilizar siempre "_    _". Si necesitas utilizar comentarios utiliza en simbolo ";".

Mensajes

Vamos ahora a permitir que el jugador examine cosas, dos partes, por un lado tenemos que definir el texto que aparecerá cuando tecleemos “examinar bolsa”, esto se realiza en la tabla de mensajes, con un formato similar al de las descripciones de localidades.

/MTX    ;Mensajes
/0
Una saludable, gorda y verde manzana golden.
/1
Es un emparedado delicioso de jamón y queso.
/2
El billete tiene un número y el nombre de la compañía de transportes para aventureros,
impreso.
/3
El banco está anclado firmemente a una base de concreto.


Hay una serie de caracteres especiales que se pueden imprimir utilizando una "secuencia de escape", que consiste en el simbolo "\" y un caracter (distinto en mayusculas y minusculas), entre ellos destacaremos:

\s  es un espacio, se utiliza para forzarlo al final de un mensaje.

\\ es el simbolo "\"

Y los mas importantes \F \G \H \I \J  son las vocales acentuadas á é í ó ú, \K \L son la ñ minuscula y Ñ mayusculas, \O y \P son ü y Ü, otro simbolos son \A = ª, \B = ¡, \C =¿, \D y \E son <<  y >> , \M y \N son ç y Ç.

Existe también la tabla /STX, que contiene los mensajes del sistema, y son utilizados internamente en varias situaciones, no deberiamos modificar el sentido de esas frases o usarlas para otra cosa distinta, pues podria dar lugar a errores o sinsentidos.

Y por otro lado vamos ahora a indicar al parser, cuando debe indicar estos mensajes.

En este ejemplo el proceso 5 es el encargado de la evaluación de las frases del jugador, asi que insertaremos antes de la linea MIRAR   _       RESTART las siguientes líneas:

EX MANZAN PRESENT 3
                MESSAGE 0
                DONE

EX EMPADE PRESENT 2
                MESSAGE 1
                DONE

EX BILLETE PRESENT 4
                MESSAGE 2
                DONE

EX BANCO AT 4
                MESSAGE 3
                DONE

Mirar y EX son sinonimos, debemos colocar estas lineas antes, pues si el parser al ejecuta el condact restart saldra de la tabla de procesos.

En los tres primeros grupos comprobamos si el objeto está presente, imprimimos el mensaje y damos por finalizada la orden.

En el cuarto caso lo que comprobamos es que estemos en la localidad 4, que es donde esta el banco, que no es un objeto, pero vamos a permitir examinarlo.

Tablas de procesos

En el PAWS, los procesos 1 y 2 son llamados antes y despues de cada turno, en DAAD el sistema es mas flexible, si se observa el archivo de ejemplo y se recuerda lo que comentamos de que al iniciar el juego se ejecuta la tabla de procesos 0 y al finalizarla se acababa el juego, vemos:

Si estamos en la localidad 0 (la inicial) se llama al proceso 6, este es el que utilizaremos para la pantalla inicial de presentacion y otras cosas ha realizar al comienzo del juego.

Luego se muestra la pantalla grafica de la localidad y se describe la localidad, tras eso se llama al proceso 3, (este es el antiguo proceso 1 del PAWS), aqui es donde se describen los objetos de la localidad.

Finalmente se salta al proceso 1, este es el bucle principal del juego, si este proceso finalizase, volveriamos al 0, y al acabar el 0 se terminaria el programa.

En el proceso 1 lo primero que se hace es llamar al proceso 4 (el antiguo proceso 2 del PAWS), en nuestro ejemplo esta vacio.

En el resto del proceso 1 se observa que en caso de una frase que no entienda o de un timeout, se llama al proceso 2, luego se llama al proceso 5 para ver si hay algo que hacer, y en caso de que no se haya echo nada, se comprueba si la orden era un movimiento,  y se vuelve a pedir otra orden.

Esta complejidad que no existia en el paws (en realidad que no era visible al programador) nos permitira en el futuro mas complejidad en los juegos.

 Vamos ahora a añadir un final para el juego y ver como podemos utilizar nosotros nuevos procesos.
Añadimos un nuevo mensaje a la tabla /MTX:

/4
El autobús llega. Le doy el billete al conductor, quien sonríe y dice: "siento haber llegado
tarde, supongo que no ha tenido que esperar mucho".


Añadimos un nuevo nombre al vocabulario:

AUTOBU  64 noun

Y añadimos una nueva entrada al proceso 5:

_ AUTOBUS AT 2
                CARRIED 4
                MESSAGE 4
                PROCESS TURNOS
                END

De esta manera cuando volvamos a la parada, llevando el billete, bastara que escribamos cualquier cosa con la palabra autobus, para que este llegue y termine el juego, por ejemplo “ESPERAR AUTOBUS”.

Pero si lo compilamos ahora va a dar error, en el paw existen dos contact TURNS y SCORE, que imprimen unos mensajes y el valor de una banderas, pero como ya hemos comentado en CAAD esto se deja al programador del juego.

Aprobecharemos para ver un ejemplo del uso de los defines.

Asi, debemos ir al principio del documento, y tras la inclusion del archivo symbols.sce escribimos:

#define TURNOS 7


Esto nos permite crear una nueva tabla de procesos con la orden
/PRO TURNOS
Que es equivalente a
/PRO 7
Podemos considerar las tablas de procesos como subrutinas de programacion, asi que escribiremos:

/PRO TURNOS
_       _       sysmess 17
                dprint Turns
                sysmess 18
             
_       _       GT Turns 1
                sysmess 19
             
_       _       sysmess 20
                sysmess 21
                print   Score
                sysmess 22


Cuando en las tablas de procesos se utiliza como verbo y nombre el simbolo "_" se va a ejecutar siempre, asi que estos condactos se ejecutaran siempre imprimiento in mensaje tipo "Ha jugado durante 17 turnos. Y a realizado un 50%."

Notese que "Score" y "Turns" son dos simbolos definidos en el archivo SYMBOLS.SCE que viene incluido al principio, y corresponde a las banderas 30 y 31.

Gracias al define, ahora la linea PROCESS TURNOS si tendra sentido, y cuando se llegue a ella se ejecutara el proceso 7.

A lo largo del tutorial hemos visto los condactos que finalizan entradas, vamos a describirlos uno a uno:
  • REDO - vuelve a iniciar la tabla de procesos, en el proceso 1 es responsable del bucle tras una orden valida.
  • RESTART - sale de todos los procesos y vuelve a ejecutar el proceso 0
  • DONE - hace que la tabla de procesos actual finalize, e indica a DAAD que fue satisfactoriamente. esto puede ser comprobado desde la tabla de procesos padre con los condact ISDONE e ISNDONE
  • END - aparece el mensaje "¿Quieres volver a jugar otra vez?" en caso de que la respuesta no empieze por el mensaje del sistema 31 ("s") se saldra al sistema operativo o reiniciara el ordenador.
En el manual de DAAD encontraras mas condacts para el control de la ejecucion.

Contenedores

Los objetos que pueden tener otros objetos sigue la misma filosofía que en el PAWS, utilizamos una habitación como interior del objeto, caad incluye una serie de condacts para facilitar el trabajo,
Técnicamente no es necesario que la localidad tenga el mismo numero que el objeto, pero facilita las cosas, p.e. si utilizas un #DEFINE, en nuestro ejemplo dejamos a posta la localidad 1 vacía, que es el mismo numero que el objeto bolsa.
Añadimos un mensaje para cuando miremos dentro:

/5
En la bolsa hay:


Sacar no esta en la lista de verbo:

SACAR   32      verb

Y por ultimo el codigo en el proceso 5, hay que incluir unas lineas entra las existentes, asi que voy a poner un bloque de codigo, incluyendo lineas que ya existen del archivo BLANK.SCE original:

PONER   TODO    DOALL   CARRIED


PONER   _       NOUN2 BOLSA

                PREP EN
                PRESENT 1
                AUTOP 1
                DONE


PONER   _       AUTOW

                DONE


SACAR   TODO NOUN2 BOLSA

                PREP DE
                PRESENT 1
                DOALL 1


SACAR   _ NOUN2 BOLSA

                PREP DE
                PRESENT 1
                AUTOT 1
                DONE 


Junto a poner introducimos las lineas, es necesario añadir nuestro PONER _  delante del existente, pues en caso contrario intentaria vestir el objeto, asi que comprobamos si ademas de PONER nombre la frase incluye "EN BOLSA".

Sacar es un verbo nuevo, incluimos una linea que repita para todos los objetos de la localidad 1 (la bolsa) y luego la orden en si que comprueba que la frase sea del tipo "SACAR nombre DE BOLSA" y lo saca automaticamente.

Notese que en SACAR TODO hemos comprobado tanto la preposicion como el segundo nombre, en teoria solo haria falta el nombre, pero si escribiesemos "SACAR TODO DEL BOLSA" el parser no haria nada, ya que una vez a ejecuta el SACAR TODO completa, considera la frase como buena y vuelve a pedir otra, de esta manera la misma frase no aplicaria y al no poder terminarse SACAR TODO, al final imprimiria un "No puedo hacer eso".

AUTOP y AUTOT  (asi como sus homologos PUTIN y TAKEOUT) realizan una serie de comprobaciones, como evitar que cojas mas objetos de los que puedes llevar (flag 37) el peso (flag 52) o incluso que intentes meter en el contenedor un objeto que llevas puesto (antes tienes que quitartelo).

Vamos ahora a ver un contact nuevo de DAAD, SYNONYM.

A la hora de dar flexibilidad, podemos definir varios nombres o verbos con el mismo numero, asi SACAR y EXTRAER podria ser sinonimos, en el caso de PONER y METER, esto solo es cierto en el caso de un contenedor, pero no en el de ropa ¿METER ANORAK?, asi que antes de la linea de PONER TODO, vamos a incluir esto:

METER     _    
PREP EN
SYNONYM PONER _

De esta manera cuando el parse se encuentre con frases tipo "METER nombre EN nombre2", sustituira el verbo METER por PONER, y a partir de ese momento la frase sera "PONER nombre EN nombre2".

Hemos comentado que PUTIN y TAKEOUT tienen en cuenta el peso y el numero de objetos que puede llevar el personaje, pero la bolsa al fin y al cabo es una localidad y como tal tiene espacio infinito para los objetos. empecemos por añadir un limite al nº de objetos:

En DAAD las banderas 0 a 63 se utilizan internamente, la primera libre es la 64, es la que utilizaremos para llevar la cuenta de objetos en la bolsa, es conveniente documentar su uso en alguna parte del documento, una buena idea es utilizar #DEFINE para darle un nombre, asi que en la parte inicial del archivo escribiremos:

; Banderas utilizadas en el juego
#DEFINE FsizeBolsa 64


debemos descontar uno cada vez que saquemos un objeto, y aumentar en uno cada vez que lo metamos, vamos a hacer que la bolsa sea pequeña y solo entren 3 objetos, así que debemos comprobar que FsizeBolsa vale menos de 3 antes de meter algo en la bolsa.

Quedarían así :

PONER   _       PREP EN

                NOUN2 BOLSA
                PRESENT 1
                LT FsizeBolsa 3
                AUTOP 1
                PLUS FsizeBolsa 1
                DONE

PONER   _       PREP EN

                NOUN2 BOLSA
                PRESENT 1
                GT FsizeBolsa 2
                MESSAGE 6
                DONE

SACAR   _ NOUN2 BOLSA
                PREP DE
                PRESENT 1
                AUTOT 1
                MINUS FsizeBolsa 1
                DONE

Hemos duplicado PONER _ , hay una comprobación LT FsizeBolsa 3, en caso de que el valor no sea menor de 3, saltaría el resto de condacts y seguiría la tabla de procesos, así que comprobamos si el problema es que había demasiados he imprime el mensaje:

/6
No puedo meter _, la bolsa esta llena.


Cabe destacar el símbolo _ que en el mensaje es sustituido por el texto del objeto actual (y le quita el punto del final, si lo lleva), así si intentamos meter la antorcha, y hay 3 objetos el mensaje seria algo así a "No puedo meter la antorcha apagada, la bolsa esta llena.

Como en el resto de condact la serie solo continua si el anterior fue correcto, asi que la orden PLUS y MINUS colocadas detrás de AUTOP y AUTOT solo se ejecutan si estas son correctas.

 Para el peso se haria algo similar, lo voy a dejar como ejercicio, y en próximas entregas daré la solución, pero unas pistas:

WEIGHT objno. flagno.  calcula el peso de un objeto (o un contenedor) y lo pone en flagno.
WHATO evalua el nombre y adjetivo 1 y actualiza una serie de flags con la info del objeto, entre ellos el flag 55 definido como COWei con el peso del objeto nombrado.

El archivo SCE tal como quedaria tras esta parte se puede descargar de este link: https://dl.dropboxusercontent.com/u/15390320/pajarito_2.SCE

3 comentarios:

Toninote dijo...

Qué diferencia hay en insertar las líneas en el proceso 5 antes o después de la línea:
MIRAR _ RESTART?

Alvaro dijo...

En paws (si no recuerdo mal) cuando intruduces nuevos grupos de condacts, los ordena automaticamente segun el valor numerico del verbo y nombre, por lo que cualquier entrada "mirar nombre" (ex y mirar son sinonimos) quedaria delante de "mirar _".
En el daad esto no es asi, respeta el orden que aparezca en el archivo, y si ponemos mirar _ restart el primero, cuando toque, lo ejecutara, y como restart sale de la tabla de procesos y vuelve a describir la localidad, el resto de ordenes "ex objeto" nunca se ejecutaria.

Toninote dijo...

Ahora si que resulta fácil hacer una aventura en DAAD para Spectrum y Amstrad.
Gracias!

Lo que no sé es como se añaden los gráficos en la de Spectrum.