/****************************************************************
Modul: CoachAnalyser
Autor: Jaroslav Zajac
Funkcia: analyza protivnika, odporucanie obrannej a utocnej 
		 formacie koucovi, textovy vystup analyzy do suboru
*****************************************************************/

#include "CoachAnalyser.h"
//#include "Player/Formation.h"
#include <memory.h>
#include <stdio.h>

// konstrukcia
CoachAnalyser::CoachAnalyser()
{
	reset();
}

// destrukcia
CoachAnalyser::~CoachAnalyser()
{
}

// doplni do field posledne visual_info od kouca
void CoachAnalyser::update(const COACH_VISUAL_INFO *vi)
{
	for(int i = 0;i<vi->theirCount; i++)
	{
		if (vi->their[i].goalie) continue;
		int x = (int)((vi->their[i].pos.GetX() + FIELDWIDTH/2.0) / SECTORSIZE);
		int y = (int)((vi->their[i].pos.GetY() + FIELDHEIGHT/2.0) / SECTORSIZE);
		field[x][y]++;
	}
}

// vytlaci analyzu do textoveho suboru
void CoachAnalyser::printToFile(const char *file)
{
	FILE *f;
	
	if(!(f = fopen(file, "w")))
	{
		printf("error opening file");
	}
	else
	{
		for(int i = 0; i < FIELDHEIGHT/SECTORSIZE; i++)
		{
			for(int j = 0; j < FIELDWIDTH/SECTORSIZE; j++)
				fprintf(f, "%5d", field[j][i]);
			fprintf(f, "\n");
		}
	}

}
// najde najvhodnejsiu subformaciu pre utok
unsigned CoachAnalyser::countAttackFitness(Formation *f)
{
	Point p; //pomocna premenna, pozicia hraca v subformacii
	int i,j,k, form;
	float opposition=0, min=100000; 
	unsigned bestsubformation=0; //odporucana subformacia

	float obstacles[FIELDHEIGHT/SECTORSIZE]; //prekazky v utoku
	memset(obstacles, 0, sizeof(float)*FIELDHEIGHT/(SECTORSIZE));

	for (i=0;i<FIELDHEIGHT/SECTORSIZE;i++)
//		for (j = 0;j<2;j++)
// pocitame prekazky od stredu ihriska smerom ku brane
		for (k=(FIELDWIDTH/2)/SECTORSIZE; k<FIELDWIDTH/SECTORSIZE; k++)
			obstacles[i]+=field[k][i];

	// zoberieme z utocnej subformacie y suradnicu hracov, zistime,
	// do ktoreho sektoru prislucha a +-1(2) sektory okolo daneho sektoru
	// budeme scitavat odpor protihracov a hladat minimalne pokrytie 
	// v danych riadkoch(sektorovych)
	for(form=0;form<f->GetUnitsCount();form++)
	{
		if (f->GetPlayersCountInUnit(form) < 3) 
			continue;
		opposition = 0.0f;
		for(i=0; i<f->GetPlayersCountInUnit(form); i++)
		{
			p=f->GetPlayerPosInUnit(form, i);
			p.SetY(p.GetY()+FIELDHEIGHT/2.0f);
			for(j=((int)(p.GetY()/2.0f))-2;j<((int)(p.GetY()/2.0f))+2;j++)
				opposition+=obstacles[j];
		}
		if(opposition/f->GetPlayersCountInUnit(form) < min)
		{
			bestsubformation=form;
			min = opposition/f->GetPlayersCountInUnit(form);
		}
	}
	
	return bestsubformation;
}


// najde najvhodnejsiu subformaciu pre obranu
unsigned CoachAnalyser::countDefenceFitness(Formation * f)
{
	int i,j, offset, form;
	unsigned bestformation, bestoffset;
	float max=0, fitness;
	float ohodnotenie[35][11];
	Point p;
	//pre vsetky formacie
	for (form = 0; form<f->GetUnitsCount(); form++)
//		if(f->GetUnitType(form) {		// tato funkcia neexistuje, typy formacii tam su, ale nevyuzivaju sa
		// pre vsetky offsety danej formacie
	{
		if (f->GetPlayersCountInUnit(form) < 3) 
			continue;
		for (offset=0; offset<MAXOFFSET;offset+=SECTORSIZE)
		{
			fitness=0.0f;
			f->GetUnitCoverage(form, ohodnotenie);
			p = f->GetUnitDimensions(form);
			// pre cele pole, ktore moze subformacia pokryt
			for (i=0;i<p.GetX()/*FIELDHEIGHT/SECTORSIZE*/; i++)
				for (j=0;j<p.GetY()/*f->GetUnitWidth(form)*/;j++)
					fitness += field[offset/SECTORSIZE+j][i] * ohodnotenie[i][j];
			//ak je formacia lepsia, zapamatame	
			if (fitness/f->GetPlayersCountInUnit(form) > max)
			{
				bestformation = form;
				bestoffset = offset/2;
				max = fitness/f->GetPlayersCountInUnit(form);
			}

		}
	}
	// vratim v cisle zakodovanu formaciu a offset
	return 100*bestformation+bestoffset; // ta -1 je ladiaca konstanta, aby umiestnoval obranu medzi utocnikov a branu.
}

void CoachAnalyser::reset()
{
	for(int i = 0; i < FIELDWIDTH/SECTORSIZE; i++)
//		for(int j = 0; j < FIELDHEIGHT/SECTORSIZE; j++)
//			field[i][j] = 0;
		memset(&field[i], 0, sizeof(unsigned)*FIELDHEIGHT/SECTORSIZE); 

}
