CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

Test dans une variable aléatoire en C

Rorann
Rorann
Niveau 8
29 avril 2013 à 19:35:01

Salut à tous !

Voilà, je suis encore débutant en programmation, et je tente de développer un démineur. Pour l'instant, le programme est essentiellement composé de fonctions assez simples (afficher le plateau, gérer les clics droits et gauches...). Je suis actuellement en train de générer les mines aléatoirement. Le problème étant, certaines mines sont positionnées au même endroit. En effet, les coordonnées de la mine sont définis aléatoirement en x et en y avant d'être centrées au centre de la case à partir de ces coordonnées. Les cases faisant 50 pixels de côté et le plateau 501 pixels sur 500 (10 x 10 cases donc), la probabilité d'avoir plusieurs mines sur une même case est assez élevée (je voudrais entre 10 et 20 mines).

J'ai essayé plusieurs choses pour remédier à ce problème, utilisation de conditions, différents types de boucles, mais rien n'y fait, je me retrouve soit avec une boucle infinie, ou le même problème qu'avant...

J'utilise une seule bibliothèque graphique simplifiant certaines fonctions graphiques (je ne m'en sers ici que pour la variable aléatoire et tracer un cercle plein)

DEMIN mines(DEMIN dm) //fonction de placement de mines
{
POINT mine;
int nombre_mines;

for(nombre_mines=1; nombre_mines<15; nombre_mines++)
{
mine.x = alea_int(499); mine.y = alea_int(499); //définition aléatoire des coordonnées en x et en y sur un intervalle de 1 à 499
mine.x = (mine.x/50)*50+25; mine.y = (mine.y/50)*50+25; //centrage des mines au centre de la case
draw_fill_circle(mine, 13, color5); //dessin de la mine à partir du centre de la case
dm.tab[mine.x/50][mine.y/50] = 1; //placement de la mine dans un quadrillage virtuel défini plus haut (10 x 10 cases)
}
}

Voilà, c'est la "première" version du programme qui fonctionne, qui place les mines aléatoirement mais qui peut en placer plusieurs sur la même case.

Merci d'avance pour votre aide ! :)

unitedelite29
unitedelite29
Niveau 10
29 avril 2013 à 19:41:59

fait un tableau 2d (avec des 0 pour rien et des 1 pour une mine), puis tu fait l'affichage en parcourant se tableau et en multipliant les coordonné par 50, ainsi tu pourra verifier si une case est occupé ou non (via par exemple tableau[x][y] == 1)

Rorann
Rorann
Niveau 8
29 avril 2013 à 20:45:56

Oui mais là le problème est toujours le même, comment intégrer le test

unitedelite29
unitedelite29
Niveau 10
29 avril 2013 à 20:54:17

ben c'est simple, au début tu fait ton tableau de 10*10 (par exemple bool matrice[10][10]) que t'initialise tout a "false" (pas de bombe)

tu choisi aléatoirement des coordonné de bombes entre 0:0 et 10:10, tu vérifie si la case de la matrice est occupé (matrice[x][y] != true) si elle est pas occupé tu défini cette case comme true, et tu fait ça jusqu'a ce que t'ai ton nombre de bombe de posé.

ensuite sur ta fonction de dessin tu parcours ton tableau et tu dessine les cases en multipliant la coordonnée X par la largeur de ton sprite et la coordonnée Y par la hauteur du sprite (via un double for

for( int y = 0;y<10;y++)
{
    for(int x=0;x<10;x++)
    {
if(niveau[x][y] == false)
niveau[x][y] == true;
{
}

Rorann
Rorann
Niveau 8
29 avril 2013 à 21:58:50

Sauf que là c'est pas vraiment placé aléatoirement non ?

MeCulpa
MeCulpa
Niveau 5
29 avril 2013 à 22:00:33

Toutes les cases sont des bombes

Rorann
Rorann
Niveau 8
29 avril 2013 à 22:05:05

C'était pas vraiment le but...
Bon, pour l'instant j'en suis là, je sais toujours pas où et comment intégrer le test :

DEMIN mines(DEMIN dm)
{
POINT mine;
int nombre_mines;

for(nombre_mines=1; nombre_mines<16; nombre_mines++)
{
mine.x = alea_int(10); mine.y = alea_int(10);
dm.tab[mine.x][mine.y] == 1;
mine.x = mine.x * 50; mine.y = mine.y * 50;
mine.x = mine.x + 25; mine.y = mine.y + 25;
draw_fill_circle(mine, 13, color5);
}
}

Et ça peut paraître con, mais comment on initialise toutes les cases d'un coup à false ?

Yololo
Yololo
Niveau 4
29 avril 2013 à 22:21:55

:d) Oyez Oyez Ceci est un message de pub pour http://waar.me :g)

- Qu'est-ce que c'est waar.me ? C'est tout simplement le plus petit jeux en ligne, jouable de la ds au pc en passant par votre vieux mobile de clochard :hap:

- Un concepts additif, une communauté soudé, une ambiance sympa, alors pourquoi bordel irait tu payer sur ogame alors qu'il y'a tout près de chez toi http://waar.me ? :non:

- http://waar.me depuis 2006 le plus petit jeux en ligne php :ok:

- Ce soir waar.me, http://waar.me alors qu'est ce qu'on attend ? :content:

- On s'enjaille sur http://waar.me :oui:

- Si vous avez un souhait, faut il appeler http://waar.me ?

- A la fin de http://waar.me tu meurs et tu incarne personne vue que t'aura jamais de meuf et donc de fils

- L'abus de http://waar.me n'est pas nocif pour votre santé

Alors go http://waar.me, le plus petit jeux en ligne, sympa, claire, simple, ça roxx du pâté au morille mon gars, prépare toi a sacrifier le peut de vie social qu'il te reste hap:

(Ceci est un message du ministère de la culture rédiger par pépito )

:ok: http://waar.me ma couille :ok:

]pseudotest[
]pseudotest[
Niveau 3
29 avril 2013 à 22:30:35

Comme dit unitedelite29, il faut séparer la partie jeu et la partie graphique.
Si alea_int() représente ta fonction de hasard :

int nombre_mines=1;
int nombre_mines_voulues=16;
bool plateau[nb_case_x][nb_case_y];

for(int i=0 ; i<nb_case_x ; i++)
for(int j=0 ; j<nb_case_x ; j++)
plateau[i][j] = false;

while(nombre_mines<nombre_mines_voulues)
{
int place = alea_int(nb_case_x*nb_case_y);
int place_x = place/nb_case_x;
int place_y = place%nb_case_x

if(plateau[place_x][place_y]) //Si la place est occupée
continue; //On revient au début de la boucle

plateau[place_x][place_y] = true;

nombre_mines++;
}

    • ***********

A ce niveau tu as un tableau rempli aléatoirement de façon safe.
Pour l'affichage, tu prends les coordonnées qui correspondent à place_x et place_y, et tu les multiplie par la longueur et la hauteur d'une case.

MeCulpa
MeCulpa
Niveau 5
29 avril 2013 à 22:47:32

Image: https://image.noelshack.com/fichiers/2013/18/1367268334-sans-titre.png

Code : http://pastebin.com/BvqqF4gC

]pseudotest[
]pseudotest[
Niveau 3
29 avril 2013 à 23:06:18

Pour mon code, ca sera plutôt
for(int i=0 ; i<nb_case_x ; i++)
for(int j=0 ; j<nb_case_y ; j++) // <== erreur de frappe ici

MeCulpa :
T'as inversé les lignes et les colonnes dans le placement.
Ensuite euh c'est quoi ce test exactement ? :p)
if ((rand()%10+1) == 5)

Rorann
Rorann
Niveau 8
29 avril 2013 à 23:10:33

Merci pour ton aide ! Mais bon, j'ai dû faire une connerie au niveau des accolades ou je sais pas quoi puisque il y a toujours un bug, un nombre insuffisant de mines ou une boucle infinie. Pour l'instant ça ressemble à ça :

DEMIN mines(DEMIN dm)
{int nombre_mines=1;
POINT mine;
int i; int j;

for(i=0; i<10; i++)
{
for(j=0; j<10; j++)
{
dm.tab[i][j] = false;

while(nombre_mines<16)
{
int place = alea_int(10*10);
int place_x = place/10;
int place_y = place%10;

if(dm.tab[place_x][place_y] = true) //Si la place est occupée
{continue;} //On revient au début de la boucle

dm.tab[place_x][place_y] = true;
mine.x = place_x * 50; mine.y = place_y * 50;
mine.x = mine.x + 25; mine.y = mine.y + 25;
draw_fill_circle(mine, 13, color5);
nombre_mines++;
}
}
}
}

MeCulpa
MeCulpa
Niveau 5
29 avril 2013 à 23:10:45

Une chance sur 10 que la case soit une mine

]pseudotest[
]pseudotest[
Niveau 3
29 avril 2013 à 23:30:01

Il n'y a des accolades que là ou je les ai mises.
Un for sans accolade considérera qu'il ne devra répéter que la ligne suivante ;)

MeCulpa : Ah ok je me disais aussi ^^
Le but étant de pouvoir contrôler le nombre de mines placées, il faudra en plus soit intégrer un compteur (solution qui répartira "mal" les mines) , soit opter pour une boucle "de placement".
Sinon remplace aussi le test par
if(rand()%10)
ça évite les instructions inutiles.

Rorann
Rorann
Niveau 8
29 avril 2013 à 23:48:15

En C ça fonctionne les for sans accolade ? Au temps pour moi, je croyais que ce n'était qu'en C++.

Rorann
Rorann
Niveau 8
29 avril 2013 à 23:51:49

Et pas d'accolade après le if non plus ?

int place_y = place%nb_case_x
Bon là j'imagine qu'il y a un point-virgule à la fin, mais le % c'est normal ?

]pseudotest[
]pseudotest[
Niveau 3
30 avril 2013 à 00:15:02

Ah vi j'ai oublié le point virgule aussi.

En gros tu génère un nombre entre 0 et le nombre de case totales (disons 150 en 15x10). Si tu obtiens 74, ce sera la case de la ligne 74/15=4 (division ENTIERE) et de colonne 74%15=14

]pseudotest[
]pseudotest[
Niveau 3
30 avril 2013 à 00:20:55

[tab pressed]
Tu fais ça 16 fois (enfin ton nombre de mine) en t'assurant qu'on ne place pas deux fois au même endroit et c'est gagné :)

Tu peux aussi gérer avec
int place_x = alea_int(nb_case_x);
int place_y = alea_int(nb_case_y);
si le modulo te dérange. Je procède comme ça économiser un accès à rand() ou alea_int(), mais les deux fonctionnent :)

Rorann
Rorann
Niveau 8
30 avril 2013 à 10:15:09

Parfait, ça fonctionne enfin, merci ! :-d
Çà peut paraître basique mais ça fait plus de 2 jours que je galère là-dessus :hum:
Bon, bah maintenant je vais m'attaquer à l'affichage des nombres en fonction des mines, c'est pas gagné !

Rorann
Rorann
Niveau 8
30 avril 2013 à 13:27:54

Hum, lorsqu'on définit la case comme true en fin de boucle, en sortie de cette boucle, toutes les valeurs true sont-elles retenues ou seulement la dernière ? Car j'ai rajouté à la suite la fonction de traçage de mines (en graphique) et une seule s'affiche, or il faudrait que les valeurs restent...

DEMIN mines(DEMIN dm)
{int nombre_mines=1;
POINT mine;
int i; int j;
int place, place_x, place_y;

for(i=0; i<10; i++)
for(j=0; j<10; j++)
dm.tab[i][j] = false;

while(nombre_mines<16)
{
place = alea_int(10*10);
place_x = place/10;
place_y = place%10;

if(dm.tab[place_x][place_y]) //Si la place est occupée
continue; //On revient au début de la boucle

dm.tab[place_x][place_y] = true;
nombre_mines++;
}

if(dm.tab[place_x][place_y] == 1)
{
mine.x = place_x * 50; mine.y = place_y * 50;
mine.x = mine.x + 25; mine.y = mine.y + 25;
draw_fill_circle(mine, 13, color5);}
else{
POINT aff_nombre;
aff_nombre.x = place_x * 50; aff_nombre.y = place_y * 50;
aff_nombre.x = aff_nombre.x + 10; aff_nombre.y = aff_nombre.y + 30;
//int nombre_adj = 1;
aff_pol("A", 20, aff_nombre, color5);}

}

Le else à la fin est juste un test d'affichage de texte (ce sera un chiffre par la suite) quand la case est en false.

Sous forums
  • Aide à l'achat Mac
  • Macintosh
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Steam Deck
  • Hardware
La vidéo du moment