⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c-doku.c

📁 1、较复杂的数独游戏
💻 C
📖 第 1 页 / 共 5 页
字号:
    // 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 + -