public class Prologin extends Interface {
	// Fonction appelée au début de la partie.
	public void partie_init() {
		// Interface.moi();
		System.out.println("Player " + API.moi() + ": Begin");
		API.init();
	}

	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 &= !Interface.est_libre(toChange);

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

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

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

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

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

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

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

		return toReturn;
	}

	public Position getBestPulsar() {
		int min = -1;
		Position nearestPulsar = null;
		for (Position p : Interface.liste_pulsars()) {
			if (isEntoure(p))
				continue;
			int distance = distanceToBase(p);
			double score = Interface.info_pulsar(p).puissance * Interface.info_pulsar(p).pulsations_restantes;
			score /= distance;
			if (min == -1 || distance < min) {
				min = distance;
				nearestPulsar = p;
			}
		}
		return nearestPulsar;
	}

	public void 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 (Interface.est_libre(position(x, y)) || Interface.est_tuyau(position(x, y))
						|| Interface.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;
		int action = 5;
		
		while(k > 0 && action > 0)
		{
			Position actuelle = position(startx, starty);
			if(Interface.est_debris(actuelle))
			{
				action -= 3;
				API.deblayer(actuelle);
				API.construire(actuelle);
			}
			if(Interface.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++)
				{
					if(Interface.est_libre(actuelle))
					{
						action -= 1;
						API.construire(actuelle);
					}
				}
			}
		}
	}

	// Fonction appelée à chaque tour.
	public void jouer_tour() {
		if (API.tour_actuel() == 100) {
			printMap();
		}
		aspirationThing();
		Position pulsar2go2 = getBestPulsar();
		buildPipeTo(pulsar2go2);
	}

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