#include "Solution.h"
#include <sstream>
#include <fstream>
#include <vector>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <algorithm>

using namespace std;

#define sqr(a) ((a)*(a))
#define forn(i,n) for (int i = 0; i < (int)(n); ++i)

typedef CoordsXY point;
typedef long double ld;

FILE *LOG = 0;

ld dist (const point &a, const point &b) {
	return sqrtl(sqr(a.x - b.x) + sqr(a.y - b.y));
}

map<int, int> Strategy() {
	map<int, int> answer;
	int k = 0;
	for (int i = 0; i < MAX_FACTORY_COUNT; i++) {
		const Factory &f = pWorld->factories[i];
		if (f.id < 0) continue; //пропускаем "мёртвые" заводы
		if (f.owner != playerIndex) continue; //пропускаем чужие заводы
		answer[f.id] = 0; //говорим, что на нашем заводе надо строить!
	}
	return answer;
}

ld factAttackPrior (int i) {
	ld score = 0;
	const Factory &g = pWorld->factories[i];
	forn (j, 7) {
		const Factory &f = pWorld->factories[j];
		if (i == j) {
			continue;
		}
		if (f.owner == playerIndex) {
			score += 1000.l / dist(f.position, g.position);
		}
		if (f.owner == 1 - playerIndex) {
			score -= 1000.l / dist(f.position, g.position) * 0.5;
		}
	}
	return expl(2 * score);
}

int my_at (int i) {
	const Factory &g = pWorld->factories[i];
	int ans = 0;
	forn (j, 1024) {
		const Robot &r = pWorld->robots[j];
		if (r.id != -1 && r.owner == playerIndex) {
			if (dist(r.position, g.position) < g.radius) {
				ans++;
			}
		}	
	}
	return ans;
}

int enemy_at (int i) {
	const Factory &g = pWorld->factories[i];
	int ans = 0;
	forn (j, 1024) {
		const Robot &r = pWorld->robots[j];
		if (r.id != -1 && r.owner == 1 - playerIndex) {
			if (dist(r.position, g.position) < g.radius) {
				ans++;
			}
		}
	}
	return ans;
}

int enemy_near (int i) {
	const Factory &g = pWorld->factories[i];
	int ans = 0;
	forn (j, 1024) {
		const Robot &r = pWorld->robots[j];
		if (r.id != -1 && r.owner == 1 - playerIndex) {
			if (dist(r.position, g.position) < g.radius * 4) {
				ans++;
			}
		}
	}
	return ans;
}

char buff[10240];

bool operator < (const point &a, const point &b) {
	return 0;
}

int submit[7];

pair<string, string> Program(int robotIndex) {
	const Robot &cur_r = pWorld->robots[robotIndex];
	
	int cur_id = 0;
	forn (i, 7) {
		if (dist(cur_r.position, pWorld->factories[i].position) < dist(cur_r.position, pWorld->factories[cur_id].position)) {
			cur_id = i;
		}
	}

	const Factory &cur_f = pWorld->factories[cur_id];

	if (!LOG) {
		sprintf(buff, "PlayerLog_%d.txt", playerIndex);
		LOG = fopen(buff, "w");
	}
	ld prAttack[7];
	forn (i, 7) {
		const Factory &f = pWorld->factories[i];
		if (f.owner == playerIndex) {
			prAttack[i] = 0;
			continue;
		}
		prAttack[i] = factAttackPrior(i);
		if (f.owner == 1 - playerIndex) {
			prAttack[i] /= 100;
		}
	}
	ld sum = 0;
	forn (i, 7) {
		sum += prAttack[i];
	}
	ld rd = (ld)rand() / RAND_MAX * sum;
	int num = 0;
	while (rd >= 0) {
		rd -= prAttack[num++];
	}
	num--;
	prAttack[num] = 1e20l;

	if (enemy_near(cur_id) > 0) {
		prAttack[cur_id] = 1e21l;
	}

	vector<pair<ld, point> > points;
	forn (i, 7) {
		points.push_back(make_pair(prAttack[i], pWorld->factories[i].position));
	}
	sort(points.begin(), points.end());
	reverse(points.begin(), points.end());
	int bufs = 0;
	sprintf(buff, "path = {}\n");
	forn (i, 7) {
		sprintf(buff + strlen(buff), "path[%d] = {x = %lf, y = %lf}\n", i, double(points[i].second.x), double(points[i].second.y));
	}
	fputs(buff, stderr);

//	if ((double)rand() / RAND_MAX < 1. - (double)my_at(cur_id) / 3 && pWorld->currentTime > 600) {
//		num = cur_id;
//	}
//	sprintf(buff, "capture = {x = %lf, y = %lf}", pWorld->factories[num].position.x, pWorld->factories[num].position.y);

	return make_pair("", string(buff));
}
                        