• No se han encontrado resultados

Modelado de las acciones de juego

4. Diseño e Implementación del juego propuesto 

4.3.  Planteo de la solución 

4.4.3.  Modelado de las acciones de juego

Teniendo ya la lógica que da soporte a las variables básicas del juego, se tienen que        modelar las acciones de juego; para esto, conviene revisar el formato propio de las acciones        del juego. Como se asentó en la sección 2.1, el juego consta de ciertas acciones básicas        que se ejecutan constantemente durante el juego (descartes de ciertas cartas, tiradas de        dados, movimientos de fichas), y de actividades más complejas y muy diversas entre sí,        únicas de cada escenario o momentos de juego (actividades que deben hacerse en ronda,        descartes comunes a todos los jugadores, todo tipo de combinaciones de las actividades        básicas). La idea es modelar estas acciones de manera tal de que sea simple incorporar        acciones nuevas a partir de la composición de acciones más simples. 

La solución empleada fue un esquema de actualizaciones de juego (“game updates”) que        ocurren cuando existe algún cambio en la lógica de juego. Esto se llevó a cabo a través de        la creación de una clase         Activity, que sirve como superclase abstracta de una serie de        clases que modelan las distintas actividades de juego.  

Ante la llegada de un mensaje “game update” al servidor, se actualiza el estado de juego        de acuerdo al código contenido una actividad de esta clase (con un método “update”); cada        juego tiene una variable “currentActivity” que almacena la actividad en curso.  

Ante la llegada de un evento de esta clase al cliente, se actualiza la interfaz para reflejar        los cambios que la actividad ha generado en el estado de juego con el código contenido en        la actividad (con un método “draw”).  

De esta forma, la funcionalidad tanto como para el servidor como para el cliente queda        encapsulada en una instancia de una clase derivada de Activity. Cada actividad, también,        podrá tener subactividades en sí, a ejecutarse secuencialmente, para permitir la        composición precisa para formar actividades más complejas. 

 

Fig. 13. Diagrama de Clases mostrando la estructura de las actividades del juego.   

El código que compone a las actividades del juego que extienden a la clase Activity se        especificó en un archivo (“gameActions.js”) donde todas están presentes; este código,        visible para el cliente y para el servidor, permite que el envío de mensajes posea        simplemente el nombre de la actividad a ejecutar y algunos parámetros extra, propios de        cada actividad, evitando así tener que enviar en cada mensaje de actualización todo el        código de cada actividad. Ésto, además, permite encontrar salida a una limitación propia de        la plataforma: los parámetros de formato JSON de los mensajes en socket.io permiten sólo        el envío de objetos con pares clave­valor, pero no de código (en este caso, funciones de        Javascript).  

Se puede observar entonces, a través de un diagrama de secuencia, el flujo general de        actualización a través de actividades: 

 

 

Fig. 14. Diagrama de Secuencia de Actualización del juego a través de la clase Activity.   

Se ha descrito la clase Activity y cómo se lleva a cabo la actualización del estado de        juego a través de ella. Sin embargo, todavía queda el problema de la composición de        actividades para formar otras más complejas. 

En el juego, es muy común tener una actividad que represente una elección: de acuerdo        al input del cliente, se deben agregar tales o cuáles subactividades a la actividad que        actualmente está en curso. Es decir, además de soporte para la actualización, es preciso        tener soporte para agregar nuevas subactividades a la actividad en curso en forma        dinámica, y para señalar que una actividad ha terminado de manera tal de que el juego se        actualice propagando la siguiente subactividad en la lista. Esto se lleva a cabo a través de        los mensajes “add activity” y “resolve activity”.      Fig. 15. Diagrama de Secuencia de Agregar nueva subactividad.      Fig. 16. Diagrama de Resolver actividad.    El siguiente diagrama de clases completa la implementación con las clases y atributos  faltantes. No se representan las instancias de las distintas actividades que heredan la  estructura de Activity, por su número.   

 

   

Figs. 17 (a y b). Diagrama de Clases (dividido en dos partes por cuestiones de legibilidad). El  código de la clase “Activity”, así como las derivadas de ella, son visibles tanto al cliente como al  servidor.    El diseño planteado permite, entonces, instanciar los componentes de juego, definir  actividades simples y a partir de ellas actividades más complejas. Una parte central del  juego es la resolución de las actividades y eventos propios de cada escenario; cada uno de  estos eventos  generalmente constan una decisión entre varias alternativas donde cada  alternativa es una conjunción de acciones. De esta forma, así como las actividades básicas  del juego utilizan el esquema de la clase Activity, también los eventos de cada escenario  han sido definidos como extensiones de ella.   Las actividades simples, que se repiten a lo largo del juego, se encuentran definidas en  un archivo de acciones de juego, que se cargan e instancian de acuerdo a las necesidades  de cada momento de la partida; lo mismo aplica para los eventos y actividades de cada  escenario que presentan las decisiones y en los que se forman las acciones más complejas  a partir de la combinación de acciones de juego, y para las cartas especiales que al  utilizarse llevan a cabo alguna acción de juego especial. 

4.5. Persistencia de los datos 

Como último término de la solución planteada para dar respuesta a los requerimientos        funcionales, hay que referirse a la persistencia de los datos. Los requerimientos especifican        que se desea guardar toda la información sobre las partidas disputadas por los usuarios.        Como se ha dicho, la solución elegida (una base de datos MongoDB) permite almacenar en        un esquema orientado a documentos, objetos con estructura JSON, de atributos variantes,        en colecciones que agrupan elementos de similares características.  

Si bien en muchos casos se explota la capacidad de almacenar objetos de formato        heterogéneo, si se han definido esquemas para los objetos de distintas colecciones, que        especifican los atributos “mínimos”, aquellos que seguramente han de estar presentes en        todos los documentos que conforman cada colección (es importante aclarar que, si bien        estos esquemas modelan atributos que seguramente estarán presentes, no existen        chequeos en la base de datos que fuercen este hecho). Las distintas colecciones        (representadas en la Figura 6), agrupan de forma intuitiva los datos de distinta naturaleza        que se desean guardar (información sobre usuarios, sobre partidas, etcétera). 

La funcionalidad central y menos trivial a la que es preciso dar respuesta en este        apartado es el almacenamiento de toda la información sobre las partidas. Además de datos        precisos sobre sus participantes y la configuración inicial de la partida, existe el requisito de        almacenar toda la información respecto a cada acción de cada jugador a lo largo de la        partida. 

Esto fue resuelto siguiendo el esquema de “actividades” planteado en el inciso anterior:        para cada partida, se almacena en un arreglo JSON cada una de las actividades que han        ocurrido y quién es el jugador activo que las llevó a cabo o fue objeto de los cambios        ocasionados por ellas. En este apartado es donde se ve más explotada la prestación de        MongoDB que permite almacenar objetos de diferentes formatos: en el esquema está        definido un espacio para guardar las acciones de juego, pero éstas tienen un formato muy       

heterogéneo (lo único que todas tienen en común es un nombre, pero los parámetros de        cada una pueden ser completamente distintos). 

El mecanismo a través del cual y momento donde se almacenan éstas acciones merece        un análisis especial. Durante la creación de una partida se crea un nuevo objeto de la        colección “game” y se almacena en la base de datos; a lo largo de ésta, por cada actividad        que llegue al servidor (a través del mensaje “update game”, cuyo funcionamiento ya se ha        detallado), se guarda el objeto actividad que llega al servidor para la actualización del        estado de juego, tal cual llega (en formato JSON, admitido por la base de datos), con su        nombre, parámetros, y el alias del jugador activo. Este flujo puede observarse a través de        una extensión del diagrama de secuencia que describe la actualización del estado de juego:      Fig. 18. Diagrama de Secuencia de Actualización del juego a través de la clase Activity (con  guardado de la actividad en la Base de Datos).     

A partir, entonces, del diseño planteado para cada uno de los componentes, se logró        proveer la funcionalidad que da respuesta a los requisitos funcionales del sistema. A        continuación, se evaluarán algunos escenarios de calidad particulares del trabajo y cómo la        solución planteada para cada uno ha extendido el diseño básico de la plataforma. 

Documento similar