1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
|
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX_MOT 50
#define DIM_MAX 60
#define MAXGRILLE 1500
/*TYPES*/
const short incr1[8]= {-1,0,1, 0,-1,1, 1,-1};
const short incr2[8]= { 0,1,0,-1, 1,1,-1,-1};
enum DIRECTION {NORD=0,EST,SUD,OUEST,NORDEST,SUDEST,SUDOUEST,NORDOUEST};
typedef int indice_t;
typedef struct
{
char *listeCars;
enum DIRECTION sens;
indice_t indice;
} SousGrille_t;
typedef struct
{
SousGrille_t *y;
} SousGrilleParCar_t;
typedef struct
{
char *grille;
SousGrilleParCar_t *x;
int largeur;
int hauteur;
} GrilleMotsMeles_t;
/*PROTOTYPES*/
GrilleMotsMeles_t *initGrilleMotsMeles(FILE *);
char *initCaracteres(FILE *,int *,int *);
SousGrille_t *initElementSousGrille(char *,int,int,int,int);
void resoudreGrille(GrilleMotsMeles_t *,FILE*);
void afficherResultat(GrilleMotsMeles_t *);
void assure(void *, const char *);
/*SOLVEUR DE MOTS MELES
PRE: "tableau.txt" contient la grille de caractères
"mots.txt" contient un mot par ligne. Ce sont les mots dont les caractères doivent être
barrés dans la grille
POST "result.txt" contient la suite de lettre de la grille qui n'ont pas été barrées
(sens gauche vers droite, haut vers bas)
*/
int main()
{
GrilleMotsMeles_t *grillemelimelo;
FILE* fGrille;
FILE* fMots;
/*redirection de la sortie standard vers RESULT.TXT*/
freopen("RESULT.TXT","w",stdout);
/*initialise la grille et les structures sous-jacentes*/
fGrille=fopen("tableau.txt","r");
grillemelimelo=initGrilleMotsMeles(fGrille);
/*trouve les mots à chercher dans la grille et barre les lettres une fois trouvées*/
fMots=fopen("mots.txt","r");
resoudreGrille(grillemelimelo,fMots);
/*affiche les lettres qui n'ont pas été barrées*/
afficherResultat(grillemelimelo);
return 1;
}
/*initialisation de la structure GrilleMotMeles_t à partir d'un tableau de caractères présent
dans le fichier fichierGrille*/
GrilleMotsMeles_t *initGrilleMotsMeles(FILE *fichierGrille)
{
GrilleMotsMeles_t *p;
SousGrille_t *tmp;
indice_t tailleGrille;
int i,j;
p=(GrilleMotsMeles_t *)malloc(sizeof(GrilleMotsMeles_t));
assure(p,"initGrilleMotsMeles: erreur malloc");
/*on a besoin d'avoir tous les caractères de la grille de mots mêlés*/
p->grille=initCaracteres(fichierGrille,&(p->hauteur),(&p->largeur));
tailleGrille=p->hauteur*p->largeur;
p->x=calloc(tailleGrille,sizeof(SousGrilleParCar_t));
assure(p,"initGrilleMotsMeles: erreur calloc");
/*chargement des données*/
/*pour tous les caractères de la grille...*/
for(i=0;i<tailleGrille;i++) {
p->x[i].y=calloc(8,sizeof(SousGrille_t));
assure(p->x[i].y,"initCaracteres:erreur calloc");
/*...pour les 8 directions DIR...*/
for(j=0;j<8;j++) {
/*...on charge les sous-grilles partant du caractère et allant jusqu'au bord de la grille,
dans la direction DIR*/
tmp=initElementSousGrille(p->grille,i,p->hauteur,p->largeur,j);
memcpy((p->x[i].y)+j,tmp,sizeof(SousGrille_t));
free(tmp);
};
};
return p;
}
/*charge la grille de caractères, base de la Grille de Mots Meles*/
char *initCaracteres(FILE *f,int *hauteur,int *largeur)
{
int j,k;
char *p;
char c;
long taille;
p=calloc(MAXGRILLE+1,sizeof(char));
assure(p,"initCaracteres:erreur calloc");
j=0;
taille=0;
*largeur=0;
for (k=0;(c=getc(f))!=EOF; k++)
if (c!='\n') {
j++;
taille++;
/*on met la lettre en majuscules*/
p[k]=toupper(c);
}
else {
*largeur=j;
j=0;
k--; /*on ne met pas '\n' dans le tableau*/
};
*hauteur=taille/(*largeur);
return p;
}
/*pour un caractère de la grille et une direction donnée, renvoie un pointeur sur une chaine égale
à la sous-grille partant du caractère donné, dans la direction donnée, et se terminant en bord de grille*/
SousGrille_t *initElementSousGrille(char *grille,int i, int h, int l, int numDir)
{
char tmpCar[DIM_MAX];
int k,increment;
SousGrille_t *p;
p=malloc(sizeof(SousGrille_t));
assure(p,"initElementSousGrille: erreur malloc");
p->indice=i;
p->sens=numDir;
/*détermination de l'incrément des indices à partir de la direction*/
increment=incr1[numDir]*l+incr2[numDir];
k=0;
/* il y a au moins une lettre de la grille à charger*/
/* on les mémorise, et on charge la suivante, jusqu'à ce que celle-ci dépasse le bord de la grille*/
/*quand on se déplace vers la gauche de la grille, on n'enregistre pas l'élement pour lequel
l'indice%largeur==largeur-1*/
/*quand on se déplace vers la droite de la grille, on n'enregistre pas l'élement pour lequel
l'indice%largeur==0*/
do{
tmpCar[k++]=grille[i];
i+=increment;
if(incr2[numDir]>0 && i%l==0)
break;
else if(incr2[numDir]<0 && i%l==l-1)
break;
} while (i>=0 && i<l*h);
tmpCar[k]='\0';
p->listeCars=calloc(k+1,sizeof(char));
assure(p->listeCars,"initSousGrille:erreur calloc");
strcpy(p->listeCars,tmpCar);
return p;
}
/*pour tous les mots M de fichierMots (un mot par ligne), on va trouver la sous-grille
(couple caractère-directio), pour lequel le début de la sous-grille égale le mot M.*/
void resoudreGrille(GrilleMotsMeles_t *p,FILE* fichierMots)
{
char mot [MAX_MOT];
int i,k,dir,increment,len;
indice_t tailleGrille;
tailleGrille=p->largeur*p->hauteur;
/*tant qu'il y a une ligne contenant un mot*/
while ((fscanf(fichierMots,"%s\n",mot))!=EOF) {
len=strlen(mot);
/*on met le mot en majuscules*/
for(i=0;i<len;i++)
mot[i]=toupper(mot[i]);
/*on va rechercher dans pour tous les les caractères de la grille....*/
for(i=0;i<tailleGrille;i++)
/*...toutes les directions*/
for(dir=0;dir<8;dir++) {
/*test d'égalité entre le mot et le début de la listeCars*/
if (0==strncmp(mot,p->x[i].y[dir].listeCars,len)) {
/*la SousGrille_t [i,dir] égale le mot à trouver*/
/*on élimine de la grille les lettres du mot trouvé, en les mettant à ' '*/
increment=incr1[dir]*(p->largeur)+incr2[dir];
for(k=0;k<len;k++)
p->grille[i+k*increment]= ' ';
}
}
}
return;
}
void afficherResultat(GrilleMotsMeles_t *p)
{
char c;
/*on affiche toutes les lettres de la grilles qui n'ont pas été supprimées (= différentes de ' ')*/
while((c=*(p->grille++))!='\0')
if (c!=' ')
putchar(c);
return;
}
/*affiche un message si pointeur ptr NULL*/
void assure(void *ptr, const char *msg)
{
if (ptr==NULL)
{
fprintf(stdout,"\n");
fprintf(stdout,msg);
fprintf(stdout,"\n");
fflush(stdout);
exit(EXIT_FAILURE);
}
} |
Partager