package src.estrategias;
import java.util.*;
import src.*;
import src.estadisticas.*;
import com.gameloftProgrammersCup.client.ClientCommand;
import com.gameloftProgrammersCup.clientInterfaces.BasicPJ;
import com.gameloftProgrammersCup.clientInterfaces.Command;
import com.gameloftProgrammersCup.clientInterfaces.MapElement;
import com.gameloftProgrammersCup.clientInterfaces.Point;
import com.gameloftProgrammersCup.*;
import com.gameloftProgrammersCup.clientInterfaces.*;
/**
* @override
* @author puppeteer
*
*/
public class EstrategiaEquilibrada extends EstrategiaGeneral{
//proporciones de creaci�n sobre 100
private final int PORC_EXPLORADOR = 5;
private final int PORC_COLECTOR = 30;
private final int PORC_GUARDIA = 35;
private final int PORC_ASESINO = 30;
private final int PORC_OPTIMO = 10;//se calcula que unidad esta produciendo m�s
private final int PORC_GUARDIAS_FIJOS = 40;
private final int PORC_GUARDIAS_PATRULLANDO = 25;
private final int PORC_GUARDIAS_PERIMETREANDO = 20;
//private final int PORC_GUARDIAS_PERIMETREANDO = 0;
private final int PORC_GUARDIAS_MINEROS = 15;
private int radioSeguridadTurnoAnterior = 0;
public int numeroOleada=1;
private boolean ataqueEnCurso=false;
private int unidadACrear = -1;//para acordarme en el ciclo siguiente
public EstrategiaEquilibrada(List unidades){
super(unidades);
}
public void actualizarEstrategias(List listaUnidades, src.estadisticas.Estadisticas estadisticas){
if (Cliente.turno>300 && Fortaleza.fortalezaEnemiga.salud<Fortaleza.instanciaFortaleza.vidaInicial*80/100)
Fortaleza.instanciaFortaleza.setEstrategia(new EstrategiaAtaqueEnPatota(listaUnidades));
if(hayAtaqueMasivoNOW())
{
if ((Fortaleza.instanciaFortaleza.getJugador().turno - ultimoTurnoDetecctionAtaqueMasivo)< 15)
{
Fortaleza.instanciaFortaleza.setEstrategia(new EstrategiaEmergencia(Fortaleza.instanciaFortaleza.unidades,this));
return;
}
else
ultimoTurnoDetecctionAtaqueMasivo = Fortaleza.instanciaFortaleza.getJugador().turno;
}
if (Cliente.turno>0 && Cliente.turno%5==0)//cada 5 turnos
Guardia.setRiesgoAtaqueMasivo(evaluarRiesgoAtaqueMasivo());
//chequeo enemigos cerca
Enemigo enemigoAcechando=chequearEnemigosEnRangoSeguridad();
if (enemigoAcechando!=null)
{
if (!hayEnemigosEnRangoSeguridad)
{
hayEnemigosEnRangoSeguridad = true;
dirigirDefensasAEnemigo(enemigoAcechando);
}
}
else //no hay moros
{
if(hayEnemigosEnRangoSeguridad)//si antes hab�a... tengo que volver todo a la normalidad
{
nullearEstrategiasGuardias();
hayEnemigosEnRangoSeguridad = false;
}
}
Iterator it = listaUnidades.iterator();
while(it.hasNext())
{
UnidadBasica unidad=(UnidadBasica)it.next();
if(unidad.getTipoInternoUnidad()==UnidadBasica.TIPO_GUARDIA)
actualizarUnidad((Guardia)unidad);
else if(unidad.getTipoInternoUnidad()==UnidadBasica.TIPO_ASESINO)
actualizarUnidad((Asesino)unidad);
else if(unidad.getTipoInternoUnidad()==UnidadBasica.TIPO_COLECTORINICIAL)
actualizarUnidad((ColectorInicial)unidad);
else if(unidad.getTipoInternoUnidad()==UnidadBasica.TIPO_COLECTORNORMAL)
actualizarUnidad((ColectorNormal)unidad);
else if(unidad.getTipoInternoUnidad()==UnidadBasica.TIPO_EXPLORADOR)
actualizarUnidad((Explorador)unidad);
else
System.out.println("ERROR: unidad no procesable");
}
}
/**
* @overrride
* Decide qu� unidad fabricar a continuacion, lleva a cabo la accion y devuelve el comando
* @param f
* @return comando a llevar a cabo
* @author Fernando Rivas @version 1.0
*/
static boolean inversionCreacion = false;
public ClientCommand fabricarUnidad(Fortaleza f ){
int iUnidadElegida = -1;
if(f.getUnidadesSize()<4)
{
iUnidadElegida =f.getUnidadesSize();//estan numeradas por orden de creacion en las constantes, 0 es la que se crea primero si size es cero
if((f.getUnidadesSize()==2) && chequearEnemigosEnRangoSeguridad()==null)
{
inversionCreacion = true;
iUnidadElegida = UnidadBasica.TIPO_ASESINO;
}
else if(f.getUnidadesSize()==2)
inversionCreacion = false;
if(f.getUnidadesSize()==3 && inversionCreacion)
iUnidadElegida = UnidadBasica.TIPO_GUARDIA;
}
else //decidir
{
int[] iaCantidades=f.cantidadesUnidades();
//random a ver si sale optimo
if (Math.random()*100 < PORC_OPTIMO)
iUnidadElegida = Estadisticas.getUnidadOptima();
//chequeo porcentajes
else if(((iaCantidades[UnidadBasica.TIPO_COLECTORNORMAL]+iaCantidades[UnidadBasica.TIPO_COLECTORINICIAL])* 100/f.getUnidadesSize()) <=PORC_COLECTOR)
iUnidadElegida=UnidadBasica.TIPO_COLECTORNORMAL;
else if (iaCantidades[UnidadBasica.TIPO_EXPLORADOR ]* 100/f.getUnidadesSize()<=PORC_EXPLORADOR)
iUnidadElegida=UnidadBasica.TIPO_EXPLORADOR;
else if (iaCantidades[UnidadBasica.TIPO_GUARDIA ]* 100/f.getUnidadesSize()<=PORC_GUARDIA)
iUnidadElegida=UnidadBasica.TIPO_GUARDIA;
else if (iaCantidades[UnidadBasica.TIPO_ASESINO]* 100/f.getUnidadesSize()<=PORC_ASESINO)
iUnidadElegida=UnidadBasica.TIPO_ASESINO;
}
unidadACrear = iUnidadElegida;
//creo comando y seteo segun unidad
ClientCommand nuevoComando=new ClientCommand();
f.getJugador().incIdComando();
nuevoComando.setId(f.getJugador().getIdComando()+1);
switch(iUnidadElegida){
case UnidadBasica.TIPO_ASESINO:
f.unidadACrear = new Asesino(f.getTroopId(), f.getJugador(),new EstrategiaAsesinoColector());
nuevoComando.setIdUnit(f.getTroopId());
nuevoComando.setType("create");
nuevoComando.setDestination(f.getPosition());
nuevoComando.setLife(Asesino.ASESINO_LIFE);
nuevoComando.setActionRange(Asesino.ASESINO_ACTIONRANGE);
nuevoComando.setActionSpeed(Asesino.ASESINO_ACTIONSPEED);
nuevoComando.setMovementSpeed(Asesino.ASESINO_MOVEMENTSPEED);
nuevoComando.setViewRange(Asesino.ASESINO_VIEWRANGE);
nuevoComando.setUnitType(BasicPJ.TYPE_ATTACKER);
break;
case UnidadBasica.TIPO_COLECTORINICIAL:
f.unidadACrear = new ColectorInicial(f.getTroopId(), f.getJugador(),new EstrategiaColectorNormal());
nuevoComando.setIdUnit(f.getTroopId());
nuevoComando.setType("create");
nuevoComando.setDestination(f.getPosition());
nuevoComando.setLife(ColectorInicial.COLECTOR_LIFE);
nuevoComando.setActionRange(ColectorInicial.COLECTOR_ACTIONRANGE);
nuevoComando.setActionSpeed(ColectorInicial.COLECTOR_ACTIONSPEED);
nuevoComando.setMovementSpeed(ColectorInicial.COLECTOR_MOVEMENTSPEED);
nuevoComando.setViewRange(ColectorInicial.COLECTOR_VIEWRANGE);
nuevoComando.setMaxCarry(ColectorInicial.COLECTORINICIAL_MAXPAYLOAD);
nuevoComando.setUnitType(BasicPJ.TYPE_COLLECTOR);
break;
case UnidadBasica.TIPO_EXPLORADOR:
f.unidadACrear = new Explorador(f.getTroopId(), f.getJugador(),new EstrategiaExplorador());
nuevoComando.setIdUnit(f.getTroopId());
nuevoComando.setType("create");
nuevoComando.setDestination(f.getPosition());
nuevoComando.setLife(Explorador.EXPLORADOR_LIFE );
nuevoComando.setActionRange(Explorador.EXPLORADOR_ACTIONRANGE);
nuevoComando.setActionSpeed(Explorador.EXPLORADOR_ACTIONSPEED);
nuevoComando.setMovementSpeed(Explorador.EXPLORADOR_MOVEMENTSPEED);
nuevoComando.setViewRange(Explorador.EXPLORADOR_VIEWRANGE);
nuevoComando.setMaxCarry(Explorador.EXPLORADOR_MAXPAYLOAD);
nuevoComando.setUnitType(BasicPJ.TYPE_COLLECTOR);
break;
case UnidadBasica.TIPO_GUARDIA:
f.unidadACrear = new Guardia(f.getTroopId(), f.getJugador(),null);
nuevoComando.setIdUnit(f.getTroopId());
nuevoComando.setType("create");
nuevoComando.setDestination(f.getPosition());
nuevoComando.setLife(Guardia.GUARDIA_LIFE);
nuevoComando.setActionRange(Guardia.GUARDIA_ACTIONRANGE);
nuevoComando.setActionSpeed(Guardia.GUARDIA_ACTIONSPEED);
nuevoComando.setMovementSpeed(Guardia.GUARDIA_MOVEMENTSPEED);
nuevoComando.setViewRange(Guardia.GUARDIA_VIEWRANGE);
nuevoComando.setUnitType(BasicPJ.TYPE_ATTACKER);
break;
case UnidadBasica.TIPO_COLECTORNORMAL:
f.unidadACrear = new ColectorNormal(f.getTroopId(), f.getJugador(),new EstrategiaColectorNormal());
nuevoComando.setIdUnit(f.getTroopId());
nuevoComando.setType("create");
nuevoComando.setDestination(f.getPosition());
nuevoComando.setLife(ColectorNormal.COLECTOR_LIFE);
nuevoComando.setActionRange(ColectorNormal.COLECTOR_ACTIONRANGE);
nuevoComando.setActionSpeed(ColectorNormal.COLECTOR_ACTIONSPEED);
nuevoComando.setMovementSpeed(ColectorNormal.COLECTOR_MOVEMENTSPEED);
nuevoComando.setViewRange(ColectorNormal.COLECTOR_VIEWRANGE);
nuevoComando.setMaxCarry(ColectorNormal.COLECTOR_MAXPAYLOAD);
nuevoComando.setUnitType(BasicPJ.TYPE_COLLECTOR);
break;
}
return nuevoComando;
}
public void setearEstrategiaUnidad(UnidadBasica ub){/*TODO!*/}
/**
* calcula distancias entre ataques. intenta determinar si el enemigo est� concentrado
*
*/
public int evaluarRiesgoAtaqueMasivo(){
/* if (Fortaleza.fortalezaEnemiga == null)
return 0;//no se va a poder evaluar, me temo ( a menos que haga fortaleza estimada)*/
int iCantidadAtaques =0;
int iSumatoriaDistancias = 0;
List <Point> nodosAtacados = new ArrayList();
for(int x=0;x<Fortaleza.anchoMapa;x++)
{for(int y=0;y<Fortaleza.altoMapa;y++)
{ int q = Estadisticas.mapaEstadistico[x][y].getCantidadAtaques();
if (q>0)
{//hubo ataques
iCantidadAtaques += q;
Iterator it = nodosAtacados.iterator();
Point actual = new Point(x,y);
while(it.hasNext())
{
Point anterior=(Point)it.next();
iSumatoriaDistancias+=anterior.distance(actual);
}
nodosAtacados.add(actual);
}
}//for
}
return iSumatoriaDistancias / factorial(iCantidadAtaques);
}
/**
* s�, estoy loco.
* @param i
* @return
*/
public int factorial(int i){
if (i==0) return 1;
else return (factorial(i-1)+i);
}
/**
* el nombre lo dice todo. sirve para guardias
*/
public Point getPosicionMasPeligrosaEnRangoSeguridad(){
int maxPuntosEvaluados = 5;
Point [] listaMaxPuntos= new Point[maxPuntosEvaluados];//candidatos, necesito varios por las dudas que la casilla est� ocupada
for(int y=Fortaleza.instanciaFortaleza.getPosition().getY()-Fortaleza.instanciaFortaleza.getRadioSeguridad();y<=Fortaleza.instanciaFortaleza.getPosition().getY()+Fortaleza.instanciaFortaleza.getRadioSeguridad();y++)
{
for(int x= Fortaleza.instanciaFortaleza.getPosition().getX()-Fortaleza.instanciaFortaleza.getRadioSeguridad();x<=Fortaleza.instanciaFortaleza.getPosition().getX()+Fortaleza.instanciaFortaleza.getRadioSeguridad();x++)
{
Point pEvaluado = new Point(x,y);
if(!Fortaleza.isPointAfuera(pEvaluado)&& pEvaluado.distance(Fortaleza.instanciaFortaleza.getPosition())<=Fortaleza.instanciaFortaleza.getRadioSeguridad())
{
/*MapElement meEvaluado = Fortaleza.getElementoMapaEnPosicion(pEvaluado);
if (meEvaluado != null && meEvaluado.getClass().getName().equals("src.Enemigo") && ((Enemigo)meEvaluado).getUltimoTurnoVisto()==Fortaleza.instanciaFortaleza.getJugador().turno )
return (Enemigo)meEvaluado;*/
for(int i=0;i<maxPuntosEvaluados;i++)
{
if(listaMaxPuntos[i]==null)
{
listaMaxPuntos[i] = pEvaluado;
break;
}
else if (Estadisticas.mapaEstadistico[listaMaxPuntos[i].getX()][listaMaxPuntos[i].getY()].getPeligrosidad()< Estadisticas.mapaEstadistico[pEvaluado.getX()][pEvaluado.getY()].getPeligrosidad())
{
listaMaxPuntos[i] = pEvaluado;
break;
}
}
}
}
}
/* prefiero que randomice entre el top 5 for(int i=0;i<maxPuntosEvaluados;i++)
{
if (Fortaleza.getElementoMapaEnPosicion(listaMaxPuntos[i])== null ||
((Fortaleza.getElementoMapaEnPosicion(listaMaxPuntos[i]).getClass().equals(Enemigo.class)
&& ((Enemigo)Fortaleza.getElementoMapaEnPosicion(listaMaxPuntos[i])).getUltimoTurnoVisto() != Fortaleza.instanciaFortaleza.getJugador().turno))
)
return listaMaxPuntos[i];
}*/
//bue, si no te gusta ninguna, agarr� cualquiera nom�s
return listaMaxPuntos[(int)((Math.round(Math.random()*100))%5)];
}
/**
* @override
*/
public void actualizarUnidad(Guardia guardia){
// me tengo que fijar si subio el radio de seguridad, tengo que resetear al que anda por el perimetro
if(guardia.getEstrategia()!= null && guardia.getEstrategia().getClass().equals(EstrategiaGuardiaPerimetreando.class))
if(Fortaleza.instanciaFortaleza.getRadioSeguridad()!=radioSeguridadTurnoAnterior)
guardia.setEstrategia(new EstrategiaGuardiaPerimetreando());
radioSeguridadTurnoAnterior = Fortaleza.instanciaFortaleza.getRadioSeguridad();
if (guardia.getEstrategia() == null)
{//calculo:
double iRand = (Math.random()*100);
if(iRand < PORC_GUARDIAS_PERIMETREANDO)
{
guardia.setEstrategia(new EstrategiaGuardiaPerimetreando());
}
else if(iRand < PORC_GUARDIAS_PERIMETREANDO + PORC_GUARDIAS_PATRULLANDO)
guardia.setEstrategia(new EstrategiaGuardiaPatrullando());
else if (iRand < PORC_GUARDIAS_PERIMETREANDO + PORC_GUARDIAS_PATRULLANDO + PORC_GUARDIAS_MINEROS)
guardia.setEstrategia(new EstrategiaGuardiaMinero(guardia));
else //c
guardia.setEstrategia(new EstrategiaGuardianFijo(getPosicionMasPeligrosaEnRangoSeguridad(), guardia));
}
}
public void actualizarUnidad(Asesino asesino){
Fortaleza fortaleza=Fortaleza.instanciaFortaleza;
Iterator it= fortaleza.unidades.iterator();
int cantidadAsesinos=0;
if (asesino.getEstrategia() == null)
asesino.setEstrategia(new EstrategiaAsesinoColector());
while (it.hasNext()){
UnidadBasica unidad =(UnidadBasica)it.next();
if (unidad.getTipoInternoUnidad()==UnidadBasica.TIPO_ASESINO){
cantidadAsesinos++;
}
}
it= fortaleza.unidades.iterator();
int cantidadAtacantes=0;
while (it.hasNext()){
UnidadBasica unidad =(UnidadBasica)it.next();
if (unidad.getTipoInternoUnidad()==UnidadBasica.TIPO_ASESINO && asesino.getEstrategia().getClass().getName().equals("src.estrategias.EstrategiaAsesinoFortaleza")){
cantidadAtacantes++;
}
}
if (!ataqueEnCurso && !(cantidadAtacantes<numeroOleada*3-2)){
ataqueEnCurso=true;
}
if (ataqueEnCurso && cantidadAtacantes==0){
ataqueEnCurso=false;
numeroOleada++;
}
if (cantidadAsesinos<numeroOleada*3-2 && !ataqueEnCurso)
asesino.setEstrategia(new EstrategiaAsesinoColector());
else if (!(cantidadAsesinos<numeroOleada*3-2) && !ataqueEnCurso)
asesino.setEstrategia(new EstrategiaAsesinoFortaleza());
}
public void actualizarUnidad(ColectorInicial colector){
if(colector.getEstrategia()== null)
colector.setEstrategiaUnidad(new EstrategiaColectorNormal());
Fortaleza fortaleza=Fortaleza.instanciaFortaleza;
Iterator it= fortaleza.getKnownResources().iterator();
int cantidadMinasActivas=0;
while (it.hasNext()){
Mina mina =(Mina)it.next();
if ((mina.resourcesStored()<fortaleza.resourcesPayload || fortaleza.resourcesPayload==0) && !mina.isMaxedOut()){
cantidadMinasActivas++;
}
}
int cantidadPuntosNoDescubiertos=0;
for (int i = 0; i<fortaleza.anchoMapa;i++ ){
for (int j=0;j<fortaleza.altoMapa;j++){
if (!fortaleza.estadisticas.mapaEstadistico[i][j].isDescubierto())
cantidadPuntosNoDescubiertos++;
}
}
if (cantidadMinasActivas<1 && cantidadPuntosNoDescubiertos>0)
colector.setEstrategia(new EstrategiaExploracionEspiral());
else
colector.setEstrategia(new EstrategiaColectorNormal());
}
public void actualizarUnidad(ColectorNormal colector){
if(colector.getEstrategia()== null)
colector.setEstrategiaUnidad(new EstrategiaColectorNormal());
Fortaleza fortaleza=Fortaleza.instanciaFortaleza;
Iterator it= fortaleza.getKnownResources().iterator();
int cantidadMinasActivas=0;
while (it.hasNext()){
Mina mina =(Mina)it.next();
if ((mina.resourcesStored()<fortaleza.resourcesPayload || fortaleza.resourcesPayload==0) && !mina.isMaxedOut()){
cantidadMinasActivas++;
}
}
int cantidadPuntosNoDescubiertos=0;
for (int i = 0; i<fortaleza.anchoMapa;i++ ){
for (int j=0;j<fortaleza.altoMapa;j++){
if (!fortaleza.estadisticas.mapaEstadistico[i][j].isDescubierto())
cantidadPuntosNoDescubiertos++;
}
}
if (cantidadMinasActivas<1 && cantidadPuntosNoDescubiertos>0)
colector.setEstrategia(new EstrategiaExploracionEspiral());
else
colector.setEstrategia(new EstrategiaColectorNormal());
}
public void actualizarUnidad(Explorador explorador){
if(explorador.getEstrategia()== null)
explorador.setEstrategiaUnidad(new EstrategiaExploradorAcecharColector());
Fortaleza fortaleza=Fortaleza.instanciaFortaleza;
Iterator it= fortaleza.getKnownResources().iterator();
int cantidadMinasActivas=0;
while (it.hasNext()){
Mina mina =(Mina)it.next();
if (mina.resourcesStored()<fortaleza.resourcesPayload || fortaleza.resourcesPayload==0){
cantidadMinasActivas++;
}
}
int cantidadPuntosNoDescubiertos=0;
for (int i = 0; i<fortaleza.anchoMapa;i++ ){
for (int j=0;j<fortaleza.altoMapa;j++){
if (!fortaleza.estadisticas.mapaEstadistico[i][j].isDescubierto())
cantidadPuntosNoDescubiertos++;
}
}
it= fortaleza.unidades.iterator();
int acechador=0;
while (it.hasNext()){
UnidadBasica unidad =(UnidadBasica)it.next();
if (unidad.getTipoInternoUnidad()==UnidadBasica.TIPO_EXPLORADOR && ((Explorador)unidad).getEstrategia().getClass().getName().equals("src.estrategias.EstrategiaExploradorAcecharColector")){
acechador++;
}
}
if (!explorador.getEstrategia().getClass().getName().equals("src.estrategias.EstrategiaExploradorAcecharColector")){
if ((cantidadMinasActivas<3 || acechador>0) && cantidadPuntosNoDescubiertos>0 )
explorador.setEstrategia(new EstrategiaExploracionEspiral());
else if (fortaleza.fortalezaEnemiga==null)
explorador.setEstrategia(new EstrategiaExplorador());
else
explorador.setEstrategia(new EstrategiaExploradorAcecharColector());
}
}
/**
* setea todos los guardias a estrategia de guardia est�tico con objetivo en el enemigo
*
*/
public void dirigirDefensasAEnemigo(Enemigo e){
Iterator it = Fortaleza.instanciaFortaleza.unidades.iterator();
while(it.hasNext())
{
Object oCandidato= it.next();
if (oCandidato.getClass().equals(Guardia.class))
((Guardia)oCandidato).setEstrategiaUnidad(new EstrategiaGuardianFijo(e.getPosition(),(Guardia)oCandidato));
}
}
/**
* esto sirve para resetear estrategias
*
*/
public void nullearEstrategiasGuardias(){
Iterator it = Fortaleza.instanciaFortaleza.unidades.iterator();
while(it.hasNext())
{
Object oCandidato= it.next();
if (oCandidato.getClass().equals(Guardia.class))
((Guardia)oCandidato).setEstrategiaUnidad(null);
}
}
}