Descripción detallada de los algoritmos desarrollados - AdrianTEC/Proyecto-No1-Datos1 GitHub Wiki

A continuación se dará una explicación de cómo funciona el algoritmo del juego, secciones como los minijuegos, dados, y otros no tienen un algoritmo lógico como tal, simplemente son implementaciones gráficas, con código sumamente sencillo, por lo cual se considera poco provechoso explicarlos. Se explicará las secciones fundamentales, en las cuales sí existe un algoritmo para solucionar un problema en específico, se procederá por medio de secciones de solución a problemas en específico.



Creación de los caminos (armado del tablero)


El algoritmo de formado del tablero consiste en instanciar objetos de la clase camino que contienen de atributo una matriz y un método de conversión a listas. Posteriormente a estos objetos se les insertará una matriz de posiciones en forma de float[][] este objeto convertirá esa matriz en una lista, se debe indicar qué tipo de lista se quiere, y si es normal o doblemente enlazada.

Camino FaseD= new Camino(); FaseD.dobleEnlaze=true; FaseD.matrizPosiciones= new float[][]{{10,80},{117,80},{240,80},{363,80},{480,80},{528,80},{528,138},{528,256} }; ListaCircular caminoD = (ListaCircular) FaseD.convertirMatrizALista(new ListaCircular());


Movimiento de personajes:


Primero debe explicarse que existen dos tipos de casillas (nodos de una lista) en donde un jugador puede estar; casillas dobles o simples, el método "moverPersonaje" recibe el personaje que tiene que mover según el turno, un número de dos dados lanzados anteriormente, un puntero ya que es una función recursiva(esto se explicará más adelante) y cuenta con un booleano llamado "hasnotMovingYet" que sirve para saber para modificar *casillas dobles anexadas *, moverPersonaje simplemente le pregunta al jugador en que tipo de casilla se encuentra, y de qué tipo es la siguiente casilla para finalizar por mover al personaje a ella.

La función es recursiva, por el simple hecho estético de dar una animación de movimiento a la ficha del jugador, de otro modo, hecho con iteración el movimiento ocurre tan rápido que es imposible de ver. Otra función de este método es que actualiza el tipo de casilla en la que está el jugador para que esté disponible la baraja correspondiente, la cual es un botón que activa el método "takeACard" de la clase eventManager, de la que se hablara más adelante. Este botón se muestra como una baraja que cambia color según la casilla en la que se encuentre el jugador, este botón se encarga de crear la carta llamándola a través de las instancias de baraja que habían inicialmente y gracias a saber en que tipo de casilla se encuentra puede diferenciar entre a cual baraja realizar la petición, después de esto agrega la carta y la descripción a la pantalla.

Como anteriormente se explicó para la formación de caminos y otros se utilizaron lista dado la demanda de distintas fases anexadas al camino principal es necesario una forma de poner moverse entre fases, por lo que optó por insertar casillas dobles en puntos específicos del camino (casillas dobles anexadas) con el objetivo de utilizar su nodo anterior como punto de conección con las otras fases.

Cuando un jugador deja de moverse, se pregunta el tipo de casilla en la que está, en caso que esta sea una intersección contiene una letra "i" y el jugador recibe un booleano que significa la dirección en la que debe proceder, por lo que si su dirección es derecha (true) le pedirá el nodo siguiente a las casillas, en caso contrario, le pedirá el nodo anterior

La clase jugador es la que tiene toda la información acerca de los jugadores (estadisticas, posición). Aunque en tablero se encuentre el método que hace que el jugador se mueva. La verdad, lo único que hace es, hacer un casteo pesado de su casilla actual y su siguiente para pedirle a al jugador que se mueva, aquí se aplica modularidad el jugador es ide

Para el movimiento de los jugadores se tiene dos métodos moverA donde se ingresa un tipo de casilla, el jugador accede a la información posición que contiene y modifica la posición de su imagen por medio de las propiedades intrínsecas de imágenes de javafx.

A continuación se muestra un ejemplo de las clases dobles anexadas



Tablero posee otros métodos secundarios como generar estrella , mover estrella o lanzar dado, generar estrella se encarga de que al pasar el primer turno (todos los jugadores jueguen una vez) aparezca una estrella en un punto aleatorio del tablero, luego moverEstrella se encarga de simplemente mover la estrella ya existente a una casilla nueva una vez un jugador haya comprado la estrella y esta se le añada al inventario, y lanzar dado funciona para generar dos números aleatorios que van a significar cuanto tiene que moverse el personaje por el tablero en su turno. Por ultimo, existe un botón que se encarga de que el jugador pueda tomar una carta para que el efecto, de la casilla en la que se encuentra, suceda y finalmente le pasa el turno al siguiente jugador.


EventManager


EventManager se puede ver como un trabajador, más como un "asistente", esto se debe a que el se encarga de todo el trabajo que hay detrás de cada evento que va a ocurrir durante la partida. EventManager se va a encargar tanto de los eventos que ocurren al caer en una casilla dorada, como de los minijuegos que hay al final de cada ronda.


¿Como funciona esta clase?

EventManager es una baraja, contiene un arreglo de strings con el nombre de los métodos que puede hacer , este listado es tomado por un método llamado barajar, método que explora el arreglo y por medio de dos punteros intercambia posiciones del string, cuando termina de desordenar el arreglo procede a agregar uno por uno los elementos a una nueva pila.

    for(int i=0; i< eventos.length;i++)
    {
        String aux= eventos[i];
        int numb=(int) (Math.random()*eventos.length);
        eventos[i]=eventos[numb];
        eventos[numb]= aux;
    }
    barajaDeEventos.especialPush(eventos);

*Especial push es un método que recibe un string[] y agrega todos lo valores contenidos explorando uno por uno las posiciones del arreglo por medio de iteración


Push Pop y peek


En la pila se implementaron esos tres métodos que el primero, simplemente crea una casillaExtraSimple y le referencia el último de la pila como su siguiente y este pasa a ser el siguiente.

Pop retorna el último y declara que su siguiente es un null, por último declara que el siguiente será el útlimo

peek simplemente retorna el último

specialPush : este recibe un string[][] y por medio de un for explora el arreglo crea una Casilla extra simple, le inserta la información y agrega esta casilla a una pila


Generación de eventos y minijuegos


Cuando se invoca el método takeAcard de Event Manager, se remueve y se lee el último valor de la pila, a su vez se le asigna este valor a una nueva carta (recordemos que Event Manager es una baraja), a su vez, con el valor obtenido se llama a "magicFunction" la cual es una función que utiliza "Reflection" lo que le permite llamar a un método cualquiera por su String, lo implementamos de esta manera para evitar tener que generar cada uno de los casos posibles por medio de "if" (32-40) lineas de código aproximadamente.

La mayoría de eventos como robar monedas, o teletransporte se reducen a acceder a algún componente del jugador y modificarlo }

public void ganar2Estrellas(Jugador px11)// { px11.setEstrellas(px11.getEstrellas()+2); }

Pero para generar los juegos es distinto, y también lo es entre juegos y duelos el algoritmo de generación de juegos consiste en recibir un jugador y un numero que le va a indicar al programa cual de los minijuegos disponibles escoger, posteriormente se crea una instancia del minijuego, una instancia de Stage(ventana) y se llama al método start del minijuego y se le inserta esa ventana, posteriormente esta se abre y como el algoritmo de la mayoría de videojuegos es mover una imagen, recibir un texto y compararlo, apretar botones ... no se considerarán como algoritmos importantes debido a su simpleza.

Los minijuegos se diferencian de los duelos esencialmente en que los minijuegos para saber cuando terminan utilizan el patrón observer y se abren la cantidad de jugadores que hay, entonces se ocupa registrar una puntuación, para realizar esto en tablero implementamos un algoritmo de recursividad "asistida" (un método que se llama a sí mismo después de cierto tiempo en vez de cada iteración) este método tiene un puntero que corresponde a la cantidad de jugadores y por cada uno va a abrir un minijuego, al hacer esto eventManager levanta un booleano que indica que hay un juego abierto y que se tiene que esperar a que termine su turno, una vez que el juego se cierra , se le notifica a eventManager que ya se cerró el juego, por lo que si quedan jugadores esperando les asigna su turno. Cada vez que se termina un juego se le dice a eventManager qué jugador jugó y cuanto fue su puntaje, esto para que cuando ya se cerrara el último juego y no hayan más jugadores esperando él diga quién fue el que obtuvo mayor puntuación.

Los duelos son mucho más sencillos, simplemente crean una instancia del duelo y le insertan los jugadores que competirán, se abre una ventana, se decide quien gana y quien pierde ahí mismo, y se le premia al jugador.