Salve ragazzi!
Sto implementando un programmino didattico: sarebbe una emulazione del gioco di space invaders (ma molto grezzo!),con grafica scarna.
Il programma è quasi analogo al classico problema dei "produttori-consumatori": creo dei processi con relativi thread, che accedono ad un buffer condiviso (protetto da semafori), basandomi sulle librerie lpthread e lncurses.
Riesco a creare correttamente i processi (e i thread) ma non riesco a fare altrettanto correttamente in fase di visualizzazione,gli alieni vengono sovrapposti su un'unica casella, così da sembrare che ve ne fosse solo uno, e non riesco a capirne il motivo. Per ora cerco di fare stampare solo gli alieni, in seguito implementerò le bombe e la nave del personaggio principale.
Qualcuno può darmi una mano? Vi allego il codice:
P.S. Compilare con le opzioni -lpthread & -lncurses, es:codice:#include <stdio.h> #include <curses.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <semaphore.h> #define NUM_MAX_RIGHE 5 #define SINISTRA 68 #define DESTRA 67 #define N_INIZIALE_ALIENI 4 #define SPAZIO 1 #define SPAZIO_RIGHE 1 #define PASSO_X 2 #define PASSO_Y 1 #define MAX_BOMBE_NAVE 1 #define DIM_BUFFER N_INIZIALE_ALIENI struct pos { char *c; int x; int y; int xPrec; int yPrec; int index; int id; }; struct pos alieni[N_INIZIALE_ALIENI]; int info_elementi[DIM_BUFFER]; void *alieno(void *); void *controllo(void *); pthread_t array_alieni[N_INIZIALE_ALIENI]; pthread_mutex_t semaforo = PTHREAD_MUTEX_INITIALIZER; sem_t vuoto, pieno; int dimAlieni, bufferScrittura, bufferLettura, counter; int main() { int i = 0, j = 1, k, nAlieniRiga; pthread_t nave; pthread_t bombaNave[MAX_BOMBE_NAVE]; pthread_t bombaAlieno[N_INIZIALE_ALIENI]; initscr(); noecho(); curs_set(0); bufferScrittura = 0; bufferLettura = 0; counter = 0; dimAlieni = 1; nAlieniRiga = 20 / (dimAlieni + SPAZIO); //20 è inteso come numero COLS (pechè non abbiamo inizializzato le variabili di ncurses sem_init(&vuoto, 0, DIM_BUFFER); sem_init(&pieno, 0, 0); for (k = 0; k < N_INIZIALE_ALIENI; k++){ //struct pos pos_alieno; i = k % nAlieniRiga; j = (k / nAlieniRiga) + 1; alieni[k].x = i * (SPAZIO + 1); alieni[k].y = j * (SPAZIO_RIGHE + 1); alieni[k].c = "#"; alieni[k].index = k; pthread_create(&array_alieni[k], NULL, &alieno, &alieni[k]); } controllo(NULL); getchar(); endwin(); exit(0); } void *alieno(void *args) { struct pos pos_alieno = *(struct pos*) args; pos_alieno.id = pthread_self(); int dir = 1, dx, dy; srand(pos_alieno.id); while(1) { pos_alieno.yPrec = pos_alieno.y; pos_alieno.xPrec = pos_alieno.x; dx = PASSO_X * dir; dy = 0; if (pos_alieno.x + dx >= COLS -1 || pos_alieno.x + dx <= 0) { if(dir > 0) pos_alieno.x = COLS - 1; else pos_alieno.x = 0; dir = -dir; dx = PASSO_X * dir; dy = PASSO_Y; } pos_alieno.x += dx; pos_alieno.y += dy; //sleep(rand() % 2); non funziona sem_wait(&vuoto); //Segnala che è stata scritta un altra posizione nel buffer pthread_mutex_lock(&semaforo); //equivale ad una wait su valore 1, che poi viene reincrementata dall'unlock che gli ri da valore 1 info_elementi[bufferScrittura] = pos_alieno.index; bufferScrittura = (bufferScrittura + 1) % DIM_BUFFER; //printf("Buffer Scrittura %d\n", bufferScrittura); //facevo un po di debug! alieni[pos_alieno.index] = pos_alieno; pthread_mutex_unlock(&semaforo); sem_post(&pieno); //Segnala che c'è una posizione in più da leggere nel buffer sleep(1); } } void *controllo(void *args) { struct pos valore_letto; int index, i = 0; do { //sleep(rand() % 2); non funziona nemmeno così sem_wait(&pieno); //Segnala che è stata letta una posizione dal buffer pthread_mutex_lock(&semaforo); index = info_elementi[bufferLettura]; bufferLettura = (bufferLettura + 1) % DIM_BUFFER; valore_letto = alieni[index]; pthread_mutex_unlock(&semaforo); sem_post(&vuoto); move(valore_letto.yPrec, valore_letto.xPrec); printw(" "); //printw move(valore_letto.y, valore_letto.x); printw("%s",valore_letto.c); move(index, 0); //printw("%d",i); tutto questo è debug //printw("Valore letto x: %d, Valore letto y: %d, Numero alieno %d,\n", valore_letto.x, valore_letto.y, valore_letto.index); //move(0,15); //printw("\tlivello %d",livello); //move(0,27); //printw("\tvite %d",nave_vita); refresh(); i++; } while (true); }
gcc -o alieni alienThread.c -lncurses -lpthread

Rispondi quotando