Souhaitez-vous participer à la création d'un jeu vidéo inspiré de Stardew Valley, ou le tester lorsque la version bêta sera disponible ? Remplissez notre sondage ou inscrivez-vous à notre lettre d'information (en bas de page)
1

generer SUDOKU

le  9-10-2010 à 09:38 #
Bonjour,

Je doit crée un SUDOKU pour un TP de C, je bloque à l'étape ou je doit générer une grille aléatoire :

int generer(int a, int grille[N][N])

{
srand(a);
int m=(rand()%(81-1+1))+1, l=0, n, i, j;
printf("m = %d \n", m);
srand(time(NULL));

while (l!=m)
{
i=(rand()%(0-8+1))+0;
j=(rand()%(0-8+1))+0;

if (grille[i][j]==0)
{
n=(rand()%(1-9+1))+1;
grille[i][j]=n;
printf("n = %d ; i = %d ; j = %d \n", n, i, j);

while (verifierGrille(grille)!=1)
{
n=(rand()%(1-9+1))+1;

printf("n = %d", n);

grille[i][j]=n;
}
++l;
}
}
return m;
}


Les "printf" sont inutile.

Mon raisonnement :
- "m" est le nombre d'éléments qui seront placée dans la grille
- Tant que l'on a pas placé ce nombre m d'éléments, on continue la boucle
- On se place à une ligne i et une colonne j aléatoirement, si cette emplacement ne contient pas déjà un nombre (normalement non ...) on continu
- Dans cette emplacement vide, on force, avec la boucle, à entrez un nombre "n" jusqu'à ce que "verifierGrille" soit correct

Mon problème, sa tourne en boucle ...
Y'a t'il équiprobabilité de la fonction rand ?

Re: generer SUDOKU
le  9-10-2010 à 11:34 #
Si ça t'intéresse, j'ai eu à faire un petit projet en java pour résoudre des grilles de sudoku justement (c'est pas tout à fait la même problématique). Il n'y a pas le détail de ta fonction verifierGrille mais si ça peux t'aider à avancer.

http://marine-et-fred.homeftp.net/wordpress/?p=827


(Modifié par -Fred- le 09-10-2010 à 11:37)
Re: generer SUDOKU
le  9-10-2010 à 14:05 #
Yop!


srand(a);
/*...*/
srand(time(NULL));

Srand ne doit être initialisé qu'une fois avant rand, tu le fais bien avec le second, mais à quoi sert le premier??

Ensuite,


n=(rand()%(1-9+1))+1;

Tu fais un modulo -5 ici, si j'ai bien compris ce que tu veux faire, tu devrais plutôt mettre:


n=(rand()%(9))+1;

En gros, ici rand va te générer des nombres totalement aléatoire comme 0, 2.32, 1.2,100,2541.21,...
Tu lui demande de faire un modulo 9, il va donc y avoir les nombres: 0,1,2,3,4,5,6,7,8, et ensuite tu ajoutes 1 au total, ce qui va te donner les nombres: 1,2,3,4,5,6,7,8,9, ce que tu souhaites obtenir!

Essai de voir si en corrigeant ça, ça marche un peu mieux!
Re: generer SUDOKU
le 10-10-2010 à 15:43 #
je met deux "srand" pour ne pas tomber sur la mm grille a chaque fois

pour la fonction "rand", j'ai trouver cette forme sur le site du zero

J'ai fini par comprendre d'où vient le problème, il n'y a équiprobabilité, je tombe tjr sur les mêmes chiffres.
J'ai changer mon algo pour ne plus avoir ce pb, mais je tombe sur des grilles impossible lorsque "m" est trop grand.

J'ai chercher un peu sur internet et c trop bcp long a faire des algo performant :s

J'abandonne :p
Re: generer SUDOKU
le 10-10-2010 à 15:58 #
Il ne faut pas mettre deux fois srand!
Mettre une seule fois srand(time(NULL)); suffit, étant donné que la valeur généré par time(NULL) est unique. (ne sera jamais 2 fois la même)

Si tu veux, envoi moi en mp/poste ton code en entier, j’essaierai de voir si ça s'arrange pas, ça m'occupera!

Si j'ai bien compris, ce que tu veux faire, c'est créer une grille aléatoire de sudoku?

(Modifié par Ichigo11 le 10-10-2010 à 16:01)

Ajout du 10-10-2010 à 18:23:

Bon, j'ai essayé de compiler, et tu as pas mal d'erreur de compilation déjà! Tu compiles bien avec les options -Wall -ansi -perdantic ?
Re: generer SUDOKU
le 10-10-2010 à 19:11 #
je compile avec CodeBlock, sa passe ...
Re: generer SUDOKU
le 10-10-2010 à 19:23 #
Parce que tu n'as pas indiqué à CodeBlocks les options de compilations!
Tu le lances, tu vas dans settings -> compiler, et là tu coches les cases qui correspondent à -Wall, -ansi, -pedantic. Elles sont indiquées en fin de ligne entre des crochets!
Re: generer SUDOKU
le 10-10-2010 à 19:31 #
Oui, exact

J'avais pas compiler la dernière version ...

#include <stdio.h>

#include <stdlib.h>
#define N 9

int initialiser(int grille[N][N])
{
int i, j;

for (i=0;i<=N-1;++i)
{
for (j=0;j<=N-1;++j)
{
grille[i][j]=0;
}
}
return 0;
}

void afficher(int grille[N][N])
{
int i, j, m=0, n=0;

for (i=0;i<=N-1;++i)
{
for (j=0;j<=N-1;++j)
{
printf("%d", grille[i][j]);
if (m==2||m==5)
printf("|");
++m;
}
m=0;
if (n==2||n==5)
{
printf("\n");
printf("-----------");
}
++n;
printf("\n");
}
}

void saisir(int grille[N][N])
{
int i, j, v;

printf("Ligne : ");
scanf("%d%*c", &i);
printf("Colonne : ");
scanf("%d%*c", &j);
printf("Numero : ");
scanf("%d", &v);

grille[i-1][j-1]=v;
}

int verifierLigne(int numero, int sens, int grille[N][N])
{
int i=0, T[N]={0}, correct=1;

if (sens==0)
{
while (i<=N-1&&correct==1)
{
if (grille[numero][i]!=0&&T[grille[numero][i]-1]==0)
{
T[grille[numero][i]-1]=grille[numero][i];
++i;
}
else if (grille[numero][i]==0)
++i;
else correct=0;
}
}
else
{
while (i<=N-1&&correct==1)
{
if (grille[i][numero]!=0&&T[grille[i][numero]-1]==0)
{
T[grille[i][numero]-1]=grille[i][numero];
++i;
}
else if (grille[i][numero]==0)
++i;
else correct=0;
}
}
return correct;
}

int verifierRegion(int k, int l, int grille[N][N])
{
int i, j, m=0, p=0, TAB[N]={0}, T[N]={0}, correct=1;

for (i=(3*k);i<=(3*k+2);++i)
{
for (j=(3*l);j<=(3*l+2);++j)
{
TAB[m]=grille[i][j];
++m;
}
}
while (p<=(N-1)&&correct==1)
{
if (TAB[p]!=0&&T[TAB[p]-1]==0)
{
T[TAB[p]-1]=TAB[p];
++p;
}
else if (TAB[p]==0)
++p;
else correct=0;
}
return correct;
}

int verifierGrille(int grille[N][N])
{
int k=0, l, numero=0, correct=1;

while (k<=2&&correct==1)
{
l=0;
while (l<=2&&correct==1)
{
if (verifierRegion(k,l,grille)==1)
++l;
else correct=0;
}
++k;
}
while (numero<=N-1&&correct==1)
{
if (verifierLigne(numero,0,grille)==1)
++numero;
else correct=0;
}
numero=0;
while (numero<=N-1&&correct==1)
{
if (verifierLigne(numero,1,grille)==1)
++numero;
else correct=0;
}
return correct;
}

int generer(int a, int grille[N][N])
{
srand(a);
int m=(rand()%(81-1+1))+1, l=0, n, i, j; /* Si m est trop grand, le programme tombe sur des grilles impossibles et tourne en boucle */
printf("m = %d \n", m);
srand(time(NULL));

while (l!=m)
{
i=(rand()%(0-8+1))+0;
j=(rand()%(0-8+1))+0;
printf("i = %d ; j = %d \n", i, j);
if (grille[i][j]==0)
{
n=(rand()%(1-9+1))+1;
grille[i][j]=n;
printf("n = %d ; i = %d ; j = %d \n", n, i, j);

while (verifierGrille(grille)!=1)
{
if (n==9)
{
n=1;
}
else ++n;
afficher(grille);
printf("n = %d i = %d j = %d \n", n, i, j);
grille[i][j]=n;
}
++l;
}
}
return m;
}


int main()
{
int grille[N][N], remplissage=N*N, a=2, i=0;
printf("S U D O K U\n\n");
initialiser(grille);
generer(a,grille);
afficher(grille);

while (i<=remplissage-generer(a,grille))
{
saisir(grille);
++i; /* On suppose que le joueur saisi des chiffres uniquement dans des cases vide */
afficher(grille);
if (i=remplissage-generer(a,grille))
{
if (verifierGrille(grille)==1)
printf("Vous avez réussi !");
else printf("C'est faux ! Vous pouvez recommencer");
}
}
return 0;
}
Re: generer SUDOKU
le 10-10-2010 à 20:32 #
Voilà, j'ai un script qui fonctionne, enfin, qui te demande d'afficher les lignes quoi, après j'ai pas regarder en détail le reste du truc, j'ai juste corriger le problème de boucle:

#include <stdio.h>

#include <stdlib.h>
#include <time.h> /*a inclure l'initialisation de srand avec la fonction time*/
#define N 9

int initialiser(int grille[N][N])
{
int i, j;

for (i=0;i<=N-1;++i)
{
for (j=0;j<=N-1;++j)
{
grille[i][j]=0;
}
}
return 0;
}

void afficher(int grille[N][N])
{
int i, j, m=0, n=0;

for (i=0;i<=N-1;++i)
{
for (j=0;j<=N-1;++j)
{
printf("%d", grille[i][j]);
if (m==2||m==5)
printf("|");
++m;
}
m=0;
if (n==2||n==5)
{
printf("\n");
printf("-----------");
}
++n;
printf("\n");
}
}

void saisir(int grille[N][N])
{
int i, j, v;

printf("Ligne : ");
scanf("%d%*c", &i);
printf("Colonne : ");
scanf("%d%*c", &j);
printf("Numero : ");
scanf("%d", &v);

grille[i-1][j-1]=v;
}

int verifierLigne(int numero, int sens, int grille[N][N])
{
int i=0, T[N]={0}, correct=1;

if (sens==0)
{
while (i<=N-1&&correct==1)
{
if (grille[numero][i]!=0&&T[grille[numero][i]-1]==0)
{
T[grille[numero][i]-1]=grille[numero][i];
++i;
}
else if (grille[numero][i]==0)
++i;
else correct=0;
}
}
else
{
while (i<=N-1&&correct==1)
{
if (grille[i][numero]!=0&&T[grille[i][numero]-1]==0)
{
T[grille[i][numero]-1]=grille[i][numero];
++i;
}
else if (grille[i][numero]==0)
++i;
else correct=0;
}
}
return correct;
}

int verifierRegion(int k, int l, int grille[N][N])
{
int i, j, m=0, p=0, TAB[N]={0}, T[N]={0}, correct=1;

for (i=(3*k);i<=(3*k+2);++i)
{
for (j=(3*l);j<=(3*l+2);++j)
{
TAB[m]=grille[i][j];
++m;
}
}
while (p<=(N-1)&&correct==1)
{
if (TAB[p]!=0&&T[TAB[p]-1]==0)
{
T[TAB[p]-1]=TAB[p];
++p;
}
else if (TAB[p]==0)
++p;
else correct=0;
}
return correct;
}

int verifierGrille(int grille[N][N])
{
int k=0, l, numero=0, correct=1;

while (k<=2&&correct==1)
{
l=0;
while (l<=2&&correct==1)
{
if (verifierRegion(k,l,grille)==1)
++l;
else correct=0;
}
++k;
}
while (numero<=N-1&&correct==1)
{
if (verifierLigne(numero,0,grille)==1)
++numero;
else correct=0;
}
numero=0;
while (numero<=N-1&&correct==1)
{
if (verifierLigne(numero,1,grille)==1)
++numero;
else correct=0;
}
return correct;
}

int generer(int a, int grille[N][N])
{
int m=(rand()%(81-1+1))+1, l=0, n, i, j,ok=1 ; /*ok: variable qui sert a savoir si une grille est possible, et éviter de boucler sur une grille impossible*/
printf("m = %d \n", m);
srand(time(NULL));

while (l<m)
{
if(!ok) /*si la grille n'est plus possible, on la vide, et on recommence*/
{
initialiser(grille);
l=0;
ok=1;
}
i=(rand()%(0-8+1))+0;
j=(rand()%(0-8+1))+0;
printf("i = %d ; j = %d \n", i, j);
if (grille[i][j]==0)
{
n=(rand()%(1-9+1))+1;
grille[i][j]=n;
printf("n = %d ; i = %d ; j = %d \n", n, i, j);
n=1;
while (verifierGrille(grille)!=1&&ok) /*tant qu'on ne trouve pas un bon n, et que la grille est possible*/
{
if(n==9) /*si on a fait tout les n, et que c’est toujours pas bon, c'est que la grille est impossible*/
ok=0;
else /*sinon on essai en testant le n supérieur*/
{
afficher(grille);
printf("n = %d i = %d j = %d \n", n, i, j);
grille[i][j]=n;
n++;
}
}
++l;
}
}
return m;
}


int main()
{
int grille[N][N], remplissage=N*N, a=2, i=0;
printf("S U D O K U\n\n");
initialiser(grille);
generer(a,grille);
afficher(grille);

while (i<=remplissage-generer(a,grille))
{
saisir(grille);
++i; /* On suppose que le joueur saisi des chiffres uniquement dans des cases vide */
afficher(grille);
if (i==remplissage-generer(a,grille)) /*= pour l'affectation, == pour la comparaison*/
{
if (verifierGrille(grille)==1)
printf("Vous avez réussi !");
else printf("C'est faux ! Vous pouvez recommencer");
}
}
return 0;
}


(Modifié par Ichigo11 le 10-10-2010 à 20:36)
Re: generer SUDOKU
le 10-10-2010 à 21:09 #
Il tourne longtemps pour générer une grille ^^

J'ai un autre problème :

Partie D, que dois je faire ?

Sujet

Deux dernières étapes de la partie B, je comprend pas

#include <stdio.h>

#include <stdlib.h>

void swap(char *ptrc1, char *ptrc2)
{
*ptrc1=1;
*ptrc2=2;
}

int main()
{
int i=50, *ptri = &i;
char c1, c2, *ptrc1 = &c1, *ptrc2 = &c2;
double d, *ptrd = &d;

printf("Valeur pointee : ptri = %d \n", *ptri);

printf("ptri = %d ; ptrc1 = %d \n", ptri, ptrc1);
printf("ptri = %x ; ptrc1 = %x \n", ptri, ptrc1);
ptri++;
printf("ptri = %d ; ptrc1 = %d \n", ptri, ptrc1);

printf("Valeur pointee : i = %d ; c1 = %d ; d = %d \n", *ptri, *ptrc1, *ptrd);
printf("Adresse contenue : ptri = %d ; ptrc1 = %d ; ptrd = %d \n", ptri, ptrc1, ptrd);
printf("Adresse pointeurs : ptri = %d ; ptrc1 = %d ; ptrd = %d \n", &ptri, &ptrc1, &ptrd);

ptrd+=2;
printf("ptrd = %d \n", ptrd);

printf("c1 = %d ; c2 = %d \n", *ptrc1, *ptrc2);
swap(&c1,&c2);
printf("c1 = %d ; c2 = %d \n", *ptrc1, *ptrc2);


return 0;
}

Re: generer SUDOKU
le 10-10-2010 à 21:21 #
Ouaip, mais au moins il tourne!

Après le reste, j'ai pas du tout vu en cours, donc je vais pas pouvoir trop t'aider!
Re: generer SUDOKU
le 10-10-2010 à 21:22 #
ok merci bien :)
Re: generer SUDOKU
le  7-10-2017 à 22:40 #
Bonsoir.
Je me suis fait un outil sur tableur Excel pour résoudre les sudokus.
Avec ce même outil, je crée des grilles 9*9.
De ces grilles je tire des sudokus.
Ce sont des sudokus où la solution découle des chiffres initiaux sans qu'il y ait besoin de faire des essais.
On peut rendre le sudoku plus difficile en lui enlevant des chiffres. il faut alors faire des essais pour le résoudre.
On peut aussi rendre le sudoku plus facile en lui rajoutant des chiffres de la grille.
C'est du travail artisanal. Il me faut une demi-heure pour faire une grille et une bonne heure pour en tirer un sudoku.
Mes sudokus comportent 23 à 26 caractères.




Ces discussions pourraient vous intéresser également:


Javascript Sudoku
Générer aléatoirement un tableau en C
Générer des serie de 10 chiffres aléatoire
generer un message d'erreur (visual basic)
Récupérer le code source non générer d'une page(PHP)