/* Se configura el costo de Manhattan basado con respecto al punto final. */ public void setCostoManhattan(Ficha puntoFinal) { int cost1 = Math.Abs(puntoFinal.getX() - this.x); int cost2 = Math.Abs(puntoFinal.getY() - this.y); this.costoManhattan = cost1 + cost2; }
/* ******************************************************* * Obtengo todos los posibles movimientos de una ficha. * Se recibe la ficha a la que desea saber los posibles movimientos. * Se permiten movimientos laterales y diagonales. * Agrega a la lista de buscados. *********************************************************/ public void obtenerAliadosDiagonal(Ficha posActual) { Ficha meta = this.campoJuego.getMeta(); int x = posActual.getX() - 1; int y = posActual.getY() - 1; for (int posX = x; posX < (x + 3); posX++) { for (int posY = y; posY < (y + 3); posY++) { // Si no se sale del tablero y además no se evalua la misma ficha. if ((posX >= 0 && posX < this.rows) && (posY >= 0 && posY < this.cols) && (posActual.getX() != posX || posActual.getY() != posY)) { // Si es un movimiento válido (No es un enemigo y no lo había hecho previamente). if (movimientoValido(posActual, posX, posY)) { Blanco nuevaFicha = new Blanco(posX, posY, posActual); nuevaFicha.setCostoManhattan(meta); // Si es diagonal me muevo en diagonal. En caso contrario me muevo en línea Recta. moverFicha(posX, posY, posActual, nuevaFicha); listaBuscados.insert(nuevaFicha); // Se inserta la nueva ficha. } } } } }
/* ******************************************************* * Obtengo todos los posibles movimientos de una ficha. * Se recibe la ficha a la que desea saber los posibles movimientos. * Solo se permiten movimientos laterales (arriba, abajo, derecha e izquierda). * Agrega a la lista de buscados. *********************************************************/ public void obtenerAliadosLaterales(Ficha posActual) { Ficha meta = this.campoJuego.getMeta(); int x = posActual.getX(); int y = posActual.getY(); int[,] positions = new int[4, 2] { { x - 1, y }, { x + 1, y }, { x, y - 1 }, { x, y + 1 } }; // Realice cuatro veces por las diagonales de las fichas. for (int pos = 0; pos < 4; pos++) { int posX = positions[pos, 0]; int posY = positions[pos, 1]; // Si no se sale del tablero y además no se evalua la misma ficha. if ((posX >= 0 && posX < this.rows) && (posY >= 0 && posY < this.cols) && (posActual.getX() != posX || posActual.getY() != posY)) { // Compare tablero[i, j]; if (movimientoValido(posActual, posX, posY)) { Blanco nuevaFicha = new Blanco(posX, posY, posActual); nuevaFicha.setCostoManhattan(meta); // Si es diagonal me muevo en diagonal. En caso contrario me muevo en línea Recta. moverFicha(posX, posY, posActual, nuevaFicha); listaBuscados.insert(nuevaFicha); // Se inserta la nueva ficha. } } } }
/* Inserto los valores de la ruta óptima. */ public void seleccionarRutaOptima(Ficha ficha) { while (ficha != null) { this.listaCompletados.Insert(0, ficha); ficha = ficha.getPrevious(); } }
/* Obtengo una ficha al azar del tablero. */ public Ficha obtenerficha() { Random r = new Random(); int x = r.Next(0, this.filas); int y = r.Next(0, this.columnas); Ficha fichaSeleccionada = tablero[x, y]; return(fichaSeleccionada); }
/* ******************************************************* * Se selecciona el jugador por primera vez. * No se deben haber generado enemigos. *********************************************************/ public void seleccionarInicio() { Ficha fichaTemp = obtenerficha(); // Si la ficha del jugador no está en el mismo lugar que la meta. while (fichaTemp.compararFicha(this.meta)) { fichaTemp = obtenerficha(); } this.jugador = new Jugador("Temp", fichaTemp.getX(), fichaTemp.getY()); }
/* ******************************************************* * Se selecciona la meta a seguir. * No se deben haber generado enemigos. *********************************************************/ public void seleccionarMeta() { Ficha fichaTemp = obtenerficha(); // Si la ficha de la meta no está en el mismo lugar que el jugador. while (fichaTemp.compararFicha(this.jugador)) { fichaTemp = obtenerficha(); } this.meta = new Meta(fichaTemp.getX(), fichaTemp.getY()); }
/* Mueve la ficha dependiendo de las posiciones X y Y. */ public void moverFicha(int posX, int posY, Ficha posActual, Blanco nuevaFicha) { // Si es diagonal me muevo en diagonal. En caso contrario me muevo en línea Recta. if (posX == posActual.getX() || posY == posActual.getY()) { nuevaFicha.advanceNormal(campoJuego.getCostoLateral()); } else { nuevaFicha.advanceDiagonal(campoJuego.getCostoDiagonal()); } }
/* Compare si llegue a la meta. */ public Boolean compararMeta(int x, int y) { Ficha meta = this.campoJuego.getMeta(); Ficha fichaTemp = this.campoJuego.getFicha(x, y); // Si es la meta. if (fichaTemp.compararFicha(meta)) { return(true); } return(false); }
/* Compare si las coordenadas entre las fichas son equivalentes. */ public Boolean compararFicha(Ficha f) { if (f == null) { return(false); } if (this.x == f.getX() && this.y == f.getY()) { return(true); } return(false); }
/* Revise si ya había hecho ese movimiento previamente. */ public Boolean compararPrevios(Ficha posActual, Ficha nuevoHijo) { Ficha temp = posActual.getPrevious(); while (temp != null) { if (temp.compararFicha(nuevoHijo)) { return(true); } temp = temp.getPrevious(); } return(false); }
/* ******************************************************* * Se seleccionan las posiciones para asignar los enemigos. * Se deben haber seleccionado previamente la meta y el inicio. *********************************************************/ public void seleccionarEnemigos(int numeroEnemigos) { this.enemigos = new Enemigo[numeroEnemigos]; // Creo N número de enemigos. for (int i = 0; i < numeroEnemigos; i++) { Ficha fichaTemp = obtenerficha(); // La ficha no puede ser la meta o el jugador. while (fichaTemp.compararFicha(this.meta) || fichaTemp.compararFicha(this.jugador) || fichaTemp.compararMuchasFichas(this.enemigos)) { fichaTemp = obtenerficha(); } this.enemigos[i] = new Enemigo(fichaTemp.getX(), fichaTemp.getY()); // Agregué el nuevo enemigo. } }
/* Realiza el algoritmo Estrella. */ public Boolean accion(Boolean Diagonales) { Ficha jugador = this.campoJuego.getJugador(); listaInsertados.Insert(0, jugador); DateTime tiempoInicial = DateTime.Now; /* Compare si llegue a la meta. O sea ¿Inicio == Final? */ while (compararMeta(jugador.getX(), jugador.getY()) == false) { if (Diagonales) // Se permiten diagonales { obtenerAliadosDiagonal(jugador); } else // No se permiten diagonales { obtenerAliadosLaterales(jugador); } jugador = listaBuscados.getFicha(); // Retorna el posible movimiento con el costo más bajo. listaInsertados.Insert(0, jugador); // Si no hay rutas óptimas. if (jugador == null) { return(false); } } DateTime tiempoFinal = DateTime.Now; tiempoAlgoritmo = new TimeSpan(tiempoFinal.Ticks - tiempoInicial.Ticks); this.distanciaRecorrida = jugador.getCostoTotal(); seleccionarRutaOptima(jugador); // Inicializo la ruta óptima con la meta hasta el punto inicial. return(true); }
/* Compare si es un movimiento válido. */ public Boolean movimientoValido(Ficha posActual, int x, int y) { Ficha[] enemigos = this.campoJuego.getEnemigos(); Ficha fichaTemp = this.campoJuego.getFicha(x, y); // Si es un enemigo. if (fichaTemp.compararMuchasFichas(enemigos)) { return(false); // No es válido } if (fichaTemp.compararMuchasFichas(listaInsertados.ToArray())) { return(false); // No es válido. } // Si ya lo había insertado previamente. if (compararPrevios(posActual, fichaTemp)) { return(false); // No es válido. } return(true); // Movimiento válido. }
/* Asigne el valor previo. */ public void setPrevious(Ficha previous) { this.previous = previous; }
/* Constructor para almacenar la ficha previa. */ public Blanco(int x, int y, Ficha previous) : base(x, y) { costoManhattan = 0; this.previous = previous; // Defino el valor previo. this.costoTotal += previous.getCostoTotal(); }