public class Prologin extends Interface {
	

	
	Position cible;
	
	// Fonction appelée au début de la partie.
	public void partie_init() {
		// API.moi();
		System.out.println("Player " + API.moi() + ": Begin");
		API.init();
		cible = getBestPulsar();
	}

	public void printMap() {
		Position p = new Position();
		System.out.println("Printing");
		for (int y = 0; y < 39; y++) {
			for (int x = 0; x < 39; x++) {
				p.x = x;
				p.y = y;
				System.err.print(" " + (API.est_libre(p) ? 1 : 0));
			}
			System.err.println();
		}
	}

	public Position position(int x, int y) {
		Position p = new Position();
		p.x = x;
		p.y = y;
		return p;
	}

	public void aspirationThing() {
		int max = -1;
		Position maxP = null;
		for (Position p : API.ma_base()) {
			if (p.y == 18 || p.y == 19 || p.y == 20)
				continue;
			if (API.puissance_aspiration(p) >= max) {
				max = API.puissance_aspiration(p);
				maxP = p;
			}
		}
		Position dest = position(0, 19);
		if (API.puissance_aspiration(dest) == API.LIMITE_ASPIRATION)
			dest.y += 1;
		if (API.puissance_aspiration(dest) == API.LIMITE_ASPIRATION) {
			dest.y -= 1;
			dest.x = 38;
		}
		if (API.puissance_aspiration(dest) == API.LIMITE_ASPIRATION) {
			dest.y += 1;
		}
		if (API.puissance_aspiration(dest) != API.LIMITE_ASPIRATION) {
			API.deplacer_aspiration(maxP, dest);
		}
	}

	public int distanceToBase(Position p) {
		Position symmetrid = new Position();
		if (p.x > 20)
			symmetrid.x = 38 - p.x;
		else
			symmetrid.x = p.x;
		if (p.y > 20)
			symmetrid.y = 38 - p.y;
		else
			symmetrid.y = p.y;
		int distance = 0;
		distance += symmetrid.x;
		if (symmetrid.y < 13)
			distance += 13 - distance;
		return distance;
	}

	public boolean isEntoure(Position pulsar) {
		boolean toReturn = true;
		Position toChange = new Position();
		toChange.x = pulsar.x - 1;
		toChange.y = pulsar.y - 1;
		toReturn &= !API.est_libre(toChange);

		toChange.x = pulsar.x;
		toChange.y = pulsar.y - 1;
		toReturn &= !API.est_libre(toChange);

		toChange.x = pulsar.x + 1;
		toChange.y = pulsar.y - 1;
		toReturn &= !API.est_libre(toChange);

		toChange.x = pulsar.x - 1;
		toChange.y = pulsar.y;
		toReturn &= !API.est_libre(toChange);

		toChange.x = pulsar.x - 1;
		toChange.y = pulsar.y + 1;
		toReturn &= !API.est_libre(toChange);

		toChange.x = pulsar.x;
		toChange.y = pulsar.y + 1;
		toReturn &= !API.est_libre(toChange);

		toChange.x = pulsar.x + 1;
		toChange.y = pulsar.y + 1;
		toReturn &= !API.est_libre(toChange);

		toChange.x = pulsar.x + 1;
		toChange.y = pulsar.y;
		toReturn &= !API.est_libre(toChange);

		return toReturn;
	}

	public Position getBestPulsar() {
		double max = 0.0000001;
		Position nearestPulsar = null;
		for (Position p : API.liste_pulsars()) {
			if (isEntoure(p))
				continue;
			int distance = distanceToBase(p);
			PulsarInfo info = API.info_pulsar(p);
			int modulo = API.tour_actuel()%info.periode;
			modulo = info.periode-modulo;
			double score = info.puissance * (info.pulsations_restantes-((modulo < 4)?1:0));
			score /= distance;
			if (score > max) {
				max = score;
				nearestPulsar = p;
			}
		}
		return nearestPulsar;
	}
	
	public int[][] getPipesArray()
	{
		
	}
	// faire un array des tuyaux qui "M'appartiennent"
	// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	
	// faire la distance au tuyaux qui m'appartient le + proche
	// reconstruire les tuyaux qui m'appartiennent
	
	public int buildPipeTo(Position pulsar) {
		int[][] map = new int[39][39];

		for (int y = 0; y < map.length; y++) {
			for (int x = 0; x < map.length; x++) {
				if (API.est_libre(position(x, y)) || API.est_tuyau(position(x, y))
						|| API.est_debris(position(x, y)))
					map[y][x] = -1;
				else
					map[y][x] = -2;
			}
		}

		for (Position p : API.ma_base()) {
			map[p.y][p.x] = -3;
		}

		map[pulsar.y][pulsar.x] = 0;
		int k = 0;
		int startx = 0, starty = 0;
		int[][] ways = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } };
mainloop: for (k = 0; k < 100; k++) {
			for (int y = 0; y < map.length; y++) {
				for (int x = 0; x < map.length; x++) {
					if (map[y][x] == k) {
						for (int[] direction : ways) {
							int ycor = y + direction[0];
							int xcor = x + direction[1];
							if (ycor >= 0 && ycor < 39 && xcor >= 0 && xcor < 39) {
								if (map[ycor][xcor] == -3) {
									startx = x;
									starty = y;
									break mainloop;
								}
								if (map[ycor][xcor] == -1) {
									map[ycor][xcor] = k + 1;
								}
							}
						}
					}
				}
			}
		}
		if(k==100)
			return -1;
		int action = 5;
		
		while(k > 0 && action > 0)
		{
			Position actuelle = position(startx, starty);
			if(API.est_debris(actuelle))
			{
				action -= 3;
				API.deblayer(actuelle);
				API.construire(actuelle);
			}
			if(API.est_libre(actuelle))
			{
				action -= 1;
				API.construire(actuelle);
			}
			for (int[] direction : ways) {
				int ycor = starty + direction[0];
				int xcor = startx + direction[1];
				if (ycor >= 0 && ycor < 39 && xcor >= 0 && xcor < 39) {
					if (map[ycor][xcor] == k-1) {
						startx = xcor;
						starty = ycor;
						break;
					}
				}
			}
			k-=1;
		}
		if(action > 0)
		{
			for(int i = -1 ; i < 2 ; i++)
			{
				for(int j = -1 ; j < 2 ; j++)
				{
					Position decal = position(pulsar.x+i, pulsar.y+j);
					if(API.est_libre(decal))
					{
						action -= 1;
						API.construire(decal);
					}
				}
			}
		}
		return action;
	}

	// Fonction appelée à chaque tour.
	public void jouer_tour() {
		
		if(cible != null && isEntoure(cible))
		{
			cible = getBestPulsar();
		}
		
		if (API.tour_actuel() == 100) {
			printMap();
		}
		//aspirationThing();
		
		int action = 0;
		if(cible != null)
		{
			buildPipeTo(cible);
		}
	}

	// Fonction appelée à la fin de la partie.
	public void partie_fin() {
		// Place ton code ici
	}
}
