/**
  * Jeu de la vie.
  */

import java.awt.image.*;
import javax.imageio.*;

public class JeuDeLaVieEnConsole {

/**
* Menu principal de l'application.
*
* @return L'entier correspondant a l'option choisie.
*/
  public static int resultatExecutionMenu() {
    int v;
    Console.sautDeLigne();
    Console.afficherln("1: Lancer le jeu de la vie");
    Console.afficherln("2: Aleatoire");
    Console.afficherln("3: Galaxie");
    Console.afficherln("4: Vaisseau");
    Console.afficherln("0: Quitter");
    Console.afficher("Que voulez vous faire ? ");
    v = Console.saisirInt();
    Console.sautDeLigne();
    return v;
  }

  public static int valeurVoisin(boolean [][] tb,int l,int c) {
    if ( ( l < 0 ) || ( c < 0 ) || ( l >= tb.length ) || ( c >= tb[l].length ) )
      return(0);
      else
      return((tb[l][c]) ? 1 : 0);
  }

  public static int nombreVoisins(boolean [][] tb,int l,int c) {
    int nb = 0;
    nb += valeurVoisin(tb,l+1,c);
    nb += valeurVoisin(tb,l+1,c+1);
    nb += valeurVoisin(tb,l,c+1);
    nb += valeurVoisin(tb,l-1,c+1);
    nb += valeurVoisin(tb,l-1,c);
    nb += valeurVoisin(tb,l-1,c-1);
    nb += valeurVoisin(tb,l,c-1);
    nb += valeurVoisin(tb,l+1,c-1);
    return(nb);
  }

  public static boolean [][] evolution(boolean [][] tb) {
    boolean [][] ntb = new boolean[tb.length][tb[0].length];
    for ( int l = 0 ; l < tb.length ; l++ ) {
      for ( int c = 0 ; c < tb[l].length ; c++ ) {
        //if ( nombreVoisins(tb,l,c) != 0 ) {
        //  Console.afficherln(l," ",c," ",nombreVoisins(tb,l,c)); }
        switch (nombreVoisins(tb,l,c)) {
          case 2 :
            ntb[l][c] = tb[l][c];
            break;
          case 3 :
            ntb[l][c] = true;
            break;
          default :
            ntb[l][c] = false;
            break; } } }
    return(ntb);
  }

  public static void afficherCellule(int l,int c) {
    int px = 1+c*10;
    int py = 1+l*10;
    EcranGraphique.drawLine(px,py,px+8,py);
    EcranGraphique.drawLine(px+8,py,px+8,py+8);
    EcranGraphique.drawLine(px+8,py+8,px,py+8);
    EcranGraphique.drawLine(px,py+8,px,py);
  }

  public static void afficher(boolean [][] tb) {
    for ( int l = 0 ; l < tb.length ; l++ ) {
      for ( int c = 0 ; c < tb[l].length ; c++ ) {
        if ( tb[l][c] ) {
          afficherCellule(l,c); } } }
  }

/**
* Programme principal.
*
*/
  public static void main(String [] args) {
    Console.setTitle("JeuDeLaVie");
    int choix;
    EcranGraphique.init(30,30,720,720,641,641,"Jeu de la vie");
    boolean [][] tb = new boolean[64][64];
    int n;
    int deltaT;
    afficher(tb);
    EcranGraphique.flush();
    choix = resultatExecutionMenu();
    while ( choix != 0 ) {
      switch (choix) {
        case 1 : {
          int nbIterations;
          Console.afficher("Combien d'iterations? : ");
          nbIterations = Console.saisirInt();
          Console.afficher("DeltaT?               : ");
          deltaT = Console.saisirInt();
          for ( int i = 0 ; i < nbIterations ; i++ ) {
            try {
              Thread.sleep(deltaT); }
            catch (Exception e) { }
            tb = evolution(tb);
            EcranGraphique.clear();
            afficher(tb);
            EcranGraphique.flush(); } }
          break;
        case 2 :
          tb = new boolean[64][64];
          Console.afficher("Combien de cellules? : ");
          n = Console.saisirInt();
          for ( int i = 0 ; i < n ; i++ )
            tb[(int)(Math.random()*64)][(int)(Math.random()*64)] = true;
          EcranGraphique.clear();
          afficher(tb);
          EcranGraphique.flush();
          break;
        case 3 :
          tb = new boolean[64][64];
          tb[30][30] = true;
          tb[30][31] = true;
          tb[30][32] = true;
          tb[30][33] = true;
          tb[30][34] = true;
          tb[30][35] = true;
          tb[31][30] = true;
          tb[31][31] = true;
          tb[31][32] = true;
          tb[31][33] = true;
          tb[31][34] = true;
          tb[31][35] = true;
          tb[30][27] = true;
          tb[31][27] = true;
          tb[32][27] = true;
          tb[33][27] = true;
          tb[34][27] = true;
          tb[35][27] = true;
          tb[30][28] = true;
          tb[31][28] = true;
          tb[32][28] = true;
          tb[33][28] = true;
          tb[34][28] = true;
          tb[35][28] = true;
          tb[37][27] = true;
          tb[37][28] = true;
          tb[37][29] = true;
          tb[37][30] = true;
          tb[37][31] = true;
          tb[37][32] = true;
          tb[38][27] = true;
          tb[38][28] = true;
          tb[38][29] = true;
          tb[38][30] = true;
          tb[38][31] = true;
          tb[38][32] = true;
          tb[33][34] = true;
          tb[34][34] = true;
          tb[35][34] = true;
          tb[36][34] = true;
          tb[37][34] = true;
          tb[38][34] = true;
          tb[33][35] = true;
          tb[34][35] = true;
          tb[35][35] = true;
          tb[36][35] = true;
          tb[37][35] = true;
          tb[38][35] = true;
          EcranGraphique.clear();
          afficher(tb);
          EcranGraphique.flush();
          break;
        case 4 :
          tb = new boolean[64][64];
          tb[30][4] = true;
          tb[32][4] = true;
          tb[33][5] = true;
          tb[33][6] = true;
          tb[33][7] = true;
          tb[33][8] = true;
          tb[32][8] = true;
          tb[31][8] = true;
          tb[30][7] = true;
          EcranGraphique.clear();
          afficher(tb);
          EcranGraphique.flush();
          break; }
    choix = resultatExecutionMenu(); }
    EcranGraphique.exit();
  }
}