Código: Seleccionar todo
// Motor4.cpp: archivo de implementación
//
#include "stdafx.h"
#include "ogArenaMonitor.h"
#include "Motor4.h"
// CMotor
CMotor4::CMotor4()
{
}
CMotor4::~CMotor4()
{
if (m_pFuegoRapido) {
for (int i=0;i<300;i++) if (m_pFuegoRapido[i]) free(m_pFuegoRapido[i]);
free(m_pFuegoRapido);
}
if (m_costes) free(m_costes);
}
int orden4(const void *na, const void *nb)
{
const TNave *a,*b;
a=(const TNave *)na;
b=(const TNave *)nb;
if (!a->nGrupo) return b->nGrupo ? 1:0;
if (a->rondaMuerta!=b->rondaMuerta) return (a->rondaMuerta > b->rondaMuerta) ? -1:1;
if (a->capturada!=b->capturada) return (a->capturada<b->capturada) ? -1:1;
if (a->blindaje!=b->blindaje) return (a->blindaje<b->blindaje) ? -1:1;
if (a->escudo!=b->escudo) return (a->escudo<b->escudo) ? -1:1;
return 0;
}
int ordenIndice(const void *na, const void *nb)
{
const TIndiceGrupos *a,*b;
a=(const TIndiceGrupos *)na;
b=(const TIndiceGrupos *)nb;
if (a->capturada!=b->capturada) return (a->capturada<b->capturada) ? -1:1;
if (a->blindaje!=b->blindaje) return (a->blindaje<b->blindaje) ? -1:1;
if (a->escudo!=b->escudo) return (a->escudo<b->escudo) ? -1:1;
return 0;
}
int checkIndex(TIndiceGrupos *base,int nGrupos,TNave *grupos)
{
#ifdef _DEBUG
int i;
TNave *n;
for (i=0;i<nGrupos;i++) {
if (i) ASSERT(ordenIndice(base+i-1,base+i)<=0);
ASSERT(base[i].grupo>=0);
// ASSERT(base[i].grupo<nGrupos); -- No es correcto, no se trata del mismo contador
n=grupos+base[i].grupo;
if (base[i].capturada!=-1) { // Flag grupo muerto antes
ASSERT( n->escudo==base[i].escudo);
ASSERT( n->blindaje==base[i].blindaje);
ASSERT( n->capturada==base[i].capturada);
}
}
return 1;
#else
return 1;
#endif
}
int buscaIndiceGrupos(TIndiceGrupos *base,int nGrupos,int capturada,int escudo,int blindaje,int buscar,int numGrupo=-1)
{
TIndiceGrupos test;
int inf,sup,centro,comp;
TIndiceGrupos *p;
test.capturada=capturada;
test.escudo=escudo;
test.blindaje=blindaje;
inf=0;
sup=nGrupos-1;
while (inf<=sup) {
centro=(inf+sup)/2;
p=&base[centro];
comp=ordenIndice(&test,p);
if (!comp) { // Encontrado valor
if (numGrupo==-1) return centro;
inf=centro; // si se busca grupo concreto buscar atras y alante
while (true) {
if (base[inf].grupo==numGrupo) return inf;
if (!inf) break;
inf--;
if (ordenIndice(&test,&base[inf])) break;
}
sup=centro;
while (true) {
sup++;
if (sup>=nGrupos) break;
if (ordenIndice(&test,&base[sup])) break;
if (base[sup].grupo==numGrupo) return sup;
}
return -1;
}
if (comp<0) sup=centro-1;
else inf=centro+1;
}
if (buscar==0) return -1;
if (comp<0) return centro; // test es menor que centro, almacenar en centro
return centro+1; // test es mayor que centro, devolver siguiente
}
void moveIndex(TIndiceGrupos *base,int nGrupos,int lPos,int newPos)
{
TIndiceGrupos t;
ASSERT(lPos>=0);
ASSERT(newPos>=0);
if (lPos==newPos) return;
memcpy(&t,base+lPos,sizeof(TIndiceGrupos));
if (newPos>lPos) {
memcpy(base+lPos,base+lPos+1,sizeof(TIndiceGrupos)*(newPos-lPos));
} else if (newPos<lPos) {
memcpy(base+newPos+1,base+newPos,sizeof(TIndiceGrupos)*(lPos-newPos));
}
memcpy(base+newPos,&t,sizeof(TIndiceGrupos));
}
void CMotor4::batallar(CString &txt)
{
CString reporte,tS;
int i,j,iFlota,iLin,m,n,nToks,gid,bando,nFlotas;
__int64 navesA,navesD;
int soloSondas=1,numSondasA=0,bEstampadaSondas=0; // Comprobacion rápida solosondas && numFR>numSondas->muerte directa
__int64 numFRASondas=0;
int talismanes;
__int64 escombros1pc;
DWORD inicio,fin;
unsigned int seed;
inicio=GetTickCount();
seed=(unsigned int)inicio;
tS.Format("srand(%u)",seed);
log(tS);
srand(seed);
#ifdef _DEBUG
srand(44505125);
#endif
m_perdidas[0]=0;
m_perdidas[1]=0;
m_escombros[0] =m_escombros[1]=0;
CString *toks=split("|",txt,n);
ASSERT(n>6);
CString batCP=toks[1];
CString batCoords=toks[2];
int idF=atoi(toks[3]);
m_defEscombros=atof(toks[4]);
m_porcEscombros=atof(toks[5]);
int lunable=atoi(toks[6]);
escombros1pc=_atoi64(toks[7]);
if (n>8) talismanes=atoi(toks[8]);
else talismanes=0;
delete []toks;
toks=split("|-|",txt,n);
CString t=toks[1];
delete []toks;
CString *flotaStr=split("||",t,nFlotas);
m_flotas[0]=new TFlotas[nFlotas]; m_flotas[1]=new TFlotas[nFlotas];
time_t ahora; time(&ahora); reporte.Format("%li",ahora);
m_totNaves=0;
navesA=navesD=0;
m_nFlotas[0]=m_nFlotas[1]=0;
// comprobar muerte de sondas
for (iFlota=0;iFlota<nFlotas;iFlota++) {
toks=split("|",flotaStr[iFlota],nToks);
bando=toks[0]=='A' ? 0:1;
for (n=10;n<nToks-3;n+=5) {
j=atoi(toks[n]); // gid
i=atoi(toks[n+1]); // cant
if (!bando) {
if (j!=210) soloSondas=0;
else numSondasA+=i;
}
if (!soloSondas) break;
if (bando) {
if (m_pFuegoRapido[j-200])
numFRASondas+=(__int64)i*m_pFuegoRapido[j-200][210-200];
}
}
delete []toks;
}
bEstampadaSondas=soloSondas && numFRASondas>numSondasA;
// Crear flotas y grupos de naves
for (iFlota=0;iFlota<nFlotas;iFlota++) {
toks=split("|",flotaStr[iFlota],nToks);
bando=toks[0]=='A' ? 0:1;
for (n=10;n<nToks-3;n+=5) {
i=atoi(toks[n+1]);
m_totNaves+=i;
if (!bando) navesA+=i;
else navesD+=i;
}
delete []toks;
}
m_batDivisor=1;
while (m_totNaves>10000000 && navesA>100000 && navesD>100000) {
m_batDivisor*=2;
m_totNaves/=2; navesA/=2; navesD/=2;
}
m_totNaves=0; navesA=0; navesD=0;
for (iFlota=0;iFlota<nFlotas;iFlota++) {
toks=split("|",flotaStr[iFlota],nToks);
bando=toks[0]=='A' ? 0:1;
i=m_nFlotas[bando];
m_flotas[bando][i].idJug=atoi(toks[1]);
m_flotas[bando][i].nick=toks[2];
m_flotas[bando][i].CP=atoi(toks[3]);
m_flotas[bando][i].coords=toks[4];
m_flotas[bando][i].tipoIdPlan=toks[8][0];
m_flotas[bando][i].idJuego=atoi(toks[9]);
// m_flotas[bando][i].ataques=(int *)calloc(500,sizeof(int));
// m_flotas[bando][i].maxEscudos =(int *)calloc(500,sizeof(int));
// m_flotas[bando][i].maxBlind=(int *)calloc(500,sizeof(int));
// m_flotas[bando][i].tocadas=(TTocadas **)calloc(500,sizeof(TTocadas*));
m_flotas[bando][i].capturas=(int *)calloc(500,sizeof(int));
m_flotas[bando][i].vCapturas=m_flotas[bando][i].vPerdidas=0;
// m_flotas[bando][i].blindajeIntacto=(int *)calloc(500,sizeof(int));
m_flotas[bando][i].lineas=(TLinea *)calloc(50,sizeof(TLinea)); m_flotas[bando][i].nLineas=0;
m_flotas[bando][i].ataques=(int *)calloc(500,sizeof(int));
m_flotas[bando][i].escudos=(int *)calloc(500,sizeof(int));
m_flotas[bando][i].blindajes=(int *)calloc(500,sizeof(int));
for (n=10,iLin=0;n<nToks-3;n+=5,iLin++) {
// t.Format("Flota %i %s %s*%s",iFlota,toks[0],toks[n],toks[n+1]);
// log(t);
gid=atoi(toks[n]);
m_flotas[bando][i].lineas[iLin].gid=gid;
m_flotas[bando][i].ataques[gid]=m_flotas[bando][i].lineas[iLin].ataques=atoi(toks[n+2]);
m_flotas[bando][i].escudos[gid]=m_flotas[bando][i].lineas[iLin].maxEscudo=atoi(toks[n+3]);
m_flotas[bando][i].blindajes[gid]=m_flotas[bando][i].lineas[iLin].maxBlindaje=atoi(toks[n+4]);
m=atoi(toks[n+1]);
m_flotas[bando][i].lineas[iLin].nGrupoOrig=m;
m=m/m_batDivisor;
if (!m) m=1;
m_totNaves+=m;
if (!bando) navesA+=m;
else navesD+=m;
m_flotas[bando][i].lineas[iLin].nGrupo=m_flotas[bando][i].lineas[iLin].nGrupoOrigDiv=m;
if (m<5000000 && !bEstampadaSondas) { // Lineal
m_flotas[bando][i].lineas[iLin].maxGrupos=-1;
m_flotas[bando][i].lineas[iLin].grupos=(TNave *)calloc(m ? m:1,sizeof(TNave));
m_flotas[bando][i].lineas[iLin].grupos[0].nGrupo=1;
m_flotas[bando][i].lineas[iLin].grupos[0].blindaje=m_flotas[bando][i].lineas[iLin].maxBlindaje;
for (j=1;j<m;j++) memcpy(&m_flotas[bando][i].lineas[iLin].grupos[j],&m_flotas[bando][i].lineas[iLin].grupos[0],sizeof(TNave));
m_flotas[bando][i].lineas[iLin].nGrupos=m;
} else { // Agrupado
m_flotas[bando][i].lineas[iLin].maxGrupos=100;
m_flotas[bando][i].lineas[iLin].grupos=(TNave *)calloc(100,sizeof(TNave));
m_flotas[bando][i].lineas[iLin].grupos[0].nGrupo=m_flotas[bando][i].lineas[iLin].nGrupo;
m_flotas[bando][i].lineas[iLin].grupos[0].blindaje=m_flotas[bando][i].lineas[iLin].maxBlindaje;
m_flotas[bando][i].lineas[iLin].nGrupos=1;
if (!bando && bEstampadaSondas) m_flotas[bando][i].lineas[iLin].grupos[0].blindaje=-1,m_flotas[bando][i].lineas[iLin].grupos[0].rondaMuerta=1;
}
}
m_flotas[bando][i].nLineas=iLin;
m_nFlotas[bando]++;
reporte+="/"+toks[0]; for (n=2;n<=7;n++) reporte+="/"+toks[n];
delete []toks;
}
delete []flotaStr;
int ganador=0,ronda=1;
int bAtaque=0;
if (bEstampadaSondas) ganador=2,ronda=2;
// fin=GetTickCount(); t.Format(_T("call cronoIns('%s',%f);"),_T("IniRondas"),(fin-inicio)/1000.0); log(t);
for (;ronda<=7 && !ganador;ronda++) {
TNave *iNave;
//t.Format("Ronda %i ",ronda);
// log(t);
m_navBandos[0]=m_navBandos[1]=0;
for (bando=0;bando<=1;bando++) {
for (iFlota=0;iFlota<m_nFlotas[bando];iFlota++) {
for (iLin=0;iLin<m_flotas[bando][iFlota].nLineas;iLin++) {
m_flotas[bando][iFlota].lineas[iLin].nGrupo=0;
if (ronda==1) m_flotas[bando][iFlota].lineas[iLin].nav2grupos=NULL;
}
}
}
bAtaque=0;
// maxEscudos+comprobar ataque
for (bando=0;bando<=1;bando++) {
for (iFlota=0;iFlota<m_nFlotas[bando];iFlota++) {
for (iLin=0;iLin<m_flotas[bando][iFlota].nLineas;iLin++) {
if (m_flotas[bando][iFlota].lineas[iLin].maxGrupos==-1) { // Lineal
iNave=m_flotas[bando][iFlota].lineas[iLin].grupos;
n=m_flotas[bando][iFlota].lineas[iLin].maxEscudo;
m=0;
for (i=m_flotas[bando][iFlota].lineas[iLin].nGrupos;i;i--,iNave++) {
if (iNave->blindaje>=0) {
iNave->escudo=n;
m++;
} else {
if (!iNave->rondaMuerta) iNave->rondaMuerta=ronda-1;
}
}
m_flotas[bando][iFlota].lineas[iLin].nGrupo=m;
m_navBandos[bando]+=m;
if (!bAtaque && !bando && m) bAtaque=m_flotas[bando][iFlota].lineas[iLin].ataques;
} else {
if (m_flotas[bando][iFlota].lineas[iLin].nav2grupos) {
free(m_flotas[bando][iFlota].lineas[iLin].nav2grupos);
m_flotas[bando][iFlota].lineas[iLin].nav2grupos=NULL;
}
for (i=0;i<m_flotas[bando][iFlota].lineas[iLin].nGrupos;i++) {
iNave=&m_flotas[bando][iFlota].lineas[iLin].grupos[i];
if (iNave->blindaje>=0) {
iNave->escudo=m_flotas[bando][iFlota].lineas[iLin].maxEscudo;
m_flotas[bando][iFlota].lineas[iLin].nGrupo+=iNave->nGrupo;
m_navBandos[bando]+=iNave->nGrupo;
if (!bAtaque && !bando) bAtaque=m_flotas[bando][iFlota].lineas[iLin].ataques;
} else {
if (!iNave->rondaMuerta) iNave->rondaMuerta=ronda-1;
}
}
qsort(&m_flotas[bando][iFlota].lineas[iLin].grupos[0],m_flotas[bando][iFlota].lineas[iLin].nGrupos,sizeof(TNave),orden4);
for (n=0,i=1;i<m_flotas[bando][iFlota].lineas[iLin].nGrupos;i++) {
if (m_flotas[bando][iFlota].lineas[iLin].grupos[i].nGrupo) {
if (!m_flotas[bando][iFlota].lineas[iLin].grupos[i].rondaMuerta
&& !m_flotas[bando][iFlota].lineas[iLin].grupos[n].rondaMuerta
&& m_flotas[bando][iFlota].lineas[iLin].grupos[i].capturada==m_flotas[bando][iFlota].lineas[iLin].grupos[n].capturada
&& m_flotas[bando][iFlota].lineas[iLin].grupos[i].blindaje==m_flotas[bando][iFlota].lineas[iLin].grupos[n].blindaje) {
m_flotas[bando][iFlota].lineas[iLin].grupos[n].nGrupo+=m_flotas[bando][iFlota].lineas[iLin].grupos[i].nGrupo;
m_flotas[bando][iFlota].lineas[iLin].grupos[i].nGrupo=0;
} else {
n++;
if (i!=n)
memcpy(&m_flotas[bando][iFlota].lineas[iLin].grupos[n],&m_flotas[bando][iFlota].lineas[iLin].grupos[i],sizeof(TNave));
}
}
}
m_flotas[bando][iFlota].lineas[iLin].nGrupos=n+1;
}
}
}
}
if (!m_navBandos[0]) ganador=2;
else if (!m_navBandos[1] && bAtaque) ganador=1;
if (ganador) break;
if (ronda==7) break;
if (!batDispara(ronda)) break;
// fin=GetTickCount(); t.Format(_T("call cronoIns('%s',%f);"),_T("Disparos"),(fin-inicio)/1000.0); log(t);
if (bAtaque==0 && m_navBandos[1]==0) break; // Empate si nada contra nada, despues de batDispara para q saque disparos en reporte
}
//t.Format("Fin de batalla, rondas=%i, atacantes=%i, defensores=%i\r\n",ronda,m_navBandos[0],m_navBandos[1]);
// log(t);
for (bando=0; bando<=1; bando++)
for (iFlota=0;iFlota<m_nFlotas[bando];iFlota++)
navesMuertas(bando,iFlota);
// fin=GetTickCount(); t.Format(_T("call cronoIns('%s',%f);"),_T("Muertas"),(fin-inicio)/1000.0); log(t);
for (i=1;i<=ronda;i++) {
t.Format("/%i",i); reporte+=t;
for (bando=0;bando<=1;bando++)
for (iFlota=0;iFlota<m_nFlotas[bando];iFlota++)
reporte+="/"+battFl(bando,iFlota,i==1,i);
if ((ganador && i==ronda) || i==7) break;
for (n=0;n<2;n++) {
t.Format("/%s/%I64i/%I64i/%I64i",n ? "DD":"DA",m_rondas[i].disparos[n],m_rondas[i].fuerza[n],m_rondas[i].absor[n]);
reporte+=t;
}
}
i=reporte.GetLength();
t.Format("/F/%i",ganador); reporte+=t;
// fin=GetTickCount(); t.Format(_T("call cronoIns('%s',%f);"),_T("Info1"),(fin-inicio)/1000.0); log(t);
if (ganador==1) {
// Robo
t.Format("%i",idF);
t=theApp.callRobo(t);
toks=split("|",t,n);
reporte+="/R";
for (i=0;i<n;i++) reporte+="/"+toks[i];
delete []toks;
}
t.Format("/PA/%I64i",m_perdidas[0]);
reporte+=t;
t.Format("/PD/%I64i",m_perdidas[1]);
reporte+=t;
t.Format("/ES/%I64i/%I64i",m_escombros[0],m_escombros[1]);
reporte+=t;
__int64 esc=m_escombros[0] +m_escombros[1];
int diamLuna=0,porcLuna;
if (lunable && esc>=escombros1pc) {
if (esc>20*escombros1pc) porcLuna=20;
else porcLuna=(int)(esc/escombros1pc);
porcLuna=porcLuna > 20 ? 20:porcLuna;
t.Format("/L/%i",porcLuna); reporte+=t;
// Check creacion luna
do {
if ((rand()*1.0/RAND_MAX)<porcLuna/100.0) {
reporte+="/NL";
diamLuna=400*porcLuna;
break;
}
} while (talismanes--);
}
// fin=GetTickCount(); t.Format(_T("call cronoIns('%s',%f);"),_T("Info2"),(fin-inicio)/1000.0); log(t);
if (reporte.GetLength()>1024) {
theApp.callProc("reporteIni","","reporteIni");
for (i=0;i<reporte.GetLength();i+=1024)
theApp.callProc("reporteAdd","'"+reporte.Mid(i,1024)+"'","reporteAdd");
reporte="REPORTE";
}
t.Format("%i,%i,'%s',%I64i,%I64i,%I64i,%I64i,%i,%i",
idF,ganador,reporte,m_escombros[0],m_escombros[1],m_perdidas[0],m_perdidas[1],diamLuna,ronda);
theApp.callProc("eg_FinBatalla",t,"eg_FinBatalla");
// fin=GetTickCount(); t.Format(_T("call cronoIns('%s',%f);"),_T("Fin"),(fin-inicio)/1000.0); log(t);
log("Finalizado\r\n");
for (bando=0;bando<2;bando++) {
for (iFlota=0;iFlota<m_nFlotas[bando];iFlota++) {
for (iLin=0;iLin<m_flotas[bando][iFlota].nLineas;iLin++) {
delete []m_flotas[bando][iFlota].lineas[iLin].grupos;
}
delete []m_flotas[bando][iFlota].capturas;
delete []m_flotas[bando][iFlota].lineas;
delete []m_flotas[bando][iFlota].ataques;
delete []m_flotas[bando][iFlota].escudos;
delete []m_flotas[bando][iFlota].blindajes;
}
delete []m_flotas[bando];
}
fin=GetTickCount();
t.Format(_T("'Batalla',%f"),(fin-inicio)/1000.0);
theApp.callProc("cronoIns",t,"cronos");
log(t);
}
CString CMotor4::battFl(int bando,int iFlota,bool bExtraInfo,int ronda)
{
int *gids=(int *)calloc(600,sizeof(int));
int *tot=(int *)calloc(600,sizeof(int));
int *nGrupo=(int *)calloc(600,sizeof(int));
int *nOrig=(int *)calloc(600,sizeof(int));
int nNave,i,iLin;
for (iLin=0;iLin<m_flotas[bando][iFlota].nLineas;iLin++) {
nGrupo[m_flotas[bando][iFlota].lineas[iLin].gid]+=m_flotas[bando][iFlota].lineas[iLin].nGrupoOrigDiv;
nOrig[m_flotas[bando][iFlota].lineas[iLin].gid]+=m_flotas[bando][iFlota].lineas[iLin].nGrupoOrig;
for (nNave=0;nNave<m_flotas[bando][iFlota].lineas[iLin].nGrupos;nNave++) {
TNave *iNave=&m_flotas[bando][iFlota].lineas[iLin].grupos[nNave];
if (bExtraInfo) {
if (iNave->rondaMuerta)
tot[m_flotas[bando][iFlota].lineas[iLin].gid]+=iNave->nGrupo;
}
if (!iNave->rondaMuerta || iNave->rondaMuerta>=ronda)
gids[m_flotas[bando][iFlota].lineas[iLin].gid]+=iNave->nGrupo;
}
}
if (m_batDivisor>1) {
for (i=0;i<600;i++) {
if (nOrig[i]) {
if (tot[i]==nGrupo[i]) tot[i]=nOrig[i];
else tot[i]*=m_batDivisor;
if (gids[i]==nGrupo[i]) gids[i]=nOrig[i];
else gids[i]*=m_batDivisor;
}
}
}
CString ret,t;
for (i=0;i<600;i++) if (gids[i]) { t.Format("%i/",i); ret+=t; }
if (ret=="") {
ret="0";
} else {
ret+="/";
for (i=0;i<600;i++) if (gids[i]) { t.Format("%i/",gids[i]); ret+=t; }
ret+="/";
if (bExtraInfo) {
for (i=0;i<600;i++) if (gids[i]) { t.Format("%i/",m_flotas[bando][iFlota].ataques[i]); ret+=t; }
ret+="/";
for (i=0;i<600;i++) if (gids[i]) { t.Format("%i/",m_flotas[bando][iFlota].escudos[i]); ret+=t; }
ret+="/";
for (i=0;i<600;i++) if (gids[i]) { t.Format("%i/",m_flotas[bando][iFlota].blindajes[i]); ret+=t; }
ret+="/";
for (i=0;i<600;i++) if (gids[i]) { t.Format("%i/",tot[i]); ret+=t; }
ret+="/";
if (m_flotas[bando][iFlota].vPerdidas) { t.Format("P/%I64i/",m_flotas[bando][iFlota].vPerdidas); ret+=t; }
if (m_flotas[bando][iFlota].vCapturas) { t.Format("C/%I64i/",m_flotas[bando][iFlota].vCapturas); ret+=t; }
}
}
free(gids); free(tot);
return ret;
}
void CMotor4::init(void)
{
CRecordset r(&theApp.m_db);
CDBVariant v;
m_pFuegoRapido=(int **)calloc(300,sizeof(int *));
for (int i=0;i<300;i++) m_pFuegoRapido[i]=NULL;
r.Open(-1,_T("select * from fuegoRapido"));
while (!r.IsEOF()) {
// r.GetFieldValue((short)0,v);
r.GetFieldValue((short)0,v,SQL_C_SLONG);
int gidA=v.m_iVal;
if (!m_pFuegoRapido[gidA-200]) m_pFuegoRapido[gidA-200]=(int *)calloc(300,sizeof(int));
r.GetFieldValue(1,v,SQL_C_SLONG);
int gidD=v.m_iVal;
r.GetFieldValue(2,v,SQL_C_SLONG);
int n=v.m_iVal;
m_pFuegoRapido[gidA-200][gidD-200]=n;
r.MoveNext();
}
r.Close();
log(_T("Cargados fuegos rápidos\r\n"));
m_costes=(TCoste *)calloc(300,sizeof(TCoste));
r.Open(-1,_T("select gid,costeM_gid,costeC_gid,costeD_gid from gids where gid between 200 and 499"));
while (!r.IsEOF()) {
r.GetFieldValue((short)0,v,SQL_C_SLONG);
int gid=v.m_iVal;
r.GetFieldValue(1,v,SQL_C_SLONG);
m_costes[gid-200].costeM=v.m_lVal;
r.GetFieldValue(2,v,SQL_C_SLONG);
m_costes[gid-200].costeC=v.m_lVal;
r.GetFieldValue(3,v,SQL_C_SLONG);
m_costes[gid-200].costeD=v.m_lVal;
r.MoveNext();
}
r.Close();
log(_T("Cargados costes\r\n"));
}
void CMotor4::log(CString txt)
{
theApp.log(txt);
}
void CMotor4::navesMuertas(int bando,int iFlota)
{
int *muertas=(int *)calloc(600,sizeof(int));
int *capturadas=(int *)calloc(600,sizeof(int));
int *grupo=(int *)calloc(600,sizeof(int));
int *reales=(int *)calloc(600,sizeof(int));
int nNave,iLin,gid,i;
__int64 n,muertasi,nPerd;
for (iLin=0;iLin<m_flotas[bando][iFlota].nLineas;iLin++) {
for (nNave=0;nNave<m_flotas[bando][iFlota].lineas[iLin].nGrupos;nNave++) {
gid=m_flotas[bando][iFlota].lineas[iLin].gid;
TNave *iNave=&m_flotas[bando][iFlota].lineas[iLin].grupos[nNave];
if (iNave->rondaMuerta) {
if (iNave->capturada)
capturadas[gid]+=iNave->nGrupo;
else muertas[gid]+=iNave->nGrupo;
}
}
grupo[gid]+=m_flotas[bando][iFlota].lineas[iLin].nGrupoOrigDiv;
reales[gid]+=m_flotas[bando][iFlota].lineas[iLin].nGrupoOrig;
}
CString ret,t,sql;
for (i=0;i<600;i++) {
if (muertas[i]+capturadas[i]) {
n=(__int64)(muertas[i]+capturadas[i]);
muertasi=(__int64)muertas[i];
if (m_batDivisor>1) {
if (n==grupo[i]) n=reales[i];
else n*=m_batDivisor;
if (muertasi==grupo[i]) muertasi=reales[i];
else muertasi*=m_batDivisor;
}
nPerd=n*(m_costes[i-200].costeM+m_costes[i-200].costeC+m_costes[i-200].costeD);
m_perdidas[bando]+=nPerd;
m_flotas[bando][iFlota].vPerdidas+=nPerd;
if (i<400) {
m_escombros[0]+=(__int64)(muertasi*(m_costes[i-200].costeM*m_porcEscombros));
m_escombros[1]+=(__int64)(muertasi*(m_costes[i-200].costeC*m_porcEscombros));
} else {
m_escombros[0]+=(__int64)(muertasi*(m_costes[i-200].costeM*m_defEscombros));
m_escombros[1]+=(__int64)(muertasi*(m_costes[i-200].costeC*m_defEscombros));
}
sql.Format("'%c',%i,%i,%i",
m_flotas[bando][iFlota].tipoIdPlan,m_flotas[bando][iFlota].idJuego,i,n);
theApp.callProc("eg_FinBatFl",sql,"FinBatFl");
}
}
for (i=0;i<500;i++) {
if(n=m_flotas[bando][iFlota].capturas[i]) {
if (m_batDivisor>1) {
if (n==grupo[i]) n=reales[i];
else n*=m_batDivisor;
}
sql.Format("'%c',%i,%i,%i",
m_flotas[bando][iFlota].tipoIdPlan,m_flotas[bando][iFlota].idJuego,i,-n);
m_flotas[bando][iFlota].vCapturas+=(__int64)(n*(m_costes[i-200].costeM+m_costes[i-200].costeC+m_costes[i-200].costeD));
theApp.callProc("eg_FinBatFl",sql,"FinCapturas");
}
}
sql.Format("'%c',%i,%i,%i",
m_flotas[bando][iFlota].tipoIdPlan,m_flotas[bando][iFlota].idJuego,-1,0);
theApp.callProc("eg_FinBatFl",sql,"FinCapturas");
free(muertas); free(capturadas);
free(grupo); free(reales);
}
int CMotor4::fuegoRapido(int gidA,int gidD)
{
if (!m_pFuegoRapido[gidA-200]) return 0;
int n=m_pFuegoRapido[gidA-200][gidD-200];
if (!n) return 0;
if (!(rand()%n)) {
return 0;
}
return 1;
}
int CMotor4::almacenar(TLinea * pvLinea,TNave *vNave,int iGrV,int iVict,
int escudo,int blinda,unsigned __int8 capturada)
{
int iH,vAGrupo,n,m;
TIndiceGrupos *pig;
TNave * tNave;
if (vNave->blindaje<0) { // Ya estaba muerta de antes
;
} else {
if (pvLinea->maxGrupos==-1) { // Array lineal
vNave->blindaje=blinda;
vNave->escudo=escudo;
vNave->capturada=capturada;
} else {
iH=-1; vAGrupo=-1;
if (vNave->nGrupo==1) {
n=-1;
if (pig=pvLinea->indiceGrupos) {
n=buscaIndiceGrupos(pvLinea->indiceGrupos,pvLinea->nIndiceGrupos,vNave->capturada,vNave->escudo,vNave->blindaje,0,iGrV);
ASSERT(pvLinea->grupos[pig[n].grupo].blindaje==vNave->blindaje);
ASSERT(pvLinea->grupos[pig[n].grupo].escudo==vNave->escudo);
ASSERT(pvLinea->grupos[pig[n].grupo].capturada==vNave->capturada);
DEBUG_ONLY(checkIndex(pvLinea->indiceGrupos,pvLinea->nIndiceGrupos,pvLinea->grupos));
}
vNave->blindaje=blinda;
vNave->escudo=escudo;
vNave->capturada=capturada;
if (n!=-1) {
m=buscaIndiceGrupos(pvLinea->indiceGrupos,pvLinea->nIndiceGrupos,vNave->capturada,vNave->escudo,vNave->blindaje,-1);
pig[n].blindaje=blinda;
pig[n].capturada=capturada;
pig[n].escudo=escudo;
moveIndex(pvLinea->indiceGrupos,pvLinea->nGrupos,n,m);
DEBUG_ONLY(checkIndex(pvLinea->indiceGrupos,pvLinea->nIndiceGrupos,pvLinea->grupos));
}
} else {
if (pvLinea->indiceGrupos) {
vAGrupo=buscaIndiceGrupos(pvLinea->indiceGrupos,pvLinea->nIndiceGrupos,capturada,escudo,blinda,0);
if (vAGrupo!=-1) {
vAGrupo=pvLinea->indiceGrupos[vAGrupo].grupo; tNave=&pvLinea->grupos[vAGrupo];
n=0;
if (tNave->escudo == escudo)
if (tNave->blindaje ==blinda)
if (!tNave->rondaMuerta)
if (tNave->capturada==capturada)
n=1;
if (n==0)
ASSERT(0);
}
} else {
for (vAGrupo=0,tNave=&pvLinea->grupos[0];vAGrupo<pvLinea->nGrupos;vAGrupo++,tNave++) {
if (!tNave->nGrupo) {
if (iH==-1) iH=vAGrupo;
} else {
if (tNave->escudo == escudo)
if (tNave->blindaje ==blinda)
if (!tNave->rondaMuerta)
if (tNave->capturada==capturada)
break;
}
}
if (vAGrupo>=pvLinea->nGrupos) vAGrupo=-1;
}
if (vAGrupo!=-1) { // traspasar
pvLinea->grupos[vAGrupo].nGrupo++;
vNave->nGrupo--;
if (pvLinea->nav2grupos) pvLinea->nav2grupos[-iVict-1]=vAGrupo;
} else { // Nuevo grupo
if (iH==-1) { // no hay sitio, ampliar
iH=pvLinea->nGrupos;
pvLinea->nGrupos++;
if (iH>=pvLinea->maxGrupos) {
pvLinea->maxGrupos+=1000;
pvLinea->grupos=(TNave *)realloc(pvLinea->grupos,(pvLinea->maxGrupos)*sizeof(TNave));
if (!pvLinea->grupos) { log("Sin memoria"); return 0; }
memset(&pvLinea->grupos[iH],0,1000*sizeof(TNave));
vNave=NULL; // en principio no me hace falta. Ojo movido
if (pig=pvLinea->indiceGrupos) {
pig=(TIndiceGrupos *)realloc(pig,(pvLinea->maxGrupos)*sizeof(TIndiceGrupos));
if (!pig) free(pvLinea->indiceGrupos);
pvLinea->indiceGrupos=pig;
}
}
}
memcpy(&pvLinea->grupos[iH],&pvLinea->grupos[iGrV],sizeof(TNave));
pvLinea->grupos[iGrV].nGrupo--;
pvLinea->grupos[iH].nGrupo=1;
pvLinea->grupos[iH].blindaje=blinda;
pvLinea->grupos[iH].escudo=escudo;
pvLinea->grupos[iH].capturada=capturada;
if (pvLinea->nav2grupos)
pvLinea->nav2grupos[-iVict-1]=iH;
if (pig=pvLinea->indiceGrupos) {
n=buscaIndiceGrupos(pvLinea->indiceGrupos,pvLinea->nIndiceGrupos,capturada,escudo,blinda,1);
if (n>0) {
if ((pig[n-1].blindaje>blinda && pig[n-1].capturada==capturada) || pig[n-1].blindaje<-1)
ASSERT(0);
}
if (n<pvLinea->nIndiceGrupos-1) {
if ((pig[n+1].blindaje<blinda && pig[n+1].capturada==capturada) || pig[n+1].blindaje<-1)
ASSERT(0);
}
if (n<pvLinea->nIndiceGrupos) memmove(pig+n+1,pig+n,sizeof(TIndiceGrupos)*(pvLinea->nIndiceGrupos-n));
pig[n].blindaje=blinda;
pig[n].escudo=escudo;
pig[n].capturada=capturada;
pig[n].grupo=iH;
pvLinea->nIndiceGrupos++;
DEBUG_ONLY(checkIndex(pvLinea->indiceGrupos,pvLinea->nIndiceGrupos,pvLinea->grupos));
ASSERT(n==buscaIndiceGrupos(pvLinea->indiceGrupos,pvLinea->nIndiceGrupos,capturada,escudo,blinda,0,iH));
}
}
}
}
}
return 1;
}
int CMotor4::batDispara(int ronda)
{
int fuego,fuego2;
int navesMuertas[2];
int nGrupo;
int navesAhorro=0;
int iH,iVict,bando,fr,n,*pi;
int iFl,iLin,iGr; TFlotas *pFlota; TLinea *pLinea; TNave *iNave;
int iFlV,iLiV,iGrV; TFlotas *pvFlota; TLinea *pvLinea; TNave * vNave;
TIndiceGrupos *pig;
unsigned __int8 capturada;
bool bMuerta;
TRondas *pRonda=&m_rondas[ronda];
DWORD inicio,fin;
pRonda->n=ronda;
pRonda->disparos[0]=pRonda->disparos[1]=0;
pRonda->fuerza[0]=pRonda->fuerza[1]=0;
pRonda->absor[0]=pRonda->absor[1]=0;
navesMuertas[0]=navesMuertas[1]=0;
for (bando=0;bando<2;bando++) {
TRACE("Ronda %d bando %d",ronda,bando);
inicio=GetTickCount();
for (iFl=0;iFl<m_nFlotas[1-bando];iFl++) {
pFlota=&m_flotas[1-bando][iFl];
for (iLin=0;iLin<pFlota->nLineas;iLin++) {
pLinea=&pFlota->lineas[iLin];
pLinea->nav2grupos=NULL;
if (pLinea->nGrupo>=10000000) TRACE(" Uf(%d)",pLinea->nGrupo);
if (pLinea->maxGrupos==-1) { // Array lineal de naves
pLinea->indiceGrupos=NULL;
n=sizeof(int)*pLinea->nGrupo;
pi=pLinea->nav2grupos=(int *)malloc(n);
if (pi) {
for (iGrV=0;iGrV<pLinea->nGrupos;iGrV++) {
if (!pLinea->grupos[iGrV].rondaMuerta)
*(pi++)=iGrV;
}
}
} else { // Naves agrupadas
if (pLinea->nGrupo<25000000 && pLinea->nGrupo>0) { // Array directo
n=sizeof(int)*pLinea->nGrupo;
pi=pLinea->nav2grupos=(int *)malloc(n);
if (pi) {
for (iGrV=0;iGrV<pLinea->nGrupos;iGrV++) {
if (!pLinea->grupos[iGrV].rondaMuerta)
for (n=pLinea->grupos[iGrV].nGrupo;n;n--) *(pi++)=iGrV;
}
}
n=sizeof(TIndiceGrupos)*pLinea->maxGrupos;
pig=pLinea->indiceGrupos=(TIndiceGrupos *)malloc(n);
pLinea->nIndiceGrupos=0;
if (pig) {
for (iGrV=0;iGrV<pLinea->nGrupos;iGrV++) {
if (!pLinea->grupos[iGrV].rondaMuerta) {
pig[iGrV].blindaje=pLinea->grupos[iGrV].blindaje;
pig[iGrV].escudo=pLinea->grupos[iGrV].escudo;
pig[iGrV].capturada=pLinea->grupos[iGrV].capturada;
} else {
pig[iGrV].blindaje=0;
pig[iGrV].escudo=0;
pig[iGrV].capturada=-1; // que no se mezcle con otros grupos
pig[iGrV].grupo=iGrV;
}
pig[iGrV].grupo=iGrV;
pLinea->nIndiceGrupos++;
}
qsort(pig,pLinea->nIndiceGrupos,sizeof(TIndiceGrupos),ordenIndice);
}
}
}
}
}
for (iFl=0;iFl<m_nFlotas[bando];iFl++) {
pFlota=&m_flotas[bando][iFl];
for (iLin=0;iLin<pFlota->nLineas;iLin++) {
pLinea=&pFlota->lineas[iLin];
for (iGr=0;iGr<pLinea->nGrupos;iGr++) {
iNave=&pLinea->grupos[iGr];
if (!iNave->rondaMuerta) {
if (navesMuertas[1-bando]>=m_navBandos[1-bando]) continue; // No hay naves enemigas vivas, paso
nGrupo=iNave->nGrupo; if (!nGrupo) nGrupo=1;
ASSERT(nGrupo>=0);
for (;nGrupo;nGrupo--) {
fuego=fuego2=m_flotas[bando][iFl].lineas[iLin].ataques;
if (!fuego) break;
for (fr=0;;fr++) {
fuego=fuego2=m_flotas[bando][iFl].lineas[iLin].ataques;
iVict=rand();
if (m_navBandos[1-bando]>RAND_MAX) iVict=iVict*(1+RAND_MAX)+rand();
iVict%=m_navBandos[1-bando];
iH=iVict;
iVict=iH;
for (iFlV=0;iFlV<m_nFlotas[1-bando];iFlV++) {
pvFlota=&m_flotas[1-bando][iFlV];
for (iLiV=0;iLiV<pvFlota->nLineas;iLiV++) {
pvLinea=&pvFlota->lineas[iLiV];
if (pvLinea->nGrupo>iVict) {
if (pvLinea->maxGrupos==-1) { //Array lineal
iGrV=pvLinea->nav2grupos[iVict];
iVict=-1;
} else {
if (pvLinea->nav2grupos) {
iGrV=pvLinea->nav2grupos[iVict];
iVict=-iVict-1;
} else {
n=0;
for (iGrV=0;iGrV<pvLinea->nGrupos;iGrV++) {
if (!pvLinea->grupos[iGrV].rondaMuerta) {
iVict-=pvLinea->grupos[iGrV].nGrupo;
n+=pvLinea->grupos[iGrV].nGrupo;
if (n>pvLinea->nGrupo)
ASSERT(0);
if (iVict<0) break;
}
else
iVict=iVict;
}
}
}
if (iVict>=0)
ASSERT(0);
if (iVict<0) break;
} else {
iVict-=pvLinea->nGrupo;
}
}
if (iVict<0) break;
}
if (pvLinea->maxGrupos==-1) vNave=&pvLinea->grupos[iGrV];
else vNave=&m_flotas[1-bando][iFlV].lineas[iLiV].grupos[iGrV];
// mina térmica
if (pLinea->gid==223) {
// victima coste igual o inferior a crucero
if (m_costes[pvLinea->gid-200].costeM+m_costes[pvLinea->gid-200].costeC+m_costes[pvLinea->gid-200].costeD<=29000) {
fuego=fuego2=2*(vNave->escudo+vNave->blindaje);
almacenar(pLinea,iNave,iGr,-iGr-1,0,-1,0);
navesMuertas[bando]++;
} else {
fuego=fuego2=0;
}
}
pRonda->disparos[bando]++;
pRonda->fuerza[bando]+=fuego;
int escudo,blinda,maxBlinda,maxEscudo;
capturada=vNave->capturada;
maxEscudo=pvLinea->maxEscudo;
maxBlinda=pvLinea->maxBlindaje;
escudo=vNave->escudo;
blinda=vNave->blindaje;
if (escudo>0) {
if (fuego<escudo) {
pRonda->absor[bando]+=fuego;
} else {
pRonda->absor[bando]+=escudo;
}
}
if (fuego<escudo) {
int perc=(int)((100.0*fuego)/maxEscudo);
fuego=maxEscudo*perc;
fuego/=100;
fuego2=fuego;
}
if (escudo<=0 || fuego>0) {
fuego-=escudo;
escudo-=fuego2;
if (fuego<0) fuego=0;
} else fuego=0;
if (escudo<0) escudo=0;
bMuerta=false;
if (fuego>0) {
if (blinda>=0) {
if ((blinda-=fuego)<0) blinda=-1;
else {
if (blinda<0.7*maxBlinda) {
if ((rand()%100) >(100*blinda)/maxBlinda) blinda=-1;
}
}
if (blinda==-1) { // Nave murio con este disparo
if (pLinea->gid==222 && pvLinea->gid<400 && pvLinea->gid!=212 && pvLinea->gid!=223) { // y no es defensa ni sat ni mina
capturada=1;
pFlota->capturas[pvLinea->gid]++;
}
navesMuertas[1-bando]++;
bMuerta=true;
}
}
}
if (!almacenar(pvLinea,vNave,iGrV,iVict,escudo,blinda,capturada)) return 0;
if (bMuerta) {
if (navesMuertas[1-bando]>=m_navBandos[1-bando]) {
// Cortar iteraciones, ya no quedan enemigas
nGrupo=1; // Salir del bucle de naves atacantes agrupadas
break; // Salir de fuegos rápidos
}
}
if (!fuegoRapido(pLinea->gid,pvLinea->gid)) break;
}
}
}
}
}
}
for (iFl=0;iFl<m_nFlotas[1-bando];iFl++) {
pFlota=&m_flotas[1-bando][iFl];
for (iLin=0;iLin<pFlota->nLineas;iLin++) {
pLinea=&pFlota->lineas[iLin];
if (pLinea->nav2grupos) free(pLinea->nav2grupos);
pLinea->nav2grupos=NULL;
if (pLinea->indiceGrupos) free(pLinea->indiceGrupos);
pLinea->indiceGrupos=NULL;
}
}
fin=GetTickCount();
TRACE(" %f secs\n",(fin-inicio)/1000.0);
}
return 1;
}