Beispiel #1
0
void CRUELstart() {
    int i, j, k;
    list ll = LISTinit(), q;
    /* inicializa as 4 pilhas de naipes */
    for( i = 0; i < 4; i++ ) {
        suitStack[i] = STACKinit( 13 );
        LISTaddStart( ll, CARDcreate( i, 1 ) ); 
    }
    /* aleatoriza a ordem das 4 pilhas de naipes */
    for( i = 0; i < 4; i++ ) {
        k = rand() % (4 - i);
        q = LISTgetNterm( ll, k );
        STACKpush( &suitStack[i], LISTgetVal(q) );
        suitPosition[ CARDsuit(LISTgetVal(q)) ] = i;
        LISTremove(q);

    }
    
    /* inicializa as 12 pilhas de cartas */
    for( i = 0; i < 12; i++ )
        cardStack[i] = STACKinit( 26 );
        
    /* coloca as 48 cartas na lista ligada */
    for( j = 0; j < 4; j++ ) {
        for( i = 2; i <= 13; i++ ) {
            LISTaddStart( ll, CARDcreate( j, i ) );
        }
    }
    
    /* preechemos as 12 pilhas de cartas linearmente, mas com
        cartas escolhidas aleatoriamente */
    for( i = 0; i < 12; i++ ) {
        for( j = 0; j < 4; j++ ) {
            k = rand() % (48 - (4 * i + j) );
            q = LISTgetNterm( ll, k );
            STACKpush( &cardStack[i], LISTgetVal(q) );
            LISTremove(q);
        }
    }
    LISTdestroy(ll);
    
    /* Selecionar uma carta aleatoria. Como funciona:
        Coloca-se todas as cartas numa LL.
        Sempre que precisar de uma carta aleatoria, fazer 
          k = rand() % TOTAL_DE_CARTAS_NA_LL e pegar a 
          k-esima carta da LL, removendo-a da lista. */
    
    cardLeft = 48;
    movedSinceDist = 0;
    lastSugest = ACTIONcreate(-1,-1,-1);
}
Beispiel #2
0
void CRUELredistribute() {
    list ll = LISTinit(), q;
    int j = 0, i = 0;
    while( i < 12 ) {
        if( STACKempty( cardStack[i] ) )
            i++;
        else
            LISTaddEnd( ll, STACKpop( &cardStack[i] ) );
    }
    i = 0;
    while( !LISTempty( ll ) ) {
        if( j >= 4 ) {
            j = 0;
            i++;
        }
        q = LISTgetNterm( ll, 3 - j );
        if( q ) {
            STACKpush( &cardStack[i], LISTgetVal( q ) );
            LISTremove(q);
        }
        j++;
    }
    LISTdestroy(ll);
    movedSinceDist = 0;
    lastSugest = ACTIONcreate(-1,-1,-1);
}
Beispiel #3
0
/*Destroi a entidade passada, liberando a memoria usada por ela.*/
void destroiEntidade(Entity ent)
{
	/*Remove uma entidade da lista que seja considerada igual a ent, de acordo com a funcao de comparacao passada.*/
	LISTremove(entityList, ent, compareEntities, _freeEntity );
	ent = NULL;
}
void* CiclistaThread(void* arg) {
    /* This is our thread. There are many like it, this one is ours. */
    ciclista c = (ciclista) arg;
    double vel;
    int tempo_gasto_trecho_atual = 0;

    /* Ciclista ja terminou a corrida. Nao corre mais poar. */
    while(c->km < tamanho_estrada) {
        /* Espera o ciclo começar. */
        sem_wait(&c->continua_ciclo);
        if(modo_simula) {
            char tipo = c->trecho_atual ? ((trecho)c->trecho_atual->val)->tipo :
                ((trecho)trechos->first->val)->tipo;
            switch(tipo) {
            case 'P': vel = c->vel_plano; break;
            case 'S': vel = c->vel_subida; break;
            case 'D': vel = c->vel_descida; break;
            default: vel = 0.0;
            }
        } else {
            vel = c->vel_plano;
        }

        c->tempo_gasto_total += CICLO_TIME;
        tempo_gasto_trecho_atual += CICLO_TIME;
        c->metros += kmh2ms(vel) * CICLO_TIME;

        /* Precisa mudar de KM? */
        if(c->metros >= 1000) {

            /* Estou terminando a corrida? */
            if(c->km + 1 >= tamanho_estrada) {
                /* YEAH TERMINEI! */

                /* Pega lock pra colocar na lista dos que terminaram. */
                pthread_mutex_lock(&terminar_mutex);
                LISTaddEnd(ciclistas_terminaram, c);
                pthread_mutex_unlock(&terminar_mutex);

                /* Pega lock para se tirar da lista de quem tava no ultimo km. 
                    Esse lock também me permite modificar a lista do trecho, que termina nesse mesmo km. */
                pthread_mutex_lock( &estrada[c->km].mutex);
                LISTremove(estrada[c->km].ciclistas, c);

                /* Eu certamente terminei o último trecho. */
                c->tempo[c->numero_trecho_atual] = tempo_gasto_trecho_atual;
                tempo_gasto_trecho_atual = 0;
                LISTaddOrder(((trecho) trechos->last->val)->checkpoint_ranking, c, lessOperation);
                (c->numero_trecho_atual)++;

                pthread_mutex_unlock(&estrada[c->km].mutex);

                c->km++;
                c->metros -= 1000;
            } else {
                /* Pega lock para Ler e possívelmente escrever no próximo KM. */
                pthread_mutex_lock(&estrada[c->km + 1].mutex);
                if(LISTsize(estrada[c->km + 1].ciclistas) < largura_estrada) {

                    /* Opa, consegui entrar no proximo km, to rox. */
                    LISTaddEnd(estrada[c->km + 1].ciclistas, c);
                    pthread_mutex_unlock(&estrada[c->km + 1].mutex);

                    c->kms_no_trecho++;

                    if(c->km >= 0) {
                        trecho trecho_atual = (trecho) c->trecho_atual->val;

                        /* Se eu não estou no limbo de começo de corrida...
                            1. vou me tirar da lista do km anterior. Preciso travar o mutex senão da merda. 
                            2. Preciso ver se eu estou terminando algum trecho.
                            -> Se sim, o mesmo lock do km me permite mexer nesse mutex. */

                        pthread_mutex_lock(  &estrada[c->km].mutex);
                        LISTremove(estrada[c->km].ciclistas, c);
                        if(c->kms_no_trecho == trecho_atual->distancia) {
                            /* Opa, terminei o meu trecho! :D */
                            c->tempo[c->numero_trecho_atual] = tempo_gasto_trecho_atual;
                            tempo_gasto_trecho_atual = 0;

                            LISTaddOrder(trecho_atual->checkpoint_ranking, c, lessOperation);
                            (c->numero_trecho_atual)++;
                            c->trecho_atual = c->trecho_atual->next;
                            c->kms_no_trecho = 0;
                        }
                        pthread_mutex_unlock(&estrada[c->km].mutex);
                    } else {
                        /* Estou começando a corrida agora. */
                        c->trecho_atual = trechos->first;
                        c->kms_no_trecho = 0;
                    }

                    /* Tudo ok, atualiza variaveis. */
                    c->km++;
                    c->metros -= 1000;

                } else {
                        /* Fico parado esperando abrir espaço. Tomando cuidado pra não dormir.
                    Tb libero o lock. */
                    pthread_mutex_unlock(&estrada[c->km + 1].mutex);
                    c->metros = 1000;
                }
            }
        }
        sem_post(&c->terminou_ciclo);
    }
    return NULL;
}