Advertisement
Guest User

Untitled

a guest
Nov 15th, 2018
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 33.35 KB | None | 0 0
  1. /* Programme répondant au sujet de devoir: Mots mélés
  2. Ne pas compiler avec le -ansi
  3. */
  4.  
  5.  
  6. /* ce qu'il reste à faire :
  7. fichier:
  8. charger une grille
  9.  
  10. graphique
  11. ecire rejouer et abandon dans les cases BOF
  12. detecter les clics sur ces cases FAIT
  13. placer les mots à droite du plateau FAIT
  14. surligner les mots quand ils sont trouvés BUG
  15. quand tous les mots sont trouvés, afficher msg de fin FAIT
  16. avec possibilité de rejouer PEUT ETRE EASY
  17.  
  18. main: arranger un peu tout ça snif
  19. */
  20.  
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <time.h>
  26. #include <MLV/MLV_all.h>
  27.  
  28. /**************************************
  29. ******* STRUCTURES
  30. ***************************************/
  31.  
  32.  
  33.  
  34.  
  35. /* Cette structure permet de retrouver la taille du plateau
  36. ainsi que la grille toute entière
  37. */
  38. typedef struct {
  39. int taille;
  40. char plateau[20][20];
  41. } InfoGrille;
  42.  
  43. /* Cette structure permet de retrouver tout ce qui est lié
  44. à un mot de l'utilisateur */
  45.  
  46. typedef struct {
  47. char mot[15]; // Le mot en lui même
  48. int taille; // La taille du mot
  49.  
  50. int xDebut; // Les coordonnées (x,y) de sa première lettre
  51. int yDebut;
  52.  
  53. int xFin; // Les coordonnées (x,y) de sa dernière lettre
  54. int yFin;
  55.  
  56. int dx; // L'orientation du mot
  57. int dy;
  58.  
  59. int dejaClique;
  60. } Mot ;
  61.  
  62. /* Cette structure est l'endroit où on retrouve la totalité des mots */
  63.  
  64. typedef struct {
  65. // On impose une taille maximale au mot
  66. // (souvent la taille de la grille)
  67. int tailleMax;
  68.  
  69. // Le nombre de mots à saisir
  70. int nbMots;
  71.  
  72. int nbMotsTrouves;
  73.  
  74.  
  75. // Ainsi qu'une liste où on stocke les mots choisis
  76. Mot listeMots[15];
  77. } InfoMots;
  78.  
  79.  
  80.  
  81. typedef struct {
  82. int longueur;
  83. int largeur;
  84. int tailleGrille;
  85. int tailleCase;
  86.  
  87. } Graph ;
  88.  
  89.  
  90.  
  91. /* Cette structure rassemble toutes les informations précédemment collectées */
  92. typedef struct {
  93. InfoGrille grille;
  94. InfoMots mots;
  95. Graph graph;
  96.  
  97. } Tableaux; // Les variables du type Tableaux seront donc les éléments essentiels
  98.  
  99.  
  100.  
  101. /**************************************
  102. ******* PROTOTYPES
  103. ***************************************/
  104. int main( int argc, char const *argv[] ) ;
  105.  
  106.  
  107. // Initialisation du plateau
  108. void propJeu( Tableaux * jeu );
  109. int demandeTaille();
  110. int estDansIntervalle( int point, int min, int max );
  111. void initPlateau( Tableaux * jeu );
  112. void affichePlateau( Tableaux jeu );
  113.  
  114.  
  115.  
  116. // Placement des mots dans le plateau
  117. void gestionPlacement( Tableaux *jeu );
  118. void afficheReglesDirection();
  119.  
  120. // Choix des mots dans la grille
  121. void demandeLesMots( Tableaux * jeu );
  122. void choixDesMots( Tableaux * jeu );
  123. void saisirMot( Tableaux * jeu, int numMot );
  124. int verifieMotCorrect( int tailleMot, char mot[tailleMot] );
  125. void afficheLesMots( Tableaux jeu );
  126.  
  127. // diverses vérifications pour avoir le droit de placer un mot
  128. void demandeCoordonnes( Tableaux * jeu, int numMot, int *x, int *y );
  129. void demandeDirection ( Tableaux *jeu, int numMot, int *dx, int *dy );
  130. int verifieDirCorrecte( int direction, int *dx, int *dy );
  131. int verifieInterference( Tableaux jeu, int numMot );
  132. int calculeDerniereCoord( Tableaux * jeu, int numMot );
  133. void placerMot( Tableaux * jeu, int numMot );
  134.  
  135. // Une fois qu'on a placé tous les mots, on complete aléatoirement la grille
  136. void completeGrille( Tableaux * jeu );
  137.  
  138. // C'est le moment où le joueur joue enfin
  139. void reglesPhaseDeJeu();
  140. int phaseDeJeu( Tableaux jeu );
  141. int coupleEgal( int numMot, int a, int b, Tableaux jeu );
  142.  
  143.  
  144. // Gestion des fichiers
  145.  
  146. int menuFichier( int argc, const char ** argv );
  147.  
  148. void metMotsDansFichier( FILE * fichier, Tableaux jeu );
  149. void metGrilleDansFichier( FILE * fichier, Tableaux jeu );
  150. void metCoordDansFichier( FILE * fichier, Tableaux jeu );
  151.  
  152.  
  153.  
  154. void affichePlateauGraph( Tableaux jeu );
  155. void placerLettresGraph( Tableaux jeu );
  156. void afficheLesMotsGraph( Tableaux jeu );
  157.  
  158.  
  159. void motEnCouleur ( Tableaux jeu );
  160. void boutonsGraph( Tableaux jeu );
  161. int afficheConsigne( Tableaux jeu, int motChoisi, int numMot );
  162. int clicDansCase( Tableaux jeu, int x, int y, int numMot );
  163. int clicSurBoutons( Tableaux jeu, int x );
  164. int clicDansFenetre( Tableaux jeu );
  165. void dessineTout( Tableaux jeu );
  166. void modeGraphique( Tableaux * jeu );
  167.  
  168.  
  169.  
  170. /**************************************
  171. ******* FONCTIONS
  172. ** - Dans toutes les fonctions, le paramètre "jeu"
  173. ** contient toutes les informations nécéssaires.
  174. ** - Les noms de variables sont sans équivoque.
  175. ** - Le parametre numMot indique le numéro du mot dont on parle.
  176. ** - La plupart des fonctions de vérification renvoient 0 pour indiquer
  177. ** que le test doit être refait
  178. ***************************************/
  179.  
  180.  
  181.  
  182. /**************************************
  183. ******* Initialisation du jeu
  184. ***************************************/
  185.  
  186.  
  187. /* Fonction demandant la taille de diverses choses, renvoie une taille sécurisée*
  188. *sécurisée: dans l'intervalle souhaité par le codeur
  189. */
  190.  
  191. int demandeTaille( int max ){
  192. int n;
  193. do {
  194. scanf( "%d", &n ) ;
  195. } while ( estDansIntervalle( n, 1, max ) == 0 );
  196. return n;
  197. }
  198.  
  199.  
  200. /* Fonction initialisant les principales caractéristiques des tableaux
  201. la taille de la grille,
  202. le nombre maximum de mots à placer,
  203. la taille max que peuvent avoir les mots.
  204. */
  205. void propJeu( Tableaux * jeu ){
  206. // on fait attention à bien sécuriser les saisies
  207. printf( "De quelle taille voulez vous le plateau ( max 15 ) ?\n" );
  208.  
  209. jeu -> grille.taille = demandeTaille( 15 );
  210.  
  211. // On ne peut entrer qu'un nombre de mots inférieur à la taille de la grille
  212. printf( "Combien de mots voulez vous entrer (max %d) ?\n", jeu -> grille.taille );
  213. jeu -> mots.nbMots = demandeTaille( jeu -> grille.taille );
  214.  
  215. // La taille max est définie par la longueur d'une grille
  216. // Pour être sûr de ne pas se retrouver avec un mot implaçable dans la grille
  217. jeu -> mots.tailleMax = jeu -> grille.taille;
  218.  
  219. jeu -> graph.longueur = 800;
  220. jeu -> graph.largeur = 640;
  221. jeu -> graph.tailleGrille = 500;
  222. jeu -> graph.tailleCase = ( jeu -> graph.tailleGrille ) / ( jeu -> grille.taille ) ;
  223.  
  224. }
  225.  
  226.  
  227.  
  228.  
  229. /* Fonction remplissant la grille d'espaces jusqu'à la taille demandée */
  230. void initPlateau( Tableaux * jeu ){
  231. for ( size_t i = 0; i < jeu -> grille.taille; i++ ) {
  232. for ( size_t j = 0; j < jeu -> grille.taille; j++ ) {
  233. jeu -> grille.plateau[i][j] = ' ';
  234. }
  235. }
  236. }
  237.  
  238. /* Fonction affichant la grille sur le terminal */
  239. void affichePlateau( Tableaux jeu ){
  240. int i;
  241. int j;
  242. // Affiche 0,1,2...n en haut de la grille pour se repérer avec les colonnes
  243. for ( i = 0; i < jeu.grille.taille; i++ ) {
  244. printf( "|%d", i + 1 );
  245. }
  246. printf( "\n\n" );
  247.  
  248. // Affiche case par case la grille avec le caractere à l'intérieur
  249. for ( i = 0; i < jeu.grille.taille; i++ ) {
  250. for ( j = 0; j < jeu.grille.taille; j++ ) {
  251. printf( "|%c", jeu.grille.plateau[i][j] );
  252. }
  253.  
  254. // Affiche les mots à droite de la grille (nbMots toujours <= à grille.taille)
  255. if ( i < jeu.mots.nbMots ){
  256. printf( "| %d \t\t%d:%s", i + 1, i, jeu.mots.listeMots[i].mot );
  257. }
  258. printf( "| %d\n", i + 1 );
  259.  
  260. }
  261. printf( "%d %d \n", jeu.mots.listeMots[0].xFin, jeu.mots.listeMots[0].yFin );
  262. }
  263.  
  264.  
  265.  
  266.  
  267.  
  268. /* Fonction renvoyant 0 si un point appartient à un intervalle fermé, 1 sinon
  269. :param point: peut correspondre à un nombre ou une lettre dont on veut
  270. vérifier l'appartenance à un intervalle ([min, max] ou ['A', 'Z'] par exemple)
  271. :param min, max: peuvent être des lettres ou entiers puisque
  272. le type char est inclu dans le type int
  273. */
  274.  
  275. int estDansIntervalle( int point, int min, int max ){
  276. return ( ( point >= min ) && ( point <= max) );
  277. }
  278.  
  279.  
  280.  
  281. /**************************************
  282. ******* GESTIONS DES MOTS
  283. ***************************************/
  284.  
  285.  
  286.  
  287. /* Fonction principale pour la saisie des mots,
  288. faisant la liaison avec tout le reste
  289. On y demande l'ensemble des mots, on les stocke dans la structure listeMots[]
  290. et on affiche ceux-ci
  291. */
  292. void choixDesMots( Tableaux * jeu ){
  293. printf( "Veuillez saisir %d mots\n", jeu -> mots.nbMots );
  294. demandeLesMots( &* jeu );
  295. afficheLesMots( * jeu );
  296. }
  297.  
  298. /* Fonction secondaire pour la saisie des mots,
  299. On demande nbMots* à l'utilisateur
  300. *nbMots: nombre de mots précédemment demandé à l'utilsateur
  301. */
  302.  
  303. void demandeLesMots( Tableaux * jeu ){
  304. for ( size_t i = 0; i < jeu -> mots.nbMots; i++ ) {
  305. saisirMot( jeu, i );
  306. }
  307. }
  308.  
  309.  
  310. /* Fonction secondaire pour la saisie des mots,
  311. On demande à l'utilisateur d'entrer un mot,
  312. on VERIFIE si le mot est bien un mot en majuscule de taille correcte
  313. puis on stocke le mot ainsi que sa taille dans la liste des mots.
  314. */
  315.  
  316. void saisirMot( Tableaux * jeu, int numMot ){
  317. char mot [50]; // On essaie de prévoir si l'utilsateur fait des bêtises
  318. int tailleMot; // On aura besoin de comparer la taille du mot
  319. // avec la taille max autorisée
  320. do {
  321. // Sécurisation du procéssus,
  322. // tant que l'utilisateur fait des bêtises, on recommence
  323. printf( "Saisir le %de mot en majuscule de taille max %d\n",
  324. numMot + 1, jeu -> mots.tailleMax );
  325.  
  326. scanf( "%s", mot );
  327. tailleMot = strlen( mot );
  328. // On a donc besoin de vérifier la taille et si le mot est en majuscule
  329. } while ( ( tailleMot >= jeu -> mots.tailleMax ) ||
  330. ( verifieMotCorrect( tailleMot, mot ) == 0 ) );
  331.  
  332. // Une fois qu'on est sûr que l'utilsateur est conscient de ce qu'il fait
  333. // On peut ajouter le mot à la liste des mots
  334. strcpy( jeu -> mots.listeMots[numMot].mot, mot );
  335. jeu -> mots.listeMots[numMot].taille = strlen( mot );
  336.  
  337.  
  338. }
  339.  
  340.  
  341. /* Fonction découlant de la précédente,
  342. on vérifie si le mot est en majuscule, on renvoie 1 si c'est le cas, 0 sinon
  343. les paramètres ne sont pas Tableaux * jeu car on veut être sûr de ne pas
  344. ajouter des bêtises de l'utilisateur
  345. :param tailleMot: taille du mot saisi (la taille est vérifiée avant les majs)
  346. :param mot: le mot saisi par l'utilsateur
  347. */
  348. int verifieMotCorrect( int tailleMot, char mot[tailleMot] ){
  349.  
  350. for ( size_t i = 0; i < tailleMot; i++ ) {
  351. // Parcours de l'ensemble des lettre du mot
  352. if ( estDansIntervalle( mot[i], 'A', 'Z' ) == 0 ){
  353. // Si une seule n'est pas en majuscule (ou n'est pas une lettre)
  354. // on renvoie 0 pour signifier qu'on recommence la saisie
  355. printf( "Le mot saisi n'est pas en majuscule\n" );
  356. return 0;
  357. }
  358. }
  359. // Si tout s'est bien passé jusqu'ici, on a un mot en majuscule, on renvoie 1
  360. return 1;
  361. }
  362.  
  363. /* Fonction affichant les mots après les avoir saisis, rien de particulier
  364. */
  365. void afficheLesMots( Tableaux jeu ){
  366. printf( "Les mots séléctionnés sont: \n" );
  367. for ( size_t i = 0; i < jeu.mots.nbMots; i++ ) {
  368. printf( "%s\n", jeu.mots.listeMots[i].mot );
  369. }
  370.  
  371. }
  372.  
  373.  
  374.  
  375. /* Fonction affichant les règles pour la direction d'un mot
  376. DIFFERENCE AVEC L'ENNONCÉ:
  377. on trouvait plus pratique de s'orienter grâce au pavé numérique
  378. plutôt qu'avec le plateau donné
  379. */
  380.  
  381. void afficheReglesDirection( ){
  382. printf( "Le pavé numérique correspond aux directions, donc:\n\
  383. 8 pour Nord\n\
  384. 9 pour Nord-Est\n\
  385. 6 pour Est\n\
  386. 3 pour Sud-Est\n\
  387. 2 pour Sud\n\
  388. 1 pour Sud-Ouest\n\
  389. 4 pour Ouest\n\
  390. 7 pour Nord-Ouest\n" );
  391.  
  392. }
  393.  
  394.  
  395.  
  396. /* Fonction s'executant après avoir obtenu tous les mots
  397. On demande, pour chaque mot, la coordonnées de la première lettre
  398. On vérifiera plus tard que deux mots ne peuvent pas se chevaucher
  399. sauf cas particulier (fonction interference).
  400. */
  401.  
  402. void demandeCoordonnes( Tableaux * jeu, int numMot, int *x, int *y){
  403.  
  404. // On attend de l'utilisateur qu'il essaie de rentrer des coordonnées
  405. // valables jusqu'à reussir, il peut le faire !!
  406.  
  407. do {
  408. printf( "Veuillez saisir les coordonnées (x,y) pour la première lettre de %s\n",
  409. jeu -> mots.listeMots[numMot].mot );
  410.  
  411. scanf( "%d%d", &*x, &*y ); // &*x est la même chose que x
  412.  
  413. } while( ( estDansIntervalle( *x, 0, jeu -> grille.taille ) == 0 )
  414. || ( estDansIntervalle( *y, 0, jeu -> grille.taille ) == 0 ) );
  415.  
  416. // Une fois qu'il a réussi, on stocke le couple (x,y) correspondant à
  417. // La première lettre.
  418. jeu -> mots.listeMots[numMot].xDebut = *x;
  419. jeu -> mots.listeMots[numMot].yDebut = *y;
  420.  
  421. }
  422.  
  423.  
  424.  
  425. /* Fonction palpitante transmettant par adresse l'orientation du mot choisi
  426. :param direction: voir afficheReglesDirection()
  427. :param *dx et *dy: sens en x et sens en y
  428. On renvoie 1 si l'utilisateur a entré une direction correcte,
  429. 0 s'il n'est pas doué. (dans ce cas on recommence)
  430. */
  431. int verifieDirCorrecte( int direction, int *dx, int *dy ){
  432. switch ( direction ) {
  433. // Adaptation selon le modèle N NE E SE S SO O NO
  434. case 8:
  435. *dx = -1; *dy = 0; break;
  436. case 9:
  437. *dx = -1; *dy = 1; break;
  438. case 6:
  439. *dx = 0; *dy = 1; break;
  440. case 3:
  441. *dx = 1; *dy = 1; break;
  442. case 2:
  443. *dx = 1; *dy = 0; break;
  444. case 1:
  445. *dx = 1; *dy = -1; break;
  446. case 4:
  447. *dx = 0; *dy = -1; break;
  448. case 7:
  449. *dx = -1; *dy = -1; break;
  450. default: return 0;
  451. }
  452. return 1;
  453. }
  454.  
  455. /* Fonction récupérant la direction du mot en vérifiant encore que l'utilisateur
  456. entre une direction correcte.
  457. Une fois qu'il est intelligent, on ajoute dans jeu l'orientation choisie
  458. */
  459. void demandeDirection ( Tableaux *jeu, int numMot, int *dx, int *dy ){
  460.  
  461. int direction;
  462. int mauvaiseValeur = 0;
  463. do {
  464. printf( "Veuillez saisir la direction pour placer %s\n",
  465. jeu -> mots.listeMots[numMot].mot );
  466.  
  467. scanf( "%d", &direction );
  468. // On teste si l'utilisateur donne une direction correcte au cas où
  469. mauvaiseValeur = verifieDirCorrecte( direction, &*dx, &*dy );
  470.  
  471. } while ( mauvaiseValeur == 0);
  472.  
  473. jeu -> mots.listeMots[numMot].dx = * dx;
  474. jeu -> mots.listeMots[numMot].dy = * dy;
  475.  
  476.  
  477. }
  478.  
  479.  
  480. /* Fonction assez importante, vérifie si -- après saisie des coordonnées
  481. et direction -- le mot se situe toujours dans la grille ou pas
  482. renvoie 0 si non, 1 si oui
  483. */
  484. int calculeDerniereCoord( Tableaux * jeu, int numMot ){
  485.  
  486. // Le calcul n'est pas palpitant par contre, on trouve par magie la dernière
  487. // coordonnée en x et en y et on compare après selon l'intervalle
  488. // [0, grille.taille]
  489. jeu -> mots.listeMots[numMot].xFin = jeu -> mots.listeMots[numMot].xDebut
  490. + jeu -> mots.listeMots[numMot].taille
  491. * jeu -> mots.listeMots[numMot].dx;
  492.  
  493.  
  494. jeu -> mots.listeMots[numMot].yFin = jeu -> mots.listeMots[numMot].yDebut
  495. + jeu -> mots.listeMots[numMot].taille
  496. * jeu -> mots.listeMots[numMot].dy;
  497.  
  498. // Tout ça pour indiquer si on doit recommencer la saisie
  499. // des coords et de la direction ou pas
  500. return ( ( estDansIntervalle( jeu -> mots.listeMots[numMot].xFin, 0, jeu -> grille.taille ) )
  501. && ( estDansIntervalle( jeu -> mots.listeMots[numMot].yFin, 0, jeu -> grille.taille ) ) );
  502.  
  503. }
  504.  
  505.  
  506. /* Fonction aussi importante, elle sert à ne pas écraser un mot placé
  507. dans la grille par les mots suivants sauf cas particulier*
  508. * cas particulier: une lettre est en commun avec plusieurs mots
  509. à une position précise
  510. Renvoie 1 si tout s'est bien passé, 0 si le mot est impossible à placer
  511. */
  512.  
  513. int verifieInterference( Tableaux jeu, int numMot ){
  514. // On pourrait ne pas utliser 4 variables mais l'écriture serait trop lourde.
  515. int x = jeu.mots.listeMots[numMot].xDebut;
  516. int y = jeu.mots.listeMots[numMot].yDebut;
  517. int dx = jeu.mots.listeMots[numMot].dx;
  518. int dy = jeu.mots.listeMots[numMot].dy;
  519.  
  520. // Le premier mot à être placé n'a par définition aucun autre mot qui le gène
  521. if ( numMot == 0 ) return 1;
  522.  
  523. for ( size_t numLettre = 0; numLettre < jeu.mots.listeMots[numMot].taille; numLettre++ ) {
  524. // On parcours, case par case, selon les coords de la première
  525. // et de la direction choisie, la grille, et si on rencontre un problème
  526. // On renvoie 0, sinon on continue jusqu'à la fin et on renverra 1.
  527.  
  528. if ( jeu.grille.plateau[ x + numLettre * dx ][y + numLettre * dy ] != ' ' ){
  529.  
  530. if ( jeu.grille.plateau[x + numLettre * dx ][y + numLettre * dy]
  531. == jeu.mots.listeMots[numMot].mot[numLettre] ){
  532.  
  533. continue;
  534. }
  535.  
  536. else{ return 0; }
  537. }
  538. }
  539. return 1;
  540. }
  541.  
  542.  
  543.  
  544. /* Fonction qui, après être sûr et certain que les mots ont le droit
  545. d'être placés, les place...
  546. les coordonnées (x,y) indiquant la position de la dernière lettre
  547. sont stockés avec le mot
  548. */
  549. void placerMot( Tableaux * jeu, int numMot ){
  550. // Pareil qu'au dessus
  551. int x = jeu -> mots.listeMots[numMot].xDebut;
  552. int y = jeu -> mots.listeMots[numMot].yDebut;
  553. int dx = jeu -> mots.listeMots[numMot].dx;
  554. int dy = jeu -> mots.listeMots[numMot].dy;
  555.  
  556. int numLettre;
  557. for ( numLettre = 0 ; numLettre < (jeu -> mots.listeMots[numMot].taille); numLettre ++ ) {
  558.  
  559. // Place lettre par lettre le mot dans la grille
  560. jeu -> grille.plateau[x + numLettre * dx ][y + numLettre * dy ]
  561. = jeu -> mots.listeMots[numMot].mot[numLettre];
  562.  
  563. }
  564.  
  565. // Stocke les coordonnées de dernière lettre
  566. jeu -> mots.listeMots[numMot].xFin = x + numLettre * dx;
  567. jeu -> mots.listeMots[numMot].yFin = y + numLettre * dy;
  568.  
  569. }
  570.  
  571.  
  572.  
  573.  
  574. /* Fonction principale pour la gestion des mots, fait le liaison
  575. entre le main et toutes les fonctions gérant ça
  576. elle demande simplement pour chaque mots:
  577. les coordonnées
  578. la direction
  579. une fois qu'on a rentré ces deux infos correctes, il reste à vérifier:
  580. les interferences
  581. et une fois que tout ceci est vérifier, on place le mot
  582. et on re-affiche la grille pour rappeler à l'utilisateur où il en est.
  583. */
  584.  
  585. void gestionPlacement( Tableaux * jeu ){
  586. afficheReglesDirection( );
  587. for ( size_t numMot = 0; numMot < jeu -> mots.nbMots ; numMot++ ) {
  588.  
  589. // "booleens" servant à la vérification des bonnes saisies
  590. int coordValable = 0;
  591. int interferenceValable = 0;
  592.  
  593. // variables temporaires avant d'avoir les vrais stockés dans la structure
  594. int x;
  595. int y;
  596. int dx = 0;
  597. int dy = 0;
  598.  
  599.  
  600. do { // Il faut que les 3 conditions soient correctes
  601. do { // Mais on doit d'abord vérifier les deux premières,
  602. // la 3e n'a aucun sens sinon
  603.  
  604. demandeCoordonnes( jeu, numMot, &x, &y );
  605. demandeDirection( jeu, numMot, &dx, &dy );
  606. coordValable = calculeDerniereCoord( jeu, numMot );
  607.  
  608. } while ( coordValable == 0 );
  609.  
  610.  
  611. interferenceValable = verifieInterference( * jeu, numMot );
  612. } while ( interferenceValable == 0 );
  613.  
  614. // On place le mot et on re-affiche le plateau
  615. placerMot( jeu, numMot );
  616. affichePlateau( * jeu );
  617. jeu -> mots.listeMots[numMot].dejaClique = 0;
  618.  
  619.  
  620. }
  621. }
  622.  
  623.  
  624. /* Fonction complétant aléatoirement par des lettres minuscules la grille
  625. Pas grand chose de spécial ici
  626. */
  627. void completeGrille( Tableaux * jeu ){
  628. char lettre;
  629. srand( time( NULL ) );
  630.  
  631. for ( size_t i = 0; i < jeu -> grille.taille; i++ ) {
  632. for ( size_t j = 0; j < jeu -> grille.taille; j++ ) {
  633. if ( jeu -> grille.plateau[i][j] == ' ' ){
  634.  
  635. lettre = rand( ) % ('z' - 'a' + 1) + 'a';
  636. jeu -> grille.plateau[i][j] = lettre;
  637. }
  638. }
  639. }
  640. }
  641.  
  642.  
  643.  
  644. /**************************************
  645. ******* RETROUVER LES MOTS
  646. ***************************************/
  647.  
  648. /* Fonction donnant 1 si (a,b) == (c,d) ou (a,b) == (e,f), 0 sinon
  649. elle permet de comparer si l'utilsateur entre des coords correctes
  650. au moment où il doit retrouver un mot
  651. */
  652. int coupleEgal( int numMot, int a, int b, Tableaux jeu ){
  653. int c = jeu.mots.listeMots[numMot].xDebut;
  654. int d = jeu.mots.listeMots[numMot].yDebut;
  655. int e = jeu.mots.listeMots[numMot].xFin;
  656. int f = jeu.mots.listeMots[numMot].yFin;
  657.  
  658. return ( a == c && b == d ) || ( a == e && b == f );
  659. }
  660.  
  661.  
  662.  
  663. /* Dernière partie du déroulement du jeu, c'est ici que l'utilsateur va
  664. devoir retrouver les mots cachés dans la grille
  665. L'utilisateur a le droit de rentrer les coords du debut OU de la fin du mot
  666. cependant, s'il veut tricher et rentrer deux fois les mêmes coords,
  667. c'est impossible
  668. L'utilisateur entre le numéro du mot qu'il pense avoir trouvé
  669. (indiqué à droite de la grille), puis les coordonnées.
  670. renvoie 1 s'il a gagné, 0 sinon
  671.  
  672. */
  673. int phaseDeJeu( Tableaux jeu ){
  674. // Nombre de mots déjà trouvés par l'utilsateur
  675. int motsTrouves = 0;
  676.  
  677. //
  678. int numMot; // Numéro du mot que l'utilsateur saisira
  679. int x,y; // coordonnées x, y que l'utilsateur saisira
  680. int tmpx, tmpy; // coordonnées x et y pour avoir une trace au cas où
  681. // l'user essaie de tricher
  682.  
  683. do {
  684. // Les seuls moyens de sortir de la boucle sont de gagner ou abandonner
  685.  
  686. printf( "Quel numéro de mot pensez vous avoir trouvé ?\n" );
  687. scanf( "%d", &numMot );
  688.  
  689. // Abandon du joueur, comme précisé dans les règles
  690. if ( numMot == -1 ) return 0;
  691.  
  692. printf( "Indiquez les coordonnées du début du mot.\n" );
  693. scanf( "%d%d", &x, &y );
  694.  
  695.  
  696. if ( coupleEgal( numMot, x, y, jeu ) == 1 ){
  697. tmpx = x;
  698. tmpy = y;
  699.  
  700. printf( "Entre les coordonnées de la fin du mot\n" );
  701. scanf( "%d%d", &x, &y );
  702.  
  703. // Vérification si l'user n'essaie pas de tricher
  704. if ( ( tmpx != x || tmpy != y ) && ( coupleEgal(numMot, x, y, jeu) == 1 ) ){
  705.  
  706. printf( "FELICITATIONS vous avez trouvé le mot %s\n",
  707. jeu.mots.listeMots[numMot].mot );
  708. // Si l'utilisateur trouve les coords de la première et dernière lettre
  709. motsTrouves += 1; // On augmente le nombre de mots trouvés
  710. }
  711.  
  712. else{
  713. printf( "Non, le mot ne se termine pas ici, recommencez\n" );
  714. }
  715. }
  716.  
  717. } while( motsTrouves < jeu.mots.nbMots );
  718.  
  719. // L'utilisateur a trouvé tous les mots qu'il fallait, il a gagné
  720. printf("Bravo, vous avez gagné\n");
  721. return 1;
  722. }
  723.  
  724.  
  725.  
  726. void reglesPhaseDeJeu( ){
  727. printf( "Vous entrez désormais dans la phase de jeu.\n\
  728. Le but est de trouver les mots affichés à droite du tableau\n\
  729. Pour y parvenir, vous devez simplement entrer le numéro du mot ainsi que \n\
  730. les coordonnées (x, y) de la première et de la dernière du mot que vous voulez trouver.\n\
  731. Les mots trouvés apparaîtront en minuscule.\n\
  732. Ecrivez -1 pour abandonner\n" );
  733. }
  734.  
  735.  
  736.  
  737.  
  738.  
  739. /**************************************
  740. ******* FICHIERS: Ecriture
  741. ***************************************/
  742.  
  743.  
  744. /* Valeurs de renvoi:
  745. 0: mode ascii sans fichier
  746. 1: mode graphique avec sauvegarde dans fichier
  747. 2: mode ascii avec sauvegarde dans fichier
  748. 3: mode graphique en chargeant un fichier
  749. 4: mode ascii en chargeant un fichier
  750. */
  751.  
  752. int menuFichier( int argc, const char ** argv ){
  753. if ( argc == 3 ){
  754.  
  755. if ( (argv[1][0] != '-' ) && (argv[2][0] == '-') ){
  756. if (argv[2][1] == 'c'){
  757. if ( argv[2][2] == 'g' ) return 1;
  758.  
  759. printf("La grille que aller créer sera enregistrée dans %s\n", argv[1]);
  760. return 2;
  761.  
  762. }
  763. else if ( argv[2][1] == 'r'){
  764. if ( argv[2][2] == 'g' ) return 3;
  765.  
  766. printf("La grille du fichier %s sera lue si elle existe\n", argv[1]);
  767. return 4;
  768. }
  769.  
  770. }
  771.  
  772. }
  773. return 0;
  774. }
  775.  
  776.  
  777. void metGrilleDansFichier( FILE * fichier, Tableaux jeu ){
  778. int i;
  779. int j;
  780. for ( i = 0; i < jeu.grille.taille; i++ ){
  781. for ( j = 0; j < jeu.grille.taille; ++j ){
  782. fprintf( fichier, "%c", jeu.grille.plateau[i][j] );
  783. }
  784. fputs( "\n", fichier );
  785. }
  786. }
  787.  
  788.  
  789.  
  790. void metMotsDansFichier( FILE * fichier, Tableaux jeu ){
  791. int numMot;
  792. for ( numMot = 0; numMot < jeu.mots.nbMots; numMot++ ){
  793. fprintf( fichier, "%s;\n", jeu.mots.listeMots[numMot].mot );
  794. }
  795. }
  796.  
  797. void metCoordDansFichier( FILE * fichier, Tableaux jeu ){
  798. int i;
  799. for ( i = 0; i < jeu.mots.nbMots; i++ ){
  800. fprintf( fichier, "%2d", jeu.mots.listeMots[i].xDebut );
  801. fprintf( fichier, "%2d", jeu.mots.listeMots[i].yDebut );
  802. fprintf( fichier, "%2d", jeu.mots.listeMots[i].xFin );
  803. fprintf( fichier, "%2d", jeu.mots.listeMots[i].yFin );
  804.  
  805. }
  806. fputs( "\n", fichier );
  807. }
  808.  
  809.  
  810.  
  811. void reglesFichier(){
  812. printf("Le mode par défaut est le mode ASCII.\n\
  813. Aucun fichier n'est utlisé par défaut.\n\
  814. Pour utiliser un fichier, veuillez re-executer\
  815. en suivant les instructions suivantes:\n\
  816. ./nomFichier -ca fichier.txt pour\
  817. créer un fichier, le stocker et jouer en ASCII\n\
  818. ./nomFichier -cg fichier.txt pour\
  819. créer un fichier, le stocker et jouer en mode graphique\n\
  820. ./nomFichier -ra fichier.txt pour\
  821. charger un fichier et le jouer en ASCII\n\
  822. ./nomFichier -rg fichier.txt pour\
  823. charger un fichier et le jouer en graphique\n\n\
  824. Si vous faites une erreur (charger un fichier qui n'existe pas)\
  825. Le mode par défaut sera executé\n ");
  826. }
  827.  
  828.  
  829.  
  830.  
  831.  
  832. /**************************************
  833. ******* Graphique
  834. ******* note: les fonctions s'adaptent
  835. ******* parfaitement à n'importe quelle grille
  836. ***************************************/
  837.  
  838.  
  839.  
  840. /* Cette fonction affiche les cases d'une grille,
  841. le nord ouest de la grille commence à (40,40)
  842. le sud est se fini à (jeu.graph.tailleGrille (540 par défaut ))
  843. */
  844.  
  845.  
  846.  
  847. void messageFin( Tableaux jeu ){
  848. MLV_clear_window( MLV_COLOR_WHITE );
  849. MLV_draw_text( jeu.graph.longueur / 3,
  850. jeu.graph.largeur / 2,
  851. "FELICITATIONS ! Vous avez gagné !",
  852. MLV_COLOR_GREY );
  853. MLV_actualise_window();
  854. }
  855.  
  856. void affichePlateauGraph( Tableaux jeu ){
  857. int i;
  858. int j;
  859.  
  860. for ( i = 40 ; i < jeu.graph.tailleGrille ; i += jeu.graph.tailleCase ){
  861. for ( j = 40 ; j < jeu.graph.tailleGrille ; j += jeu.graph.tailleCase ){
  862.  
  863. MLV_draw_rectangle( i, j, jeu.graph.tailleCase,
  864. jeu.graph.tailleCase, MLV_COLOR_GREY );
  865.  
  866. MLV_actualise_window();
  867.  
  868. }
  869. }
  870.  
  871. }
  872.  
  873. /* Cette fonction, sur le modèle de la précédente, affiche une par une
  874. les lettres de la grille, mêmes calculs à peu près
  875. */
  876. void placerLettresGraph( Tableaux jeu ){
  877. int tailleCase = jeu.graph.tailleCase;
  878. char copieLettre[2];
  879.  
  880. int i,j;
  881. for ( i = 0; i < jeu.grille.taille; i++ ){
  882. for ( j = 0; j < jeu.grille.taille ; j++ ){
  883.  
  884. copieLettre[0] = jeu.grille.plateau[i][j];
  885. copieLettre[1] = '\0';
  886.  
  887. MLV_draw_text( 35 + tailleCase * ( 0.5 + j ),
  888. 35 + tailleCase * ( 0.5 + i ),
  889. copieLettre , MLV_COLOR_GREY );
  890.  
  891. MLV_actualise_window();
  892. }
  893. }
  894. }
  895.  
  896.  
  897. void afficheLesMotsGraph( Tableaux jeu ){
  898. int i;
  899. int tailleMot;
  900. for ( i = 0; i < jeu.mots.nbMots; i++){
  901.  
  902. tailleMot = jeu.mots.listeMots[i].taille;
  903. jeu.mots.listeMots[i].mot[tailleMot + 1] = '\0';
  904.  
  905. MLV_draw_text( 35 + jeu.graph.tailleGrille + jeu.graph.tailleCase,
  906. (i + 1.5 ) * jeu.graph.tailleCase ,
  907. jeu.mots.listeMots[i].mot,
  908. MLV_COLOR_GREY );
  909. MLV_actualise_window();
  910.  
  911.  
  912. }
  913. }
  914.  
  915.  
  916. /* Cette fonction met un mot que l'on a trouvé en couleur
  917. le calcul pour placer le mot est un peu plus compliqué mais pas intéressant
  918. on a besoin d'écrire lettre par lettre le mot
  919. voir verifieInterference() pour un peu plus de détails sur dx et dy
  920. */
  921. /*
  922. void motEnCouleur ( Tableaux jeu, int numMot ){
  923. int lettre;
  924. char copieLettre[2];
  925. int tailleCase = jeu.graph.tailleCase;
  926. dessineTout( jeu );
  927. int id;
  928.  
  929. for ( id = 0; id < jeu.mots.listeMots[id].taille; id++ ){
  930. if ( jeu.mots.listeMots[id].dejaClique == 1){
  931. printf("ET ICI ON A %d\n", id );
  932. for (lettre = 0; lettre < jeu.mots.listeMots[id].taille ; lettre++ ){
  933.  
  934. copieLettre[0] = jeu.mots.listeMots[id].mot[lettre];
  935. copieLettre[1] = '\0';
  936.  
  937. MLV_draw_text( 35 + tailleCase *
  938. ( 0.5 + jeu.mots.listeMots[id].dy * lettre),
  939. 35 + tailleCase * (0.5 + jeu.mots.listeMots[id].dx * lettre),
  940. copieLettre , MLV_COLOR_RED );
  941.  
  942. MLV_actualise_window();
  943.  
  944. }
  945. }
  946. }
  947. }
  948. */
  949. void motEnCouleur( Tableaux jeu ){
  950. int lettre, numMot;
  951. char copieLettre[2];
  952. for (size_t numMot = 0; numMot < jeu.mots.nbMots; numMot++) {
  953. if ( jeu.mots.listeMots[numMot].dejaClique == 1 ){
  954. for (size_t lettre = 0; lettre < jeu.mots.listeMots[mot].taille; lettre++) {
  955.  
  956. copieLettre[0] = jeu.mots.listeMots[numMot].mot[lettre];
  957. copieLettre[1] = '\0';
  958. MLV_draw_text( 35 + tailleCase *
  959. ( 0.5 + jeu.mots.listeMots[id].dy * lettre),
  960. 35 + tailleCase * (0.5 + jeu.mots.listeMots[id].dx * lettre),
  961. copieLettre , MLV_COLOR_RED );
  962.  
  963. MLV_actualise_window();
  964. }
  965. }
  966. }
  967.  
  968. }
  969.  
  970. /* Fonction affichant des boutons en bas de la grille
  971. Boutons Quitter à gauche, rejouer à droite de quitter
  972. Pas spécialement intéréssant
  973. */
  974. void boutonsGraph( Tableaux jeu ){
  975. // Boutons Quitter et Rejouer en bas de la grille
  976. MLV_draw_rectangle( 40 + jeu.graph.tailleGrille / 10,
  977. 60 + jeu.graph.tailleGrille,
  978. 0.4 * jeu.graph.tailleGrille, 40, MLV_COLOR_GREY );
  979.  
  980. MLV_actualise_window();
  981.  
  982. MLV_draw_rectangle( 40 + 0.4*jeu.graph.tailleGrille + jeu.graph.tailleGrille / 10,
  983. 60 + jeu.graph.tailleGrille,
  984. 0.4 * jeu.graph.tailleGrille, 40, MLV_COLOR_GREY );
  985.  
  986. MLV_actualise_window();
  987. }
  988.  
  989.  
  990.  
  991. /* Fonction affichant un texte en bas de l'écran dans un cas particulier *
  992. *cas particulier: le joueur a selectionné un mot
  993. mais s'est trompé sur son emplacement
  994. si le joueur a en fait trouvé le mot, il sera affiché en rouge:
  995. renvoie 0 ou 1, 0: le joueur n'a pas trouvé de mot,
  996. 1: il l'a fait donc ça fait un mot de plus
  997. */
  998.  
  999. int afficheConsigne( Tableaux jeu, int motChoisi, int numMot ){
  1000.  
  1001. if ( motChoisi == 0 ){
  1002. MLV_draw_text( 40 + jeu.graph.tailleCase,
  1003. 2 * jeu.graph.tailleCase + jeu.graph.tailleGrille,
  1004. "La case ne correspond à aucun mot, cliquez à nouveau sur un mot.",
  1005. MLV_COLOR_GREY);
  1006.  
  1007. MLV_actualise_window();
  1008. }
  1009. else {
  1010. printf("MARCHE STP\n");
  1011. jeu.mots.listeMots[numMot].dejaClique = 1;
  1012. motEnCouleur( jeu );
  1013. }
  1014. return motChoisi;
  1015. }
  1016.  
  1017.  
  1018. /* Fonction assez importante traitant celle du dessus,
  1019. elle détecte sur quelle case on a cliqué et agit en conséquence
  1020. et renvoie la valeur trouvée au dessus (voir le commentaire)
  1021. */
  1022.  
  1023. int clicDansCase( Tableaux jeu, int x, int y, int numMot ){
  1024. int i, j;
  1025. int tailleCase = jeu.graph.tailleCase;
  1026.  
  1027. for ( i = 40 ; i < jeu.graph.tailleGrille ; i += jeu.graph.tailleCase ){
  1028. for ( j = 40 ; j < jeu.graph.tailleGrille ; j += jeu.graph.tailleCase ){
  1029. if ( ( estDansIntervalle( y, i, i + tailleCase ) != 0 ) &&
  1030. ( estDansIntervalle( x, j, j + tailleCase ) != 0 ) ) {
  1031. return afficheConsigne( jeu,
  1032. ( coupleEgal ( numMot, i / 40 - 1, j / 40 - 1, jeu ) != 0 ),
  1033. numMot );
  1034. }
  1035. }
  1036. }
  1037. }
  1038.  
  1039. /* Fonction donnant un signal pour fermer la fenetre si l'utilisateur
  1040. veut abandonner, ou relance une partie si l'utilisateur veut rejouer
  1041. */
  1042.  
  1043.  
  1044. /*
  1045. void convertitClicEnCoord( int x, int y, * i, * j ){
  1046. float a = ( x / jeu.graph.tailleCase);
  1047. float b = ( y / jeu.graph.tailleCase);
  1048.  
  1049. *i = int (a);
  1050. *j = int (b);
  1051.  
  1052. }
  1053.  
  1054. */
  1055.  
  1056. int clicSurMots( Tableaux jeu, int x, int y ){
  1057. float a = ( y / jeu.graph.tailleCase ) ;
  1058.  
  1059. return (int) a ;
  1060.  
  1061. }
  1062.  
  1063.  
  1064. int clicSurBoutons( Tableaux jeu, int x ){
  1065.  
  1066. // Le joueur clique sur quitter
  1067. if ( x < jeu.graph.tailleGrille / 2 ) return -100;
  1068.  
  1069. // Le joueur clique sur rejouer
  1070. return 100;
  1071. }
  1072.  
  1073.  
  1074.  
  1075. /* Fonction sans doute la plus importante du mode graphique
  1076. Elle trouve dans quelle zone de la fenetre le joueur a cliqué
  1077. et renvoie les valeurs de retour expliquées plus haut
  1078. les calculs ne sont pas intéréssants
  1079. */
  1080.  
  1081. int clicDansFenetre( Tableaux jeu ){
  1082.  
  1083. int x, y;
  1084.  
  1085. MLV_wait_mouse( &x, &y );
  1086.  
  1087. int numMot = clicSurMots( jeu, x, y ) - 1;
  1088. printf("LE NUMERO DU MOT EST %d\n", numMot);
  1089.  
  1090. // On vérifie d'abord si le joueur a cliqué dans la grille
  1091. if ( ( estDansIntervalle( x, 40, jeu.graph.tailleGrille ) ) &&
  1092. ( estDansIntervalle( y, 40, jeu.graph.tailleGrille ) ) ){
  1093. return clicDansCase( jeu, x, y, numMot );
  1094.  
  1095. }
  1096. // Si c'est pas le cas, il a peut-êtr cliqué sur un bouton
  1097. else if ( ( estDansIntervalle( x, 40 + jeu.graph.tailleCase,
  1098. 40 + jeu.graph.tailleCase + 0.4 * jeu.graph.tailleGrille ) ) &&
  1099. ( estDansIntervalle( y, jeu.graph.tailleCase + jeu.graph.tailleGrille,
  1100. jeu.graph.tailleCase + jeu.graph.tailleGrille + 40 ) ) ){
  1101. //return clicSurBoutons()
  1102. }
  1103.  
  1104.  
  1105.  
  1106. return 0;
  1107.  
  1108. }
  1109.  
  1110.  
  1111. /* Fonction appelant les fonctions de dessin */
  1112.  
  1113. void dessineTout( Tableaux jeu ){
  1114. MLV_clear_window( MLV_COLOR_WHITE );
  1115. affichePlateauGraph( jeu );
  1116. placerLettresGraph( jeu );
  1117. afficheLesMotsGraph( jeu );
  1118.  
  1119. boutonsGraph( jeu );
  1120.  
  1121.  
  1122. }
  1123.  
  1124. /* Fonction principale du mode graphique, c'est ici que le jeu va se dérouler
  1125. elle est très semblable à la fonction phaseDeJeu()
  1126. On commence par créer une fenetre, on initialise le nombre de mots trouvés à 0
  1127. on dessine tout à chaque nouveau clic et les valeurs de retour de
  1128. clicDansFenetre() sont: {-100: abandon, 0: mot non trouvé, 1, mot trouvé,
  1129. 100, rejouer }
  1130. une fois que c'est fini, par une victoire, un abandon ou après avoir rejoué
  1131. on ferme la fenetre et le programme se fini
  1132. */
  1133. void modeGraphique( Tableaux * jeu ){
  1134.  
  1135. MLV_create_window( "Mots Mélés", "Partie Graphique",
  1136. jeu -> graph.longueur, jeu -> graph.largeur );
  1137.  
  1138. jeu -> mots.nbMotsTrouves = 0;
  1139. do {
  1140. dessineTout( * jeu );
  1141. jeu -> mots.nbMotsTrouves += clicDansFenetre( * jeu );
  1142. if ( jeu -> mots.nbMotsTrouves < 0 ||
  1143. jeu -> mots.nbMotsTrouves > 30 ) break;
  1144.  
  1145.  
  1146.  
  1147. } while ( jeu -> mots.nbMotsTrouves < jeu -> mots.nbMots );
  1148.  
  1149. MLV_wait_seconds( 2 );
  1150.  
  1151. messageFin( * jeu );
  1152.  
  1153. MLV_wait_seconds( 6 );
  1154. MLV_free_window();
  1155.  
  1156.  
  1157. }
  1158.  
  1159.  
  1160.  
  1161. /**************************************
  1162. ******* main
  1163. ***************************************/
  1164.  
  1165. /* Fonction en plusieurs temps
  1166. D'abord on initialise les constituants principaux d'une partie
  1167. Puis on initialise le plateau
  1168. on demande les mots à l'utilisateur, on les place
  1169. on complète aléatoirement la grille
  1170. et enfin on joue
  1171. TODO: rajouter les fichiers et le mode graphique
  1172.  
  1173. */
  1174. int main( int argc, char const *argv[] ) {
  1175.  
  1176. FILE * fichier = NULL;
  1177. int mode = 1;
  1178.  
  1179. Tableaux jeu;
  1180. propJeu( &jeu );
  1181.  
  1182.  
  1183.  
  1184. initPlateau ( &jeu);
  1185. choixDesMots( &jeu );
  1186.  
  1187. gestionPlacement( &jeu );
  1188. completeGrille( &jeu );
  1189. //affichePlateau( jeu );
  1190.  
  1191. if (mode == 1){
  1192. fichier = fopen(argv[1], "w");
  1193. if (NULL != fichier){
  1194. metMotsDansFichier(fichier, jeu );
  1195. metGrilleDansFichier( fichier, jeu );
  1196. metCoordDansFichier( fichier, jeu );
  1197. }
  1198. }
  1199.  
  1200. affichePlateau( jeu );
  1201. modeGraphique( &jeu );
  1202. //reglesPhaseDeJeu( );
  1203. //phaseDeJeu( jeu );
  1204.  
  1205.  
  1206.  
  1207.  
  1208. return 0;
  1209. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement