#include "ExploreManager.h"



ExploreManager::ExploreManager(){}


void ExploreManager::move(BWAPI::Unit unit){
	BWAPI::Unitset foes = BWAPI::Broodwar->enemy()->getUnits();
	if (foes.size() == 0)
		exploreTerrain(unit);
	else{
		trackEnemy(unit, foes);
	}
}

void ExploreManager::trackEnemy(BWAPI::Unit unit, BWAPI::Unitset foes){
	/*BWAPI::Unit closestFoe;
	int distance = 9999;
	for (auto &foe : foes){
		if (unit->getDistance(foe) < distance){
			distance = unit->getDistance(foe);
			closestFoe = foe;
		}
	}*/
	BWAPI::Unit closestFoe = unit->getClosestUnit(BWAPI::Filter::IsEnemy);
	if (closestFoe != NULL && closestFoe->exists()){
		//BWAPI::Broodwar->drawTextMap(unit->getPosition(), "%s at %d", closestFoe->getType().getName().c_str(), unit->getDistance(closestFoe)); // DEBUG!!!!!!!!!!!!!!!!!
		unit->attack(closestFoe->getPosition());
	}
	else exploreTerrain(unit);
	
}

void ExploreManager::exploreTerrain(BWAPI::Unit unit){
	int x, y, len = unit->getType().sightRange()/2; // Distance to target each exploration step
	double dir, angle;
	BWAPI::Position pos;
	if (Utils::flipCoin(0.9)){ // 80% of the time it keeps going forward
		angle = unit->getAngle();

		if (angle < 0.380427) dir = E;
		else if (angle < 1.165825) dir = SE;
		else if (angle < 1.975767) dir = S;
		else if (angle < 2.7611655) dir = SW;
		else if (angle < 3.52202) dir = W;
		else if (angle < 4.307418) dir = NW;
		else if (angle < 5.11736) dir = N;
		else if (angle < 5.90276) dir = NE;
		else dir = E;

		x = unit->getPosition().x + len*cos(dir);
		y = unit->getPosition().y + len*sin(dir);
		pos = BWAPI::Position(x, y);
	}
	else{ // 20% chance to change direction randomly
		do{
			int r = rand() % 8; // range 0 to 7.
			switch (r){
			case 0:
				dir = E;
				break;
			case 1:
				dir = SE;
				break;
			case 2:
				dir = S;
				break;
			case 3:
				dir = SW;
				break;
			case 4:
				dir = W;
				break;
			case 5:
				dir = NW;
				break;
			case 6:
				dir = N;
				break;
			case 7:
				dir = NE;
				break;
			}

			x = unit->getPosition().x + len*cos(dir);
			y = unit->getPosition().y + len*sin(dir);
			pos = BWAPI::Position(x, y);
		} while (!unit->hasPath(pos));
	}
	unit->move(pos);
}
