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 ! ![]()
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)
Oui mais là le problème est toujours le même, comment intégrer le test
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;
{
}
Sauf que là c'est pas vraiment placé aléatoirement non ?
Toutes les cases sont des bombes
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 ?
Oyez Oyez Ceci est un message de pub pour http://waar.me
- 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
- 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 ?
- http://waar.me depuis 2006 le plus petit jeux en ligne php
- Ce soir waar.me, http://waar.me alors qu'est ce qu'on attend ?
- On s'enjaille sur http://waar.me
- 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 )
http://waar.me ma couille ![]()
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.
Image:
Code : http://pastebin.com/BvqqF4gC
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 ? ![]()
if ((rand()%10+1) == 5)
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++;
}
}
}
}
Une chance sur 10 que la case soit une mine
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.
En C ça fonctionne les for sans accolade ? Au temps pour moi, je croyais que ce n'était qu'en C++.
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 ?
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
[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 ![]()
Parfait, ça fonctionne enfin, merci ! ![]()
Çà peut paraître basique mais ça fait plus de 2 jours que je galère là-dessus ![]()
Bon, bah maintenant je vais m'attaquer à l'affichage des nombres en fonction des mines, c'est pas gagné !
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.