Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

probleme

23 réponses
Avatar
eyaarmy
Bonjour, désoler pour le dérangement
je suis en train de créer jeu 2D isométrique sur SDL en c avec generation des énigmes
mais je suis bloqué comment faire pour affficher des images aléatoire sur SDL en c ..
et merci beaucoup

10 réponses

1 2 3
Avatar
Olivier Miakinen
Bonjour,
Le 31/03/2018 23:29, eyaarmy a écrit :
Bonjour, désoler pour le dérangement

Tu ne déranges pas, mais à l'avenir tu pourrais essayer de choisir un
titre plus explicite, et aussi de mieux expliquer ton besoin parce que
là tu en dis vraiment le minimum.
je suis en train de créer jeu 2D isométrique sur SDL en c avec generation des
énigmes
mais je suis bloqué comment faire pour affficher des images aléatoire sur SDL en
c ..

Je vais supposer que tu sais déjà afficher une image avec SDL, et que
ton besoin est juste de choisir quelle image afficher, entre la numéro 0
et la numéro N-1, où N est le nombre d'images.
Si c'est bien ça, tu peux utiliser la fonction random() -- en prenant
soin d'inclure <stdlib.h> -- par exemple comme ceci :
int num_image;
num_image = random() % N;
Cordialement,
--
Olivier Miakinen
Avatar
Pascal J. Bourguignon
Olivier Miakinen <om+ writes:
Bonjour,
Le 31/03/2018 23:29, eyaarmy a écrit :
Bonjour, désoler pour le dérangement

Tu ne déranges pas, mais à l'avenir tu pourrais essayer de choisir un
titre plus explicite, et aussi de mieux expliquer ton besoin parce que
là tu en dis vraiment le minimum.
je suis en train de créer jeu 2D isométrique sur SDL en c avec generation des
énigmes
mais je suis bloqué comment faire pour affficher des images aléatoire sur SDL en
c ..

Je vais supposer que tu sais déjà afficher une image avec SDL, et que
ton besoin est juste de choisir quelle image afficher, entre la numéro 0
et la numéro N-1, où N est le nombre d'images.
Si c'est bien ça, tu peux utiliser la fonction random() -- en prenant
soin d'inclure <stdlib.h> -- par exemple comme ceci :
int num_image;
num_image = random() % N;
Cordialement,

Attention, ce n'est pas aussi simple!
random() est spécifié pour générer des nombres pseudo aléatoires entre 0
et (2^31)-1, mais rien n'est dit sur la distribution.
Même en supposant une distribution equiprobable, (on peut l'assumer,
car la période du pseudo-générateur est trés grande), le fait de partir
de 2^31-1 pour calculer le modulo va forcément introduire une
inhomogénéïté.
Par exemple, si on travaillait avec N, et 2^4-1, alors les nombres de
0 à 4 seraient deux fois plus probables qu'entre 5 et 9!
--
__Pascal J. Bourguignon
http://www.informatimago.com
Avatar
Benoit Izac
Bonjour,
Le 01/04/2018 à 03:28, Pascal J. Bourguignon a écrit dans le message
 :
Si c'est bien ça, tu peux utiliser la fonction random() -- en prenant
soin d'inclure <stdlib.h> -- par exemple comme ceci :
int num_image;
num_image = random() % N;
Cordialement,

Attention, ce n'est pas aussi simple!
random() est spécifié pour générer des nombres pseudo aléatoires entre 0
et (2^31)-1, mais rien n'est dit sur la distribution.
Même en supposant une distribution equiprobable, (on peut l'assumer,
car la période du pseudo-générateur est trés grande), le fait de partir
de 2^31-1 pour calculer le modulo va forcément introduire une
inhomogénéïté.
Par exemple, si on travaillait avec N, et 2^4-1, alors les nombres de
0 à 4 seraient deux fois plus probables qu'entre 5 et 9!

Et comme ça ?
int num_image;
int limit = RAND_MAX - RAND_MAX % num_images;
int random_num;
do
random_num = random()
while (random_num >= limit);
num_image = random_num % N;
--
Benoit Izac
Avatar
Benoit Izac
Bonjour,
Le 01/04/2018 à 03:28, Pascal J. Bourguignon a écrit dans le message
 :
Si c'est bien ça, tu peux utiliser la fonction random() -- en prenant
soin d'inclure <stdlib.h> -- par exemple comme ceci :
int num_image;
num_image = random() % N;
Cordialement,

Attention, ce n'est pas aussi simple!
random() est spécifié pour générer des nombres pseudo aléatoires entre 0
et (2^31)-1, mais rien n'est dit sur la distribution.
Même en supposant une distribution equiprobable, (on peut l'assumer,
car la période du pseudo-générateur est trés grande), le fait de partir
de 2^31-1 pour calculer le modulo va forcément introduire une
inhomogénéïté.
Par exemple, si on travaillait avec N, et 2^4-1, alors les nombres de
0 à 4 seraient deux fois plus probables qu'entre 5 et 9!

Et comme ça ?
int num_image;
assert(N > 0);
int limit = RAND_MAX - RAND_MAX % N;
int random_num;
do
random_num = random()
while (random_num >= limit);
num_image = random_num % N;
--
Benoit Izac
Avatar
Pascal J. Bourguignon
Benoit Izac writes:
Bonjour,
Le 01/04/2018 à 03:28, Pascal J. Bourguignon a écrit dans le message
 :
Si c'est bien ça, tu peux utiliser la fonction random() -- en prenant
soin d'inclure <stdlib.h> -- par exemple comme ceci :
int num_image;
num_image = random() % N;
Cordialement,

Attention, ce n'est pas aussi simple!
random() est spécifié pour générer des nombres pseudo aléatoires entre 0
et (2^31)-1, mais rien n'est dit sur la distribution.
Même en supposant une distribution equiprobable, (on peut l'assumer,
car la période du pseudo-générateur est trés grande), le fait de partir
de 2^31-1 pour calculer le modulo va forcément introduire une
inhomogénéïté.
Par exemple, si on travaillait avec N, et 2^4-1, alors les nombres de
0 à 4 seraient deux fois plus probables qu'entre 5 et 9!

Et comme ça ?
int num_image;
assert(N > 0);
int limit = RAND_MAX - RAND_MAX % N;
int random_num;
do
random_num = random()
while (random_num >= limit);
num_image = random_num % N;

Oui, c'est mieux :-)
--
__Pascal J. Bourguignon
http://www.informatimago.com
Avatar
Olivier Miakinen
Le 01/04/2018 03:28, Pascal J. Bourguignon m'a répondu :
Si c'est bien ça, tu peux utiliser la fonction random() -- en prenant
soin d'inclure <stdlib.h> -- par exemple comme ceci :
int num_image;
num_image = random() % N;

Attention, ce n'est pas aussi simple!

Oui et non. J'ai répondu en fonction du peu d'infos donné par eyaarmy,
et il m'étonnerait vraiment qu'il ait besoin de plus que ça. Mais pour
un programme ayant besoin d'une très bonne qualité de générateur
aléatoire il faudrait en effet chercher plus loin.
random() est spécifié pour générer des nombres pseudo aléatoires entre 0
et (2^31)-1, mais rien n'est dit sur la distribution.

Le man de rand() dit que dans les anciennes implémentations les bits
de poids faible n'étaient pas aussi imprévisibles que les bits de poids
fort, et que pour cette raison il vaut mieux utiliser random().
Même en supposant une distribution equiprobable, (on peut l'assumer,
car la période du pseudo-générateur est trés grande), le fait de partir
de 2^31-1 pour calculer le modulo va forcément introduire une
inhomogénéïté.
Par exemple, si on travaillait avec N, et 2^4-1, alors les nombres de
0 à 4 seraient deux fois plus probables qu'entre 5 et 9!

Certes. Et si eyaarmy avait un nombre d'images compris entre RAND_MAX/2
et RAND_MAX, certaines d'entre elles seraient effectivement bien plus
probables que d'autres. Mais avec un tel nombre d'images qui s'en
soucierait ?
Bref... sans plus d'infos, je maintiens qu'il est inutile d'aller
chercher un code plus complexe que celui que j'ai donné.
--
Olivier Miakinen
Avatar
Samuel DEVULDER
Le 01/04/2018 à 03:28, Pascal J. Bourguignon a écrit :
random() est spécifié pour générer des nombres pseudo aléatoires entre 0
et (2^31)-1, mais rien n'est dit sur la distribution.

Pas 2^31-1 mais RAND_MAX qui peut être bien inférieur.
Par exemple chez moi (-mshort-int):
$ grep -R RAND_MAX /usr/include
/usr/include/stdlib.h:#define RAND_MAX __RAND_MAX
/usr/include/sys/config.h:#undef __RAND_MAX
/usr/include/sys/config.h:#define __RAND_MAX 32767
L'avantage de ne pas avoir un gros RAND_MAX, c'est que
(random() * petit_entier)/RAND_MAX
ne fait pas d'overflow et fournit une distribution totalement uniforme
entre 0 et petit_entier (inclus) en temps constant.
Si à l'inverse RAND_MAX est gros et que le produit par notre entier
"max" risque de déborder, il suffit de choisir n tel que "max" < (1<<n),
la formule
((random()>>n)*max)/(RAND_MAX>>n)
fournit une distribution homogène entre 0 et max, toujours en temps
constant.
a+
sam.
Avatar
espie
In article , Benoit Izac wrote:
Et comme ça ?
int num_image;
assert(N > 0);
int limit = RAND_MAX - RAND_MAX % N;
int random_num;
do
random_num = random()
while (random_num >= limit);
num_image = random_num % N;

Ca reste mauvais mais pour d'autres raisons.
Specifiquement: tu n'as aucune garantie sur l'algorithme utilise pour
implementer random....
C'est cense etre vaguement mieux que rand() mais avec pas grand chose
comme garantie.
Typiquement, regarde les generateurs pseudo-aleatoires congruents.
Tu verras qu'il ne faut jamais faire % N, mais passer en flottant
et diviser par RAND_MAX, multiplier par N et arrondir...
Apres, si tu veux des bons nombres aleatoires, soit tu as arc4random_uniform,
soit tu te choppes une implementation de ce dernier.
Si vraiment tu peux faire sans, confere numerical recipes et Mersenne Twister.
En tout cas, c'est impossible de faire confiance a un bete rand()/random()
"portable" si tu veux un pseudo-aleatoire de qualite decente...
Avatar
Benoit Izac
Bonjour,
Le 01/04/2018 à 22:49, Marc Espie a écrit dans le message
<p9rgkl$119v$ :
Typiquement, regarde les generateurs pseudo-aleatoires congruents.
Tu verras qu'il ne faut jamais faire % N, mais passer en flottant
et diviser par RAND_MAX, multiplier par N et arrondir...

Là, j'avoue que je ne comprends pas pourquoi ce serait mieux que % N ;
bien au contraire, si je reprends l'exemple avec RAND_MAX et N et
que je joue un peu avec Python (je multiplie par N-1 sinon on se
retrouve avec N alors que l'on veut un nombre dans l'intervalle
[0, N[) :
[int(i/16*9) for i in range(17)]



[0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 9]
Les 4, 8 et 9 ont deux fois moins de chance de sortir.
Apres, si tu veux des bons nombres aleatoires, soit tu as arc4random_uniform,
soit tu te choppes une implementation de ce dernier.
Si vraiment tu peux faire sans, confere numerical recipes et Mersenne
Twister.
En tout cas, c'est impossible de faire confiance a un bete rand()/random()
"portable" si tu veux un pseudo-aleatoire de qualite decente...

Sans doute, mais là on parle d'afficher une photo au hasard dans un jeu,
il faut donc relativiser.
--
Benoit Izac
Avatar
espie
In article , Benoit Izac wrote:
Bonjour,
Le 01/04/2018 à 22:49, Marc Espie a écrit dans le message
<p9rgkl$119v$ :
Typiquement, regarde les generateurs pseudo-aleatoires congruents.
Tu verras qu'il ne faut jamais faire % N, mais passer en flottant
et diviser par RAND_MAX, multiplier par N et arrondir...

Là, j'avoue que je ne comprends pas pourquoi ce serait mieux que % N ;
bien au contraire, si je reprends l'exemple avec RAND_MAX et N et
que je joue un peu avec Python (je multiplie par N-1 sinon on se
retrouve avec N alors que l'on veut un nombre dans l'intervalle
[0, N[) :

T'as regarde ce que c'etait qu'un generateur pseudo-aleatoire congruent ?
typiquement c'est un machin sur lequel faire %N va te donner une periode
d'au plus N.
Par exemple, tirer a pile ou face avec un pseudo-aleatoire congruent, a
coup de %2, va te donner au mieux 0 1 0 1 0 1.
En tout cas, c'est impossible de faire confiance a un bete rand()/random()
"portable" si tu veux un pseudo-aleatoire de qualite decente...

Sans doute, mais là on parle d'afficher une photo au hasard dans un jeu,
il faut donc relativiser.

Non. On commence avec l'affichage d'une photo au hasard d'un jeu, et puis
on passe a autre chose. Ou bien quelqu'un va tomber sur ce code et le
repomper pour autre chose.
On parle ici d'un probleme connu et regle depuis des annees. Je vois zero
raison de ne pas faire les choses correctement. C'est pas comme si c'etait
beaucoup plus complique. Le code necessaire existe deja et peut s'utiliser
sans souci (oui ca existe sous licence BSD, donc tu peux en faire ce que
tu veux, meme pour utilisation commerciale)
1 2 3