Cookies policy: We use our own and third-party cookies to improve your navigation experience. By browsing this site, we assume you consent to us using them. More information here.
Accept

javacup en detalle. Parte III

Vamos a entrar en el detalle de como funciona javacup para comprender mejor los cambios que queremos introducir en una nueva versión
0
0
1 visit

Datos útiles sobre la lógica de un partido

En cada partido se ejecutaran n iteraciones, en cada iteración se enviara a las tácticas

la situación del partido, y seguido a esto las tácticas retornaran la lista de los comandos que especifiquen en el método ejecutar. De acuerdo a esto se modificará el estado del partido para la siguiente iteración. En especifico se ejecutarán Constants.ITERACIONES iteraciones.

Un jugador sólo puede ir a una dirección y sólo puede rematar de una forma durante la iteración. Es decir, se ejecutará sólo un comando “ir a” y sólo un comando “golpear balón” para cada jugador en cada iteración.

Cuando ocurra que en una misma iteración se indique más de un CommandMoveTo para el mismo jugador, los primeros comandos se ignorarán y sólo se considerará el último. Análogo sucederá con el comando CommandHitBall.

Es importante comprender que todos los comandos actúan sobre el mismo instante de tiempo. Por esto no es válido pensar que primero ejecuto un comando “ir a” para acercarme al balón y luego que estoy cerca ejecuto golpear el balón.

Un jugador está en condiciones de rematar si se encuentra a una distancia menor o igual al balón que Constants.DISTANCIA_CONTROL_BALON y además que el balón se encuentre a una altura menor o igual que Constants.ALTURA_CONTROL_BALON. Para evitar el caso de porteros perfectos, se aplica también una probabilidad de control del balón que depende de la velocidad del balón.

Dentro de los jugadores propios y rivales que estén en condiciones de rematar se seleccionará uno al azar y sólo es ese quien rematará. Al remate se le aplicara un error angular (en el plano x,y) que dependerá del error del jugador que rematara.

Para evitar excesivos rebotes, un jugador que ya remató, sólo podrá volver a rematar en Constants.ITERACIONES_GOLPEAR_BALON iteraciones después.

Cada vez que el balón sale del campo de juego, deberá sacar el equipo rival del que lanzó el balón, en la posición donde salió el balón. Si un equipo lanza el balón por detrás de su propio arco se produce un tiro de esquina, que no es más que un saque normal pero en la posición de córner. En los saques de costado se reduce la potencia de remate a un 75%.

Durante las iteraciones entre que sale el balón y cuando se realiza el saque el tiempo no avanza, y los jugadores del equipo que no saca se alejaran en un radio Constants.DISTANCIA_SAQUE desde la posición de saque. Sin embargo, si pasa un tiempo excesivo y no se realiza el saque, se multara al equipo que no saco, permitiendo sacar al otro equipo.

Un jugador se encuentra en fuera de juego cuando toca la pelota a pase de un compañero y se encuentra en una posición más adelantada que la defensa rival.

Cada vez que un jugador realiza un comando, consume la energía indicada en el parámetro Constants.ENERGIA_DIFF pero si además está realizando sprint, el consumo de energía aumentará en Constants.SPRINT_ENERGIA_EXTRA. La cantidad de energía mínima que puede llegar a tener un jugador se define en Constants.ENERGIA_MIN y la energía mínima que debe tener un jugador para poder realizar un sprint está definidia en Constants.SPRINT_ENERGIA_MIN. Cada iteración que el jugador no ejecute ninguna acción, recuperará Constants.ENERGIA_DIFF de energía.

Código de ejemplo de implementación del método execute

//Lista de comandos

LinkedList<Command> comandos = new LinkedList<Command>();

@Override
public List<Command> execute(GameSituations sp) {

//Limpia la lista de comandos

comandos.clear();

//Obtiene las posiciones de tus jugadores

Position[] jugadores = sp.myPlayers();
for (int i = 0; i < jugadores.length; i++) {

//Ordena a cada jugador que se ubique segun la alineacion1

comandos.add(new CommandMoveTo(i, alineacion1[i])); }

//Si no saca el rival

if (!sp.isRivalStarts()) {
//Obtiene los datos de recuperacion del balon

int[] recuperadores = sp.getRecoveryBall();

//Si existe posibilidad de recuperar el balon

if (recuperadores.length > 1) {

//Obtiene las coordenadas del balon en el instante donde
//se puede recuperar el balon
double[] posRecuperacion = sp.getTrajectory(recuperadores[0]);

//Recorre la lista de jugadores que pueden recuperar

for (int i = 1; i < recuperadores.length; i++) {

//Ordena a los jugadores recuperadores que se ubique

//en la posicion de recuperacion
comandos.add(new CommandMoveTo(recuperadores[i], new Position(posRecuperacion[0], posRecuperacion[1])));

}

}

}


//Instancia un generador aleatorio

Random r = new Random();
//Recorre la lista de mis jugadores que pueden rematar

for (int i : sp.canKick()) {

//Si el jugador es de indice 8 o 10

if (i == 8 || i == 10) { //condicion aleatoria

if (r.nextBoolean()) {

//Ordena que debe rematar al centro del arco

comandos.add(new CommandHitBall(i, Constants.centroArcoSup, 1, 12 + r.nextInt(6)));

} else if (r.nextBoolean()) {

//Ordena que debe rematar al poste derecho

comandos.add(new CommandHitBall(i, Constants.posteDerArcoSup, 1, 12 + r.nextInt(6)));

} else {

//Ordena que debe rematar al poste izquierdo

comandos.add(new CommandHitBall(i, Constants.posteIzqArcoSup, 1, 12 + r.nextInt(6))); }

} else {
//inicia contador en cero
int count = 0;
int jugadorDestino;
//Repetir mientras el jugador destino sea igual al jugador que remata

while (((jugadorDestino = r.nextInt(11)) == i

//o mientras la coordenada y del jugador que remata
//es mayor que la coordenada y del que recibe
|| jugadores[i].getY() > jugadores[jugadorDestino].getY())

//Y mientras el contador es menor a 20
&& count < 20) {

//incrementa el contador

count++;

}

//Si el receptor del balon es el que remata

if (i == jugadorDestino) {
while ((jugadorDestino = r.nextInt(jugadores.length)) == i) { }

}

//Ordena que el jugador que puede rematar que de un pase
//al jugador destino
comandos.add(new CommandHitBall(i, jugadores[jugadorDestino], 1, r.nextInt(45)));

} }

//Retorna la lista de comandos

return comandos;

Visor de partidos

Para usar el visor de partidos debes ejecutar la clase JavaCup, ubicada en la raíz del código fuente

En la pestaña “Tácticas” aparecerán las tácticas que agregadas al código del proyecto.

Al seleccionar una táctica y presionar “Tactica Visita” asignas el equipo visita, análogo para asignar el local.

Con el botón “Local <-> Visita” se invierte el local y la visita.

En el comboBox seleccionas visualizar el partido mediante el Visor OpenGl o mediante el visor normal.

Finalmente presione “Ver Partido” para ejecutar y ver el partido. En el Visor OpenGL:

  • Al presionar + y – se activa el zoom.
  • Al presionar F1 se activa o desactiva el estadio. Al presionar F2 se activa o desactiva el entorno. Al presionar F3 muestra los frames por segundo.
  • Al presiona F4 activa o desactiva los números y nombres.

En la pestaña “Guardados” están los partidos que has salvado, al visualizar uno de estos partidos puedes, avanzar, retroceder (con las flechas), marcar el una sección (con la tecla “Inicio” y “Fin”), puedes cortar la sección (con tecla “supr”) y puedes volver a guardar el partido con la tecla "S".

Conclusiones

Con este cubo terminamos la serie destinada a mostrar en detalle el funcionamiento de javacup.

A partir de ahora nos centraremos en los cambios a introducir en la nueva versión. Nos vemos!

Technology and scienceGamesJavaprogramaciónjavacupvideojuegos
16 Oct, 2016
Ratings
(0 votes)
Your rating
Collected
Sito
Sito