//regole GoL 3D:

//    Cells (in this case, cubes) with only 1 or less neighbours die, as if by lonliness.
//    If 5 cells surround an empty cell, they breed and fill it.
//    If a cell has 8 or more neighbours, it dies from overcrowding.

public void getFate(){
  int neightboor = 0;
  int lastCellindex = numCell-1; 
  
  //calcolo quante cellule vive esistono attorno a ogni cellula e ne imposto il destino
  for (int i = 0; i< brodo.length; i++){
    for (int j = 0; j< brodo[0].length; j++){
      for (int k = 0; k< brodo[0][0].length; k++){
        
        neightboor = calcolaVicini(i, j, k);
        
        //println(neightboor);
        
        //imposto il destino in base alle regole e al num dei vicini
        
        //se la cella è viva
        if(brodo[i][j][k].isLiving()){ 
          
          //muore per solitudine o sovraffollamento
          if(neightboor <= loneliness || neightboor >= overcrowding) brodo[i][j][k].setWilllive(false);
          
          //altrimentio vive
          else brodo[i][j][k].setWilllive(true);
        
        //se è morta
        //e ha abbastanza vicini allora nasce
        }else if(neightboor >= minNeight && maxNeight <= maxNeight) brodo[i][j][k].setWilllive(true);
        
        //altrimenti rimane morta
        else brodo[i][j][k].setWilllive(false);
        
        neightboor = 0;
      }
    }
  }
}

private int calcolaVicini(int i, int j, int k){
  int neight = 0;
  short[] signs = new short[3]; 
  
  for (int l = 0; l< 3; l++){
    for (int m = 0; m< 3; m++){
      for (int n = 0; n< 3; n++){
        
        if(l == 0) signs[0] = -1;
        else if(l == 1) signs[0] = 0;
        else signs[0] = 1;
        
        if(m == 0) signs[1] = -1;
        else if(m == 1) signs[1] = 0;
        else signs[1] = 1;
        
        if(n == 0) signs[2] = -1;
        else if(n == 1) signs[2] = 0;
        else signs[2] = 1;
        
        try {
          if((signs[0] != 0 && signs[1] != 0 && signs[2] != 0) && brodo[i + signs[0]][j + signs[1]][k + signs[2]].isLiving()) neight++;
          //println(signs[0] + " " + signs[1] + " " + signs[2]);
        }catch(IndexOutOfBoundsException e){}
      }
    }
  }  
  return neight;
}

public void setFate(){
  for (int i = 0; i< brodo.length; i++){
    for (int j = 0; j< brodo[0].length; j++){
      for (int k = 0; k< brodo[0][0].length; k++){
        brodo[i][j][k].setLiving(brodo[i][j][k].getWilllive());
      }
    }
  }
}
