import java.util.ArrayList;

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 printArray(int[][] array)
	{
		for(int y = 0 ; y < array.length ; y++)
		{
			for (int i = 0; i < array[y].length; i++) {
				System.out.print((array[y][i]<0?"":" ")+array[y][i]);
			}
			System.out.println();
		}
	}
	
	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() {
		int[][] pipes = new int[39][39];

		for (int y = 0; y < pipes.length; y++) {
			for (int x = 0; x < pipes.length; x++) {
				if (!API.est_tuyau(position(x, y)))
					pipes[y][x] = -3;
				else
					pipes[y][x] = 0;
			}
		}

		if(API.moi()==1)
		{	
		
			printArray(pipes);
			System.out.println("---------------qqqqq");
		}
		int[][] ways = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } };

		for (Position p : API.ma_base()) {
			int puissance = Interface.puissance_aspiration(p);
			pipes[p.y][p.x] = 4;
			for(int k = puissance ; k > 0 ; k--)
			{
				for (int y = 0; y < pipes.length; y++) {
					for (int x = 0; x < pipes.length; x++) {
						if (pipes[y][x] == 4) {
							pipes[y][x] = 3;
							for (int[] direction : ways) {
								int ycor = y + direction[0];
								int xcor = x + direction[1];
								if (ycor >= 0 && ycor < 39 && xcor >= 0 && xcor < 39) {
									if (pipes[ycor][xcor] == 0 || pipes[ycor][xcor] == 2) {
										pipes[ycor][xcor] = 4;
									}
								}
							}
						}
					}
				}
				if(API.moi()==1)
				{
					System.out.println(k+" ");
					printArray(pipes);
					System.out.println("---");
				}
			}
			for (int y = 0; y < pipes.length; y++) {
				for (int x = 0; x < pipes.length; x++) {
					if (pipes[y][x] == 3 || pipes[y][x] == 4) {
						pipes[y][x] = 2;
					}
				}
			}
		}

		for (Position p : API.base_ennemie()) {
			int puissance = Interface.puissance_aspiration(p);
			pipes[p.y][p.x] = 4;
			for(int k = puissance ; k > 0 ; k--)
			{
				for (int y = 0; y < pipes.length; y++) {
					for (int x = 0; x < pipes.length; x++) {
						if (pipes[y][x] == 4) {
							pipes[y][x] = 3;
							for (int[] direction : ways) {
								int ycor = y + direction[0];
								int xcor = x + direction[1];
								if (ycor >= 0 && ycor < 39 && xcor >= 0 && xcor < 39) {
									if (pipes[ycor][xcor] == 0 || pipes[ycor][xcor] == 2) {
										pipes[ycor][xcor] = 4;
									}
								}
							}
						}
					}
				}
			}
			for (int y = 0; y < pipes.length; y++) {
				for (int x = 0; x < pipes.length; x++) {
					if (pipes[y][x] == 3 || pipes[y][x] == 4) {
						pipes[y][x] = -2;
					}
				}
			}
		}
		
		if(API.moi() == 1)
			printArray(pipes);
		
		boolean continuer = true;
		while (continuer)
		{
			continuer = false;
			for (int y = 0; y < pipes.length; y++) {
				for (int x = 0; x < pipes.length; x++) {
					if (pipes[y][x] == 2) {
						continuer = true;
						pipes[y][x] = 1;
						for (int[] direction : ways) {
							int ycor = y + direction[0];
							int xcor = x + direction[1];
							if (ycor >= 0 && ycor < 39 && xcor >= 0 && xcor < 39) {
								if (pipes[ycor][xcor] == 0) {
									pipes[ycor][xcor] = 2;
								}
							}
						}
					}
					if (pipes[y][x] == -2) {
						continuer = true;
						pipes[y][x] = -1;
						for (int[] direction : ways) {
							int ycor = y + direction[0];
							int xcor = x + direction[1];
							if (ycor >= 0 && ycor < 39 && xcor >= 0 && xcor < 39) {
								if (pipes[ycor][xcor] == 0) {
									pipes[ycor][xcor] = -2;
								}
								if (pipes[ycor][xcor] == 2) {
									pipes[ycor][xcor] = -10;
								}
							}
						}
					}
				}
			}
		}
		
		for (int y = 0; y < pipes.length; y++) {
			for (int x = 0; x < pipes.length; x++) {
				if (pipes[y][x] == -10) {
					pipes[y][x] = 0;
				}
			}
		}
		return pipes;
	}
	// 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() {
		
		getPipesArray();

		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
	}
}
