(...continuo)

codice:
/** Funzione NEMICO2 **/
void * nemico2_func(void * arg)
{
pos pos_nemico2;
args *p = (args *)arg;
args pos;
int i = p->i;
int x = p->x;
int y = p->y;
int j;
int dx,dy;
int SOGLIAX;
int SOGLIA_GIU=10*(0+rand()%4)+i*5; // soglia per far scendere il nemico di una riga
int time_giu=0;
int time_bomb=1;
int SOGLIA_BOMB=30+i*(0+rand()%5); // soglia per far sganciare la bomba
pthread_t bomba_id;

pos_nemico2.c='H';
pos_nemico2.xi=x;
pos_nemico2.xf=x+G-1;
pos_nemico2.y=y;
pos_nemico2.p=i;
pos_nemico2.pid=pthread_self();

for(j=0;j<G;j++)
     pos_nemico2.nem_vivi[j]=2;

if(!(i%2)) // se il numero assegnato al nemico è pari
  {
    pos_nemico2.DIRX=1; // vÃ_ a destra
    SOGLIAX=MAXX-1; // e la soglia max in x è MAXX-1
  }
else // altrimenti
   {
     pos_nemico2.DIRX=-1; // vÃ_ a sinistra
     SOGLIAX=1; // e la soglia max in x è 1
   }

sem_wait(&disponibili);
pthread_mutex_lock(&mutex);
buffer[IN] = pos_nemico2;
IN=(IN+1)%BUFFER_DIM;
sem_post(&presenti); // incrementa il semaforo
pthread_mutex_unlock(&mutex);


while(1)
{
     if(pos_nemico2.xf>=MAXX-1 || pos_nemico2.xi<=1) // se il nemico sbatte contro una parete laterale
       {
         pos_nemico2.DIRX*=-1; // cambio la direzione
         if(SOGLIAX==MAXX-1) // se la nuova direzione è destra
            SOGLIAX=1; // la soglia è MAXX-1
         else // altrimenti
            SOGLIAX=MAXX-1; // la soglia è 1
       }  

     if(pos_nemico2.DIRX==1) // se la direzione è destra
       dx=PASSO; // il suo spostamento sarÃ_ di PASSO
     else // altrimenti
       dx=-PASSO; // il suo spostamento sarÃ_ di -PASSO
      
     pos_nemico2.xi+=dx; // scriviamo la posizione in x del primo nemico
     pos_nemico2.xf+=dx; // scriviamo la posizione in x dell'ultimo nemico

     if(!(time_giu%SOGLIA_GIU)) // ad intervalli regolari
       {
         dy=PASSO; // il nemico avanza di PASSO verso la soglia massima in Y
         time_giu=1; // riazzero il contatore
       }
    else
       {
         dy=0; // il nemico non avanza verso la soglia massima in Y
         time_giu++; // aggiorno il contatore per la discesa del nemico
       }

    pos_nemico2.y+=dy; // scriviamo la posizione in y del nemico

    // aggiorniamo la posizione del nemico e la comunichiamo al controllo
    sem_wait(&disponibili);
    pthread_mutex_lock(&mutex);
    buffer[IN] = pos_nemico2;
    IN=(IN+1)%BUFFER_DIM;
    sem_post(&presenti); // incrementa il semaforo
    pthread_mutex_unlock(&mutex);


    if(!(time_bomb%SOGLIA_BOMB)){ // ad intervalli regolari
        pos.x = pos_nemico2.x;
	pos.y = pos_nemico2.y;
        pthread_create(&bomba_id, NULL, &bomba_func, &pos); 
	//pthread_join(bomba_id, NULL);
                                }
    time_bomb++; // aggiorno il contatore per la bomba

    usleep(300000);

} // fine while

} // fine funzione Nemico2

/** Funzione CONTROLLO **/
void * controllo_func(void * arg)
{
pos astronave, missile[2], bomba, nemico[M], nem2[M], valore_letto;
args pos;
int GAME_OVER=0; // se game_over=-1 l'astronave è stata uccisa, se game_over=1 l'astronave ha vinto, se game_over=0 il gioco prosegue
int NEM_VIVI=M+M*G; // segna quanti nemici vivi ci sono
int vita_gruppo[M]; // vettore che indica lo stato di vita del gruppo iesimo
int i,j;
int vite[M][G];
pthread_t nemico2_id[M];


init_pair(1,COLOR_GREEN,COLOR_BLACK);
init_pair(2,COLOR_CYAN,COLOR_BLACK);
init_pair(3,COLOR_YELLOW,COLOR_BLACK);
init_pair(4,COLOR_RED,COLOR_BLACK);
init_pair(5,COLOR_BLUE,COLOR_BLACK);
init_pair(6,COLOR_MAGENTA,COLOR_BLACK);

astronave.x=-1;

for(i=0;i<2;i++)
    missile[i].x=-1;

for(i=0;i<M;i++)
   {
      nemico[i].x=-1;
      nemico[i].vita=1;
   
      nem2[i].xf=-1;
      nem2[i].vita=2;

      vita_gruppo[i]=4;
    }

for(i=0;i<M;i++)
   for(j=0;j<G;j++)
      vite[i][j]=2;

do
{
    sem_wait(&presenti);
    pthread_mutex_lock(&mutex);
    valore_letto = buffer[OUT];
    OUT=(OUT+1)%BUFFER_DIM;
    sem_post(&disponibili); // incrementa il semaforo
    pthread_mutex_unlock(&mutex);

switch(valore_letto.c) {
           
            case '#': /** CASO ASTRONAVE **/
                            if(astronave.x>=0) // se l'astronave è giÃ_ entrata in scena
                                {
                                   // cancello la "vecchia" posizione dell'astronave
                                   mvaddch(astronave.y,astronave.x,' ');
                                }
                            astronave=valore_letto; // aggiorno la sua nuova posizione
			    attron(COLOR_PAIR(5));
                            mvaddch(astronave.y,astronave.x,astronave.c); // e la visualizzo
                            break;


            case '*': /** CASO MISSILE **/
                          missile[valore_letto.p]=valore_letto; // aggiorno la sua nuova posizione
                          if(valore_letto.p%2)       
                             mvaddch(missile[valore_letto.p].y+1,missile[valore_letto.p].x-1,' '); //cancello la "vecchia" posizione del missile
                          else
                             mvaddch(missile[valore_letto.p].y+1,missile[valore_letto.p].x+1,' '); //cancello la "vecchia" posizione del missile
                                              
                          /** ----------------------------------- Controllo collisioni ----------------------------------- **/

                          /** missile -> pareti **/
                          if(missile[valore_letto.p].x>MAXX-1 || missile[valore_letto.p].x<0 || missile[valore_letto.p].y<0) // se il missile raggiunge uno dei bordi laterali o quello superiore
                             {
                                mvaddch(missile[valore_letto.p].y,missile[valore_letto.p].x,' '); // lo cancello
                                pthread_cancel(missile[valore_letto.p].pid); // e uccido il processo
				pthread_detach(missile[valore_letto.p].pid); // e libero la memoria
                             }
                          else // altrimenti
			       {
				attron(COLOR_PAIR(2));
                                mvaddch(missile[valore_letto.p].y,missile[valore_letto.p].x,missile[valore_letto.p].c); // lo visualizzo
			       }

                           /** missile->nemico **/
                          for(i=0;i<M;i++)
                           if((missile[valore_letto.p].x==nemico[i].x)&&(missile[valore_letto.p].y==nemico[i].y)&&nemico[i].vita<1)
                                {
                                    mvaddch(nemico[i].y,nemico[i].x,' '); // nascondo il nemico colpito
                                    mvaddch(missile[valore_letto.p].y,missile[valore_letto.p].x,' '); // nascondo il missile che ha colpito il nemico
                                    pthread_cancel(nemico[i].pid); // uccido il processo del nemico
				    pthread_detach(nemico[i].pid); // e libero la memoria
                                    pthread_cancel(missile[valore_letto.p].pid); // uccido il processo del missile
				    pthread_detach(missile[valore_letto.p].pid); // e libero la memoria
                                    NEM_VIVI--; // decremento il numero dei nemici vivi
                                    nemico[i].vita=0; // metto lo stato di vita del nemico colpito a 0
				    pos.x = nemico[i].x;
				    pos.y = nemico[i].y;
				    pos.i = nemico[i].p;
				    pthread_create(&nemico2_id[nemico[i].p], NULL, &nemico2_func, &pos); 
				    //pthread_join(nemico2_id[nemico[i].p], NULL);                                    
                                }

                            /** missile -> nemico2 **/
                            for(i=0;i<M;i++) // per ogni nemico di secondo livello
                                {
                                  if(nem2[i].xf!=-1) // entrato in scena
                                    {
                                     if((missile[valore_letto.p].x>= nem2[i].xi && missile[valore_letto.p].x<=nem2[i].xf) &&(missile[valore_letto.p].y==nem2[i].y)) // controllo se il nemico2 è stato colpito dal nemico
                                                {
                                                  j=missile[valore_letto.p].x-nem2[i].xi; // verifico quale nemico del proprio gruppo è stato colpito
                                                  if(vite[i][j]>0) // verifico che il nemico abbia ancora vite
                                                    {
						     vite[i][j]--; // decremento il valore delle sue vite
						     if(vite[i][j]<1) // se il valore delle sue vite è arrivato a zero
							{
							 vita_gruppo[i]--; // la vita del suo gruppo viene decrementata
							 NEM_VIVI--; // e anche il numero dei nemici vivi
							}
						    } // fine controllo sulla vita del nemico colpito
                                                                                                 
                                                if(vita_gruppo[i]<1){ // se la vita del gruppo è minore di 1
						    pthread_cancel(nem2[i].pid); // uccido il thread del gruppo dei nemici di 2° livello
						    pthread_detach(nem2[i].pid); // e libero la memoria allocata
						    } // fine controllo sulla vita del gruppo

                                                } // fine controllo sullo scontro missile->nemico2[i]
                                     } // fine controllo sull'entrata in scena del nemico2[i]
                               } // fine for
                                                              
                          break;
case 'H': /** CASO NEMICO2 **/
                          if(nem2[valore_letto.p].xf>=0)
                            for(i=0;i<G;i++)
                                mvaddch(nem2[valore_letto.p].y,nem2[valore_letto.p].xi+i,' '); // cancello la vecchia posizione

                          nem2[valore_letto.p]=valore_letto; // assegno il nuovo valore al nemico2
                          
                          for(i=0;i<G;i++)
                               {
                                 if(vite[valore_letto.p][i]>0) // se il singolo nemico nel gruppo è ancora vivo
				   {
				    if(vite[valore_letto.p][i]==2)
				      attron(COLOR_PAIR(6));
				    else
				      attron(COLOR_PAIR(3));
                                    mvaddch(nem2[valore_letto.p].y,nem2[valore_letto.p].xi+i,nem2[valore_letto.p].c); // lo disegno
				   }
                                 else // altrimenti
                                    mvaddch(nem2[valore_letto.p].y,nem2[valore_letto.p].xi+i,' '); // no
                               }

            /** ----------------------------------- Controllo collisioni ----------------------------------- **/

                         // nemico2 -> astronave
                         if(nem2[valore_letto.p].y==astronave.y) // se il nemico raggiunge la linea dell'astronave
                            {
                              pthread_cancel(nemico[valore_letto.p].pid); // uccido il nemico2
			      pthread_detach(nemico[valore_letto.p].pid); // e libero la memoria
                              pthread_cancel(astronave.pid); // uccido l'astronave
			      pthread_detach(astronave.pid); // e libero la memoria
                              GAME_OVER=-1; // l'astronave ha perso
                            }

                        break;
(continua...)