Advertisement
Guest User

Untitled

a guest
Nov 21st, 2017
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.49 KB | None | 0 0
  1. // File : grille.c
  2. // Author : D. DUVIVIER
  3. // Date : 19/11/14
  4. // Description : Jeu du sudoku de taille variable pour projet DEVA1 - L2 info
  5. // Copyright (c) 2014 UVHC-LISIC. All rights reserved.
  6. //
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include "grille.h"
  10.  
  11. // Alloue et initialise la grille passée en paramètre
  12. //
  13. // Une ligne supplémentaire est allouée après la dernière ligne : elle
  14. // contient la suite des caractères à utiliser pour visualiser la grille
  15. // de jeu, par exemple :
  16. // - 1 2 3 4 5 6 7 8 9
  17. // - 1 2 3 4 5 6 7 8 9 A B C D E F G
  18. // Le symbole '0' indique une case vide
  19. //
  20. void initGrille(TGrille *grille, const unsigned int GTaille)
  21. {
  22. unsigned int l, c; // lignes, colonnes
  23.  
  24. *grille = calloc(GTaille + 1, sizeof(char *)); // Allocation 1ère dimension du tableau
  25. if (*grille == NULL)
  26. {
  27. fprintf(stderr,"#\n# ERREUR: initGrille() - Impossible d'allouer le tableau contenant la grille !\n#\n");
  28. abort();
  29. }
  30.  
  31. for (l = 0; l <= GTaille; l++)
  32. {
  33. (*grille)[l] = calloc(GTaille, sizeof(char)); // Allocation 2ème dimension du tableau
  34. if ((*grille)[l] == NULL)
  35. {
  36. fprintf(stderr,"#\n# ERREUR: initGrille() - Impossible d'allouer le tableau contenant la grille !\n#\n");
  37. abort();
  38. }
  39. for (c = 0; c < GTaille; c++)
  40. (*grille)[l][c] = '0';
  41. }
  42. }
  43.  
  44. // Détruit/désalloue le contenu de la grille passée en paramètre
  45. void supprimeGrille(TGrille *grille, const unsigned int GTaille)
  46. {
  47. unsigned int l; // lignes
  48.  
  49. for (l = 0; l <= GTaille; l++)
  50. free((*grille)[l]); // Libère/désalloue 2ème dimension du tableau
  51.  
  52. free(*grille); // Libère/désalloue 1ère dimension du tableau
  53. *grille = NULL; // Pour y interdire de futurs accès
  54. }
  55.  
  56. // Affiche la grille de jeu
  57. void afficheGrille(const TGrille grille,
  58. const unsigned int GTaille, const unsigned int RTaille)
  59. {
  60. unsigned int r, l, c;
  61. for (r=0; r<2; r++)
  62. {
  63. printf("++");
  64. for (c = 0; c < GTaille; c++)
  65. {
  66. if ((c % RTaille) != RTaille - 1)
  67. printf("---+");
  68. else
  69. printf("---++");
  70. }
  71. puts("");
  72. }
  73. for (l = 0; l < GTaille; l++)
  74. {
  75. printf("||");
  76. for (c = 0; c < GTaille; c++)
  77. {
  78. if ((c % RTaille) != RTaille - 1)
  79. {
  80. if (grille[l][c] != '0')
  81. printf(" %c |", grille[l][c]);
  82. else
  83. printf(" |");
  84. }
  85. else
  86. {
  87. if (grille[l][c] != '0')
  88. printf(" %c ||", grille[l][c]);
  89. else
  90. printf(" ||");
  91. }
  92. }
  93. puts("");
  94. for (r=0; r < 1 + ((l % RTaille) == RTaille - 1); r++)
  95. {
  96. printf("++");
  97. for (c = 0; c < GTaille; c++)
  98. {
  99. if ((c % RTaille) != RTaille - 1)
  100. printf("---+");
  101. else
  102. printf("---++");
  103. }
  104. puts("");
  105. }
  106. }
  107. puts("");
  108. }
  109.  
  110. // Affiche la liste des caractères utilisables dans la grille de jeu
  111. void affichelistecaracteres(const TGrille grille, const unsigned int GTaille)
  112. {
  113. unsigned int c;
  114.  
  115. printf("+");
  116. for (c = 0; c < GTaille; c++)
  117. printf("---+");
  118. puts("");
  119. printf("|");
  120. for (c = 0; c < GTaille; c++)
  121. {
  122. if (grille[GTaille][c] != '0')
  123. printf(" %c |", grille[GTaille][c]);
  124. else
  125. printf(" |");
  126. }
  127. puts("");
  128. printf("+");
  129. for (c = 0; c < GTaille; c++)
  130. printf("---+");
  131. puts("");
  132. }
  133.  
  134. // Convertit un N° de plan (entre 1 et GTaille)
  135. // en un caractère utilisable dans la grille de jeu
  136. //
  137. // Retourne '\0' si le numéro de plan est incorrect
  138. //
  139. char plan2char(const TGrille grille, const unsigned int GTaille,
  140. const unsigned int plan)
  141. {
  142. if ((plan < 1) || (plan > GTaille))
  143. return '\0';
  144.  
  145. return grille[GTaille][plan-1];
  146. }
  147.  
  148. // Convertit un caractère (symbole situé dans la grille de jeu)
  149. // en un N° de plan (entre 1 et GTaille)
  150. // en un caractère utilisable dans la grille de jeu
  151. //
  152. // La suite des symboles n'est pas nécessairement triée, ce qui
  153. // fait que cette fonction utilise une recherche séquentielle dans
  154. // un tableau d'éléments non triés (non efficace).
  155. //
  156. // Retourne '0' si le caractère incorrect
  157. //
  158. unsigned int char2plan(const TGrille grille, const unsigned int GTaille,
  159. const char code)
  160. {
  161. unsigned int plan;
  162.  
  163. for (plan=1; plan<=GTaille; plan++)
  164. if (grille[GTaille][plan-1] == code)
  165. return plan;
  166.  
  167. return 0; // Non trouvé !
  168. }
  169.  
  170.  
  171. // Retourne vrai (1) si le symbole N°"plan" peut être placé
  172. // dans la ligne "ligne" sur la grille de jeu
  173. // faux (0) sinon
  174. // (plan doit être compris entre 1 et GTaille,
  175. // ligne doit être comprise entre 0 et GTaille-1)
  176. bool symboleautoriseenligne(const TGrille grille, const unsigned int GTaille,
  177. const unsigned int ligne,
  178. const unsigned int plan)
  179. {
  180. unsigned int c;
  181.  
  182. }
  183.  
  184. // Retourne vrai (1) si le symbole N°"plan" peut être placé
  185. // dans la colonne "colonne" sur la grille de jeu
  186. // faux (0) sinon
  187. // (plan doit être compris entre 1 et GTaille,
  188. // colonne doit être comprise entre 0 et GTaille-1)
  189. bool symboleautoriseencolonne(const TGrille grille, const unsigned int GTaille,
  190. const unsigned int colonne,
  191. const unsigned int plan)
  192. {
  193. unsigned int l;
  194.  
  195. }
  196.  
  197. // Retourne vrai (1) si le symbole N°"plan" peut être placé
  198. // dans la région à laquelle appartient le couple "(ligne, colonne)"
  199. // faux (0) sinon
  200. // (plan doit être compris entre 1 et GTaille)
  201. //
  202. // ligne et colonne doivent être comprises entre 0 et GTaille-1
  203. //
  204. bool symboleautoriseenregion(const TGrille grille,
  205. const unsigned int GTaille,
  206. const unsigned int RTaille,
  207. const unsigned int ligne,
  208. const unsigned int colonne,
  209. const unsigned int plan)
  210. {
  211. unsigned int rligne, rcolonne; // Position en haut à gauche de la région
  212. unsigned int ltmp, ctmp; // Calcul temporaire du multiple de RTaille
  213. unsigned int m, n; // ligne "modulo RTaille" et colonne "modulo RTaille"
  214.  
  215. ltmp = ligne / RTaille;
  216. ctmp = colonne / RTaille;
  217. rligne = ltmp * RTaille;
  218. rcolonne = ctmp * RTaille;
  219. for (m=0; m<RTaille; m++)
  220. for (n=0; n<RTaille; n++)
  221. if (grille[rligne+m][rcolonne+n] == plan2char(grille, GTaille, plan))
  222. return false; // Inutile de continuer, le résultat est "faux"
  223.  
  224. return true;
  225. }
  226.  
  227. // Vérifie l'unicité des chiffres déjà placés dans la grilles par région.
  228. // Retourne vrai (1) s'il n'y a aucun doublon dans la
  229. // région 3 x 3 dont la case située en haut à gauche est située à la position
  230. // (rligne, rcolonne) dans la grille du sudoku.
  231. //
  232. // rligne et rcolonne doivent être comprises entre 0 et GTaille-1
  233. //
  234. // ATTENTION : Il manque des tests de "validité"
  235. // (notamment les codes de retour de char2plan en cas de problème)
  236. //
  237. bool verifieUniciteRegion(const TGrille grille,
  238. const unsigned int GTaille,
  239. const unsigned int RTaille,
  240. const unsigned int rligne,
  241. const unsigned int rcolonne)
  242. {
  243. unsigned int p;
  244. unsigned int m, n; // ligne "modulo RTaille" et colonne "modulo RTaille"
  245.  
  246. Tusint Toccurrences[GTaille+1]; // Tableau d'occurrences ATTENTION : GTaille+1
  247.  
  248. // Ci-dessous, la boucle doit commencer à 0 et terminer à GTaille !!!
  249. for (p = 0; p <= GTaille; p++)
  250. Toccurrences[p] = 0;
  251.  
  252. for (m=0; m<RTaille; m++)
  253. for (n=0; n<RTaille; n++)
  254. Toccurrences[char2plan(grille, GTaille, grille[rligne+m][rcolonne+n])] ++;
  255.  
  256. // Ci-dessous, la boucle doit commencer à 1 et terminer à GTaille !!!
  257. for (p = 1; p <= GTaille; p++)
  258. if (Toccurrences[p] > 1) {
  259. printf("le caractere %d dans la region %d est en doublon\n",p,grille[rligne+1][rcolonne+1]);
  260. return false;
  261. }
  262.  
  263. return true;
  264. }
  265.  
  266. // Fonction qui verifie l'unicité d'une Colonne
  267. bool verifieUniciteColonne(const TGrille grille,
  268. const unsigned int GTaille,
  269. const unsigned int rligne,
  270. const unsigned int rcolonne)
  271. {
  272. unsigned int p = 0;
  273. unsigned int m; // ligne "modulo RTaille" et colonne "modulo RTaille"
  274.  
  275. Tusint Toccurrences[GTaille+1]; // Tableau d'occurrences ATTENTION : GTaille+1
  276.  
  277. // Ci-dessous, la boucle doit commencer à 0 et terminer à GTaille !!!
  278. for (p = 0; p <= GTaille; p++)
  279. Toccurrences[p] = 0;
  280.  
  281. for (m=0; m<GTaille; m++)
  282. Toccurrences[char2plan(grille, GTaille, grille[rligne+m][rcolonne])] ++;
  283.  
  284. // Ci-dessous, la boucle doit commencer à 1 et terminer à GTaille !!!
  285. for (p = 1; p <= GTaille; p++)
  286. if (Toccurrences[p] > 1)
  287. {
  288. printf("le caractere %d sur la colonne %d est en doublon\n",p,rcolonne+1);
  289. return false;
  290. }
  291.  
  292. return true;
  293. }
  294. // Fonction qui verifie l'unicité d'une Ligne
  295. bool verifieUniciteLigne(const TGrille grille,
  296. const unsigned int GTaille,
  297. const unsigned int rligne,
  298. const unsigned int rcolonne)
  299. {
  300. unsigned int p;
  301. unsigned int n; // ligne "modulo RTaille" et colonne "modulo RTaille"
  302.  
  303. Tusint Toccurrences[GTaille+1]; // Tableau d'occurrences ATTENTION : GTaille+1
  304.  
  305. // Ci-dessous, la boucle doit commencer à 0 et terminer à GTaille !!!
  306. for (p = 0; p <= GTaille; p++)
  307. Toccurrences[p] = 0;
  308.  
  309. for (n=0; n<GTaille; n++)
  310. Toccurrences[char2plan(grille, GTaille, grille[rligne][rcolonne+n])] ++;
  311.  
  312. // Ci-dessous, la boucle doit commencer à 1 et terminer à GTaille !!!
  313. for (p = 1; p <= GTaille; p++)
  314. if (Toccurrences[p] > 1)
  315. {
  316. return false;
  317. }
  318.  
  319. return true;
  320. }
  321.  
  322.  
  323. // Vérifie l'unicité des chiffres déjà placés dans la grille
  324. // - en ligne
  325. // - en colonnes
  326. // - par région
  327. //
  328. // Retourne faux/false en cas d'erreur (doublon(s) sur la grille)
  329. // et un affichage indique où est le problème.
  330. bool verifieUnicite(const TGrille grille,
  331. const unsigned int GTaille,
  332. const unsigned int RTaille)
  333. {
  334. unsigned int l, c, p;
  335. bool Tunique[GTaille+1]; // ATTENTION : GTaille+1 !!!
  336.  
  337. Tunique[0] = false;
  338.  
  339. // Vérification en ligne
  340. for(l=0; l<GTaille; l++)
  341. {
  342. Tunique[l] = verifieUniciteLigne(grille,GTaille,l,0);
  343. if(Tunique[l] == false)
  344. {
  345. return false;
  346. }
  347. }
  348.  
  349. // Vérification en colonne
  350. for(c=0; c<GTaille; c++)
  351. {
  352. Tunique[c] = verifieUniciteColonne(grille,GTaille,0,c);
  353. if(Tunique[c] == false)
  354. {
  355. return false;
  356. }
  357. }
  358. // Vérification par région
  359. for(l=0; l<GTaille; l=l+RTaille)
  360. {
  361. for(c=0; c<GTaille; c=RTaille)
  362. {
  363. p++;
  364. Tunique[p] = verifieUniciteRegion(grille,GTaille,RTaille,l,c);
  365. if(Tunique[p] == false)
  366. {
  367. printf("Il y a un doublon dans la region %d\n",p);
  368. return false;
  369. }
  370. }
  371. }
  372. return true;
  373. }
  374.  
  375.  
  376.  
  377. // Vérifie si la grille est complête ou non.
  378. // Cette fonction est nécessaire car le plan 0 de la grille3D peut être rempli
  379. // de 0 dans deux cas : soit il n'y a plus aucune possibilité de jeu, mais la
  380. // grille (2D) n'est pas pleine en raison de l'impossibilité de complêter la
  381. // grille (grille infaisable) ou la grille (2D) est pleine et en ce cas la
  382. // résolution est terminée (grille faisable, et trouvée !).
  383. // Cette fonction détecte le cas où la grille est terminée & faisable.
  384. //
  385. bool grilleComplete(const TGrille grille,
  386. const unsigned int GTaille)
  387. {
  388. unsigned int l, c, cumul = 0;
  389.  
  390. for (l = 0; l < GTaille; l++)
  391. for (c = 0; c < GTaille; c++)
  392. if (grille[l][c] != '0')
  393. cumul++;
  394. return cumul == GTaille * GTaille;
  395. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement