Problema di scrittura e ricezione pipe(credo)

di il
3 risposte

Problema di scrittura e ricezione pipe(credo)

Salve a tutti , sto programmando in linguaggio c (ambiente linux) un videogioco chiamato Plants vs Frogger , in pratica crossy Road ma con una rana e con delle piante che sparano + dei coccodrilli che nuotano in un'area centrale della mappa . Devo completare questo gioco utilizzando i processi per cui uso le pipe per comunicare tra le varie parti del programma. 
Sto riscontrando un problema cercando di inserire i processi coccodrillo.. il mio progetto è costituito da più parti, abbiamo il main dove richiamo i processi principali e una funzione controllo dove gestisco tutti i processi + le funzioni che gestiscono singolarmente le cose(come i movimenti).. la mia idea per fare questi coccodrilli era creare un array di processi e tramite un for riempire questo array, ciascuno di questi coccodrilli ha delle caratteristiche : y,direzione,velocità e status(coccodrillo buono e cattivo), queste caratteristiche le ho inserite in una struttura personaggio che uso anche per gli altri “personaggi del gioco” come la rana e le piante. Io ho inserito quindi nel main una fork chiamata fiume dove richiamo una funzione “funzFiume ” nella quale all'interno creerò i processi coccodrilli e li riempirò tramite una matrice , questa matrice sarà [8][3] ? 8 sono i flussi del mio fiume e 3 sono: y,direzione e velocità che verranno passati poi nella seguente funzione : funzCrocodile(viene richiamata ogni volta che viene creato un processo coccodrillo nel for) dove gestisco i movimenti del coccodrillo tramite un while(1) e attribuisco quei valori della matrice alla struttura personaggio. La pipe viene usata all'inizio della funz crocodile e alla fine , scrivo la posizione prima e dopo gli spostamenti. Nella funzione controllo poi tramite due funzioni ,una di cancellazione e una di stampa e l'identificazione tramite id (un parametro  della struttura personaggio) capisco che si tratta del personaggio coccodrillo e avviene la cancellazione ovvero l'aggiornamento di posizione e poi la stampa.L'errore che rilevo è uno ***stack smahing detected*** , quindi suppongo di star passando qualcosa che non posso passare… adesso caricherò una parte del codice : la parte del main , le due funzioni fiume e coccodrillo + la parte della funzione controllo.  Ringrazio in anticipo chiunque riesca ad aiutarmi e specifico in anticipo che il mio codice funzionava perfettamente prima dell'inserimento dei coccodrilli.
Se dovesse servire posso inviare anche tutto il progetto. 

int main() {

    int fineGioco;

    int maxX = 0;

    int maxY = 0;

    WINDOW *schermataGioco;

    /*

    if(LINES<10 || COLS<10){

    

    	mvprintw(LINES/2,COLS/2 , "Schermo troppo piccolo!");

    

    }else{

    

    	

    }

*/

   

    Personaggio piante[3];

	

	piante[0].id=2;

	piante[1].id=3;

	piante[2].id=4;

	

	piante[0].x=2;

	piante[1].x=1;

	piante[2].x=2;

	

	piante[0].y=8;

	piante[1].y=26;

	piante[2].y=50;

	

    initscr(); // Inizializza ncurses e schermo

    

    if (initscr() == NULL) {

    	fprintf(stderr, "Errore durante l'inizializzazione di ncurses\n");

    	exit(EXIT_FAILURE);

    }

    

    

    curs_set(0);

    noecho();

    keypad(stdscr, 1);

    

     schermataGioco=newwin(LINES,COLS,0,0);

    	box(schermataGioco,'|','-');

    refresh();

    wrefresh(schermataGioco);

    	

//sleep(3);    	

    getmaxyx(stdscr, maxY, maxX);

    

    int pipe_fds[2], i;

    int pipeFiume[2];  //Pipe per i coccodrilli e i flussi

    int pipeCall[2];

    

    // Crea la pipe, fornendo i file descriptors in "pipe_fds"

    if(pipe(pipe_fds) == -1) {

        // Scrive su stderr, ma include la descrizione dell'ultimo errore che si è presentato

        perror("Pipe call");

        exit(1);

    }

    

    // Crea la pipe, fornendo i file descriptors in "pipeFiume"

    if(pipe(pipeFiume) == -1) {

        // Scrive su stderr, ma include la descrizione dell'ultimo errore che si è presentato

        perror("Pipe call");

        exit(1);

    }

    

     // Crea la pipe, fornendo i file descriptors in "pipeCall"

    if(pipe(pipeCall) == -1) {

        // Scrive su stderr, ma include la descrizione dell'ultimo errore che si è presentato

        perror("Pipe call");

        exit(1);

    }

    

    //Rendo la pipe che comunica della morte della rana non bloccante

    

    if(fcntl(pipeCall[0],F_SETFL,O_NONBLOCK)<0){

    	perror("Pipe non block");

    	exit(1);

    }

    

    

    

    pid_t rana,p1,p2,p3,fiume;

    

    rana = fork();

    

    if(rana < 0){

    	 exit(1);

    	}

    

    else if(rana == 0){

    	close(pipe_fds[0]); //Chiusura lettura

    	funzRana(pipe_fds,pipeCall, schermataGioco);

    	

    } else if(rana>0){ // Processo padre creo la prima pianta

    

    	p1=fork();

    	if(p1 < 0){

         exit(1);

    	}

    	else if(p1 == 0){

    	close(pipe_fds[0]); //Chiusura lettura

    	funzGeneraPianta(pipe_fds,schermataGioco,piante[0]);

    	}

    	else if(p1 > 0){ //Processo padre creo la seconda pianta

    	

    	p2=fork();

    		

    	if(p2 < 0){

         exit(1);

    	}

    	else if(p2 == 0){

    	

    	  close(pipe_fds[0]); //Chiusura lettura

    	  funzGeneraPianta(pipe_fds, schermataGioco,piante[1]);

    	  }

    	  else if(p2 > 0){ //Processo padre creo la terza pianta

    	  

    	  p3=fork();

    		

    	  if(p3 < 0){

           exit(1);

    	  }

    	else if(p3 == 0){

    	

    	    close(pipe_fds[0]); //Chiusura lettura   	    

    	

    	    funzGeneraPianta(pipe_fds, schermataGioco,piante[2]);

    	   }

    	   else if(p3 > 0){

    	   

    	   mvwprintw(schermataGioco,5, 5, "entra nella fork");//Lo stampa

    	   wrefresh(schermataGioco);

    	   sleep(1);

    	   

    	   

    	   	    fiume=fork();

    	   	    if(fiume < 0){

           		exit(1);

    	  	    }

    	  	    else if(fiume == 0){

    	  	    

    	  	    mvwprintw(schermataGioco,8, 8, "esegue la fork");//Lo stampa

    	   	    wrefresh(schermataGioco);

    	   	    sleep(1);

    	   	    

    	  	    

    	  	    close(pipe_fds[0]); //Chiusura lettura

    	  	    

    	  	    funzFiume(pipe_fds, schermataGioco);

    	  	    

    	  	    mvwprintw(schermataGioco,10, 10, "esegue funzFiume");//Non la esegue

    	   	    wrefresh(schermataGioco);

    	   	    sleep(1);

    	   	    

    	  	    

    	  	    

    	  	    

    	  	    }else if(fiume > 0){

    	   	    

    	    	    close(pipe_fds[1]);  // Chiusura scrittura

            	    funzControllo(pipe_fds[0],pipeCall, schermataGioco);//Processo padre

            	    

            	    mvwprintw(schermataGioco,15,15, "entra in funzControllo");//LO stampa solo se vengo colpito

    	   	    wrefresh(schermataGioco);

    	            sleep(1);

    	            

            	    }

		}



    	    }



    	}

        

      }

      

    kill(rana,9);

    kill(p1,9);

    kill(p2,9);

    kill(p3,9);

    kill(fiume,9);

  

   

    

    clear();

    /*

    if(fineGioco == 1){

    	mvprintw(1, 1, "Hai vinto!!!\nPremi 'q' per uscire.");

    } else if(fineGioco == 0){

       	mvprintw(1, 1, "Hai perso\nPremi 'q' per uscire.");

    }

    

    char c;

    

    do {

        c = getch();

    } while (c != 'q');  

    

    if(c == 'q'){

    	endwin();

    }

    */

    return 0;

}


void funzFiume(int pipe[],WINDOW *schermataGioco) { 

   int i, j = 4, z; 
   int flusso[8][3]; //8 flussi , 3 colonne: y, direzione , velocità 

   // Inizializza il generatore di numeri casuali con il timestamp corrente 
   srand(time(NULL)); 
    
   // Inizializza le y dei flussi e la direzione 
   for (i = 0; i < 8 || j < LINES - 4; i++) { 
       flusso[i][0] = j; 
       flusso[i][1] = rand() % 2 ; 
       j += 2; 
   } 
    

   //Inizializzo le velocità 
    
       flusso[0][2] = 50000; // Valore vel. primo flusso  
    flusso[1][2] = 60000;  
    flusso[2][2] = 45000;   
    flusso[3][2] = 55000;   
    flusso[4][2] = 48000;  
    flusso[5][2] = 52000;  
    flusso[6][2] = 50000;  
    flusso[7][2] = 53000;  
     
   pid_t coccodrilli[20]; 
    
   // Creazione dei coccodrilli 
       for (int i = 0; i < 20; i++) { 
        
           int idCoc=14+i;//Parto da id 14 sino a id 34 
            
           coccodrilli[i] = fork(); 
            
           if (coccodrilli[i] < 0) { 
               perror("fork"); 
               exit(EXIT_FAILURE); 
           } else if (coccodrilli[i] == 0) { 
        
     
            close(pipe[0]); // Chiusura del lato di lettura della pipe 
            funzCrocodile(pipe,schermataGioco, flusso[i][0], flusso[i][1], flusso[i][2],idCoc);// funzione per il coccodrillo 

               exit(EXIT_SUCCESS); // Importante terminare il processo figlio correttamente 
        close(pipe[1]);  // Chiusura scrittura  
           }  
       } 

} 

void funzCrocodile(int pipe[],WINDOW *schermataGioco, int posizione, int direzione, int velocita,int id) { 


   Personaggio coccodrillo={posizione,direzione,id,getpid(),velocita};  //y,x(direzione),id,pid,velocità    
    
   write(pipe[1], &coccodrillo, sizeof(coccodrillo)); 
     


  while (1) { 
  usleep(UDELAY); 
   switch (coccodrillo.x) { 
       case 0: 
           // Movimento verso sinistra 
           coccodrillo.x -= 1; 

           break; 
       case 1: 
           // Movimento verso destra 
           coccodrillo.x += 1; 
           break; 
       // Aggiungi altri casi se necessario per gestire altre direzioni 

       default: 
        
           break; 

   } 
    
    

   // Controlla i limiti e gestisci l'attraversamento 
   if (coccodrillo.x <= 0) { 
       coccodrillo.x = COLS - 1; 
   } else if (coccodrillo.x >= COLS - 1) { 
       coccodrillo.x = 0; 
   } 

   // Scrivi la nuova posizione nella pipe per la funzione di controllo 
   write(pipe[1], &coccodrillo, sizeof(coccodrillo)); 
    

   } 
}


void funzControllo(int pipe,int pipePadre[], WINDOW *schermataGioco){



    start_color();

    //init_color(11, 0, 600, 0);//Identificativo colore, quantità di rosso, quantitativo di verde, quantitativo di blu

    init_pair(17, COLOR_BLACK, COLOR_WHITE);

    init_pair(18, COLOR_WHITE, COLOR_BLUE);

    init_pair(19, COLOR_WHITE, COLOR_GREEN);

    init_pair(21, COLOR_WHITE, COLOR_RED);

    

    

	

    int viteRana = 3;

    struct timeval timer;//Tempo del momento preso in considerazione

    struct timeval tempoInizio;

    struct timeval tempoRimasto;

    int diffTempo;//Sarebbe la differenza che otteniamo da timer - tempo iniziale e otteniamo il tempo della manche

    int tempoGiocoRimasto;

    int tempoStampa = 2000000000;

    

    static nodo* listaProiettili = NULL;

    nodo* appoggio = NULL; 

  

    

    int i, j, flagStampaDue;

    

    Personaggio p;

    Personaggio rana = { LINES-5, COLS/2, 1};

    Personaggio coccodrilli[20]; 

    Personaggio piante[3];

    Personaggio proiettiliRana[3];

    Personaggio proiettiliPiante[6];

    int appPiante[3];

    

    campoGioco(schermataGioco);

    

    gettimeofday(&tempoRimasto,NULL);

    

    gettimeofday(&tempoInizio, NULL);

    

    

    while(viteRana > 0){

    

    	

    	

    

    	

    	gettimeofday(&timer, NULL);

    	diffTempo= (timer.tv_sec - tempoInizio.tv_sec);

    	tempoGiocoRimasto = MAX_SECONDS-(timer.tv_sec-tempoRimasto.tv_sec);

    	

    	wattron(schermataGioco,COLOR_PAIR (17));

    	mvwprintw(schermataGioco,LINES-2,10,"Tempo manche:%d",diffTempo);

    	mvwprintw(schermataGioco,LINES-2,COLS/2,"Tempo rimasto:%d",tempoGiocoRimasto);

    	mvwprintw(schermataGioco,LINES - 2, COLS - 21, "Vite rana: %d", viteRana);

    	wattroff(schermataGioco,COLOR_PAIR (17));

        

        

        

        read(pipe, &p, sizeof(p));



	/*

        for(int i=0;i<20;i++){ //Sampa coordinate enormi = problema ricezione della pipe -> stacking smash detected

            mvwprintw(schermataGioco,10+i, 10+i, "coccodrillo:%d ha coordinate x:%d e y:%d",i,coccodrilli[i].x,coccodrilli[i].y);//Lo stampa

    	wrefresh(schermataGioco);

    	sleep(1);

    	}

    	*/

        

        if(p.id == rana.id){

            cancellaRanaOrPiante(schermataGioco,rana);

            rana.y = p.y;

            rana.x = p.x;

            stampaRanaOrPiante(schermataGioco,rana);   

             

        }else if (p.id == 2 || p.id == 3 || p.id == 4){

        

        	cancellaRanaOrPiante(schermataGioco,piante[p.id-PIANTA1]);

        	piante[p.id-PIANTA1]=p;

        	stampaRanaOrPiante(schermataGioco,piante[p.id-PIANTA1]);

        	

        

        }else if (p.id == 5 || p.id == 6 || p.id == 7 ) {

        

        //Controllo che colore deve essere impostato al passaggio del proiettile in base alle coordinate

        if(proiettiliRana[(p.id-PR1)].y >= 5 && proiettiliRana[(p.id-PR1)].y < LINES-5 ){

        	wattron(schermataGioco,COLOR_PAIR(18));	

        	mvwaddch(schermataGioco,proiettiliRana[(p.id-PR1)].y, proiettiliRana[(p.id-PR1)].x, ' '| COLOR_PAIR(18));

        	wattroff(schermataGioco, COLOR_PAIR(18));

        	}else{

        	

        	wattron(schermataGioco,COLOR_PAIR(19));	

        	mvwaddch(schermataGioco,proiettiliRana[(p.id-PR1)].y, proiettiliRana[(p.id-PR1)].x, ' '| COLOR_PAIR(19));

        	wattroff(schermataGioco, COLOR_PAIR(19));

        	

        	}

		proiettiliRana[(p.id-PR1)]=p;  

		wattron(schermataGioco,COLOR_PAIR(21));	

                mvwaddch(schermataGioco,proiettiliRana[(p.id-PR1)].y, proiettiliRana[(p.id-PR1)].x,'|'| COLOR_PAIR(21));

                wattroff(schermataGioco, COLOR_PAIR(21));

   	

   	

        	

        }else if (p.id >= PROIETTILEPIANTA1 && p.id <= PROIETTILEPIANTA6 ) {

        

        //Controllo che colore deve essere impostato al passaggio del proiettile in base alle coordinate

        if(proiettiliPiante[(p.id-PROIETTILEPIANTA1)].y >= 5 && proiettiliPiante[(p.id-PROIETTILEPIANTA1)].y < LINES-5 ){

        	wattron(schermataGioco,COLOR_PAIR(18));	

        	mvwaddch(schermataGioco,proiettiliPiante[(p.id-PROIETTILEPIANTA1)].y, proiettiliPiante[(p.id-PROIETTILEPIANTA1)].x, ' '| 	COLOR_PAIR(18));

        	wattroff(schermataGioco, COLOR_PAIR(18));

        	}else{

        	

        	wattron(schermataGioco,COLOR_PAIR(19));	

        	mvwaddch(schermataGioco,proiettiliPiante[(p.id-PROIETTILEPIANTA1)].y, proiettiliPiante[(p.id-PROIETTILEPIANTA1)].x, ' '| 	COLOR_PAIR(19));

        	wattroff(schermataGioco, COLOR_PAIR(19));

        	

        	}

        	

        	wattron(schermataGioco,COLOR_PAIR(21));	

		proiettiliPiante[(p.id-PROIETTILEPIANTA1)]=p;  

                mvwaddch(schermataGioco,proiettiliPiante[(p.id-PROIETTILEPIANTA1)].y, proiettiliPiante[(p.id-PROIETTILEPIANTA1)].x,'|'| COLOR_PAIR(21));

        	wattroff(schermataGioco,COLOR_PAIR(21));

        		
        //Coccodrilli		



        }else if (p.id >= COCCO1 && p.id <= COCCO20){

        	

        	

        	cancellaCoccodrillo(schermataGioco,coccodrilli[p.id-COCCO1]);

        	coccodrilli[p.id-COCCO1]=p;

        	stampaCoccodrillo(schermataGioco,coccodrilli[p.id-COCCO1]);

        	

        

        }

        

        

        //Collisioni proiettili rana con piante

        

        for(int num=0;num<3;num++){

             for(int pla=0;pla<3;pla++){

        	if((proiettiliRana[num].y==piante[pla].y && proiettiliRana[num].x==piante[pla].x)||(proiettiliRana[num].y==piante[pla].y+1 && proiettiliRana[num].x==piante[pla].x+1)){

        

        	kill(piante[pla].pid,SIGSTOP);//Mette il processo in pausa

        	

        	cancellaRanaOrPiante(schermataGioco,piante[pla]);

        	wattron(schermataGioco,COLOR_PAIR(21));	

                mvwprintw(schermataGioco,LINES/2, COLS/2, "HAI COLPITO UNA PIANTA!!!");

                wattroff(schermataGioco,COLOR_PAIR(21));	

                tempoStampa = timer.tv_sec;

        	appPiante[pla] = tempoStampa;  

        	}

             }	

        	

        }

        

        if(timer.tv_sec >= (tempoStampa+3)){

        	

        	wattron(schermataGioco,COLOR_PAIR(18));	

        	  mvwprintw(schermataGioco,LINES/2, COLS/2, "                         ");

        	wattroff(schermataGioco,COLOR_PAIR(18));

        }

        

        for(int i=0;i<3;i++){

          if(timer.tv_sec >= (appPiante[i]+10)){

        

        	  kill(piante[i].pid,SIGCONT);	

        	  stampaRanaOrPiante(schermataGioco,piante[i]);

        		

          }

        }

        

        int counter=0;

        

        //Collisioni proiettili piante con la rana

        for(int num=0;num<6;num++){

        

        	if((proiettiliPiante[num].y==rana.y && proiettiliPiante[num].x==rana.x)||(proiettiliPiante[num].y==rana.y+1 && proiettiliPiante[num].x==rana.x+1)){

        		counter++;

        		cancellaRanaOrPiante(schermataGioco,rana);

        		wattron(schermataGioco,COLOR_PAIR(21));	

        		mvwprintw(schermataGioco,LINES/2, COLS/2, "TI HANNO COLPITO %d VOLTE!",counter);

        		wattroff(schermataGioco,COLOR_PAIR(21));

        		viteRana--;

        		mvprintw(LINES - 1, 10, "                    ");	

        		gettimeofday(&tempoInizio, NULL);

        		tempoStampa = timer.tv_sec;

        		rana.y=LINES - 5;

        		rana.x=COLS / 2;

        		write(pipePadre[1],&rana,sizeof(rana));

        		stampaRanaOrPiante(schermataGioco,rana);

        		

        	}

        

        }

        if(timer.tv_sec >= (tempoStampa+3)){

        	

        	wattron(schermataGioco,COLOR_PAIR(18));	

        	  mvwprintw(schermataGioco,LINES/2, COLS/2, "                         ");

        	wattroff(schermataGioco,COLOR_PAIR(18));

        }

        

        

        //stampaSchermata(schermataGioco,rana,piante,proiettiliRana,proiettiliPiante);



   

        /*if(viteRana <= 0){

            return 0;

        }

        

        for(int num=0;num<3;num++){

	

		mvprintw(10+num,10+num,"Ecco le coordinate y:%d e x:%d della pianta:%d ",piante[num].y,piante[num].x,num);

		

	

	}*/

        

        //stampaRanaOrPiante(schermataGioco,rana);

       // wrefresh(schermataGioco);

        //sleep(3);

        wrefresh(schermataGioco);

        //sleep(3);

    }

    //return 1;  

    }











3 Risposte

  • Re: Problema di scrittura e ricezione pipe(credo)

    Il codice è poco leggibile con tutte quelle linee vuote…

    L'errore indica un buffet overflow… puoi indicare quando si manifesta?

  • Re: Problema di scrittura e ricezione pipe(credo)

    01/05/2024 - oregon ha scritto:


    Il codice è poco leggibile con tutte quelle linee vuote…

    L'errore indica un buffet overflow… puoi indicare quando si manifesta?

    Ho cercato di rendere il codice più leggibile possibile, inoltre ho inserito delle stampe commentate che ho usato per verificare da dove si ferma , si manifesta subito dopo la stampa “esegue la fork”  ? nel main dove c'e l'else if fiume==0. Aggiungo alla fine di tutto la stampa del coccodrillo e la cancellazione , anche se non credo possano essere la fonte del problema.

    int main() {
    
        int fineGioco;
    
        int maxX = 0;
    
        int maxY = 0;
    
        WINDOW *schermataGioco;
    
        /*
    
        if(LINES<10 || COLS<10){
    
        
    
        	mvprintw(LINES/2,COLS/2 , "Schermo troppo piccolo!");
    
        
    
        }else{
    
        
    
        	
    
        }
    
    */
    
       
    
        Personaggio piante[3];
    
    	
    
    	piante[0].id=2;
    
    	piante[1].id=3;
    
    	piante[2].id=4;
    
    	
    
    	piante[0].x=2;
    
    	piante[1].x=1;
    
    	piante[2].x=2;
    
    	
    
    	piante[0].y=8;
    
    	piante[1].y=26;
    
    	piante[2].y=50;
    
    	
    
        initscr(); // Inizializza ncurses e schermo
    
        
    
        if (initscr() == NULL) {
    
        	fprintf(stderr, "Errore durante l'inizializzazione di ncurses\n");
    
        	exit(EXIT_FAILURE);
    
        }
    
        
    
        
    
        curs_set(0);
    
        noecho();
    
        keypad(stdscr, 1);
    
        
    
         schermataGioco=newwin(LINES,COLS,0,0);
    
        	box(schermataGioco,'|','-');
    
        refresh();
    
        wrefresh(schermataGioco);
    
        	
    
    //sleep(3);    	
    
        getmaxyx(stdscr, maxY, maxX);
    
        
    
        int pipe_fds[2], i;
    
        int pipeFiume[2];  //Pipe per i coccodrilli e i flussi
    
        int pipeCall[2];
    
        
    
        // Crea la pipe, fornendo i file descriptors in "pipe_fds"
    
        if(pipe(pipe_fds) == -1) {
    
            // Scrive su stderr, ma include la descrizione dell'ultimo errore che si è presentato
    
            perror("Pipe call");
    
            exit(1);
    
        }
    
        
    
        // Crea la pipe, fornendo i file descriptors in "pipeFiume"
    
        if(pipe(pipeFiume) == -1) {
    
            // Scrive su stderr, ma include la descrizione dell'ultimo errore che si è presentato
    
            perror("Pipe call");
    
            exit(1);
    
        }
    
        
    
         // Crea la pipe, fornendo i file descriptors in "pipeCall"
    
        if(pipe(pipeCall) == -1) {
    
            // Scrive su stderr, ma include la descrizione dell'ultimo errore che si è presentato
    
            perror("Pipe call");
    
            exit(1);
    
        }
    
        
    
        //Rendo la pipe che comunica della morte della rana non bloccante
    
        
    
        if(fcntl(pipeCall[0],F_SETFL,O_NONBLOCK)<0){
    
        	perror("Pipe non block");
    
        	exit(1);
    
        }
    
        
    
        
    
    
    
        pid_t rana,p1,p2,p3,fiume;
    
        
    
        rana = fork();
    
        
    
        if(rana < 0){
    
        	 exit(1);
    
        	}
    
        
    
        else if(rana == 0){
    
        	close(pipe_fds[0]); //Chiusura lettura
    
        	funzRana(pipe_fds,pipeCall, schermataGioco);
    
        	
    
        } else if(rana>0){ // Processo padre creo la prima pianta
    
        
    
        	p1=fork();
    
        	if(p1 < 0){
    
             exit(1);
    
        	}
    
        	else if(p1 == 0){
    
        	close(pipe_fds[0]); //Chiusura lettura
    
        	funzGeneraPianta(pipe_fds,schermataGioco,piante[0]);
    
        	}
    
        	else if(p1 > 0){ //Processo padre creo la seconda pianta
    
        	
    
        	p2=fork();
    
        		
    
        	if(p2 < 0){
    
             exit(1);
    
        	}
    
        	else if(p2 == 0){
    
        	
    
        	  close(pipe_fds[0]); //Chiusura lettura
    
        	  funzGeneraPianta(pipe_fds, schermataGioco,piante[1]);
    
        	  }
    
        	  else if(p2 > 0){ //Processo padre creo la terza pianta
    
        	  
    
        	  p3=fork();
    
        		
    
        	  if(p3 < 0){
    
               exit(1);
    
        	  }
    
        	else if(p3 == 0){
    
        	
    
        	    close(pipe_fds[0]); //Chiusura lettura   	    
    
        	
    
        	    funzGeneraPianta(pipe_fds, schermataGioco,piante[2]);
    
        	   }
    
        	   else if(p3 > 0){
    
        	   
    
        	   mvwprintw(schermataGioco,5, 5, "entra nella fork");//Lo stampa
    
        	   wrefresh(schermataGioco);
    
        	   sleep(1);
    
        	   
    
        	   
    
        	   	    fiume=fork();
    
        	   	    if(fiume < 0){
    
               		exit(1);
    
        	  	    }
    
        	  	    else if(fiume == 0){
    
        	  	    
    
        	  	    mvwprintw(schermataGioco,8, 8, "esegue la fork");//Lo stampa
    
        	   	    wrefresh(schermataGioco);
    
        	   	    sleep(1);
    
        	   	    
    
        	  	    
    
        	  	    close(pipe_fds[0]); //Chiusura lettura
    
        	  	    
    
        	  	    funzFiume(pipe_fds, schermataGioco);
    
        	  	    
    
        	  	    mvwprintw(schermataGioco,10, 10, "esegue funzFiume");//Non la esegue
    
        	   	    wrefresh(schermataGioco);
    
        	   	    sleep(1);
    
    
    
        	  	    }else if(fiume > 0){
    
        	   	    
    
        	    	    close(pipe_fds[1]);  // Chiusura scrittura
    
                	    funzControllo(pipe_fds[0],pipeCall, schermataGioco);//Processo padre
    
                	    
    
                	    mvwprintw(schermataGioco,15,15, "entra in funzControllo");//LO stampa solo se vengo colpito
    
        	   	    wrefresh(schermataGioco);
    
        	            sleep(1);
    
        	            
    
                	    }
    
    		}
    
    
    
        	    }
    
    
    
        	}
    
            
    
          }
    
          
    
        kill(rana,9);
    
        kill(p1,9);
    
        kill(p2,9);
    
        kill(p3,9);
    
    
    
        clear();
    
        /*
    
        if(fineGioco == 1){
    
        	mvprintw(1, 1, "Hai vinto!!!\nPremi 'q' per uscire.");
    
        } else if(fineGioco == 0){
    
           	mvprintw(1, 1, "Hai perso\nPremi 'q' per uscire.");
    
        }
    
        
    
        char c;
    
        
    
        do {
    
            c = getch();
    
        } while (c != 'q');  
    
        
    
        if(c == 'q'){
    
        	endwin();
    
        }
    
        */
    
        return 0;
    
    }
    
    void funzFiume(int pipe[],WINDOW *schermataGioco) {
    
    /*
    	mvwprintw(schermataGioco,20, 20, "entra in funz fiume");//Lo stampa
        	wrefresh(schermataGioco);
        	sleep(1);
    */
        int i, j = 4, z;
        int flusso[8][3]; //8 flussi , 3 colonne: y, direzione , velocità
    
        // Inizializza il generatore di numeri casuali con il timestamp corrente
        srand(time(NULL));
        
        // Inizializza le y dei flussi e la direzione
        for (i = 0; i < 8 || j < LINES - 4; i++) {
            flusso[i][0] = j;
            flusso[i][1] = rand() % 2 ;
            j += 2;
        }
        
    
        //Inizializzo le velocità
        
        	flusso[0][2] = 50000; // Valore vel. primo flusso 
    	flusso[1][2] = 60000; 
    	flusso[2][2] = 45000;  
    	flusso[3][2] = 55000;  
    	flusso[4][2] = 48000; 
    	flusso[5][2] = 52000; 
    	flusso[6][2] = 50000; 
    	flusso[7][2] = 53000; 
    	
        pid_t coccodrilli[20];
        
        // Creazione dei coccodrilli
            for (int i = 0; i < 20; i++) {
            
                int idCoc=14+i;//Parto da id 14 sino a id 34
                
                coccodrilli[i] = fork();
                
                if (coccodrilli[i] < 0) {
                    perror("fork");
                    exit(EXIT_FAILURE);
                } else if (coccodrilli[i] == 0) {
    		
    	/*
    	mvwprintw(schermataGioco,30, 20, "fa la fork dei coccodrilli");//Lo stampa
        	wrefresh(schermataGioco);
        	sleep(1);
    	
    	mvwprintw(schermataGioco,1+coccodrilli[i], 10+coccodrilli[i], "coccodrillo:%d ha pid:%d",i,getpid());//Lo stampa
        	wrefresh(schermataGioco);
        	sleep(1);
        	*/
    	
             	close(pipe[0]); // Chiusura del lato di lettura della pipe
             	funzCrocodile(pipe,schermataGioco, flusso[i][0], flusso[i][1], flusso[i][2],idCoc);// funzione per il coccodrillo
    
                    exit(EXIT_SUCCESS); // Importante terminare il processo figlio correttamente
    		close(pipe[1]);  // Chiusura scrittura 
                } 
            }
    
        	/*
            mvwprintw(schermataGioco,20, 20, "finisce correttamente funzFiume");// lo stampa
        	wrefresh(schermataGioco);
        	sleep(1);
        	*/
    }
    
    void funzCrocodile(int pipe[],WINDOW *schermataGioco, int posizione, int direzione, int velocita,int id) {
    
    	/*
    	mvwprintw(schermataGioco,10, 20, "entro in funz crocodile");//Lo stampa
        	wrefresh(schermataGioco);
        	sleep(1);
    	*/
    
        Personaggio coccodrillo={posizione,direzione,id,getpid(),velocita};  //y,x(direzione),id,pid,velocità   
        
        write(pipe[1], &coccodrillo, sizeof(coccodrillo));
    	
    	/*
    	mvwprintw(schermataGioco,10, 20, "Assegno i valori giusti?");//Lo stampa
        	wrefresh(schermataGioco);
        	sleep(1);
    	*/
    	
    	/*
    	mvwprintw(schermataGioco,1+coccodrillo.id, 10+coccodrillo.id, "coccodrillo:%d ha pid:%d",coccodrillo.id,coccodrillo.pid);//Lo stampa
        	wrefresh(schermataGioco);
        	sleep(1);
         	   	
        	mvwprintw(schermataGioco,1+coccodrillo.id, 10+coccodrillo.id, "coccodrillo:%d ha coordinate x:%d e y:%d",coccodrillo.id,coccodrillo.x,coccodrillo.y);//Lo stampa
        	wrefresh(schermataGioco);
        	sleep(1);
        	*/
    
       while (1) {
       usleep(UDELAY);
        switch (coccodrillo.x) {
            case 0:
                // Movimento verso sinistra
                coccodrillo.x -= 1;
    
                break;
            case 1:
                // Movimento verso destra
                coccodrillo.x += 1;
                break;
            // Aggiungi altri casi se necessario per gestire altre direzioni
    
            default:
            
                break;
    
        }
    
        // Controlla i limiti e gestisci l'attraversamento
        if (coccodrillo.x <= 0) {
            coccodrillo.x = COLS - 1;
        } else if (coccodrillo.x >= COLS - 1) {
            coccodrillo.x = 0;
        }
    
        // Scrivi la nuova posizione nella pipe per la funzione di controllo
        write(pipe[1], &coccodrillo, sizeof(coccodrillo));
        
        /*
        mvwprintw(schermataGioco,1+coccodrillo.id, 10+coccodrillo.id, "ho scritto nella pipe : %ld",read(pipe[1],&coccodrillo,sizeof(int)));//Lo stampa
        	wrefresh(schermataGioco);
        	sleep(1);
         */
        }
    }
    
    void funzControllo(int pipe,int pipePadre[], WINDOW *schermataGioco){
    
        start_color();
        //init_color(11, 0, 600, 0);//Identificativo colore, quantità di rosso, quantitativo di verde, quantitativo di blu
        init_pair(17, COLOR_BLACK, COLOR_WHITE);
        init_pair(18, COLOR_WHITE, COLOR_BLUE);
        init_pair(19, COLOR_WHITE, COLOR_GREEN);
        init_pair(21, COLOR_WHITE, COLOR_RED);
    	
        int viteRana = 3;
        struct timeval timer;//Tempo del momento preso in considerazione
        struct timeval tempoInizio;
        struct timeval tempoRimasto;
        int diffTempo;//Sarebbe la differenza che otteniamo da timer - tempo iniziale e otteniamo il tempo della manche
        int tempoGiocoRimasto;
        int tempoStampa = 2000000000;
        
        static nodo* listaProiettili = NULL;
        nodo* appoggio = NULL; 
      
       
        int i, j, flagStampaDue;
        
        Personaggio p;
        Personaggio rana = { LINES-5, COLS/2, 1};
        Personaggio coccodrilli[20]; 
        Personaggio piante[3];
        Personaggio proiettiliRana[3];
        Personaggio proiettiliPiante[6];
        int appPiante[3];
        
        campoGioco(schermataGioco);
       
        gettimeofday(&tempoRimasto,NULL);
      
        gettimeofday(&tempoInizio, NULL);
         
        while(viteRana > 0){
      	
        	gettimeofday(&timer, NULL);
        	diffTempo= (timer.tv_sec - tempoInizio.tv_sec);
        	tempoGiocoRimasto = MAX_SECONDS-(timer.tv_sec-tempoRimasto.tv_sec);
        	
        	wattron(schermataGioco,COLOR_PAIR (17));
        	mvwprintw(schermataGioco,LINES-2,10,"Tempo manche:%d",diffTempo);
        	mvwprintw(schermataGioco,LINES-2,COLS/2,"Tempo rimasto:%d",tempoGiocoRimasto);
        	mvwprintw(schermataGioco,LINES - 2, COLS - 21, "Vite rana: %d", viteRana);
        	wattroff(schermataGioco,COLOR_PAIR (17));
    
            read(pipe, &p, sizeof(p));
    
    	/*
            for(int i=0;i<20;i++){ //Sampa coordinate enormi = problema ricezione della pipe -> stacking smash detected
                mvwprintw(schermataGioco,10+i, 10+i, "coccodrillo:%d ha coordinate x:%d e y:%d",i,coccodrilli[i].x,coccodrilli[i].y);//Lo stampa
        	wrefresh(schermataGioco);
        	sleep(1);
        	}
        	*/
            if(p.id == rana.id){
                cancellaRanaOrPiante(schermataGioco,rana);
                rana.y = p.y;
                rana.x = p.x;
                stampaRanaOrPiante(schermataGioco,rana);   
                 
            }else if (p.id == 2 || p.id == 3 || p.id == 4){
            
            	cancellaRanaOrPiante(schermataGioco,piante[p.id-PIANTA1]);
            	piante[p.id-PIANTA1]=p;
            	stampaRanaOrPiante(schermataGioco,piante[p.id-PIANTA1]); 
            }else if (p.id == 5 || p.id == 6 || p.id == 7 ) {
            
            //Controllo che colore deve essere impostato al passaggio del proiettile in base alle coordinate
            if(proiettiliRana[(p.id-PR1)].y >= 5 && proiettiliRana[(p.id-PR1)].y < LINES-5 ){
            	wattron(schermataGioco,COLOR_PAIR(18));	
            	mvwaddch(schermataGioco,proiettiliRana[(p.id-PR1)].y, proiettiliRana[(p.id-PR1)].x, ' '| COLOR_PAIR(18));
            	wattroff(schermataGioco, COLOR_PAIR(18));
            	}else{
            	
            	wattron(schermataGioco,COLOR_PAIR(19));	
            	mvwaddch(schermataGioco,proiettiliRana[(p.id-PR1)].y, proiettiliRana[(p.id-PR1)].x, ' '| COLOR_PAIR(19));
            	wattroff(schermataGioco, COLOR_PAIR(19));
            	
            	}
    		proiettiliRana[(p.id-PR1)]=p;  
    		wattron(schermataGioco,COLOR_PAIR(21));	
                    mvwaddch(schermataGioco,proiettiliRana[(p.id-PR1)].y, proiettiliRana[(p.id-PR1)].x,'|'| COLOR_PAIR(21));
                    wattroff(schermataGioco, COLOR_PAIR(21));
            }else if (p.id >= PROIETTILEPIANTA1 && p.id <= PROIETTILEPIANTA6 ) {
            
            //Controllo che colore deve essere impostato al passaggio del proiettile in base alle coordinate
            if(proiettiliPiante[(p.id-PROIETTILEPIANTA1)].y >= 5 && proiettiliPiante[(p.id-PROIETTILEPIANTA1)].y < LINES-5 ){
            	wattron(schermataGioco,COLOR_PAIR(18));	
            	mvwaddch(schermataGioco,proiettiliPiante[(p.id-PROIETTILEPIANTA1)].y, proiettiliPiante[(p.id-PROIETTILEPIANTA1)].x, ' '| 	COLOR_PAIR(18));
            	wattroff(schermataGioco, COLOR_PAIR(18));
            	}else{
            	
            	wattron(schermataGioco,COLOR_PAIR(19));	
            	mvwaddch(schermataGioco,proiettiliPiante[(p.id-PROIETTILEPIANTA1)].y, proiettiliPiante[(p.id-PROIETTILEPIANTA1)].x, ' '| 	COLOR_PAIR(19));
            	wattroff(schermataGioco, COLOR_PAIR(19));
            	
            	}
    
            	wattron(schermataGioco,COLOR_PAIR(21));	
    		proiettiliPiante[(p.id-PROIETTILEPIANTA1)]=p;  
                    mvwaddch(schermataGioco,proiettiliPiante[(p.id-PROIETTILEPIANTA1)].y, proiettiliPiante[(p.id-PROIETTILEPIANTA1)].x,'|'| COLOR_PAIR(21));
            	wattroff(schermataGioco,COLOR_PAIR(21));
            		
            }else if (p.id >= COCCO1 && p.id <= COCCO20){
            	cancellaCoccodrillo(schermataGioco,coccodrilli[p.id-COCCO1]);
            	coccodrilli[p.id-COCCO1]=p;
            	stampaCoccodrillo(schermataGioco,coccodrilli[p.id-COCCO1]);
            	
            
            } 
            //Collisioni proiettili rana con piante
            
            for(int num=0;num<3;num++){
                 for(int pla=0;pla<3;pla++){
            	if((proiettiliRana[num].y==piante[pla].y && proiettiliRana[num].x==piante[pla].x)||(proiettiliRana[num].y==piante[pla].y+1 && proiettiliRana[num].x==piante[pla].x+1)){
            
            	kill(piante[pla].pid,SIGSTOP);//Mette il processo in pausa
            	
            	cancellaRanaOrPiante(schermataGioco,piante[pla]);
            	wattron(schermataGioco,COLOR_PAIR(21));	
                    mvwprintw(schermataGioco,LINES/2, COLS/2, "HAI COLPITO UNA PIANTA!!!");
                    wattroff(schermataGioco,COLOR_PAIR(21));	
                    tempoStampa = timer.tv_sec;
            	appPiante[pla] = tempoStampa;  
            	}
                 }	
            	
            }
     
            if(timer.tv_sec >= (tempoStampa+3)){
            	
            	wattron(schermataGioco,COLOR_PAIR(18));	
            	  mvwprintw(schermataGioco,LINES/2, COLS/2, "                         ");
            	wattroff(schermataGioco,COLOR_PAIR(18));
            }   
            for(int i=0;i<3;i++){
              if(timer.tv_sec >= (appPiante[i]+10)){
            
            	  kill(piante[i].pid,SIGCONT);	
            	  stampaRanaOrPiante(schermataGioco,piante[i]);
            		
              }
            }
            
            int counter=0;
            
            //Collisioni proiettili piante con la rana
            for(int num=0;num<6;num++){
            
            	if((proiettiliPiante[num].y==rana.y && proiettiliPiante[num].x==rana.x)||(proiettiliPiante[num].y==rana.y+1 && proiettiliPiante[num].x==rana.x+1)){
            		counter++;
            		cancellaRanaOrPiante(schermataGioco,rana);
            		wattron(schermataGioco,COLOR_PAIR(21));	
            		mvwprintw(schermataGioco,LINES/2, COLS/2, "TI HANNO COLPITO %d VOLTE!",counter);
            		wattroff(schermataGioco,COLOR_PAIR(21));
            		viteRana--;
            		mvprintw(LINES - 1, 10, "                    ");	
            		gettimeofday(&tempoInizio, NULL);
            		tempoStampa = timer.tv_sec;
            		rana.y=LINES - 5;
            		rana.x=COLS / 2;
            		write(pipePadre[1],&rana,sizeof(rana));
            		stampaRanaOrPiante(schermataGioco,rana);
            		
            	}
            
            }
            if(timer.tv_sec >= (tempoStampa+3)){
            	
            	wattron(schermataGioco,COLOR_PAIR(18));	
            	  mvwprintw(schermataGioco,LINES/2, COLS/2, "                         ");
            	wattroff(schermataGioco,COLOR_PAIR(18));
            }
            /*if(viteRana <= 0){
                return 0;
            }
            
            for(int num=0;num<3;num++){
    	
    		mvprintw(10+num,10+num,"Ecco le coordinate y:%d e x:%d della pianta:%d ",piante[num].y,piante[num].x,num);
    
    	}*/
            
            //stampaRanaOrPiante(schermataGioco,rana);
           // wrefresh(schermataGioco);
            //sleep(3);
            wrefresh(schermataGioco);
            //sleep(3);
        }
        //return 1;  
        }
        
        void stampaCoccodrillo(WINDOW *schermataGioco,Personaggio personaggio){	
    
    	char disCocco[2][6];
    
            
    
             disCocco[0][0]= ' ' ;
    
             disCocco[0][1]= '^';
    
             disCocco[1][0]= '<';
    
             disCocco[1][1]= '-';
    
             disCocco[0][2]= '^';
    
             disCocco[1][2]= '-';
    
             disCocco[0][3]= '^';
    
             disCocco[1][3]= '-';
    
             disCocco[0][4]= '-';
    
             disCocco[1][4]= '-';
    
             disCocco[0][5]= ' ';
    
             disCocco[1][5]= '=';
    
        	
    
        	wattron(schermataGioco,COLOR_PAIR(21));	
    
        	for (int i = 0; i < 2; i++) {
    
            	for (int j = 0; j < 6; j++) {
    
                		mvwaddch(schermataGioco,personaggio.y+i,personaggio.x+j,disCocco[i][j]);
    
            	}
    
       	}
    
       	wattroff(schermataGioco,COLOR_PAIR(21));
    
    
    
    }
    
    
    
    void cancellaCoccodrillo(WINDOW *schermataGioco,Personaggio personaggio){
    
    
    
    
    
    	char cancCocco[2][6];
    
    	
    
    	for (int i = 0; i < 2; i++) {
    
            	for (int j = 0; j < 6; j++) {
    
                		mvwaddch(schermataGioco,personaggio.y+i,personaggio.x+j,' ');
    
            	}
    
       	}
    
    
    
    }
  • Re: Problema di scrittura e ricezione pipe(credo)

    01/05/2024 - oregon ha scritto:


    Il codice è poco leggibile con tutte quelle linee vuote…

    L'errore indica un buffet overflow… puoi indicare quando si manifesta?

    Ciao , ho creato anche un piccolo simil-progetto con solo implementati i coccodrilli , l'errore si vede e si può vedere anche li.

    https://pastebin.com/eYX3Z89v

Devi accedere o registrarti per scrivere nel forum
3 risposte