Torneo in c

di il
6 risposte

Torneo in c

Ciao a tutti, sto realizzando il seguente algoritmo:

Acquisisco il numero di partecipanti al torneo (deve essere pari). Se il numero di giocatori è "n", vi saranno "n/2" coppie per il primo turno del torneo. Naturalmente voglio che ogni giocatore sia estratto a random una sola volta (no ripetizioni).

Sull'acquisizione, la memorizzazione dei nomi dei giocatori eccetera non ci sono problemi, i problemi sorgono quando vado ad estrarre le coppie di sfidanti. Capita sempre che esca una coppia in cui compare un giocatore che è stato precedente estratto, e che quindi appartiene ad un'altra coppia.

Esempio:

Prima coppia: abc VS rtd
Seconda coppia: ghj VS poi
Terza coppia: xxa VS sqe
Quarta coppia: rtd VS sqe

Al momento uso un vettore in cui memorizzo uno ad uno i numeri (che identificano i giocatori) appena estratti. Ogni volta che faccio 1 estrazione controllo tutto il vettore, se il numero non si trova nel vettore allora vuol dire che non è stato estratto, altrimenti lo estraggo di nuovo...

Voi come fareste al posto mio? E' da poco che uso il C

6 Risposte

  • Re: Torneo in c

    Posteresti il codice così troviamo l'errore
  • Re: Torneo in c

    Ecco il codice "incriminato"
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define NUM_MAX_GIOCATORI      30 /* allocazione statica: numero max di giocatori */ 
    #define LUNG_MAX_NOME          10 /* allocazione statica: numero max di caratteri nome giocatori*/
     
    void estrai_coppie(int numero_giocatori);
    
    int numero_giocatori;
    char elenco[NUM_MAX_GIOCATORI][LUNG_MAX_NOME]; /* conterrà tutti i giocatori */
    
    void estrai_coppie(int n_giocatori){
    
         int n_coppie = n_giocatori / 2; // es: 8 giocatori => 4 coppie di sfidanti
         int primo, secondo;
         int k,j;
         int i = 0;
    
         int gia_estratti[n_giocatori];
        /* Qui ci memorizzo tutti i numeri relativi ai giocatori estratti.
            Ad ogni estrazione devo visitare tutto il vettore per vedere se il numero è già stato estratto.
            Se è già stato estratto ne estraggo un altro e così via, finchè non ne esce uno nuovo (mai estratto) */
    
        /* inizializzo il vettore */
         for(k=0;k<n_giocatori;k++)
                 gia_estratti[k] = 0;
    
         /* inizializzo il seme della rand tramite il tempo */
         srand((unsigned)time(NULL));
    
    
         /* I controlli vanno bene, ma per ora si controllanno solo i giocatori della coppia corrente,
            mentre bisognerebbe controllare anche che non ci siano duplicati con quelli delle altre coppie */
    
         do{ /* nel ciclo ci vanno le operazioni necessarie x estrarre 1 coppia */
    
                  primo = rand() % n_giocatori; // estraggo il primo sfidante (col modulo ottengo numeri da 0 a n_giocatori)
    
                  gia_estratti[i] = primo;      // e memorizzo il suo indice nel vettore, in modo da non estrarlo successivamente
    
                  i++;
     
                  secondo = rand() % n_giocatori; // estraggo il secondo sfidante
    
                  for(j=0;j<n_giocatori;j++){
                   while(secondo == gia_estratti[j]){
                     secondo = rand() % n_giocatori; // estraggo 1 nuovo secondo sfidante
                     }
                   }
                 /* se non è stato già estratto lo possiamo considerare*/
    
                 gia_estratti[i] = secondo; /* invalido il giocatore estratto, in modo da evitare di estrarlo di nuovo */
    
                 printf("\n\n%s <--- VS ---> %s\n\n", elenco[primo], elenco[secondo]);
    
                 i++;
     
                 n_coppie--;
    
       }while((n_coppie != 0)&&(i<n_giocatori));
    
       printf("\n\n");
    return;
    }
    
  • Re: Torneo in c

    Ciao, ho provato a lanciare il codice che hai postato ma non fa altro che visualizzare la scritta "<--- VS ---> " questo perche' sbagli ad utilizzare la printf; la variabile "elenco" non e' un vettore (quindi accessibile con la sintassi elenco[indice]) ma e' una matrice rigaXcolonna (quindi accessibile con una sintassi del tipo mat[riga][colonna]).
    Comunque, il problema e' prima della chiamata a questa printf() e cioe' nel modo con cui estrai i giocatori. Di seguito ti posto un codice che estrae N giocatori assicurandosi che non siano gia' stati estratti.
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define NUM_MAX_GIOCATORI      8  /* allocazione statica: numero max di giocatori */
    
    
    typedef enum { FALSE, TRUE } Boolean;
    
    
    
    /* Prototipi funzione */
    void estrai_coppie(int);
    
    
    
    int main(void) {
    
        estrai_coppie(NUM_MAX_GIOCATORI);
    
        return 0;
    }
    
    
    
    
    void estrai_coppie(int ngiocatori){
        Boolean invalid;
        int     gia_estratti[ngiocatori];
        int     n;
        int     i;
        int     ncoppie = ngiocatori / 2;
    
    
        /* inizializzo il vettore */
        for(i = 0; i < ngiocatori; i++) gia_estratti[i] = -1;
        srand((unsigned)time(NULL));
    
        do {
    
            // Estrazione di un giocatore valido
            do {
                invalid = FALSE;
                n       = rand() % ngiocatori + 1;
                for (i = 0; i < ngiocatori; ++i)
                    if (n == gia_estratti[i])
                        invalid = TRUE;
            } while (invalid);
            gia_estratti[n - 1] = n;
    
            printf("Giocatore estratto => %d\n", n);
    
        } while (--ncoppie > 0);
    }
    
    La parte che ti interessa di piu' naturalmente e' "Estrazione di un giocatore valido".
    Aggiungendo codice a questo puoi fare in modo che i giocatori estratti siano 2 e quindi formare le tue coppie (uniche) di giocatori.
    Saluti, netburst.

    P.S: Da quanto ho capito ogni giocatore e' caratterizzato da un nome (stringa) ed un numero (integer) esatto? Se e' cosi' non puoi usare un vettore / matrice ma dovrai optare per una struttura.
  • Re: Torneo in c

    Grazie 1000, il codice per l'estrazione del numero casuale funziona alla perfezione, non si ripete mai il numero estratto Adesso provo ad adattare il codice in modo che estragga 2 numeri invece che 1

    I numeri li uso perchè poi mi permettono di accedere al relativo nome del giocatore (nel vettore) ^^
  • Re: Torneo in c

    panik666 ha scritto:


    I numeri li uso perchè poi mi permettono di accedere al relativo nome del giocatore (nel vettore) ^^
    Si, farei anche io allo stesso modo dato che assegnando ad ogni giocatore un numero e' piu' facile gestirli, pero' quello che dicevo io e' che se un giocatore e' caratterizzato da:
    1. Numero identificativo (integer)
    2. Nome (stringa)

    Non puoi utilizzare un vettore / matrice (come hai fatto tu), ma devi fare una cosa del tipo:
    
    struct _giocatore {
        int    id;                             // Numero identificativo
        char nome[MAX_BUFF];    // Nome del giocatore
    } giocatore;
    
    In ogni caso lavoraci un po' su e se hai problemi vediamo come si puo' fare
    Una domanda, te lo sei inventato tu questo programma da scrivere o stai seguendo una consegna precisa? Se si, perfavore postala...
    Saluti, netburst.

    EDIT: Rileggendo il tuo codice probabilmente ho frainteso io, quindi l'utilizzo della struct _giocatore non dovrebbe essere necessario. Ma tutto dipende nel modo in cui un giocatore viene descritto (nome, ecc...).
    Anche per questo ti ho chiesto se stai seguendo una traccia ben precisa.
  • Re: Torneo in c

    L'idea mi è venuta giocando ad un gioco online, facendo parte di un clan di amici ho pensato di organizzare dei tornei 1vs1 tra di noi, in modo da decretare il migliore della settimana/del mese e così via (uno dei tanti modi per incentivare tutti a migliorarsi all'interno del gioco)

    Il problema restava quello dell'estrazione, a chi affidare il compito? Uno di noi avrebbe dovuto filmarsi mentre estraeva dei foglietti e postare poi il video su youtube Allora ho pensato che sarebbe stato interessante realizzare un piccolo programma che ci aiutasse

    Una possibile specifica potrebbe essere:
    Realizzare un programma in C per la gestione di un torneo 1vs1. Dato un numero pari di giocatori, acquisire i loro nomi e estrarre le coppie di sfidanti.

    Esempio: 8 giocatori in totale. Nella prima fase del torneo faccio eseguire il programma, e ottengo 8/2 = 4 coppie di sfidanti. Queste persone si sfidano nel gioco, chi vince (quindi 4 giocatori) vengono iscritti alla seconda fase del torneo. Faccio eseguire il programma per una seconda volta, e ottengo 4/2 = 2 coppie di sfidanti. I vincitori delle 2 coppie vanno in finale, chi di loro vince è il più bravo del mese

    In pratica, l'unica informazione che abbiamo sui giocatori è il loro nome. Memorizzo tutti quanti i nomi in una matrice, estraggo 2 numeri per ogni coppia e li uso per accedere ai nomi. Ad esempio:
    
    srand((unsigned)time(NULL));
    n = rand() % n_giocatori + 1;
    m = rand() % n_giocatori + 1;
    
    E poi li stampo in questo modo:
    
    printf("\n\n%s <-- VS --> %s ", elenco[n], elenco[m]);
    
    Adesso sto provando ad adattare il codice che mi hai scritto, in modo che estragga 2 giocatori ad ogni ciclo, speriamo di venirne fuori
Devi accedere o registrarti per scrivere nel forum
6 risposte