📄 c-doku.c
字号:
// Enregistre les differents coups joues
// ainsi que la grille correspondante
fprintf(fichier,"------------------------\n");
fprintf(fichier,"Nombre de coups joues :\n");
fprintf(fichier,"%i\n",nombrecoup(aux));
fprintf(fichier,"------------------------\n\n");
while(aux != NULL)
{
fprintf(fichier,"Coup numero :\n");
fprintf(fichier,"%i\n",aux->nb);
fprintf(fichier,"Valeur :\n");
fprintf(fichier,"%i\n",aux->affiche);
fprintf(fichier,"Coordonnees :\n");
fprintf(fichier,"%i %i\n",aux->x,aux->y);
fprintf(fichier,"Methode :\n");
fprintf(fichier,"%i\n\n",aux->methode);
for(i=0;i<((taille)*(taille));i++)
{
k++;
l++;
fprintf(fichier,"%i ",aux->tabgrille[i]);
if(k == taille)
{
fprintf(fichier,"\n");
k = 0;
m++;
}
if(l == zonel)
{
if(k != 0)
{
fprintf(fichier," ");
}
l = 0;
}
if(m == zoneh)
{
fprintf(fichier,"\n");
m = 0;
}
}
fprintf(fichier,"------------------------\n");
aux = aux->suivant;
}
fclose(fichier);
}
// Charge un sudoku enregistre et insere l'historique des coups joues dans une liste
// Renvoie un pointeur de type cell, car on cree la grille ici
cell** charger_allegro(char *nom, int *taille, int *niveau, int *type, int *controle_actif, int zoneh, int zonel, BITMAP *buffer)
{
int i = 0;
int j = 0;
int k = 0;
int l = 0;
int m = 0;
int t = 0;
int n = 0;
int ty = 0;
int ctrl = 0;
int sauvetmp[81];
int coup = 0;
int nb = 0;
int affiche = 0;
int x,y = 0;
int methode = 0;
int tabgrille[81];
cell** grille;
FILE *fichier;
// Ouverture du fichier en lecture
fichier = fopen(nom,"r");
if(fichier != NULL)
{
hist = supprimecoups(hist);
histpc = supprimecoups(histpc);
// Charge la taille de la grille
fscanf(fichier,"------------------------\n");
fscanf(fichier,"Taille de la grille :\n");
fscanf(fichier,"%i",&t);
fscanf(fichier,"\n\n");
// Charge la difficulte de la grille
fscanf(fichier,"------------------------\n");
fscanf(fichier,"Niveau de difficulte de la grille :\n");
fscanf(fichier,"%i",&n);
fscanf(fichier,"\n\n");
// Charge le type de la grille
fscanf(fichier,"------------------------\n");
fscanf(fichier,"Type d'affichage de la grille :\n");
fscanf(fichier,"%i",&ty);
fscanf(fichier,"\n\n");
// Charge le type de controle de la grille
fscanf(fichier,"------------------------\n");
fscanf(fichier,"Controle actif :\n");
fscanf(fichier,"%i",&ctrl);
fscanf(fichier,"\n\n");
// Charge la grille contenue dans le fichier
for(i=0;i<((t)*(t));i++)
{
k++;
l++;
fscanf(fichier,"%i ",&sauvetmp[i]);
if(k == t)
{
fscanf(fichier,"\n");
k = 0;
m++;
}
if(l == zonel)
{
if(k != 0)
{
fscanf(fichier," ");
}
l = 0;
}
if(m == zoneh)
{
fscanf(fichier,"\n");
m = 0;
}
}
k = 0;
l = 0;
m = 0;
// Charge les differents coups joues
fscanf(fichier,"------------------------\n");
fscanf(fichier,"Nombre de coups joues :\n");
fscanf(fichier,"%i\n",&coup);
fscanf(fichier,"------------------------\n\n");
for(j=0;j<coup;j++)
{
fscanf(fichier,"Coup numero :\n");
fscanf(fichier,"%i\n",&nb);
fscanf(fichier,"Valeur :\n");
fscanf(fichier,"%i\n",&affiche);
fscanf(fichier,"Coordonnees :\n");
fscanf(fichier,"%i %i\n",&x,&y);
fscanf(fichier,"Methode :\n");
fscanf(fichier,"%i\n\n",&methode);
for(i=0;i<((t)*(t));i++)
{
k++;
l++;
fscanf(fichier,"%i ",&tabgrille[i]);
if(k == t)
{
fscanf(fichier,"\n");
k = 0;
m++;
}
if(l == zonel)
{
if(k != 0)
{
fscanf(fichier," ");
}
l = 0;
}
if(m == zoneh)
{
fscanf(fichier,"\n");
m = 0;
}
}
fscanf(fichier,"------------------------\n");
grille = creegrille(t);
chargegrille(grille,t,tabgrille);
hist = ajoutcoup(grille,t,hist,nb,affiche,x,y,methode);
}
chargegrille(grille,t,sauvetmp);
fclose(fichier);
*taille = t;
*niveau = n;
*type = ty;
*controle_actif = ctrl;
return(grille);
}
}
/*
Premiere methode de resolution logique:
- Les fonctions "elimine" permettent de supprimer
les possibilites d'une case suivant sa ligne, colonne et zone
- La fonction "logique1" utilise les fonctions "elimine" sur chaque case
et determine si un candidat unique existe, dans ce cas, elle l'affiche
*/
// Elimine les possibilites de la case en cours par rapport aux autres chiffres de la ligne
void elimineligne(cell **grille, int casex, int casey, int taille)
{
int i;
for(i=0;i<taille;i++)
{
if(grille[casex][i].affiche != 0)
{
grille[casex][casey].tab[grille[casex][i].affiche] = 0;
}
}
}
// Elimine les possibilites de la case en cours par rapport aux autres chiffres de la colonnne
void eliminecolonne(cell **grille, int casex, int casey, int taille)
{
int i;
for(i=0;i<taille;i++)
{
if(grille[i][casey].affiche != 0)
{
grille[casex][casey].tab[grille[i][casey].affiche] = 0;
}
}
}
// Elimine les possibilites de la case en cours par rapport aux autres chiffres de la zone
void eliminezone(cell **grille, int casex, int casey, int zonex, int zoney, int zoneh, int zonel, int taille)
{
int i,j;
int a,b;
// Recupere les coordonnes de la zone
testzone(grille,casex,casey,&zonex,&zoney,zoneh,zonel);
// Coordonnees reelles du debut de la zone
a=zoneh*zonex;
b=zonel*zoney;
for(i=a;i<(a+zoneh);i++)
{
for(j=b;j<(b+zonel);j++)
{
if(grille[i][j].affiche != 0)
{
grille[casex][casey].tab[grille[i][j].affiche] = 0;
}
}
}
}
// Elimine toutes les possibilites d'une case suivant sa ligne, colonne et zone
void elimine(cell **grille, int casex, int casey, int zonex, int zoney, int zoneh, int zonel, int taille)
{
elimineligne(grille,casex,casey,taille);
eliminecolonne(grille,casex,casey,taille);
eliminezone(grille,casex,casey,zonex,zoney,zoneh,zonel,taille);
}
// Utilise "elimine" sur chaque case et affiche le candidat unique s'il existe
// Renvoie le nombre de cases validees grace a cette methode
int logique1(cell **grille, int zonex, int zoney, int zoneh, int zonel, int taille)
{
int i = 0;
int j = 0;
int k = 0;
int sommeposs = 0;
int s = 0;
int tabtemp[10];
// On reinitialise le tableau des possibilites
raztab(grille,taille);
for(i=0;i<taille;i++)
{
for(j=0;j<taille;j++)
{
// Si case vide, on la traite
if(grille[i][j].affiche == 0)
{
// On elimine les possibilites de la case
elimine(grille,i,j,zonex,zoney,zoneh,zonel,taille);
// On fait la somme des possibilites restantes de la case
sommeposs = 0;
for(k=0;k<(taille+1);k++)
{
if(grille[i][j].tab[k] == 1)
{
// et on insere ces possibilites restantes
// dans un tableau temporaire
tabtemp[sommeposs] = k;
sommeposs++;
}
}
// Si le nombre de possibilites restantes de la case correspond
// a 1, on affiche la possibilite
if(sommeposs == 1)
{
grille[i][j].affiche = tabtemp[0];
// On ajoute le coup a l'historique de resolution
histpc = ajoutcoup(grille,taille,histpc,nombrecoup(histpc)+1,tabtemp[0],i,j,2);
// Un chiffre a ete ajoute donc on incremente la variable
// qui compte le nombre de cases ajoutees par cette methode
s++;
}
}
}
}
// Et on le retourne
return(s);
}
/*
Seconde methode de resolution logique:
Parcourt les lignes/colonnes, verifie si dans les candidats possibles,
il en existe qui sont presents une unique fois sur la ligne/colonne, afin de les valider
*/
// Seconde methode de resolution logique au niveau de la ligne
int logiquelignes(cell **grille, int zonex, int zoney, int zoneh, int zonel, int taille)
{
int tab[10];
int i = 0;
int j = 0;
int k = 0;
// On parcourt l'ensemble des lignes
for(i=0;i<taille;i++)
{
// Remise a zero du tableau des occurences de la ligne
for(k=1;k<taille+1;k++)
{
tab[k] = 0;
}
// On parcourt la ligne en cours
for(j=0;j<taille;j++)
{
// Si la case possede plusieurs candidats
if(grille[i][j].affiche == 0)
{
// On parcourt le tableau des candidats de la case
for(k=1;k<taille+1;k++)
{
// On cherche les candidats possibles
if(grille[i][j].tab[k] !=0)
{
// Et on l'ajoute a sa place dans le tableau des occurences
tab[k] = tab[k] + 1;
}
}
}
}
// On parcourt la ligne de nouveau
for(j=0;j<taille;j++)
{
// Si la case possede plusieurs candidats
if(grille[i][j].affiche == 0)
{
// On parcourt le tableau des candidats de la case
for(k=1;k<taille+1;k++)
{
// On va comparer les candidats avec le tableau des occurences
if(grille[i][j].tab[k] != 0)
{
// Si c'est un unique, et qu'il est present sur cette case
if(tab[k] == 1)
{
// Alors on le valide
grille[i][j].affiche = k;
// On ajoute le coup a l'historique de resolution
histpc = ajoutcoup(grille,taille,histpc,nombrecoup(histpc)+1,k,i,j,3);
return(1);
}
}
}
}
}
}
return(0);
}
// Seconde methode de resolution logique au niveau de la colonne
int logiquecolonnes(cell **grille, int zonex, int zoney, int zoneh, int zonel, int taille)
{
int tab[10];
int i = 0;
int j = 0;
int k = 0;
// On parcourt l'ensemble des lignes
for(j=0;j<taille;j++)
{
// Remise a zero du tableau des occurences de la ligne
for(k=0;k<10;k++)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -