Aide Jeu de mots mêlés. Langage C

jsmmjr - Modifié le 29 juin 2023 à 15:57
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 - 28 juin 2023 à 10:52

Bonjour,

J'ai commencer à coder en C un jeu de mots mêlés où l'on trouve des mots (appartenant à un thème) dans une grille. On peut choisir le thème que l'on veut et la taille de la grille.

On peut également se déplacer dans la grille grâce aux touches 2 (pour aller en bas), 4 (gauche), 6 (droite), et 8 (en haut). Néanmoins je suis bloquée à la sélection des mots, qui doit se poursuivre de cette manière :

Lorsque le joueur trouve un mot :

  • Positionne le curseur sur la première lettre du mot, appuie sur la touche espace,
  • Puis se déplace jusqu'à la dernière lettre du mot
  • Appuie à nouveau sur espace.

Lors de la sélection, dès qu'une lettre est sélectionnée elle est mise en évidence (en changeant de couleur par exemple).

  • Si le mot est correct il prend une nouvelle couleur qu'il conservera jusqu'à la fin de la partie.
  • Si le mot est incorrect les lettres retrouvent leurs couleurs d'origine.

Lorsque le joueur a trouvé tous les mots, un message de félicitations s'affiche, il peut ensuite retourner au menu.

Voici mon code:

Merci de m'aider.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <windows.h>
#include <conio.h>
#include <stdbool.h>


#define taille_mot 20   // Taille maximale d'un mot
#define MAX_MOTS_TROUVES 25
char motsTrouves[MAX_MOTS_TROUVES][taille_mot];
int nbMotsTrouves = 0;


int taille_ligne = 22;  // Nombre de lignes de la grille
int taille_colonne = 22;  // Nombre de colonnes de la grille

int curseur_ligne = 0;
int curseur_colonne = 0;

// Déclaration de la variable 'mot'
char mot[taille_mot];

//création d'une procédure couleur pour changer la couleur du texte dans la console (feuille cours fonctions particulière)
void Color(int couleurDuTexte, int couleurDeFond) {
    HANDLE H = GetStdHandle(STD_OUTPUT_HANDLE); //handle = identifiant unique attribué par le système de gestion des fenêtres //GetStdHandle = récupere le handle //Std_output.. = périphérique de sortie standard
    SetConsoleTextAttribute(H, couleurDeFond * 16 + couleurDuTexte);
}



int collisionMot (char grille[taille_ligne][taille_colonne], char mot[], int i, int j, int direction) {
    int longueurMot = strlen(mot); //calcul de la longueur du mot pour la placer dans la variable longueurMot

    if (direction == 0) { // si le Placement est horizontal
        for (int l = 0; l < longueurMot; l++) { //on parcourt chaque caractère du mot grâce à l
            if (grille[i][j + l] != ' ' && grille[i][j + l] != mot[l]) { // si à cette position (i, j + l) il y a un espace vide ou lettre différente, alors y a une collision et on renvoit 1
                return 1;
            }
        }
    } else if (direction == 1) { // Vertical
        for (int l = 0; l < longueurMot; l++) { //idem
            if (grille[i + l][j] != ' ' && grille[i + l][j] != mot[l]) {
                return 1;
            }
        }
    } else if (direction == 4) { // Diagonale descendante
        for (int l = 0; l < longueurMot; l++) {
            if (grille[i + l][j + l] != ' ' && grille[i + l][j + l] != mot[l]) {
                return 1;
            }
        }
    }else if (direction == 5) { // Diagonale montante
        for (int l = 0; l < longueurMot; l++) {
            if (grille[i - l][j + l] != ' ' && grille[i - l][j + l] != mot[l]) {
                return 1;
            }
        }
    }
    return 0;
}

void Grillegenere(char grille[taille_ligne][taille_colonne], char mots[][taille_mot], int nbMots) {
    int i, j, k;
    int longueurMot;
    int direction;
    int collision;

    // Initialisation du générateur pour les nombres aléatoires
    srand(time(NULL));

    // Initialisation de la grille avec des espaces vides
    for (i = 0; i < taille_ligne; i++) {
        for (j = 0; j < taille_colonne; j++) {
            grille[i][j] = ' ';
        }
    }
    // Placement des mots dans la grille
    for (k = 0; k < nbMots; k++) {
        longueurMot = strlen(mots[k]);
        direction = rand() % 4; // pour les 4 directions possibles)
        collision = 0;

        if (direction == 0) { // de gauche à droite)
            do {
                i = rand() % taille_ligne; // la variable i va = à une position aléatoire dans la ligne (nombre aléatoire entre 0 et taille_ligne - 1)
                j = rand() % (taille_colonne - longueurMot + 1); // la variable j va = à une position aléatoire dans la colonne
                collision = collisionMot(grille, mots[k], i, j, direction); // on appele la fonction collisionMot pour vérifier s'il y a une collision
            } while (collision); // la boucle continue tant qu'il y a une collision

            for (int l = 0; l < longueurMot; l++) { // en  prcourant chaque caractère du mot,
                grille[i][j + l] = mots[k][l]; //
            }
        } else if (direction == 1) { // idem de (haut en bas)
            do {
                i = rand() % (taille_ligne - longueurMot + 1);
                j = rand() % taille_colonne;
                collision = collisionMot(grille, mots[k], i, j, direction);
            } while (collision);

            for (int l = 0; l < longueurMot; l++) {
                grille[i + l][j] = mots[k][l];
            }
        } else if (direction == 2) { // idem droite à gauche
            do {
                i = rand() % taille_ligne;
                j = rand() % (taille_colonne - longueurMot + 1);
                collision = collisionMot(grille, mots[k], i, j, direction);
            } while (collision);

            for (int l = 0; l < longueurMot; l++) {
                grille[i][j + l] = mots[k][longueurMot - 1 - l];
            }
        } else if (direction == 3) { // odem de bas en haut
            do {
                i = rand() % (taille_ligne - longueurMot + 1);
                j = rand() % taille_colonne;
                collision = collisionMot(grille, mots[k], i, j, direction);
            } while (collision);

            for (int l = 0; l < longueurMot; l++) {
                grille[i + l][j] = mots[k][longueurMot - 1 - l];
            }
        } else if (direction == 4) { // Diagonale descendante
            do {
                i = rand() % (taille_ligne - longueurMot + 1);
                j = rand() % (taille_colonne - longueurMot + 1);
                collision = collisionMot(grille, mots[k], i, j, direction);
            } while (collision);

            for (int l = 0; l < longueurMot; l++) {
                grille[i + l][j + l] = mots[k][l];
            }
        }else if (direction == 5) { // Diagonale montante
            do {
                i = rand() % (taille_ligne - longueurMot + 1) + longueurMot - 1;
                j = rand() % (taille_colonne - longueurMot + 1);
                collision = collisionMot(grille, mots[k], i, j, direction);
            } while (collision);

            for (int l = 0; l < longueurMot; l++) {
                grille[i - l][j + l] = mots[k][l];
            }
        }
    }

    // Génération des lettres aléatoires pour les cases vides de la grille
    for (i = 0; i < taille_ligne; i++) {
        for (j = 0; j < taille_colonne; j++) {
            if (grille[i][j] == ' ') { //si la case est vide on génére une lettr e majuscule
                grille[i][j] = 'a' + rand() % 26;
            }
        }
    }
}

void afficherMotsTheme(char mots[][taille_mot], int nbMots) {
    int motsParColonne = (nbMots + 2) / 4; // Calcul du nombre de mots par colonne

    printf("\nMots à rechercher dans la grille:\n");

    for (int i = 0; i < motsParColonne; i++) {
        printf("%-20s", mots[i]); // Affichage du mot de la première colonne

        int index2 = i + motsParColonne;
        if (index2 < nbMots) {
            printf("%-20s", mots[index2]); // Affichage du mot de la deuxième colonne
        }

        int index3 = i + motsParColonne * 2;
        if (index3 < nbMots) {
            printf("%-20s", mots[index3]); // Affichage du mot de la troisième colonne
        }

        int index4 = i + motsParColonne * 3;
        if (index4 < nbMots) {
            printf("%s", mots[index4]);
        }

        printf("\n");
    }

    printf("\n");
}





void afficherGrille(char grille[taille_ligne][taille_colonne]) {
    int i, j;

    // Affichage de la grille
    for (i = 0; i < taille_ligne; i++) {
        for (j = 0; j < taille_colonne; j++) {
            if ((i + j) % 2 == 0) { //pour le pair/impair et avoir 2 couleurs
                Color(0, 7); //1er nombre (0) pour le texte et 2e nombre (7,14) pour le fond
            } else {
                Color(0, 14);
            }
            printf("%c", grille[i][j]);
            printf(" ");
            Color(15, 0); // après la grille on remet les couleur avec fond noir

        }
        printf("\n");
    }
}

// Variable pour suivre l'état de la touche "Entrée"
bool entreeAppuyee = false;
bool copieMotEnCours = false;
int debutMot;

void afficherGrilleAvecCurseur(char grille[taille_ligne][taille_colonne]) {
    int i, j;

    // Affichage de la grille avec le curseur
    for (i = 0; i < taille_ligne; i++) {
        for (j = 0; j < taille_colonne; j++) {
            if (i == curseur_ligne && j == curseur_colonne) {
                Color(15, 4); // Curseur en couleur blanche sur fond rouge
                if (entreeAppuyee) {
    // Marquer les cases visitées après avoir appuyé sur la touche "Entrée"
    Color(0, 9);

}

            } else if ((i + j) % 2 == 0) { // Pour le pair/impair et avoir 2 couleurs
                Color(0, 7); // 1er nombre (0) pour le texte et 2e nombre (7,14) pour le fond
            } else {
                Color(0, 14);
            }
            printf("%c", grille[i][j]);
            printf(" ");
            Color(15, 0); // Après la grille, on remet les couleurs avec fond noir


        }
        printf("\n");
    }
}



// Fonction de déplacement du curseur
void deplacerCurseur(char direction, char grille[taille_ligne][taille_colonne], char mots[][taille_mot], int nbMots) {

    switch (direction) {
        case '8':  // Haut
            if (curseur_ligne > 0)
                curseur_ligne--;
            break;
        case '4':  // Gauche
            if (curseur_colonne > 0)
                curseur_colonne--;
            break;
        case '2':  // Bas
            if (curseur_ligne < taille_ligne - 1)
                curseur_ligne++;
            break;
        case '6':  // Droite
            if (curseur_colonne < taille_colonne - 1)
                curseur_colonne++;
            break;
        case ' ':  // Touche "Espace"
    if (!entreeAppuyee) {
    entreeAppuyee = true;
    debutMot = curseur_ligne * taille_colonne + curseur_colonne;
} else {
    entreeAppuyee = false;
    int finMot = curseur_ligne * taille_colonne + curseur_colonne;

    // Extraire le mot entre 'debutMot' et 'finMot' de la grille
    int indice = 0;
    int start = min(debutMot, finMot);
    int end = max(debutMot, finMot);
    for (int i = start; i <= end; i++) {
        int ligne = i / taille_colonne;
        int colonne = i % taille_colonne;
        mot[indice] = grille[ligne][colonne];
        indice++;
    }
    mot[indice] = '\0';  // Terminer la chaîne de caractères

        // Vérifier si le mot est présent dans la liste des mots à rechercher
        bool motCorrect = false;
        for (int i = 0; i < nbMots; i++) {
            if (strcmp(mot, mots[i]) == 0) {
                motCorrect = true;
                break;
            }
        }

        if (motCorrect) {
    // Vérifier si le mot a déjà été trouvé
    bool dejaTrouve = false;
    for (int i = 0; i < nbMotsTrouves; i++) {
        if (strcmp(mot, motsTrouves[i]) == 0) {
            dejaTrouve = true;
            break;
        }
    }

    if (!dejaTrouve) {
        strcpy(motsTrouves[nbMotsTrouves], mot);
        nbMotsTrouves++;
    }

    if (dejaTrouve) {
        printf("Mot déjà trouvé.\n");
    } else {
        printf("Mot correct !\n");
    }
} else {
    printf("Mot incorrect.\n");
}

    }
    break;



    }
}


void afficherMotsTrouves() {
    printf("Mots déjà trouvés :\n");
    for (int i = 0; i < nbMotsTrouves; i++) {
        printf("%s\n", motsTrouves[i]);
    }
    printf("\n");
}





//structure pour représenter un thème et ses mots :
typedef struct {
    char theme[taille_mot];
    char mots[25][taille_mot];
    int nbMots;
} Theme;

Theme themes[10];
int nbThemes = 0;

void creerTheme() {
    if (nbThemes >= 10) {
        printf("Nombre de thèmes maximum atteint.\n");
        return;
    }

    Theme theme;

    printf("Entrez le thème : ");
    scanf("%s", theme.theme);
    printf("Combien de mots ? (maximum 25) ");
    scanf("%d", &theme.nbMots);

    if (theme.nbMots > 25) {
        printf("Nombre de mots invalide.\n");
        return;
    }

    printf("Entrez les mots :\n");
    for (int i = 0; i < theme.nbMots; i++) {
        printf("Mot %d : ", i + 1);
        scanf("%s", theme.mots[i]);
    }

    themes[nbThemes] = theme;
    nbThemes++;

    printf("Thème ajouté avec succès.\n");
}

void themesDefinis() {
    Theme theme1;
    strcpy(theme1.theme, "Animaux"); // strcpy pour copier la chaîne de caractères d'une source vers une destination
    strcpy(theme1.mots[0], "chien");
    strcpy(theme1.mots[1], "chat");
    strcpy(theme1.mots[2], "kangourou");
    strcpy(theme1.mots[3], "grenouille");
    strcpy(theme1.mots[4], "gazelle");
    strcpy(theme1.mots[5], "chevre");
    strcpy(theme1.mots[6], "renard");
    strcpy(theme1.mots[7], "serpent");
    strcpy(theme1.mots[8], "abeille");
    strcpy(theme1.mots[9], "araignee");
    strcpy(theme1.mots[10], "lapin");
    strcpy(theme1.mots[11], "zebre");
    strcpy(theme1.mots[12], "phoque");
    strcpy(theme1.mots[13], "poirson");
    strcpy(theme1.mots[14], "poulet");
    strcpy(theme1.mots[15], "cheval");
    strcpy(theme1.mots[16], "chameau");
    strcpy(theme1.mots[17], "cafard");
    strcpy(theme1.mots[18], "poussin");
    strcpy(theme1.mots[19], "truie");
    strcpy(theme1.mots[20], "furet");
    strcpy(theme1.mots[21], "aigle");
    strcpy(theme1.mots[22], "leopard");
    theme1.nbMots = 23;
    themes[nbThemes] = theme1;
    nbThemes++;

    Theme theme2;
    strcpy(theme2.theme, "Fruits");
    strcpy(theme2.mots[0], "fraise");
    strcpy(theme2.mots[1], "pomme");
    strcpy(theme2.mots[2], "pamplemousse");
    strcpy(theme2.mots[3], "poire");
    strcpy(theme2.mots[4], "banane");
    strcpy(theme2.mots[5], "framboise");
    strcpy(theme2.mots[6], "cerise");
    strcpy(theme2.mots[7], "ananas");
    strcpy(theme2.mots[8], "citron");
    strcpy(theme2.mots[9], "clementine");
    strcpy(theme2.mots[10], "melon");
    strcpy(theme2.mots[11], "peche");
    strcpy(theme2.mots[12], "nectarine");
    strcpy(theme2.mots[13], "myrtille");
    strcpy(theme2.mots[14], "noix");
    strcpy(theme2.mots[15], "figue");
    strcpy(theme2.mots[16], "tomate");
    strcpy(theme2.mots[17], "mandarine");
    strcpy(theme2.mots[18], "prume");
    strcpy(theme2.mots[19], "chataigne");
    strcpy(theme2.mots[20], "groiselle");
    strcpy(theme2.mots[21], "abricot");
    strcpy(theme2.mots[22], "kiwi");
    theme2.nbMots = 23;
    themes[nbThemes] = theme2;
    nbThemes++;

            Theme theme3;
        strcpy(theme3.theme, "Villes de France");
        strcpy(theme3.mots[0], "paris");
        strcpy(theme3.mots[1], "marseille");
        strcpy(theme3.mots[2], "nice");
        strcpy(theme3.mots[3], "toulouse");
        strcpy(theme3.mots[4], "bordeaux");
        strcpy(theme3.mots[5], "lyon");
        strcpy(theme3.mots[6], "lille");
        strcpy(theme3.mots[7], "nantes");
        strcpy(theme3.mots[8], "montpellier");
        strcpy(theme3.mots[9], "strasbourg");
        strcpy(theme3.mots[10], "besancon");
        strcpy(theme3.mots[11], "rennes");
        strcpy(theme3.mots[12], "angers");
        strcpy(theme3.mots[13], "dijon");
        strcpy(theme3.mots[14], "versailles");
        strcpy(theme3.mots[15], "orleans");
        strcpy(theme3.mots[16], "amiens");
        strcpy(theme3.mots[17], "rouen");
        strcpy(theme3.mots[18], "roubaix");
        strcpy(theme3.mots[19], "perpignan");
        strcpy(theme3.mots[20], "mulhouse");
        strcpy(theme3.mots[21], "poitiers");
        strcpy(theme3.mots[22], "tourcoing");
        theme3.nbMots = 23;
        themes[nbThemes] = theme3;
        nbThemes++;


}

int genererThemeAleatoire() {
    return rand() % nbThemes;
}

void changerTailleGrille() {
    printf("Veuillez entrer la nouvelle taille de la grille (nombre de lignes et de colonnes) :\n");
    printf("Nombre de lignes : ");
    scanf("%d", &taille_ligne);
    printf("Nombre de colonnes : ");
    scanf("%d", &taille_colonne);
}

int main() {
    char grille[taille_ligne][taille_colonne];
    char mots[20][taille_mot];
    int nbMots;
    int choixMenu = 0;
     themesDefinis();
     char direction;
int jeuTermine = 0;

    while (choixMenu != 3) {

        printf("MENU\n");
        printf("1. Ajouter une nouvelle liste de mots\n");
        printf("2. Jouer\n");
        printf("3. Choisir un theme\n");
        printf("4. Choisir la taille de la grille\n");
        printf("5. Quitter\n");
        printf("Choix : ");
        scanf("%d", &choixMenu);

        switch (choixMenu) {
            case 1:
                creerTheme(mots, &nbMots);
                if (nbMots > 0) {
                    Grillegenere(grille, mots, nbMots);
                    printf("Création avec succès.\n");
                }
                break;
            case 2:
    system("cls");
    if (nbThemes > 0) {
        int themeAleatoire = genererThemeAleatoire();
        Theme theme = themes[themeAleatoire];
        Grillegenere(grille, theme.mots, theme.nbMots);


while (!jeuTermine) {
        system("cls");
        printf("Thème : %s\n", theme.theme);
        printf("Taille : %dx%d\n", taille_ligne, taille_colonne);

        afficherGrilleAvecCurseur(grille);

        afficherMotsTheme(theme.mots, theme.nbMots);
        afficherMotsTrouves();

        direction = getch();
        deplacerCurseur(direction, grille,mots, nbMots);

    }} else {
        printf("Aucun thème disponible.\n");
    }
    system("cls");
    break;
    case 3:
        system("cls");
    if (nbThemes > 0) {
        printf("Thèmes disponibles :\n");
        for (int i = 0; i < nbThemes; i++) {
            printf("%d. %s\n", i + 1, themes[i].theme);
        }

        int choixTheme;
        printf("Choisissez un thème : ");
        scanf("%d", &choixTheme);

        system("cls");

        if (choixTheme >= 1 && choixTheme <= nbThemes) {
            Theme theme = themes[choixTheme - 1];
            Grillegenere(grille, theme.mots, theme.nbMots);
            printf("Thème : %s\n", theme.theme);
        printf("Taille : %dx%d\n", taille_ligne, taille_colonne);

             while (!jeuTermine) {
                 system("cls");
                 printf("Thème : %s\n", theme.theme);
        printf("Taille : %dx%d\n", taille_ligne, taille_colonne);

        //afficher avec le theme selectionne
        afficherGrilleAvecCurseur(grille);

        afficherMotsTheme(theme.mots, theme.nbMots);

        direction = getch();
        deplacerCurseur(direction, grille,mots, nbMots);

    }} else {
            printf("Thème invalide.\n");
        }
    } else {
        printf("Aucun thème disponible.\n");
    }
    break;
    case 4:
        changerTailleGrille();
        break;
            case 5:
                printf("Au revoir.\n");
                break;
            default:
                printf("Impossible.\n");
                break;
        }

        printf("\n");
    }

    return 0;
}
A voir également:

1 réponse

[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 28 juin 2023 à 10:52

Salut jsmmjr,

L'API Windows que tu utilises déjà pour la coloration du texte, te permet aussi de déplacer le curseur de la console aux coordonnées de l'écran de ton choix.

Vois : SetConsoleCursorPosition() : https://learn.microsoft.com/fr-fr/windows/console/setconsolecursorposition

Tu peux alors t'écrire une fonction comme ceci pour t'en faciliter l'usage :

void gotoxy(int x, int y) {
    COORD point;
    point.X = x; point.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),point);
}

1