Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1
    Utente di HTML.it
    Registrato dal
    May 2009
    Messaggi
    35

    [C++] Generare numeri casuali con criteri

    Salve a tutti, ho un interrogativo per me abbastanza ostico da proporvi.
    Sto implementando un gioco in C++ e ho necessità di generare un numero casuale.
    Il gioco ha 3 difficoltà che dipendono dal fatto che il numero in questione sia composto di 3, 4 o 5 cifre.
    Ora il problema non è in se per se generare numeri casuali, questo so come farlo tramite le funzioni rand() e srand() presenti nella libreria <stdlib.h> e utilizzando l'orologio di sistema affinché il numero sia sempre diverso.
    Il punto è un altro, il numero generato dovrebbe avere dei criteri che non so come impostare, vi dico quali dovrebbero essere così potete darmi qualche consiglio:

    - Per le cifre vanno bene tutte (da 0-9)
    - Il numero non deve contenere ripetizioni (es. 1234 SI - 12 32 NO)
    - Il numero deve poter avere anche lo 0 davanti (es. 0123)

    Ovviamente i criteri devono rimanere validi sia che il numero sia di 3, di 4 o di 5 cifre in base alla difficoltà.

    Non so se rand() da in automatico la possibilità di trovarsi lo 0 davanti, o produce solo numeri che esistano davvero, avevo pensato di ovviare al problema dello 0 davanti riducendo il range di cifre da 1-9, però rimane il problema delle ripetizioni che ancora non so come risolvere.
    Se avete consigli a me farebbe piacere poter tenere anche lo 0.

    L'idea più stupida che mi viene è quella di impostare un ciclo che generi e rigeneri il numero finché non trova uno con i criteri indicati, però magari c'è qualcosa di più semplice.

    Vi ringrazio anticipatamente per il vostro aiuto, spero di aver spiegato bene il tutto.

  2. #2
    Utente di HTML.it L'avatar di linoma
    Registrato dal
    Mar 2010
    Messaggi
    1,346
    Bhe intanto lo 0 e' davanti ad ogni numero, quindi lo devi aggiungere se vuoi che sia leggibile.
    Per il resto o cicli affinche la tua cifra sia diversa o cerchi di prendere dal tuo orologio l'ultima cifra, normalmente di parla di millesimi di secondo.
    Questo vale fino a che nn termini il tuo numero casuale.
    Per gli Spartani e Sparta usa spartan Il mio github

  3. #3
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475

    Re: [C++] Generare numeri casuali con criteri

    Originariamente inviato da No_Rules
    L'idea più stupida che mi viene è quella di impostare un ciclo che generi e rigeneri il numero finché non trova uno con i criteri indicati, però magari c'è qualcosa di più semplice.
    Potrebbe metterci una vita a trovarne uno valido. Ti conviene generare singolarmente ogni cifra e scartarla se non rispetta i criteri del numero.
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

  4. #4
    Utente di HTML.it
    Registrato dal
    Mar 2001
    Messaggi
    117
    Il mio consiglio è pescare casualmente delle cifre da 0 a 9, e poi metterle assieme.
    Ora non ricordo esattamente quale range di numeri ti dà la funzione che genera numeri casuali in C++, ma in ogni caso, se non permettesse di stabilire un range, non ci vuole molto in genere a ricondursi tramite qualche operazione matematica al range da 0 a 9.


    Ogni volta che peschi una cifra da 0 a 9 controlli se non è uguale ad una precedente. Se lo è, la scarti e ne ripeschi un'altra.

    Forse l'unico problema è che facendo così, in teoria, potrebbe anche metterci molto tempo a scegliere un numero, perché potrebbe essere così sfigato da scegliere sempre numeri che ha già scelto. In teoria dopo un tempo ragionevole dovresti trovare un numero non scelto prima, ma se non vuoi correre rischi puoi fare in un'altro modo. Prendi un vettore v di 10 elementi, e scrivi in sequenza i numeri da 0 a 9:
    v=[0 1 2 3 4 5 6 7 8 9]
    Peschi un numero x da 0 a 9 (supponiamo che sia x=3) che consideri come prima cifra e consideri v[x] (che per ora sarà proprio pari a x). Quindi v[3]=3 è la tua prima cifra (te la puoi salvare su un array con le cifre che estrai). Elimina la cifra 3 dal vettore e sposta le cifre successive a sinistra di una posizione:
    v=[0 1 2 4 5 6 7 8 9 (9)]
    (in teoria ci sarebbe ancora la cifra 9 in decima posizione, ma non la consideriamo, per cui l'ho messa tra parentesi)
    Pesca ora non più un numero da 0 a 9, ma da 0 a 8. Supponiamo che sia di nuovo 3. Considera quindi come tua nuova cifra v[3]=4. E così via.

    In tal modo sei sicuro di scegliere ogni volta al primo colpo una cifra che non avevi già scelto, mantenendo tra loro le cifre equiprobabili.

  5. #5
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475
    Originariamente inviato da Cell Ogni volta che peschi una cifra da 0 a 9 controlli se non è uguale ad una precedente. Se lo è, la scarti e ne ripeschi un'altra.

    Forse l'unico problema è che facendo così, in teoria, potrebbe anche metterci molto tempo a scegliere un numero, perché potrebbe essere così sfigato da scegliere sempre numeri che ha già scelto
    Improbabile: l'overhead della seconda soluzione che hai proposto non vale il guadagno di tempo che, se c'è, è irrisorio direi... generare ogni cifra e scartandola è sicuramente la soluzione migliore.
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

  6. #6
    Utente di HTML.it
    Registrato dal
    May 2009
    Messaggi
    35
    si ippo343 credo che farò proprio così mi sembra più facile da implementare, grazie a tutti per l'aiuto, siete come sempre gentilissimi

  7. #7
    Utente di HTML.it
    Registrato dal
    May 2009
    Messaggi
    35
    Considerando che è un codice molto elementare giusto per provare e che modificherò soprattutto per quanto riguarda il controllo, come è possibile che su 10 chiamate alla funzione mi escano 2/3 numeri che si ripetono anche 2/3 volte

    codice:
    int main(){
    	
    	int v[5];
    	num(v);
    	cout<< endl;
    	num(v);
    	cout<< endl;
    	num(v);
    	cout<< endl;
    	num(v);
    	cout<< endl;
    	num(v);
    	cout<< endl;
    	num(v);
    	cout<< endl;
    	num(v);
    	cout<< endl;
    	num(v);
    	cout<< endl;
    	num(v);
    	cout<< endl;
    	num(v);
    	cout<< endl;
    
    	system("pause");
    	return 0;
    }
    
    
    int cifra(){
    
    	int i;
    
    	srand((unsigned)time(NULL));
    	i=rand()%9;
    	return i;
    
    }
    
    
    
    void num(int* v){
    
    	int i;
    
    	for(i=0;i<5;i++){
    	
    		if(i=0) v[i]=cifra();
    		
    		if(i=1){ 
    			do{
    				v[i]=cifra();
    			}while(v[i]==v[0]);
    			cout<< v[i];
    		}
    
    		if(i=2){ 
    			do{
    				v[i]=cifra();
    			}while(v[i]==v[0] || v[i]==v[1]);
    			cout<< v[i];
    		}
    
    		if(i=3){ 
    			do{
    				v[i]=cifra();
    			}while(v[i]==v[0] || v[i]==v[1] || v[i]==v[2]);
    			cout<< v[i];
    		}
    
    		if(i=4){ 
    			do{
    				v[i]=cifra();
    			}while(v[i]==v[0] || v[i]==v[1] || v[i]==v[2] || v[i]==v[3]);
    			cout<< v[i];
    		}
    	}
    }
    Eppure il sistema random l'ho utilizzato bene
    Suggerimenti???

  8. #8
    Utente di HTML.it L'avatar di linoma
    Registrato dal
    Mar 2010
    Messaggi
    1,346
    Io avrei usato un 32bits cn
    codice:
    value |= (1 << cifra)
    e avrei controllato con
    codice:
    if(value & (1 << cifra))
    puoi usare anche un qualcosa di simile, per rendere + leggibile

    codice:
    union{
    
    struct{
         int zero:1;
         int uno:1;
    .
    .
         int nove:1;
    } numeri;
    unsigned int valore;
    }
    e controllare.
    Per gli Spartani e Sparta usa spartan Il mio github

  9. #9
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475
    Non so a cosa serva tutto quel codice e non mi interessa, però è ovvio che ti vengono numeri ripetuti: riazzeri il seed di rand ad ogni chiamata, e dato che le chiamate avvengono in un intervallo di tempo minuscolo, è come se ogni volta usassi la stessa sequenza di numeri pseudocasuali per generare il numero.

    Devi chiamare la srand solo una volta, all'inizio del main.
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

  10. #10
    Utente di HTML.it
    Registrato dal
    May 2009
    Messaggi
    35
    Originariamente inviato da Ippo343
    Non so a cosa serva tutto quel codice e non mi interessa, però è ovvio che ti vengono numeri ripetuti: riazzeri il seed di rand ad ogni chiamata, e dato che le chiamate avvengono in un intervallo di tempo minuscolo, è come se ogni volta usassi la stessa sequenza di numeri pseudocasuali per generare il numero.

    Devi chiamare la srand solo una volta, all'inizio del main.
    Non tenere presente il codice perché l'ho scritto velocemente facendo copia e incolla giusto per vedere se avesse l'effetto desiderato, cmq hai ragione il problema era quello di dover chiamare solo una volta srand(), messa all'inizio del main() va tutto apposto...grazie

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.