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,' ');
}
}
}