示例#1
0
文件: scores.c 项目: SonnyJim/spang
void scores_write (void *ptr)
{
    scores_init ();
    scores_load ();
    scores_generate_html ();
    while (running)
    {
        if (score_new)
        {
            fprintf (stdout, "New score received\n");
            scores_print ();
            score_new = 0;
        }
    }
}
示例#2
0
/**
 * Funzione di rendering e gestione delle iterazioni tra gli oggetti della scena
 */
void control_task()
{
	int i;			
	
	/* System V: inizializzazione */
	// Queue id per i messaggi
	int    qid;			
	
	// Chiave del progetto per individuare la coda dei messaggi
    key_t  msgkey;
    
    // Genero la chiave ipc    
    msgkey = ftok(FTOK_PATH, FTOK_PROJ_ID);    
    
    // Apro (o creo) la coda
    if((qid = msgget(msgkey, 0666 | IPC_CREAT)) == -1)
    {
		perror("Impossibile creare la coda");
		exit(1);
    }
    
    /* Inoltre creo una queue per ogni alieno, per trasmettere le comunicazioni
     * relative alle collisioni */
    int	qid_coll[ALIEN_NUM];
    key_t msgkey_coll[ALIEN_NUM];
    
    // Struttura per memorizzare lo stato delle collisioni ed inviarlo coem messaggio all'alieno
	collision_msg_t coll_m;
	coll_m.mtype = 1;
	
	/* Genero le chiavi e creo le code */
	for(i = 0; i < ALIEN_NUM; i++)
	{
		msgkey_coll[i] = ftok(FTOK_PATH, FTOK_PROJ_ID_COLL_BASE + i);    
		
		// Apro (o creo) la coda
		if((qid_coll[i] = msgget(msgkey_coll[i], 0666 | IPC_CREAT)) == -1)
		{
			perror("Impossibile creare la coda");
			exit(1);
		}		
	}
	
    
    int last_alien_hit = -1;// Id dell'ultimo alieno colpito
	int obj_n = 1;			// Numero di oggetti nella scena
	int scores = 0;			// Punteggio
	char buffer[512];		// Buffer per stampare le stats
	unsigned long iterations = 0;	// Numero di iterazioni		
	int aliens = ALIEN_NUM;	
	
	// Buffer di ricezione
	object_data_t recv_data;
	
	// Informazioni degli oggetti; la navicella e' in posizione 0.
	// L'elemento corrente e' puntato dal puntatore current
	object_data_t objects[OBJECTS_MAX];
	
	// Oggetto corrente e suo id; spaceship = -1;
	object_data_t *current;
	int current_id;
	
	// Variabile che indica se il loop deve essere eseguito
	int playing = 1;
	
	// Variabile temporanea per lo stato delle collisioni dell'oggetto corrente
	int col;
	

	// Inizializzo le ncurses
	initscr();
	
	
	// Inizializzo i colori delle ncurses
	#ifdef COLORS
		start_color();
		init_pair(1, COLOR_WHITE, COLOR_BLACK);
		attron(COLOR_PAIR(1));
	#endif
	
		
	// Non visualizzo i tasti premuti
	noecho();
	
	// Inizializzo il generatore random
	srand((int)time(0));
	
	// Nascondo il cursore
	curs_set(0); 
	
	
	// Inizializzo la navicella
	objects[0].type = OT_SPACESHIP;
	
	// Inizializzo gli oggetti come non utilizzati
	for(i = 0; i < OBJECTS_MAX; i++)
		objects[i].x = -1;
		
		
	// Finche' il gioco non finisce, eseguo
	do 
	{ 					
		// Ricevo i dati di un oggetto dalla coda messaggi
		msgrcv(qid, &recv_data, sizeof(recv_data) - sizeof(recv_data.mtype), 1, 0);
				
		
		// Se non e' la navicella, ricerco nella lista l'oggetto ricevuto
		current = NULL;
		
		if(recv_data.type != OT_SPACESHIP)
		{
			for(i = 1; i < OBJECTS_MAX; i++)
			{
				if(recv_data.pid == objects[i].pid)
				{
					current = &objects[i];
					current_id = i;
					i = OBJECTS_MAX;
				}
			}
			
			// Non l'ho trovato, cerco uno spazio libero
			if(current == NULL)
			{
				for(i = 1; i < OBJECTS_MAX; i++)
					if(objects[i].x == -1)
					{
						obj_n++;
						current = &objects[i];
						i = OBJECTS_MAX;
					}
			}
		}
		// Altrimenti la navicella sta' in posizione 0
		else
		{
			current = &objects[0];
			current_id = 0;
		}
		
		
		// Collision detect
		int collision_count = 0;
			
		// Se l'oggetto corrente ha una posizione inizializzata, faccio
		// il check delle collisioni
		if(current->x != -1)
		{
			for(i = 0; i < OBJECTS_MAX; i++)
			{
				// Un oggetto non collide con se stesso
				if(current_id == i)
					continue;
					
				// Nella posizione i non c'e' nessun oggetto
				if(objects[i].x == -1)
					continue;
					
					
				// Se una bomba colpisce un alieno, me ne frego
				if(((objects[i].type == OT_BOMB) && (current->type == OT_ALIEN)) ||
					((objects[i].type == OT_ALIEN) && (current->type == OT_BOMB)))
					continue;
					
				// Se due missili si colpiscono, me ne frego
				if(((objects[i].type == OT_MISSILE) && (current->type == OT_MISSILE)))
					continue;
					
					
				// Controllo lo stato delle collisioni tra l'oggetto corrente
				// e quello in posizione i
				col = control_check_collision(&objects[i], current);
				
				
				// Se c'e' stata una collisione
				if(col != 0)
				{					
					// Imposto il flag			
					collision_count = 1;
					
					// Se abilitato, stampo una stringa di debug
					#ifdef DEBUG
						char cinfo[1024];
						sprintf(cinfo, "Collision: type %d and type %d, x %d and x %d, y %d and y %d",
								(int) objects[i].type, (int) current->type, objects[i].x, current->x,
								objects[i].y, current->y);
						mvaddstr(1, 1, cinfo);
					#endif
					
					// A seconda del tipo di oggetto corrente, faccio un azione diversa
					// per ogni tipo di collisione
					switch(current->type)
					{
						// Se un missile colpisce un alieno, toglie una vita
						// o lo ammazza, ed incrementa il punteggio
						case OT_MISSILE:
							if(objects[i].type == OT_ALIEN)
							{
								if((last_alien_hit == objects[i].pid) && (iterations >= MIN_HIT_DIFF))
								{
									coll_m.coll = 'z';
									last_alien_hit = -1;
								}
								else
								{
									coll_m.coll = 'c';
									last_alien_hit = objects[i].pid;	
								}
								
								iterations = 0;
								
								msgsnd(qid_coll[objects[i].id], &coll_m, sizeof(coll_m) - sizeof(coll_m.mtype), 0);
								scores += objects[i].size * 10;
							}
							// Se una bomba ed un missile collidono, killo la bomba
							else if(objects[i].type == OT_BOMB)
								kill(current->pid, SIGQUIT);							
							
							// E killo il missile in ogni caso
							kill(current->pid, SIGQUIT);
							break;
							
						// Collisione alieno
						case OT_ALIEN:
							// Se due alieni collidono rimbalzano
							if(objects[i].type == OT_ALIEN)
							{
								coll_m.coll = 'r';
									
								// Se collidono e stanno andando entrambi
								// nella stessa dir, cambio direzione solo ad uno
								if(objects[i].dir == current->dir)
								{
									if(current->x < objects[i].x)
										msgsnd(qid_coll[current->id], &coll_m, sizeof(coll_m) - sizeof(coll_m.mtype), 0);
									else
										msgsnd(qid_coll[objects[i].id], &coll_m, sizeof(coll_m) - sizeof(coll_m.mtype), 0);
								}
								else
								{
									msgsnd(qid_coll[objects[i].id], &coll_m, sizeof(coll_m) - sizeof(coll_m.mtype), 0);
									msgsnd(qid_coll[current->id], &coll_m, sizeof(coll_m) - sizeof(coll_m.mtype), 0);
								}						
							}
							// Se collide con un missile, invio il messaggio
							// all'alieno e killo il missile
							else if(objects[i].type == OT_MISSILE)
							{
								if(last_alien_hit == current->pid && iterations >= MIN_HIT_DIFF)
								{
									coll_m.coll = 'z';
									last_alien_hit = -1;
								}
								else
								{
									coll_m.coll = 'c';
									last_alien_hit = current->pid;
								}
								
								iterations = 0;
									
								msgsnd(qid_coll[current->id], &coll_m, sizeof(coll_m) - sizeof(coll_m.mtype), 0);
								
								scores += current->size * 10;
								
								kill(objects[i].pid, SIGQUIT);
							}
							// Se un alieno collide con la navicella, fine gioco
							else if(objects[i].type == OT_SPACESHIP)
							{
								playing = 0;
								usleep(SLEEP_OVER);		
							}
							break;
													
								
						// Collisione bomba	
						case OT_BOMB:
							// Se la bomba collide con la navicella, game over
							if(objects[i].type == OT_SPACESHIP)
							{
								playing = 0;			
								usleep(SLEEP_OVER);				
							}
							// Se una bomba ed un missile collidono, le killo
							else if(objects[i].type == OT_MISSILE)
							{
								kill(objects[i].pid, SIGQUIT);
								kill(current->pid, SIGQUIT);							
							}
							
							break;
							
						// Collisione navicella	
						case OT_SPACESHIP:
							// Se la navicella collide con un missile o con una bomba, fine gioco
							if((objects[i].type == OT_BOMB) || (objects[i].type == OT_ALIEN))
							{
								playing = 0;		
								usleep(SLEEP_OVER);							
							}
							break;
							
					}
					
					
					// Aggiorno lo schermo
					refresh();
				}
			}
		}
		
	
		// Qualsiasi oggetto sia, cancello prima di tutto la sua vecchia
		// porzione di schermo, ed inserisco nell'array degli oggetti i
		// dati appena ricevuti
		if(current->x != -1)
			clear_quad(current->x, current->y, current->size);
		
		*current = recv_data;
		
		
		// A seconda del tipo di oggetto, eseguo un operazione differente			
		switch(recv_data.type)
		{
			// Astronave aliena
			case OT_ALIEN:				
				// Se la vita di un alieno e' negativa, vuol dire che deve morire;
				// deve comunque inviare la struttura inizializzando come tipo
				// OT_DELETE
				if(current->life == -1)
				{					
					aliens--;
					 
					continue;
				}
					
				// A seconda del livello, disegno l'alieno in modo diverso
				switch(current->size)
				{
					case ALIEN_DATA1_SIZE:
						render_string_array(current->x, current->y, ALIEN_DATA1, ALIEN_DATA1_SIZE);	
						break;
						
					case ALIEN_DATA2_SIZE:
						render_string_array(current->x, current->y, ALIEN_DATA2, ALIEN_DATA2_SIZE);	
						break;
						
					case ALIEN_DATA3_SIZE:
						render_string_array(current->x, current->y, ALIEN_DATA3, ALIEN_DATA3_SIZE);	
						break;
				}
				
				// Il nemico e' sceso troppo in basso, game over
				if(current->y > (SCREEN_HEIGHT - ALIEN_DATA2_SIZE))
				{
					playing = 0;
					usleep(SLEEP_OVER);		
				}
					
				break;
			
			
			// Navicella	
			case OT_SPACESHIP:
				render_string_array(current->x, current->y, SPACE_SHIP_DATA, SPACE_SHIP_SIZE);	

				break;
				
			
			// Bomba aliena	
			case OT_BOMB:			
				mvaddch(current->y, current->x, BOMB_DATA);
				break;
			
			
			// Missile dell'astronave	
			case OT_MISSILE:				
				mvaddch(current->y, current->x, MISSILE_DATA);

				break;	
			
			
			// Un oggetto sta' morendo e vuole esser cancellato dall'array	
			case OT_DELETE:		
				// Invalido la sua entry nell'array
				current->x = -1;
				
				// Decremento il numero di oggetti della scena
				obj_n--;
				
				// Attendo che muoia (per non aver zombie)
				waitpid(current->pid);
				break;
		};
		
				
		
		// Cancello la riga del punteggio
		mvaddstr(0, 0, "\t\t\t\t\t\t\t\t\t\t");
				
		// Visualizzo il punteggio attuale
		sprintf(buffer, "Scores: %d", scores);		
		mvaddstr(0, 1, buffer);
		
		
		// Visualizzo il numero di oggetti della scena
		sprintf(buffer, "Active Processes: %d", obj_n);		
		mvaddstr(0, 20, buffer);
			
		// Visualizzo il numero di oggetti della scena
		//sprintf(buffer, "Last hit: %d", last_alien_hit);		
		//mvaddstr(0, 50, buffer);
			
		// Visualizzo il numero di alieni
		sprintf(buffer, "Aliens: %d", aliens);		
		mvaddstr(0, 50, buffer);
	
		
			
		// Rendo invisibile il cursore e faccio il refresh
		curs_set(0);
		refresh();
		
		// Aggiorno il numero di iterazioni
		iterations++;
	} while(playing && aliens > 0);
	
	// Fermo le ncurses
	#ifdef COLORS
		attroff(COLOR_PAIR(1));
	#endif
	endwin();
	
	// Se ci son processi rimasti, invio un segnale di kill per terminarli
	for (i = 0; i < OBJECTS_MAX; i++)
	{
		if(objects[i].x != -1)
		{
			// Se e' un alieno, utilizzo la coda dei messaggi per le collisioni
			// per dire di uccidersi
			if(objects[i].type == OT_ALIEN)
			{
				coll_m.coll = 'd';
				
				msgsnd(qid_coll[objects[i].id], &coll_m, sizeof(coll_m) - sizeof(coll_m.mtype), 0);		
			}
			else
			{
				kill(objects[i].pid, SIGQUIT);
			}
			
			// Attendo che il processo esca
			waitpid(objects[i].pid);
			obj_n--;
			objects[i].x = -1;
		}
	}
	
	
	// Elimino tutte le code dei messaggi create in precedenza
	msgctl(qid, IPC_RMID, NULL);
	
	for(i = 0; i < ALIEN_NUM; i++)
		msgctl(qid_coll[i], IPC_RMID, NULL);
	
	// Aggiungo il punteggio alla lista degli highscore e visualizzo
	// un messaggio di fine gioco
	system("clear");
	
	int pos = scores_add(scores);
	
	if(aliens == 0)
		printf("Hai vinto!\n");
	else
		printf("Hai perso!\n");
		
	if(pos == 0)
		printf("Nuovo punteggio high score! %d\n", scores);
	else
		printf("Il tuo punteggio e' %d\n", scores);
	
	// Visualizzo la lista dei punteggi alti
	int scorl[SCORES_N_MAX];
	scores_load(scorl);	
	for(i = 0; i < SCORES_N_MAX; i++)
		printf("\t%d\t%d\n", i+1, scorl[i]);
	
}