/*Executa a funcao de desenho (update grafico) de todas entidades.*/ void updateDesenho() { LISTdump(entityList, _updateEntityDraw, NULL ); }
/*Executa a funcao passada, com o item argumento opcional passado, para todas as entidades.*/ void executeForAllEntities( void (*func)(Item ent, Item arg), Item arg ) { LISTdump(entityList, func, arg ); }
/*Executa a funcao de update logico de todas entidades. Apos isso, destroi todas entidades que foram marcadas para destruicao no final do ciclo logico atual.*/ void updateLogic(double deltaTime) { LISTdump(entityList, _updateEntityLogic, &deltaTime ); LISTclear(garbageList, _destroiEntidade); }
/* O grande main incomming. Se vira ae champz. */ int main(int argc, char **argv) { int i; int ciclo; FILE* in; int num_ciclistas; ciclista* ciclistas; pthread_t* ciclistas_threads; pthread_attr_t ciclista_attr; srand((unsigned int) time(NULL)); if(argc != 2) { fprintf(stderr, "Uso: %s arquivo\n", argv[0]); return 1; } in = fopen(argv[1], "r"); if(in == NULL) { fprintf(stderr, "Erro: Arquivo '%s' não pode ser lido.\n", argv[1]); return 2; } fscanf(in, "%d", &num_ciclistas); /* m */ fscanf(in, "%d", &largura_estrada); /* n */ do modo_simula = fgetc(in); while(modo_simula == '\n'); fscanf(in, "%d", &tamanho_estrada); /* d */ trechos = readTrechos(in); fclose(in); #ifdef DEBUG printf("num_ciclistas (m) = %d\n", num_ciclistas); printf("largura_estrada (n) = %d\n", largura_estrada); printf("modo_simula = %c\n", modo_simula); printf("tamanho_estrada (d) = %d\n", tamanho_estrada); LISTdump(trechos, dumpTrecho); assert(largura_estrada >= 2); assert(modo_simula == 'U' || modo_simula == 'A'); #endif AUTOMALLOCV(ciclistas, num_ciclistas); AUTOMALLOCV(ciclistas_threads, num_ciclistas); AUTOMALLOCV(estrada, tamanho_estrada); for(i = 0; i < tamanho_estrada; ++i) { /* Inicializa o vetor estrada. */ estrada[i].ciclistas = LISTinit(); pthread_mutex_init(&estrada[i].mutex, NULL); } ciclistas_terminaram = LISTinit(); pthread_mutex_init(&terminar_mutex, NULL); modo_simula = modo_simula == 'A'; /* 0 se uniforme, 1 se diferente */ for(i = 0; i < num_ciclistas; ++i) { ciclistas[i] = newCiclista(i); AUTOMALLOCV(ciclistas[i]->tempo, num_ciclistas); } for(i = 0; i < num_ciclistas; ++i) printf("%s [%.2lf; %.2lf; %.2lf]\n", ciclistas[i]->nome, ciclistas[i]->vel_descida, ciclistas[i]->vel_plano, ciclistas[i]->vel_subida); pthread_attr_init(&ciclista_attr); pthread_attr_setdetachstate(&ciclista_attr, PTHREAD_CREATE_DETACHED); for(i = 0; i < num_ciclistas; ++i) { int rc = pthread_create(&ciclistas_threads[i], &ciclista_attr, CiclistaThread, (void *) ciclistas[i]); assert(0 == rc); } ciclo = 0; /* Enquanto alguém não terminou a corrida. */ while(LISTsize(ciclistas_terminaram) < num_ciclistas) { /* Manda todo mundo correr. */ for(i = 0; i < num_ciclistas; ++i) sem_post(&ciclistas[i]->continua_ciclo); /* Espera todo mundo que ainda não terminou a corrida acabar o ciclo. */ for(i = 0; i < num_ciclistas; ++i) if(ciclistas[i]->km < tamanho_estrada) sem_wait(&ciclistas[i]->terminou_ciclo); /* Acabamos de realizar um ciclo. */ ++ciclo; /* Passou 1 minuto? */ if(ciclo % (60 / CICLO_TIME) == 0) { printf("Minuto %d:\n", ciclo / (60 / CICLO_TIME)); for(i = 0; i < tamanho_estrada; ++i) { printf("\tKM %.3d: ", i); LISTdump(estrada[i].ciclistas, dumpCiclista); puts(""); } puts(""); } } /* Calcular pontuação dos ciclistas */ { /* Itera por todos os trechos, e distribui pontuação dos checkpoints. */ litem p; int i; trecho t; litem x; int pos; for(p = trechos->first; p; p = p->next) { t = (trecho) p->val; /* Pega o primeiro, segundo e terceiro. For conveniente que trata caso de menos de 3 ciclistas. */ for(pos = 0, x = t->checkpoint_ranking->first; pos < 6 && x; ++pos, x = x->next) { if(t->tipo == 'P') ((ciclista) x->val)->ponto_verde += notas_posicao[pos]; else if(t->tipo == 'S') ((ciclista) x->val)->ponto_branco_vermelho += notas_posicao[pos]; } } i = 1; for(p = trechos->first; p; p = p->next) { printf("Ordem de chegada no trecho %d da corrida:\n", i); t = (trecho) p->val; for(x = t->checkpoint_ranking->first; x!=NULL; x = x->next) { ciclista c1 = ((ciclista) x->val); printf("\t%s - Tempo: %d:%.2d:%.2d\n", c1->nome, c1->tempo[i-1] / 3600, (c1->tempo[i-1] % 3600) / 60, c1->tempo[i-1] % 60 ); } ++i; puts(""); } } puts(""); quickSortCiclistaAmarelo(ciclistas, num_ciclistas); puts("Ranking da Camisa Amarela:"); for(i = 0; i < num_ciclistas; ++i) printf("Pos %.2d: %s - Tempo: %d:%.2d:%.2d\n", i, ciclistas[i]->nome, ciclistas[i]->tempo_gasto_total / 3600, (ciclistas[i]->tempo_gasto_total % 3600) / 60, ciclistas[i]->tempo_gasto_total % 60); puts(""); quickSortCiclistaVerde(ciclistas, num_ciclistas); puts("Ranking da Camisa Verde:"); for(i = 0; i < num_ciclistas; ++i) printf("Pos %.2d: %s - Pontos: %d\n", i, ciclistas[i]->nome, ciclistas[i]->ponto_verde); puts(""); quickSortCiclistaBrancoVermelho(ciclistas, num_ciclistas); puts("Ranking da Camisa Branco com Bolas Vermelhas:"); for(i = 0; i < num_ciclistas; ++i) printf("Pos %.2d: %s - Pontos: %d\n", i, ciclistas[i]->nome, ciclistas[i]->ponto_verde); LISTdestroy(ciclistas_terminaram); pthread_mutex_destroy(&terminar_mutex); /* for trecho in trechos free */ LISTcallback(trechos, destroyTrecho); LISTdestroy(trechos); for(i = 0; i < num_ciclistas; ++i) { free(ciclistas[i]->tempo); destroyCiclista(ciclistas[i]); } free(ciclistas); pthread_attr_destroy(&ciclista_attr); free(ciclistas_threads); for(i = 0; i < tamanho_estrada; ++i) { LISTdestroy(estrada[i].ciclistas); pthread_mutex_destroy(&estrada[i].mutex); } free(estrada); return 0; }