Problème générateur de grille de sudoku en C

Résolu
Dovah Messages postés 10 Date d'inscription jeudi 22 décembre 2011 Statut Membre Dernière intervention 23 décembre 2011 - 22 déc. 2011 à 00:51
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 - 23 déc. 2011 à 15:51
Bonjour,

je suis débutant en programmation, et pour m'entraîner j'ai décidé de créer un programme qui génère aléatoirement une grille de sudoku en C sur console. Pas très original je sais mais bon
Mon programme génère un nombre de chiffres aléatoires, et chaque chiffre lui même est aléatoire ( enfin modulo 10 ).
Jusque là ça va très, bien, c'est tout facile, mais comme vous la savez y a 3 conditions dans une grille de sudoku : il ne faut pas plusieurs fois le même nombre dans une même ligne, colonne, et dans un carré de 3x3.
J'ai donc décidé de mettre le tout dans une boucle, qui regénérera chaque ligne et colonne ( carré pas encore fait ) jusqu'à ce que ça soit bon.

Voici mon code :
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>


int verif_lineaire (int *tob)
{
    int i, j, n=0;
    int board[9];
    for(i=0;i<9;i++)
    {
        board[i]=tob[i];
    }

    for(i=0;i<9;i++)
    {
        for(j=0;j<9;j++)
        {

            if(board[i]==board[j])
               {
                   if(board[i]!=0)
                   {
                        if(&board[i]!=&board[j])
                        {
                            n++; printf("n : %d\n", n);
                        }
                   }
               }

        }
    }
    printf("\t n final : %d\n", n);
    if (n==0) return 1;
    else return 0;
}

int main()
{
    int i, j, n, k, alea, x, y;
    int tab[9][9], tob[9], col[9];
    srand(time(NULL));

    for(i=0;i<9;i++)       //rend nul chaque case
    {
        tob[i]=0; col[i]=0;
        for(j=0;j<9;j++)
        {
            tab[i][j]=0;
        }
    }

    for(i=0;i<9;i++)        //met un nombre de chiffres aléatoires sur chaque ligne
    {
        n=rand()%7;   //nombre de chiffres à mettre
        do {
            for(j=0;j<n;j++)
            {
                k=rand()%10; alea=rand()%10;    
//k=case aléatoire, alea=nombre à mettre dans la case 
                tab[i][k]=alea;
            }
            for(j=0;j<9;j++)
            {
                tob[j]=tab[i][j];
                col[j]=tab[j][i];
            }
            x=verif_lineaire(&tob); y=verif_lineaire(&col);
        }while((x!=1)&&(y!=1));
    }


    for(i=0;i<9;i++)                //affichage
    {
        for(j=0;j<9;j++)
        {
            if(j==3) printf("|");
            if(j==6) printf("|");
            if(tab[i][j]==0) printf(" ");
            else if(tab[i][j]!=0) printf("%d", tab[i][j]);
        }
        printf("\n");
        if((i-2)==0) printf("-----------\n");
        if((i-5)==0) printf("-----------\n");
    }

    Sleep(5000);

    return 0;
}


Sauf que ça marche pas ^^
Il génère une ligne tant que ma fonction verif n'a pas renvoyé 1.
Or c'est supposé renvoyer 1 quand il n'y a pas plusieurs fois le même chiffre, que ce n'est pas un 0 ( comme j'ai mis des 0 partout, ça correspond aux "espaces" ), et que le chiffre qui est identique n'est pas dans la même case ( avec les adresses, & ).

J'ai essayé de plusieurs manières, là je trouve ça assez hideux 3 if imbriqués, mais le résultat étaient le même de toute façon.
Il génère bien plusieurs fois, mais il s'arrête alors qu'il y a plusieurs fois le même chiffre dans la ligne ou colonne, et ça j'arrive pas à comprendre pourquoi.

Si vous pouviez m'éclaircir sur ce point, merci d'avance.
Ça m'intéresse plus que d'arriver la vérification en elle même.
A voir également:

23 réponses

Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 71
22 déc. 2011 à 09:09
a toi de t'amuser a supprimer les valeurs a faire deviner...


#include <stdio.h>
#include <time.h>
#include <windows.h>

int fillGrid(int tab[9][9], int position) {
int i, x, y, validCount;
int Numbers[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // Tableau des valeurs possibles

if (position==81) // Grille remplie completement
return 1;

x = position/9;
    y = position%9;

for(i=0; i<9; i++) {
Numbers[tab[i][x]] = 0; // On supprime les chiffres de la meme colonne
Numbers[tab[y][i]] = 0; // Et de la meme ligne
Numbers[tab[(y/3)*3+(i/3)][(x/3)*3+(i%3)]] = 0; // Idem pour les carres 3x3
}

// On compte le nombre de résultats restants
validCount = 0;
for(i=1; i<=9; i++)
if (Numbers[i])
validCount++;

while(validCount) {
i = 1+(rand()%9); // Nombre aleatoire...
if (Numbers[i] != 0) { // ...parmis les chiffres valides restant
tab[y][x] = i;
if (fillGrid(tab, position+1)) // Solution validee ? on remonte l'information
return 1;
Numbers[i] = 0; // Le nombre teste n'est pas une valeur possible
validCount--;
tab[y][x] = 0;  // On reinitialise la valeur de cette cellule du tableau
}
}
return 0; // Solution non valide
}

void clearGrid (int tab[9][9]) {
for(int y=0; y<9; y++)
for (int x=0; x<9; x++)
tab[y][x] = 0;
}

void displayGrid (int tab[9][9]) {
for(int y=0; y<9; y++) { //affichage
        for(int x=0; x<9; x++)  {
            if(x==3 || x==6)
printf("|");
            if(tab[y][x]==0)
printf(" ");
            else 
printf("%d", tab[y][x]);
        }
        printf("\n");
        if(y==2 || y==5)
printf("---+---+---\n");
    }
}

int main() {
    int tab[9][9];
    srand((unsigned int)time(NULL)); // Initialisation du moteur de generation de nombres aleatoires

clearGrid(tab);
fillGrid(tab, 0);
displayGrid(tab);

getchar(); // Permet un affichage permanant, attendant la pression de [ENTER]
    return 0;
}


Renfield - Admin CodeS-SourceS - MVP Visual Basic & Spécialiste des RegExp
3
Rejoignez-nous