Una plantilla para implementar más de 251 localidades en lenguaje PAW (Superglús et al.). Nacho A. Llorente + UTO Versión 1.0 - en edición Si bien es cierto que pocas (si alguna...) son las aventuras de texto en lenguaje PAW que presentan un uso de extensivo de entidades -localidades y objetos- que haga reventar los límites del parser (sea Superglús, SINTAC o casi cualquier otro PAW) y 255 suelen ser suficientes, a veces es necesario disponer de recursos adicionales para poder emplear un estilo diferente de programación. En mi caso, suelo retorcer los parsers con el objetivo de automatizar al máximo la programación empleando indirección intensiva y aprovechando la enormidad de las listas de mensajes disponibles. Rutinas mucho más automáticas y menos carga de trabajo. En este artículo, os presento una PLANTILLA (NO es una rutina completa ni una extensión, es sólo una idea que tendrás que implementar en tu propio código fuente) pensada originalmente para SINTAC pero ahora adaptada a SUPERGLUS y que permite añadir una zona de localidades de tamaño considerable para superar el límite de 251 localidades reales. Aunque alguien se pueda sentir tentado a implementar toda una aventura empleando este tipo de localidades virtuales, no es recomendable (excepto si se trata de un ejercicio de estilo...). Está pensado para aquellos que necesitamos una referencia visual (de ahí el formato cuadrícula) y cuyos juegos incluyen zonas amplias de tipo bosque, desierto, paraje nevado, etc; es decir, zonas más o menos de paso con nivel medio o bajo de interactividad y que, excepto algún caso muy especial, son mononivel; es decir, que no conectan arriba y abajo y solo excepcionalmente permiten entrar/salir a/de algún sitio. Es perfectamente posible crear zonas multinivel, claro; pero el riesgo de crecimiento exponencial del número de entradas necesarias en la tabla de respuestas se carga la utilidad real de este sistema. Antes de empezar, ten en cuenta: * Aunque a efectos de entidades (locs/objs) los condactos no pueden gestionar valores superiores a 255, los flags de Superglús admiten valores de hasta 2^32. * Dado que los ordenadores actuales cuentan con recursos de sobra, acostúmbrate a definir en tu código fuente todas las localidades (de la /0 hasta la /251) y todos los objetos (del /0 hasta el /255) aunque no los uses; en próximos artículos verás la utilidad de hacer esto... Empezamos. Primero, diseñamos una cuadrícula de 90 localidades (10x9), y la numeramos empleando valores grandes de 5 cifras (para saber el motivo, cf. el próximo artículo) según esta secuencia: 10000 10001 10002 10003 10004 10005 10006 10007 10008 10009 20000 20001 20002 20003 20004 20005 20006 20007 20008 20009 30000 30001 30002 30003 30004 30005 30006 30007 30008 30009 40000 40001 40002 40003 40004 40005 40006 40007 40008 40009 50000 50001 50002 50003 50004 50005 50006 50007 50008 50009 60000 60001 60002 60003 60004 60005 60006 60007 60008 60009 70000 70001 70002 70003 70004 70005 70006 70007 70008 70009 80000 80001 80002 80003 80004 80005 80006 80007 80008 80009 90000 90001 90002 90003 90004 90005 90006 90007 90008 90009 Consideramos que cada número corresponde a una localidad y que todas ellas están unidas por las 8 direcciones del compás, excepto las esquinas y las laterales que tienen algunas restricciones (la localidad e.g. 10000 no admite N, NO, NE, SO ni O). Es una cuadrícula de localidades de nivel plano, sin conexiones arriba y abajo. La estrategia para crear un pseudo-algoritmo matemático que gestione las conexiones de forma automátiva es AUTOMATIZAR LA RELACIÓN MATEMÁTICA entre el valor NÚMERO DE LOCALIDAD y las direcciones del compás, de modo que se controlan las 8 salidas de cada localidad sin tener que escribir en respuestas todas las comprobaciones de dirección de cada una (que, en este caso, serían un total de 90x8 = 720 entradas...). Para ello, vamos a buscar la relación matemática entre cada pareja de números que representan localidades en la cuadrícula. Si estás en la localidad e.g. 20003: * y vas al norte, tienes que RESTAR 10000 a 20003 para obtener el número de loc 100003. * y vas al sur, tienes que SUMAR 10000 a 20003 para obtener el número de loc 30003. * y vas al noroeste, tienes que RESTAR 10001 a 20003 para obtener el número de loc 100002. * y vas al noreste, tienes que RESTAR 9999... * y vas al suroeste, tienes que SUMAR 9999... * y vas al sureste, tienes que SUMAR 10001... * y vas al oeste, tienes que RESTAR 1... * y vas al este, tienes que SUMAR 1... En resumen: NORTE ------ -10000 SUR -------- +10000 ESTE ------- +1 OESTE ------ -1 NORESTE ---- -10001 NOROESTE --- -9999 SURESTE ---- +9999 SUROESTE --- -10001 Ya sabemos los valores que hay que sumar o restar de cada localidad para obtener sus conexiones. Es importante recordar que la rutina principal está programada para calcular todas las conexiones por defecto, incluso las erróneas (ir al norte desde la localidad 10000). Lo que haremos será posicionar en el PROCESO 251 la gestión de excepciones antes de llegar a la rutina principal, de modo que nunca llegue a procesar una conexión errónea. More in a mo. Antes de empezar a programar, vamos a definir: * proceso 251: es el proceso que contiene la rutina de conexiones de la cuadrícula. * localidad 251: es la localidad contenedora de la cuadrícula. * bandera 251: es la bandera que se encargará de controlar la localidad actual dentro de la cuadrícula, mientras que la bandera 38 sea siempre igual a 251. Como todas las entidades se identifican por el mismo número (251), vamos a crear una constante LOC_EXTENDEDZONE que contenga ese valor y que no sirva para todas las referencias: ##define const LOC_EXTENDEDZONE 251 Ahora, antes de implementar el proceso 251, vamos a asegurarnos de que HAS DEJADO el campo DESCRIPCIÓN DE LOCALIDAD de la localidad 251 vacío. Es decir, la has definido pero no has introducido ningún mensaje. Es importante que esté en blanco. En la tabla de mensajes de usuario, creamos UNA SERIE DE MENSAJES cuyos números coincidan con los que hemos utilizado en la cuadrícula de localidades extendidas (queda a tu elección incluir el newline como secuencia de escape en el mensaje o llamar a los mensajes desde el proceso 1 con MESS y NEWLINE o con MESSAGE y no incluir \n en los mensajes...): /10001 Mensaje descripción localidad extendida 10001.\n /10002 Mensaje descripción localidad extendida 10002.\n /10003 Mensaje descripción localidad extendida 10003.\n ... /90009 Mensaje descripción localidad extendida 90009.\n En la tabla de respuestas, añadimos las entradas que controlan la llegada a la localidad de entrada a la cuadrícula (llegamos a la loc 90006 desde la 123): _ _ AT 123 EQ 33 2 ; VERBO NORTE LET LOC_EXTENDEDZONE 90006 ; LOCALIDAD DE ENTRADA EN LA CUADRICULA LET 38 251 ; LOCALIDAD DUMMY CONTENEDORA DE LA CUADRICULA DESC ... y la salida (salimos a la 124 desde loc 10002) _ _ AT 251 EQ 33 2 ; VERBO NORTE EQ LOC_EXTENDEDZONE 10002 ; LOCALIDAD DE SALIDA EN LA CUADRICULA LET 38 124 ; LOCALIDAD DUMMY CONTENEDORA DE LA CUADRICULA DESC De nuevo, y antes de implementar el proceso 251, vamos a retocar el proceso 1; por ejemplo: /PRO 1 _ _ ISNOTLIGHT WRITELN "No puedes ver nada sin una fuente de luz." ; ------------------------------------------------------- ; Al llegar aquí, ya se habría impreso la descripción de localidad ; pero como estamos en la loc 251 y hemos dejado su desc en ; blanco no se ha impreso nada. En su lugar, imprimimos un ; mensaje de usuario que tenga el mismo número que el ; número de localidad extendida... ; ------------------------------------------------------- _ _ EQ 38 LOC_EXTENDEDZONE ; SI ESTAMOS EN LA LOCALIDAD 251 MESS @251 ; MENSAJE DE USUARIO CUYO NÚMERO ES = NUMERO ; LOC_EXTENDEDZONE _ _ ; IMPRIMIMOS OBJETOS PRESENTES LISTOBJ _ _ LISTNPC @38 ; IMPRIMIMOS OBJETOS PRESENTES ; OJO, DEJAMOS LISTNPC @38 PERO NO FUNCIONA CON @38; HABRÍA QUE CONSTRUIR EN ; SU LUGAR UN PROCESO QUE GESTIONARA LOS NPCS DENTRO DE LA CUADRÍCULA... Y, ahora sí, llegamos al proceso 251. Añado los comentarios que permiten ir siguiendo la lógica del proceso: /PRO LOC_EXTENDEDZONE ; ==================================================== ; PROCESO DE MOVIMIENTO AUTOMATIZADO EN ZONA EXTENDIDA ; ==================================================== ; ------------------------------------------------------- ; PRIMERO ATRAPAMOS LA LOCALIDAD DE SALIDA DE LA ZONA EXTENDIDA ; e.g. loc 10002 hacia el norte ; ------------------------------------------------------- _ _ EQ 38 LOC_EXTENDEDZONE EQ LOC_EXTENDEDZONE 10002 EQ 33 2 ; VERBO NORTE LET 38 124 ; VAMOS A LOC 124 LET LOC_EXTENDEDZONE 0 ; SEAMOS LIMPIOS, DEJAMOS F251 A ZERO DESC ; ------------------------------------------------------- ; Ahora toca indicar las excepciones a las conexiones de la cuadrícula ; e.g. no queremos que haya conexión al norte desde la 40006 ; Intenta que no sean muchas... ------------------------------------------------------- _ _ EQ LOC_EXTENDEDZONE 40006 EQ 33 2 ;VERBO NORTE SYSMESS 7 DONE ; ------------------------------------------------------- ; Empezamos a gestionar la cuadrícula ; Primero la fila superior ;------------------------------------------------------- ; ESQUINAS ;------------------------------------------------------- _ _ EQ LOC_EXTENDEDZONE 10000 EQ 33 9 ;VERBO SO SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 10000 EQ 33 5 ;VERBO O SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 10009 EQ 33 8 ;VERBO SE SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 10009 EQ 33 4 ;VERBO E SYSMESS 7 DONE ;------------------------------------------------------- ; RESTO FILA ;------------------------------------------------------- _ _ GE LOC_EXTENDEDZONE 10000 LE LOC_EXTENDEDZONE 10009 EQ 33 2 ;VERBO NORTE SYSMESS 7 DONE _ _ GE LOC_EXTENDEDZONE 10000 LE LOC_EXTENDEDZONE 10009 EQ 33 6 ;VERBO NE SYSMESS 7 DONE _ _ GE LOC_EXTENDEDZONE 10000 LE LOC_EXTENDEDZONE 10009 EQ 33 7 ;VERBO NO SYSMESS 7 DONE ;------------------------------------------------------- ; Ahora la fila inferior ;------------------------------------------------------- ; ESQUINAS ;------------------------------------------------------- _ _ EQ LOC_EXTENDEDZONE 90000 EQ 33 7 ;VERBO NO SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 90000 EQ 33 5 ;VERBO O SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 10009 EQ 33 6 ;VERBO NE SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 10009 EQ 33 4 ;VERBO E SYSMESS 7 DONE ;------------------------------------------------------- ; RESTO FILA ;------------------------------------------------------- _ _ GE LOC_EXTENDEDZONE 90000 LE LOC_EXTENDEDZONE 90009 EQ 33 4 ;VERBO SUR SYSMESS 7 DONE _ _ GE LOC_EXTENDEDZONE 10000 LE LOC_EXTENDEDZONE 10009 EQ 33 8 ;VERBO SE SYSMESS 7 DONE _ _ GE LOC_EXTENDEDZONE 10000 LE LOC_EXTENDEDZONE 10009 EQ 33 9 ;VERBO SO SYSMESS 7 DONE ; ------------------------------------------------------- ; Ahora nos vamos a la fila lateral oeste ; ------------------------------------------------------- _ _ EQ LOC_EXTENDEDZONE 20000 EQ 33 7 ;VERBO NO SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 20000 EQ 33 5 ;VERBO O SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 20000 EQ 33 9 ;VERBO SO SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 30000 EQ 33 7 ;VERBO NO SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 30000 EQ 33 5 ;VERBO O SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 30000 EQ 33 9 ;VERBO SO SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 40000 EQ 33 7 ;VERBO NO SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 40000 EQ 33 5 ;VERBO O SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 40000 EQ 33 9 ;VERBO SO SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 50000 EQ 33 7 ;VERBO NO SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 50000 EQ 33 5 ;VERBO O SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 50000 EQ 33 9 ;VERBO SO SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 60000 EQ 33 7 ;VERBO NO SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 60000 EQ 33 5 ;VERBO O SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 60000 EQ 33 9 ;VERBO SO SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 70000 EQ 33 7 ;VERBO NO SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 70000 EQ 33 5 ;VERBO O SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 70000 EQ 33 9 ;VERBO SO SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 80000 EQ 33 7 ;VERBO NO SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 80000 EQ 33 5 ;VERBO O SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 80000 EQ 33 9 ;VERBO SO SYSMESS 7 DONE ; ------------------------------------------------------- ; Y seguimos con la fila lateral este ; ------------------------------------------------------- _ _ EQ LOC_EXTENDEDZONE 20009 EQ 33 6 ;VERBO NE SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 20009 EQ 33 4 ;VERBO E SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 20009 EQ 33 8 ;VERBO SE SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 30009 EQ 33 6 ;VERBO NE SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 30009 EQ 33 4 ;VERBO E SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 30009 EQ 33 8 ;VERBO SE SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 40009 EQ 33 6 ;VERBO NE SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 40009 EQ 33 4 ;VERBO E SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 40009 EQ 33 8 ;VERBO SE SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 50009 EQ 33 6 ;VERBO NE SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 50009 EQ 33 4 ;VERBO E SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 50009 EQ 33 8 ;VERBO SE SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 60009 EQ 33 6 ;VERBO NE SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 60009 EQ 33 4 ;VERBO E SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 60009 EQ 33 8 ;VERBO SE SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 70009 EQ 33 6 ;VERBO NE SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 70009 EQ 33 4 ;VERBO E SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 70009 EQ 33 8 ;VERBO SE SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 80009 EQ 33 6 ;VERBO NE SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 80009 EQ 33 4 ;VERBO E SYSMESS 7 DONE _ _ EQ LOC_EXTENDEDZONE 80009 EQ 33 8 ;VERBO SE SYSMESS 7 DONE ; ------------------------------------------------------- ; Y, por fin, si no es ningún caso excepcional, llegamos a ; la parte principal de la rutina, la que calcula automáticamente ; todas las conexiones interiores de la cuadrícula ; ------------------------------------------------------- _ _ EQ 33 2 ;VERBO NORTE MINUS LOC_EXTENDEDZONE 10000 DESC _ _ EQ 33 3 ;VERBO SUR PLUS LOC_EXTENDEDZONE 10000 DESC _ _ EQ 33 4 ;VERBO ESTE PLUS LOC_EXTENDEDZONE 1 DESC _ _ EQ 33 5 ;VERBO OESTE MINUS LOC_EXTENDEDZONE 1 DESC _ _ EQ 33 6 ;VERBO NE MINUS LOC_EXTENDEDZONE 9999 DESC _ _ EQ 33 7 ;VERBO NO MINUS LOC_EXTENDEDZONE 10001 DESC _ _ EQ 33 8 ;VERBO SE PLUS LOC_EXTENDEDZONE 10001 DESC _ _ EQ 33 2 ;VERBO SO PLUS LOC_EXTENDEDZONE 9999 DESC _ _ DONE ; Por si acaso... Si haces un cálculo rápido, hemos empleado sólo 72 entradas frente a las 720 que serían necesarias con el método habitual de hacer 8 comprobaciones (una por dirección) en cada localidad extendida. Un 10% del trabajo para conseguir el mismo efecto. Hemos añadido 90 localidades funcionales y todo ello gastando una sola localidad real! En caso de necesitar una superficie de contorno irregular, se pueden incluir más excepciones, aunque ya sabes lo que pasa... También se pueden programar acciones de todo tipo en este tipo de cuadrículas. Por ejemplo, si tu juego se desarrolla en una ciudad, puedes emplear la cuadrícula para mapearla y emplear localidades reales con entrar/salir para los interiores. O crear un espacio aéreo 3D con coordenadas X, Y y Z. Pero la recomendación principal sigue siendo: espacio simple mononivel con poca interactividad! Por cierto, este sistema de la cuadrícula y los offsets numéricos es la base de un sistema de conversaciones con psis del que espero poder contar pronto algo más. Hemos empleado números grandes de localidad para poder combinarlo después con otras rutinas y evitar que nos pisemos en los números de mensaje. En un próximo artículo, plantearé una reprogramación del proceso 1 para crear un flujo muuuuuuy personalizado de las descripciones de localidad, con múltiples variables y secciones de texto, que permiten desarrollo de storylines en formato más peliculero que el típico "Estás en...". Hasta el próximo artículo.