1
Linux / Pipe writing and receiving problem(I think)
« Dernier message par federico.castrignano le Hier à 19:59:58 »Hello everyone, I apologize in advance if what is written is not entirely correct but I am using a translator… I'm programming in C language (Linux environment) a video game called Plants vs Frogger, basically Crossy Road but with a frog and some plants that shoot + some crocodiles that swim in a central area of the map. I have to complete this game using processes whereby I use pipes to communicate between various parts of the program.
I'm having a problem trying to insert the crocodile processes... my project consists of several parts, we have the main where I recall the main processes and a control function where I manage all the processes + the functions that manage things individually (like movements ).. my idea for making these crocodiles was to create an array of processes and through a for fill this array, each of these crocodiles has characteristics: y, direction, speed and status (good and bad crocodile), I have these characteristics inserted into a character structure that I also use for the other "game characters" such as the frog and the plants. I have therefore inserted a fork called river into the main where I call a "functionRiver" function in which I will create the crocodile processes inside and fill them using a matrix, this matrix will be [8][3]? 8 are the flows of my river and 3 are: y, direction and speed which will then be passed into the following function: funcCrocodile (it is called every time a crocodile process is created in the for) where I manage the crocodile's movements via a while(1 ) and attribute those matrix values to the character structure. The pipe is used at the beginning of the crocodile function and at the end, I write the position before and after the movements. In the control function then through two functions, one for deletion and one for printing and identification via id (a parameter of the character structure) I understand that it is the crocodile character and the deletion takes place or the position is updated and then printed. The error I detect is a ***stack smahing detected***, so I suppose I'm passing something that I can't pass... now I'll load a part of the code: the main part, the two functions river and crocodile + the part of the control function. I thank in advance anyone who can help me and I specify in advance that my code worked perfectly before the inclusion of the crocodiles.
If needed, I can also send the entire project.
Inviato dal mio iPhone utilizzando Tapatalk
I'm having a problem trying to insert the crocodile processes... my project consists of several parts, we have the main where I recall the main processes and a control function where I manage all the processes + the functions that manage things individually (like movements ).. my idea for making these crocodiles was to create an array of processes and through a for fill this array, each of these crocodiles has characteristics: y, direction, speed and status (good and bad crocodile), I have these characteristics inserted into a character structure that I also use for the other "game characters" such as the frog and the plants. I have therefore inserted a fork called river into the main where I call a "functionRiver" function in which I will create the crocodile processes inside and fill them using a matrix, this matrix will be [8][3]? 8 are the flows of my river and 3 are: y, direction and speed which will then be passed into the following function: funcCrocodile (it is called every time a crocodile process is created in the for) where I manage the crocodile's movements via a while(1 ) and attribute those matrix values to the character structure. The pipe is used at the beginning of the crocodile function and at the end, I write the position before and after the movements. In the control function then through two functions, one for deletion and one for printing and identification via id (a parameter of the character structure) I understand that it is the crocodile character and the deletion takes place or the position is updated and then printed. The error I detect is a ***stack smahing detected***, so I suppose I'm passing something that I can't pass... now I'll load a part of the code: the main part, the two functions river and crocodile + the part of the control function. I thank in advance anyone who can help me and I specify in advance that my code worked perfectly before the inclusion of the crocodiles.
If needed, I can also send the entire project.
Code: [Sélectionner]
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,' ');
}
}
}
Inviato dal mio iPhone utilizzando Tapatalk