Démineur
LittDev
-
LittDev -
LittDev -
Bonjour,
J'ai programmé le jeu du Demineur sur console, j'aimerais savoir si il y a des trucs a améliorer concernant la structure du code ou concernant les algos utilisés.
Merci d'avance
J'ai programmé le jeu du Demineur sur console, j'aimerais savoir si il y a des trucs a améliorer concernant la structure du code ou concernant les algos utilisés.
#include<stdio.h> #include<stdlib.h> #include<conio.h> #include<time.h> #define X 10 #define Y 10 int NB=10; int mines[X][Y]; char grille[X][Y], affichage[X][Y]; typedef struct { int x; int y; }coordonnees; int comparer(int val, int tab[], int max) { int i, cpt=0; for(i=0;i<max;i++) { if(tab[i]==val) cpt++; } return cpt; } void initialiserMines() { int i, verif[X*Y], temp; srand(time(NULL)); for(i=0;i<X*Y;i++) { verif[i]=-1; affichage[i/Y][i%Y]=-36; grille[i/Y][i%Y]=48; mines[i/Y][i%Y]=0; } for(i=0;i<NB;i++) { do { temp=rand()%(X*Y); } while(comparer(temp,verif,i)!=0); verif[i]=temp; mines[temp/Y][temp%Y]=1; } } void initialiserGrille() { int i, k; for(i=0;i<X*Y;i++) { if(mines[i/Y][i%Y]==0) { for(k=0;k<9;k++) if( ( ((i/Y)-1+(k/3)>=0) && ((i/Y)-1+(k/3)<X) ) && ( ((i%Y)-1+(k%3)>=0) && ((i%Y)-1+(k%3)<Y) ) ) grille[i/Y][i%Y]+=mines[(i/Y)-1+(k/3)][(i%Y)-1+(k%3)]; } else { grille[i/Y][i%Y]=88; } } } int afficher() { int i, j, k, cpt; printf(" \t"); for(j=0;j<10;j++) printf("%2d", j); j=0; printf("\n\n\n\n"); for(i=0;i<X*Y;i++) { if(i%Y==0) { printf("%2d\t", j); j++; } cpt=0; for(k=0;k<9;k++) if( ( ((i/Y)-1+(k/3)>=0) && ((i/Y)-1+(k/3)<X) ) && ( ((i%Y)-1+(k%3)>=0) && ((i%Y)-1+(k%3)<Y) ) ) if(grille[(i/Y)-1+(k/3)][(i%Y)-1+(k%3)]==0) cpt++; if(grille[i/Y][i%Y]>47) { if(cpt!=0 && grille[i/Y][i%Y]!=48) { affichage[i/Y][i%Y]=grille[i/Y][i%Y]; printf("%2c", affichage[i/Y][i%Y]); } else { printf("%2c", affichage[i/Y][i%Y]); } } else { affichage[i/Y][i%Y]=0; printf("%2c", affichage[i/Y][i%Y]); } if(i%Y==Y-1) { printf("\n"); } } } void devoiler(coordonnees point) { int i, temp, j=0, c=0, verif[100]={0}; coordonnees pointsDevoiles[100]={0,0}; srand(time(NULL)); for(i=0;i<X*Y;i++) verif[i]=-1; if(grille[point.x][point.y]==48) { do { if(j==0) { grille[point.x][point.y]=0; pointsDevoiles[j].x=point.x; pointsDevoiles[j].y=point.y; j++; } else { temp=rand()%j; point.x=pointsDevoiles[temp].x; point.y=pointsDevoiles[temp].y; } for(i=1;i<9;i+=2) if( ( ((point.x)-1+(i/3)>=0) && ((point.x)-1+(i/3)<X) ) && ( ((point.y)-1+(i%3)>=0) && ((point.y)-1+(i%3)<Y) ) ) { if(grille[(point.x)-1+(i/3)][(point.y)-1+(i%3)]==48) { grille[(point.x)-1+(i/3)][(point.y)-1+(i%3)]=0; pointsDevoiles[j].x=(point.x)-1+(i/3); pointsDevoiles[j].y=(point.y)-1+(i%3); j++; } if(comparer((point.x*Y+point.y),verif,c)==0) { verif[c]=point.x*Y+point.y; c++; } } } while(c<j); } else { affichage[point.x][point.y]=grille[point.x][point.y]; } } int verifier() { int i, cpt=0; for(i=0;i<X*Y;i++) { if(affichage[i/Y][i%Y]==-36) cpt++; else if(affichage[i/Y][i%Y]==88) return 0; } return cpt; } void jouer() { int temp, continuer=1; coordonnees point; do { printf("****************************************\n"); printf("________________DEMINEUR________________\n"); printf("****************************************\n\n"); printf("1 - Jouer\n2 - Personnaliser\n3 - Quitter\n\nVotre choix : "); scanf("%d", &temp); while(temp>3||temp<1) { printf("\nRecommencez : "); scanf("%d", &temp); } if(temp==2) { do { printf("\n\nNombres de mines ( >=5 et <=50 ) : "); scanf("%d", &NB); } while(NB<5||NB>50); } system("cls"); } while(temp==2); if(temp==1) { initialiserMines(); initialiserGrille(); afficher(); do { printf("\n\n\n\n\nCase : \n\nX : "); scanf("%d", &point.x); printf("Y : "); scanf("%d", &point.y); system("cls"); devoiler(point); afficher(); if(verifier()==NB) { do { printf("\n\nVous avez gagne\nRejouer ? (Oui : 1 / Non : 0) : "); scanf("%d", &temp); } while(temp>1||temp<0); if(temp==1) { continuer=0; system("cls"); jouer(); } else { continuer=0; } } else { if(verifier()==0) { do { printf("\n\nVous avez perdu\nRejouer ? (Oui : 1 / Non : 0) : "); scanf("%d", &temp); } while(temp>1||temp<0); if(temp==1) { continuer=0; system("cls"); jouer(); } else { continuer=0; } } else { continuer=1; } } } while(continuer); } } int main(void) { jouer(); return 0; }
Merci d'avance
A voir également:
- Démineur
- Démineur google - Accueil - Services en ligne
- Accéder aux jeux cachés de Google - Guide
- Algorithme démineur inversé - Forum C
- Bloquer démineur/solitaire GPO - Forum Réseau
- Démineur/Minesweeper sur Windows 8 - Forum Windows 8 / 8.1
4 réponses
Bonjour,
Voici mes remarques sur le code (non exhaustif) :
Il manque les commentaires (à ne pas négliger, ça fait partie du code).
Eviter les variables globales. Dans ton cas, il suffit de les faire passer en argument.
void jouer(), int verifier(), ...
Le bon prototype d'une fonction sans argument est : type nomFonction(void). Sinon, la fonction n'est pas correctement définie.
int afficher()
Il manque un return dans ta fonction.
Dans ton code, tu parles des nombres -36, 88, etc. Ce n'est pas parlant. Je te conseille d'utiliser enum pour gagner en lisibilité. Ou à défaut, d'utiliser une constante.
system("cls");
Non portable. D'une manière générale, sauf si cela est pour faire un programme très simple (mais pourquoi utiliser le C dans cas...), on évite system(). Comme il n'existe pas de manière portable, le mieux est de déporter cette fonction dans un module spécifique. Sur Windows, il faut plutôt faire appel aux API pour effacer l'écran.
#include<conio.h>
Non portable...
coordonnees pointsDevoiles[100]={0,0};
Ce n'est pas bon ça. Normalement, ça fait un warning. Il faut définir chacune des lignes. Ou alors, faire une boucle for.
Concernant, les scanf(). Attention, cela n'est pas sécurisé. Imagine ce qu'il se passe si l'utilisateur tape autre chose que ce qui est attendu. Il faut donc contrôler le retour.
srand(time(NULL));
A n'appeler qu'une seule fois dans tout ton programme. Sinon, tu perds en aléa. Dans ton cas, à chaque fois que tu rejoues, tu rappelles ce code.
Cdlt,
Voici mes remarques sur le code (non exhaustif) :
Il manque les commentaires (à ne pas négliger, ça fait partie du code).
Eviter les variables globales. Dans ton cas, il suffit de les faire passer en argument.
void jouer(), int verifier(), ...
Le bon prototype d'une fonction sans argument est : type nomFonction(void). Sinon, la fonction n'est pas correctement définie.
int afficher()
Il manque un return dans ta fonction.
Dans ton code, tu parles des nombres -36, 88, etc. Ce n'est pas parlant. Je te conseille d'utiliser enum pour gagner en lisibilité. Ou à défaut, d'utiliser une constante.
system("cls");
Non portable. D'une manière générale, sauf si cela est pour faire un programme très simple (mais pourquoi utiliser le C dans cas...), on évite system(). Comme il n'existe pas de manière portable, le mieux est de déporter cette fonction dans un module spécifique. Sur Windows, il faut plutôt faire appel aux API pour effacer l'écran.
#include<conio.h>
Non portable...
coordonnees pointsDevoiles[100]={0,0};
Ce n'est pas bon ça. Normalement, ça fait un warning. Il faut définir chacune des lignes. Ou alors, faire une boucle for.
Concernant, les scanf(). Attention, cela n'est pas sécurisé. Imagine ce qu'il se passe si l'utilisateur tape autre chose que ce qui est attendu. Il faut donc contrôler le retour.
srand(time(NULL));
A n'appeler qu'une seule fois dans tout ton programme. Sinon, tu perds en aléa. Dans ton cas, à chaque fois que tu rejoues, tu rappelles ce code.
Cdlt,
Ok merci, mais, je ne suis qu'un debutant .....
1 - Par quoi je pourrais remplacer scanf ?
2 - Et aussi, comment pourrais-je utiliser l'API pour effacer l'écran ?
J'ai mis volontairement des variables globales parce que la plupart des fonctions on en besoin, j'ai commencer, au tout début, par les faire passer en argument, mais c'était trop long et ça devenait trop compliqué
En quoi les variables globales poseraient-elles problème ?
1 - Par quoi je pourrais remplacer scanf ?
2 - Et aussi, comment pourrais-je utiliser l'API pour effacer l'écran ?
J'ai mis volontairement des variables globales parce que la plupart des fonctions on en besoin, j'ai commencer, au tout début, par les faire passer en argument, mais c'était trop long et ça devenait trop compliqué
En quoi les variables globales poseraient-elles problème ?
Ton code est très bien si tu débutes.
Maintenant, mes remarques visent à améliorer ton code et ton niveau ;-).
Pour scanf(), le plus simple est d'utiliser fgets() pour lire une chaîne de caractère et de convertir en nombre avec strtol().
Pour effacer l'écran : https://c.developpez.com/faq/?page=Gestion-du-clavier-et-de-l-ecran-en-mode-console#Comment-effacer-l-ecran
Pour les variables globales, c'est déconseillé pour plusieurs raisons :
1/ on ne sait pas qui accède à cette variable : pas bon si tu souhaites sécuriser ton programme, mauvaise lisibilité
2/cela peut poser problème par la suite si tu souhaites utiliser des thread, faire de la récursivité, etc.
Bref, c'est un mauvais réflexe.
Maintenant, mes remarques visent à améliorer ton code et ton niveau ;-).
Pour scanf(), le plus simple est d'utiliser fgets() pour lire une chaîne de caractère et de convertir en nombre avec strtol().
Pour effacer l'écran : https://c.developpez.com/faq/?page=Gestion-du-clavier-et-de-l-ecran-en-mode-console#Comment-effacer-l-ecran
Pour les variables globales, c'est déconseillé pour plusieurs raisons :
1/ on ne sait pas qui accède à cette variable : pas bon si tu souhaites sécuriser ton programme, mauvaise lisibilité
2/cela peut poser problème par la suite si tu souhaites utiliser des thread, faire de la récursivité, etc.
Bref, c'est un mauvais réflexe.
Salut
Je l'ai essayé, mais ça marche pas, il me signale que les types ne sont pas reconnus
Et comment utilisetons strtol() ? je n'ai pas trouvé beaucoup de documentation sur elle.
#include <windows.h>
void windows_clear_screen(void)
{
HANDLE hConsole;
CONSOLE_CONS_BUFFER_INFO Info;
DWORD NbOctetsEcrits; /* Requis par FillConsoleOutputCharacter */
COORD Debut = {0, 0};
/* STD_OUTPUT_HANDLE fait référence a la sortie standard du programme qui est par défaut la console */
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
/* Lit les infos sur le buffer de l'écran */
GetConsoleScreenBufferInfo(hConsole, &Info);
/* Remplit l'écran avec le caractère espace */
FillConsoleOutputCharacter(hConsole, ' ', Info.dwSize.X*Info.dwSize.Y, Debut, &NbOctetsEcrits);
/* Remet le curseur au début de l'écran */
SetConsoleCursorPosition(hConsole, Debut);
}
Je l'ai essayé, mais ça marche pas, il me signale que les types ne sont pas reconnus
Et comment utilisetons strtol() ? je n'ai pas trouvé beaucoup de documentation sur elle.
Bizarre, il y a une erreur sur leur site.
Remplace CONSOLE_... par CONSOLE_SCREEN_BUFFER_INFO
Ca devrait être mieux.
Pour strtol(), il y a un exemple sur le man : http://manpagesfr.free.fr/man/man3/strtol.3.html
Remplace CONSOLE_... par CONSOLE_SCREEN_BUFFER_INFO
Ca devrait être mieux.
Pour strtol(), il y a un exemple sur le man : http://manpagesfr.free.fr/man/man3/strtol.3.html
Re-salut
Pour ce qui est de strtol(), c'est bon j'ai réglé le problème, voilà le code final, merci à tous :
Pour ce qui est ds variables globales, je peux pas m'en passer, parce que c'est compliqué de faire tout passer en arguments, et la fonction jouer s’appelle elle même, ça pose problème dans ce cas ....
Ya pas un moyen pour limiter l'acces au variables ?
Pour ce qui est de strtol(), c'est bon j'ai réglé le problème, voilà le code final, merci à tous :
#include<stdio.h> #include<stdlib.h> #include<string.h> #include <windows.h> #include<time.h> #define XMAX 20 #define YMAX 20 typedef enum { CASE=-36,VIDE=0,ZERO=48,MINE=88,ACTIF=1,INACTIF=0 }etat; int nombreDeMines=10, longueur=10, largeur=10, mines[XMAX][YMAX]; char grille[XMAX][YMAX], affichage[XMAX][YMAX]; typedef struct { int x; int y; }coordonnees; void windowsClearScreen(void) { HANDLE hConsole; CONSOLE_SCREEN_BUFFER_INFO Info; DWORD NbOctetsEcrits; COORD Debut = {0, 0}; hConsole = GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleScreenBufferInfo(hConsole, &Info); FillConsoleOutputCharacter(hConsole, ' ', Info.dwSize.X*Info.dwSize.Y, Debut, &NbOctetsEcrits); SetConsoleCursorPosition(hConsole, Debut); } void cleanStdin(void) { int c; do { c = getchar(); } while (c != '\n' && c != EOF); } int lireNombre(void) { int n; char entree[256], *p; fgets(entree, sizeof(entree), stdin); if((p=strchr(entree,'\n'))!=NULL) *p ='\0'; else cleanStdin(); n=strtol(entree, &p, 10); if(*p=='\0') return n; } int comparer(int val, int tab[], int max) { int i, cpt=0; for(i=0;i<max;i++) { if(tab[i]==val) cpt++; } return cpt; } void initialiserMines(void) { int i, temp; for(i=0;i<XMAX*YMAX;i++) { affichage[i/YMAX][i%YMAX]=CASE; grille[i/YMAX][i%YMAX]=ZERO; mines[i/YMAX][i%YMAX]=INACTIF; } for(i=0;i<nombreDeMines;i++) { do { temp=rand()%(longueur*largeur); } while(mines[temp/largeur][temp%largeur]==ACTIF); mines[temp/largeur][temp%largeur]=ACTIF; } } void initialiserGrille(void) { int i, k; for(i=0;i<longueur*largeur;i++) { if(mines[i/largeur][i%largeur]==INACTIF) { for(k=0;k<9;k++) if( ( ((i/largeur)-1+(k/3)>=0) && ((i/largeur)-1+(k/3)<longueur) ) && ( ((i%largeur)-1+(k%3)>=0) && ((i%largeur)-1+(k%3)<largeur) ) ) grille[i/largeur][i%largeur]+=mines[(i/largeur)-1+(k/3)][(i%largeur)-1+(k%3)]; } else { grille[i/largeur][i%largeur]=MINE; } } } void afficher(void) { int i, j, k, cpt; printf("\n \t"); for(j=0;j<largeur;j++) printf("%3d", j); j=0; printf("\n\n\n\n"); for(i=0;i<longueur*largeur;i++) { if(i%largeur==0) { printf(" %2d\t", j); j++; } cpt=0; for(k=0;k<9;k++) if( ( ((i/largeur)-1+(k/3)>=0) && ((i/largeur)-1+(k/3)<longueur) ) && ( ((i%largeur)-1+(k%3)>=0) && ((i%largeur)-1+(k%3)<largeur) ) ) if(grille[(i/largeur)-1+(k/3)][(i%largeur)-1+(k%3)]==0) cpt++; if(grille[i/largeur][i%largeur]>47) { if(cpt!=0 && grille[i/largeur][i%largeur]!=ZERO) { affichage[i/largeur][i%largeur]=grille[i/largeur][i%largeur]; printf("%3c", affichage[i/largeur][i%largeur]); } else { printf("%3c", affichage[i/largeur][i%largeur]); } } else { affichage[i/largeur][i%largeur]=VIDE; printf("%3c", affichage[i/largeur][i%largeur]); } if(i%largeur==largeur-1) { printf("\n\n"); } } } void afficherMines(void) { int i, j; printf("\n \t"); for(j=0;j<largeur;j++) printf("%3d", j); j=0; printf("\n\n\n\n"); for(i=0;i<longueur*largeur;i++) { if(i%largeur==0) { printf(" %2d\t", j); j++; } if(affichage[i/largeur][i%largeur]==CASE) { if(grille[i/largeur][i%largeur]==MINE) printf("%3c", MINE); else printf("%3c", CASE); } else { if(affichage[i/largeur][i%largeur]>ZERO) printf("%3c", affichage[i/largeur][i%largeur]); else printf("%3c", VIDE); } if(i%largeur==largeur-1) { printf("\n\n"); } } } void devoiler(coordonnees point) { int i, temp, j=0, c=0, verif[XMAX*YMAX]={0}; coordonnees pointsDevoiles[XMAX*YMAX]; for(i=0;i<XMAX*YMAX;i++) { pointsDevoiles[XMAX*YMAX].x=0; pointsDevoiles[XMAX*YMAX].y=0; } for(i=0;i<XMAX*YMAX;i++) verif[i]=-1; if(grille[point.x][point.y]==ZERO) { do { if(j==0) { grille[point.x][point.y]=0; pointsDevoiles[j].x=point.x; pointsDevoiles[j].y=point.y; j++; } else { temp=rand()%j; point.x=pointsDevoiles[temp].x; point.y=pointsDevoiles[temp].y; } for(i=1;i<9;i+=2) if( ( ((point.x)-1+(i/3)>=0) && ((point.x)-1+(i/3)<longueur) ) && ( ((point.y)-1+(i%3)>=0) && ((point.y)-1+(i%3)<largeur) ) ) { if(grille[(point.x)-1+(i/3)][(point.y)-1+(i%3)]==ZERO) { grille[(point.x)-1+(i/3)][(point.y)-1+(i%3)]=VIDE; pointsDevoiles[j].x=(point.x)-1+(i/3); pointsDevoiles[j].y=(point.y)-1+(i%3); j++; } if(comparer((point.x*largeur+point.y),verif,c)==0) { verif[c]=point.x*largeur+point.y; c++; } } } while(c<j); } else { affichage[point.x][point.y]=grille[point.x][point.y]; } } int verifier(void) { int i, cpt=0; for(i=0;i<longueur*largeur;i++) { if(affichage[i/largeur][i%largeur]==CASE) cpt++; else if(affichage[i/largeur][i%largeur]==MINE) return 0; } return cpt; } void jouer(void) { int temp, inter, continuer=1; coordonnees point; do { printf(" ****************************************\n"); printf(" ________________DEMINEUR________________\n"); printf(" ****************************************\n\n"); printf(" 1 - Jouer\n 2 - Personnaliser\n 3 - Quitter\n\n Votre choix : "); temp=lireNombre(); while(temp>3||temp<1) { printf("\n Recommencez : "); temp=lireNombre(); } if(temp==2) { do { printf("\n\n Longueur ( >=5 et <=20, actuel : %d ) : ", longueur); inter=lireNombre(); } while(inter<5||inter>XMAX); longueur=inter; do { printf("\n\n Largeur ( >=5 et <=20, actuel : %d ) : ", largeur); inter=lireNombre(); } while(inter<5||inter>YMAX); largeur=inter; do { printf("\n\n Nombres de mines ( >=2 et <=%d , actuel : %d ) : ", longueur*largeur/2, nombreDeMines); inter=lireNombre(); } while(inter<2||inter>longueur*largeur/2); nombreDeMines=inter; } windowsClearScreen(); } while(temp==2); if(temp==1) { initialiserMines(); initialiserGrille(); afficher(); do { printf("\n\n\n\n\n Case : \n\n X : "); point.x=lireNombre(); while(point.x>=longueur) { printf(" Recommencez ( X<%d ) : ", longueur); point.x=lireNombre(); } printf(" Y : "); point.y=lireNombre(); while(point.y>=largeur) { printf(" Recommencez ( Y<%d ) : ", largeur); point.y=lireNombre(); } windowsClearScreen(); devoiler(point); afficher(); if(verifier()==nombreDeMines) { do { windowsClearScreen(); afficherMines(); printf("\n\n Vous avez gagne\n Rejouer ? (Oui : 1 / Non : 0) : "); temp=lireNombre(); } while(temp>1||temp<0); if(temp==1) { continuer=0; windowsClearScreen(); jouer(); } else { continuer=0; } } else { if(verifier()==0) { do { windowsClearScreen(); afficherMines(); printf("\n\n Vous avez perdu\n Rejouer ? (Oui : 1 / Non : 0) : "); temp=lireNombre(); } while(temp>1||temp<0); if(temp==1) { continuer=0; windowsClearScreen(); jouer(); } else { continuer=0; } } else { continuer=1; } } } while(continuer); } } int main(void) { srand(time(NULL)); jouer(); return 0; }
Pour ce qui est ds variables globales, je peux pas m'en passer, parce que c'est compliqué de faire tout passer en arguments, et la fonction jouer s’appelle elle même, ça pose problème dans ce cas ....
Ya pas un moyen pour limiter l'acces au variables ?
Une manière de limiter la portée de tes variables est de les utiliser comme variables globales statiques.
Cela est possible si tu construis ton code de façon modulaire, en divisant le programme en couples de .c et .h et en précédant la déclaration de ces variables globales du spécificateur "static". Dans le cas de variables déclarées de dehors d'une fonction, la portée de ces variables sera alors limitée aux fonctions relevant de cette même unité de compilation.
Dal
Cela est possible si tu construis ton code de façon modulaire, en divisant le programme en couples de .c et .h et en précédant la déclaration de ces variables globales du spécificateur "static". Dans le cas de variables déclarées de dehors d'une fonction, la portée de ces variables sera alors limitée aux fonctions relevant de cette même unité de compilation.
Dal
Pour ce qui est ds variables globales, je peux pas m'en passer, parce que c'est compliqué de faire tout passer en arguments, et la fonction jouer s’appelle elle même, ça pose problème dans ce cas ....
C'est peut-être un peu fastidieux, et encore pas tant que ça, mais c'est pourtant une bonne habitude à prendre. Au pire, s'il y a vraiment trop de variable, il y a certainement de l'élagage à faire (structure, ...).
Pour la fonction jouer qui s'appelle elle-même, ce n'est pas un problème. Ca fonctionne très bien ainsi/
Maintenant, c'est toi qui codes ;-). Sinon, tu as static comme précisé par [Dal]
C'est peut-être un peu fastidieux, et encore pas tant que ça, mais c'est pourtant une bonne habitude à prendre. Au pire, s'il y a vraiment trop de variable, il y a certainement de l'élagage à faire (structure, ...).
Pour la fonction jouer qui s'appelle elle-même, ce n'est pas un problème. Ca fonctionne très bien ainsi/
Maintenant, c'est toi qui codes ;-). Sinon, tu as static comme précisé par [Dal]
OK merci
J'ai surtout galérer avec algo qui dévoile les cases, la ou des fois il faut dévoiler tous les zéros contigus ainsi que leur pourtour
Alors pour devoiler le groupe de cases, il commence par dévoiler la case sélectionné par l'utilisateur, puis il vois si il n'y a pas de zéros au 4 coins de la case, si oui, il va les devoiler, et les prendre en considération, et puis il va choisir au hasard une case parmi les cases qu'il a dévoilé, il vérifie s'y il n'y a pas de zéros autour, si oui, il continue de la même manière, il re-selectionne une case au hasard parmi celles qu'il a activées et ...........
Il n'y aurait pas un algo plus simple que ça ?