package src.estrategias;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import src.Asesino;
import src.Cliente;
import src.Enemigo;
import src.Explorador;
import src.Fortaleza;
import src.FortalezaEnemiga;
import src.Mina;
import src.UnidadBasica;
import src.estadisticas.Estadisticas;
import src.estadisticas.NodoMapaEstadisticas;
import src.pathFinding.Astar;
import com.gameloftProgrammersCup.client.ClientCommand;
import com.gameloftProgrammersCup.client.Vision;
import com.gameloftProgrammersCup.clientInterfaces.MapElement;
import com.gameloftProgrammersCup.clientInterfaces.Point;
public class EstrategiaExploradorAcecharColector extends EstrategiaUnidad{
public List waypoints=new ArrayList();
public int orden=-1;
public int cantidadActividad=0;
static public int perimetro=6;
@Override
public ClientCommand accionDeTurno(UnidadBasica unidad) {
ClientCommand nuevoComando=new ClientCommand();
//chequeo la vision
int centroX=unidad.getPosition().getX();
int centroY=unidad.getPosition().getY();
int rango=unidad.getVision();
boolean noSirve=true;
boolean ampliarPerimetro=false;
MapElement meEvaluado=null;
//int debug=0;
for(int y=unidad.getPosition().getY()-1;y<=unidad.getPosition().getY()+1;y++)
{
for(int x= unidad.getPosition().getX()-1;x<=unidad.getPosition().getX()+1;x++)
{
Point pEvaluado = new Point(x,y);
if (!Fortaleza.isPointAfuera(pEvaluado))
meEvaluado= Fortaleza.instanciaFortaleza.getElementoMapaEnPosicion(pEvaluado);
if (meEvaluado != null && meEvaluado.getClass().getName().equals("src.Enemigo") && ((Enemigo)meEvaluado).getUltimoTurnoVisto()==Cliente.turno && meEvaluado.getType()==Vision.TYPE_ENEMY_ATTACKER)
ampliarPerimetro=true;
}
}
int limiteIzquierdo=(centroX-rango)>=0 ? centroX-rango : 0;
int limiteDerecho=(centroX+rango)<unidad.getJugador().getFortaleza().anchoMapa ? centroX+rango : unidad.getJugador().getFortaleza().anchoMapa-1;
int limiteSuperior=(centroY-rango)>=0 ? centroY-rango : 0;
int limiteInferior=(centroY+rango)<unidad.getJugador().getFortaleza().altoMapa ? centroY+rango : unidad.getJugador().getFortaleza().altoMapa-1;
System.out.println("Turnos siguiendo colector " +((Explorador)unidad).turnosSiguiendoColector);
for (int i = limiteIzquierdo; i<=limiteDerecho;i++ ){
for (int j=limiteSuperior;j<=limiteInferior;j++){
if (unidad.getPosition().distance(new Point(i,j))<=rango){
if(!unidad.getJugador().getFortaleza().isPointAfuera(new Point(i,j))
&& !(i>Fortaleza.fortalezaEnemiga.getPosition().getX()-perimetro
&& i<unidad.getJugador().getFortaleza().fortalezaEnemiga.getPosition().getX()+perimetro
&& j>unidad.getJugador().getFortaleza().fortalezaEnemiga.getPosition().getY()-perimetro
&& j<unidad.getJugador().getFortaleza().fortalezaEnemiga.getPosition().getY()+perimetro)){
MapElement meCandidato= unidad.getJugador().getFortaleza().mapa[i][j];
if(meCandidato!= null && meCandidato.getClass().getName().equals("src.Enemigo")
&& ((Enemigo)meCandidato).getUltimoTurnoVisto()==unidad.getJugador().turno
&& ((Enemigo)meCandidato).getType()==Vision.TYPE_ENEMY_ATTACKER ){
if (Fortaleza.instanciaFortaleza.getEstrategia().getClass().getName().equals("src.estrategias.EstrategiaEquilibrada") && ((EstrategiaEquilibrada)Fortaleza.instanciaFortaleza.getEstrategia()).numeroOleada==1){
((EstrategiaEquilibrada)Fortaleza.instanciaFortaleza.getEstrategia()).numeroOleada=2;
Iterator it=Fortaleza.instanciaFortaleza.unidades.iterator();
while (it.hasNext()){
UnidadBasica ub=(UnidadBasica)it.next();
if (ub.getTipoInternoUnidad()==UnidadBasica.TIPO_ASESINO && ub.getPosition().distance(Fortaleza.fortalezaEnemiga.getPosition())>10)
((Asesino)ub).setEstrategia(new EstrategiaAsesinoColector());
}
}
}
}
}
}
}
for (int i = limiteIzquierdo; i<=limiteDerecho;i++ ){
for (int j=limiteSuperior;j<=limiteInferior;j++){
if (unidad.getPosition().distance(new Point(i,j))<=rango){
if(!unidad.getJugador().getFortaleza().isPointAfuera(new Point(i,j)) && !(i>unidad.getJugador().getFortaleza().fortalezaEnemiga.getPosition().getX()-perimetro && i<unidad.getJugador().getFortaleza().fortalezaEnemiga.getPosition().getX()+perimetro && j>unidad.getJugador().getFortaleza().fortalezaEnemiga.getPosition().getY()-perimetro && j<unidad.getJugador().getFortaleza().fortalezaEnemiga.getPosition().getY()+perimetro)){
MapElement meCandidato= unidad.getJugador().getFortaleza().mapa[i][j];
if(meCandidato!= null && meCandidato.getClass().getName().equals("src.Enemigo")
&& ((Enemigo)meCandidato).getUltimoTurnoVisto()==unidad.getJugador().turno
&& ((Enemigo)meCandidato).getType()==Vision.TYPE_ENEMY_COLLECTOR ){
//
noSirve=false;
Point destino=new Point(i,j);
if (unidad.destino==null || !destino.equals(unidad.destino)){
((Explorador)unidad).turnosSiguiendoColector++;
}
else{
((Explorador)unidad).turnosSiguiendoColector=0;
Iterator itRecursos=unidad.getJugador().getFortaleza().resources.iterator();
noSirve=true;
while (itRecursos.hasNext()){
Mina mina=(Mina)itRecursos.next();
if (mina.getPosition().distance(destino)<=1){
noSirve=false;
break;
}
}
}
if (noSirve)
continue;
unidad.setPeligrosidad(false);
unidad.setDescubir(true);
unidad.setARangoDeAccion(false);
unidad.setWayPoints(Astar.intentoDePathFinding(destino, unidad, unidad.getJugador().getFortaleza()));
unidad.destino=destino;
nuevoComando.setId(unidad.getJugador().getIdComando());
nuevoComando.setIdUnit(unidad.getId());
nuevoComando.setUnitType(unidad.getType());
nuevoComando.setType("move");
nuevoComando.setDestination((Point)unidad.getWayPoints().get(0));
unidad.setCommand(nuevoComando);
return nuevoComando;
}
}
}
}
}
if (noSirve){
for (int i = limiteIzquierdo; i<=limiteDerecho;i++ ){
for (int j=limiteSuperior;j<=limiteInferior;j++){
if (unidad.getPosition().distance(new Point(i,j))<=rango){
if (!unidad.getJugador().getFortaleza().isPointAfuera(new Point(i,j)) && (i>=unidad.getJugador().getFortaleza().fortalezaEnemiga.getPosition().getX()-perimetro && i<=unidad.getJugador().getFortaleza().fortalezaEnemiga.getPosition().getX()+perimetro && j>=unidad.getJugador().getFortaleza().fortalezaEnemiga.getPosition().getY()-perimetro && j<=unidad.getJugador().getFortaleza().fortalezaEnemiga.getPosition().getY()+perimetro)){//adentro del perimetro, espero a que salga
MapElement meCandidato= unidad.getJugador().getFortaleza().mapa[i][j];
if(meCandidato!= null && meCandidato.getClass().getName().equals("src.Enemigo")
&& ((Enemigo)meCandidato).getUltimoTurnoVisto()==unidad.getJugador().turno
&& ((Enemigo)meCandidato).getType()==Vision.TYPE_ENEMY_COLLECTOR
&& ((Explorador)unidad).turnosSiguiendoColector<=Explorador.MAXIMO_TURNOS_SIGUIENDO_EXPLORADOR){
if (!((unidad.getPosition().getX()>unidad.getJugador().getFortaleza().fortalezaEnemiga.getPosition().getX()-perimetro && unidad.getPosition().getX()<unidad.getJugador().getFortaleza().fortalezaEnemiga.getPosition().getX()+perimetro && unidad.getPosition().getY()>unidad.getJugador().getFortaleza().fortalezaEnemiga.getPosition().getY()-perimetro && unidad.getPosition().getY()<unidad.getJugador().getFortaleza().fortalezaEnemiga.getPosition().getY()+perimetro))){
noSirve=false;
((Explorador)unidad).turnosSiguiendoColector++;
nuevoComando=null;
}
}
}
}
}
}
}
if (ampliarPerimetro)
perimetro=perimetro+2;
if (noSirve){
if (((Explorador)unidad).turnosSiguiendoColector>0)
System.out.println("Aborto seguimiento");
((Explorador)unidad).turnosSiguiendoColector=0;
Point centro=unidad.getJugador().getFortaleza().fortalezaEnemiga.getPosition();
nuevoComando=pasearPorPerimetro(unidad,perimetro,perimetro,centro);
}
return nuevoComando;
}
public ClientCommand pasearPorPerimetro(UnidadBasica unidad,int perimetroX,int perimetroY,Point centro){//perimetro de 4 puntos
int perimetroExteriorX=perimetroX;
int perimetroExteriorY=perimetroY;
//int perimetroInterior=9;
boolean afuera=true;
Point destino=null;
int centroX=centro.getX();
int centroY=centro.getY();
if (waypoints.size()==0 ||( ((Point)waypoints.get(0)).getX()-centroX<perimetroX && ((Point)waypoints.get(0)).getY()-centroY<perimetroY)) {
waypoints.clear();
orden=-1;
// Arma los punto. El -5 es porque no tiene sentido que pase tan cerca del borde, le da un margen
int limiteIzquierdo=(centroX-perimetroExteriorX)>=0 ? centroX-perimetroExteriorX : 0;
int limiteDerecho=(centroX+perimetroExteriorX)<unidad.getJugador().getFortaleza().anchoMapa-5 ? centroX+perimetroExteriorX : unidad.getJugador().getFortaleza().anchoMapa-1;
int limiteSuperior=(centroY-perimetroExteriorY)>=0 ? centroY-perimetroExteriorY : 0;
int limiteInferior=(centroY+perimetroExteriorY)<unidad.getJugador().getFortaleza().altoMapa-5 ? centroY+perimetroExteriorY : unidad.getJugador().getFortaleza().altoMapa-1;
Point waypoint1=new Point (limiteDerecho,limiteSuperior);
Point waypoint2=new Point (limiteDerecho,limiteInferior);
Point waypoint3=new Point (limiteIzquierdo,limiteInferior);
Point waypoint4=new Point (limiteIzquierdo,limiteSuperior);
//Chequeo para ver si algun way queda afuera, si es una esquina me quedan solo 3 ways
if (Math.abs(waypoint1.getX()-centroX)==perimetroExteriorX || Math.abs(waypoint1.getY()-centroY)==perimetroExteriorY)
waypoints.add(waypoint1);
if (Math.abs(waypoint2.getX()-centroX)==perimetroExteriorX || Math.abs(waypoint2.getY()-centroY)==perimetroExteriorY)
waypoints.add(waypoint2);
if (Math.abs(waypoint3.getX()-centroX)==perimetroExteriorX || Math.abs(waypoint3.getY()-centroY)==perimetroExteriorY)
waypoints.add(waypoint3);
if (Math.abs(waypoint4.getX()-centroX)==perimetroExteriorX || Math.abs(waypoint4.getY()-centroY)==perimetroExteriorY)
waypoints.add(waypoint4);
//armo la secuencia de los ways
if (waypoints.size()==3){
//el 0 es el del medio
if ((((Point)waypoints.get(0)).getX() == ((Point)waypoints.get(1)).getX() && ((Point)waypoints.get(0)).getY() == ((Point)waypoints.get(2)).getY())
|| (((Point)waypoints.get(0)).getX() == ((Point)waypoints.get(2)).getX() && ((Point)waypoints.get(0)).getY() == ((Point)waypoints.get(1)).getY())){
Point punto=(Point)waypoints.remove(0);
waypoints.add(1,punto);
waypoints.add(punto);
}
//el 1 es el del medio
if ((((Point)waypoints.get(1)).getX() == ((Point)waypoints.get(2)).getX() && ((Point)waypoints.get(1)).getY() == ((Point)waypoints.get(0)).getY())
|| (((Point)waypoints.get(1)).getX() == ((Point)waypoints.get(0)).getX() && ((Point)waypoints.get(1)).getY() == ((Point)waypoints.get(2)).getY())){
Point punto=(Point)waypoints.remove(1);
waypoints.add(1,punto);
waypoints.add(punto);
}
//el 2 es el del medio
if ((((Point)waypoints.get(2)).getX() == ((Point)waypoints.get(0)).getX() && ((Point)waypoints.get(2)).getY() == ((Point)waypoints.get(1)).getY())
|| (((Point)waypoints.get(2)).getX() == ((Point)waypoints.get(1)).getX() && ((Point)waypoints.get(2)).getY() == ((Point)waypoints.get(0)).getY())){
Point punto=(Point)waypoints.remove(2);
waypoints.add(1,punto);
waypoints.add(punto);
}
}
else{
//armo la secuencia de los ways
if (limiteIzquierdo!=centroX-perimetroExteriorX){
//orden de los way
//123214
waypoints.add(3,waypoints.get(0));
waypoints.add(3,waypoints.get(1));
}
if (limiteDerecho!=centroX+perimetroExteriorX){
//143234
waypoints.add(1,waypoints.get(waypoints.size()-2));
waypoints.add(1,waypoints.get(waypoints.size()-1));
}
if (limiteSuperior!=centroY-perimetroExteriorY){
//123432
waypoints.add(waypoints.get(2));
waypoints.add(waypoints.get(1));
}
if (limiteInferior!=centroY+perimetroExteriorY){
//121434
waypoints.add(2,waypoints.get(waypoints.size()-1));
waypoints.add(2,waypoints.get(0));
}
}
Iterator it=waypoints.iterator();
while (it.hasNext()){
Point punto=(Point)it.next();
if (destino==null || punto.distance(unidad.getPosition())<destino.distance(unidad.getPosition())){
destino=punto;
}
}
unidad.destino=destino;
}
if (unidad.getWayPoints()==null || unidad.getWayPoints().size()==0 || !Astar.verificarCamino(unidad)){
Iterator it=waypoints.iterator();
while (it.hasNext()){
Point punto=(Point)it.next();
if (destino==null || punto.distance(unidad.getPosition())<destino.distance(unidad.getPosition())){
destino=punto;
}
}
if (orden<0 && destino.distance(unidad.getPosition())<3){
orden=waypoints.indexOf(destino);
}
unidad.destino=destino;
if (orden>=0){
if (destino.distance(unidad.getPosition())<3){
orden++;
orden=orden%waypoints.size();
destino=(Point)waypoints.get(orden);
unidad.destino=destino;
}
destino=(Point)waypoints.get(orden);
unidad.destino=destino;
}
if (orden==0){
if (((Explorador)unidad).turnoInicioPerimetro!=0){
int actividadActual=0;
for (int i=Fortaleza.fortalezaEnemiga.getPosition().getX()-EstrategiaExploradorAcecharColector.perimetro;i<=Fortaleza.fortalezaEnemiga.getPosition().getX()+EstrategiaExploradorAcecharColector.perimetro;i++){
for (int j=Fortaleza.fortalezaEnemiga.getPosition().getY()-EstrategiaExploradorAcecharColector.perimetro;j<=Fortaleza.fortalezaEnemiga.getPosition().getY()+EstrategiaExploradorAcecharColector.perimetro;j++){
if (!Fortaleza.isPointAfuera(new Point(i,j))
&& Fortaleza.mapa[i][j]!=null
&& Fortaleza.mapa[i][j].getClass().getName().equals("src.Enemigo")
&& Fortaleza.mapa[i][j].getType()==Vision.TYPE_ENEMY_ATTACKER
&& ((Enemigo)Fortaleza.mapa[i][j]).getUltimoTurnoVisto()>((Explorador)unidad).turnoInicioPerimetro){
actividadActual++;
}
}
}
if (cantidadActividad!=0 && cantidadActividad>6 && actividadActual*100/cantidadActividad<40){//disparo emergencia
Fortaleza.instanciaFortaleza.setEstrategia(new EstrategiaEmergencia(Fortaleza.instanciaFortaleza.unidades, Fortaleza.instanciaFortaleza.getEstrategia()));
}
((Explorador)unidad).turnoInicioPerimetro=Cliente.turno;
perimetro=Math.max(6, perimetro-2);
}
((Explorador)unidad).turnoInicioPerimetro=Cliente.turno;
}
unidad.setPeligrosidad(false);
unidad.setDescubir(false);
unidad.setARangoDeAccion(false);
unidad.setWayPoints(Astar.intentoDePathFinding(unidad.destino, unidad, unidad.getJugador().getFortaleza()));
unidad.destino=unidad.destino;
}
ClientCommand nuevoComando=new ClientCommand();
nuevoComando.setId(unidad.getJugador().getIdComando());
nuevoComando.setIdUnit(unidad.getId());
nuevoComando.setType("move");
nuevoComando.setDestination((Point)unidad.getWayPoints().get(0));
nuevoComando.setUnitType(unidad.getType());
unidad.setCommand(nuevoComando);
return nuevoComando;
}
public int getCantidadActividad() {
return cantidadActividad;
}
public void setCantidadActividad(int cantidadActividad) {
this.cantidadActividad = cantidadActividad;
}
}