
import java.io.FileWriter;
import java.io.IOException;

public class ForestFire extends CAtoolbox {

	private static int norm(int n, int p) {
		return (n + p) % p;
	}

	public static void main(String[] args) throws IOException {

		int dx = 50;
		int dy = 50;
		
		int[][] tableauCourant = new int[dx][dy];
		int[][] nouveauTableau = new int[dx][dy];
		
		int delai = 0;//100;
		
		int nombreDePasMaximum = 10000;//1000;
		int it = 0;
		
		double densite = 0.6; //0.55; // seuil de percolation a 0.55

		// notre fichier
		FileWriter csv = new FileWriter("forest_"+densite+".csv");
		csv.write("# it, nbArbresSains, nbArbresEnFeu\n");
		csv.flush();

		// les valeurs qu'on va utiliser pour compter
		int nbSains = 0;
		int nbArbresEnFeu = 0;
		
		// optionnel: initialise la visualisation dans une fenetre
		
		CAImageBuffer image = new CAImageBuffer(dx,dy);
	    ImageFrame imageFrame =	ImageFrame.makeFrame( "Forest fire", image, delai, 200, 200 );

		// initialisation (peuple la foret)
	    
	    for ( int x = 0 ; x != dx ; x++ )
	    	for ( int y = 0 ; y != dy ; y++ )
	    		if ( densite >= Math.random() )
	    			tableauCourant[(int)x][(int)y]=1; // tree

	    tableauCourant[dx/2][dy/2] = 2; // burning tree
	    
		// on fait tourner l'automate
		
		while ( it != nombreDePasMaximum )
		{
			// 1a - affiche de l'etat courant dans la fenetre graphique (toutes les cellules)
			image.updateForest(tableauCourant);

			// la ligne qu'on va
			String csvLigne = "" + it;
			nbSains = 0;
			nbArbresEnFeu = 0;

			// 1 - mise a jour de l'automate (dans le tableau en tampon)
			for ( int x = 0 ; x != tableauCourant.length ; x++ )
				for ( int y = 0 ; y != tableauCourant[0].length ; y++ )
				{
					// on compte le statut des arbres
					if (tableauCourant[x][y] == 1)
						nbSains++;
					if (tableauCourant[x][y] == 2)
						nbArbresEnFeu++;

					// par défaut on garde
					nouveauTableau[x][y] = tableauCourant[x][y];

					int gauche = 0, droite = 0, haut = 0, bas = 0;

					// on normalise x et y pour éviter des array out of bounds
					gauche = tableauCourant[ norm(x-1, tableauCourant.length) ][y];
					droite = tableauCourant[ norm(x+1, tableauCourant.length) ][y];
					haut = tableauCourant[x][ norm(y-1, tableauCourant[0].length) ];
					bas = tableauCourant[x][ norm(y+1, tableauCourant[0].length) ];

					// si on était déjà en feu, on devient
					if (tableauCourant[x][y] == 2)
						nouveauTableau[x][y] = 3;
					// vérifie si au moins un arbre voisin est en feu et si on est un arbre on peut prendre feu
					if ((gauche == 2 || droite == 2 || haut == 2 || bas == 2) && tableauCourant[x][y] == 1)
						nouveauTableau[x][y] = 2;
				}

			csvLigne += "," + nbSains + "," + nbArbresEnFeu + "\n";
			csv.write(csvLigne);
			
			// 2 - met a jour le tableau affichable
			
			for ( int x = 0 ; x != tableauCourant.length ; x++ )
				for ( int y = 0 ; y != tableauCourant[0].length ; y++ )
					tableauCourant[x][y] = nouveauTableau[x][y];

			it++;
			
			// ne va pas trop vite...
			
			try {
				Thread.sleep(delai);
			} catch (InterruptedException e) 
			{
			}
		}

		// et on ferme le fichier
		csv.flush();
		csv.close();
		
	}

}
