Créer un simple jeu de morpion en langage C

CBeginner
Pratiquer maintenant

Introduction

Dans ce projet, vous apprendrez à créer un simple jeu de Morpion en C. Le jeu se jouera entre deux joueurs qui prendront tour à tour pour marquer les cases d'une grille 3x3. Le premier joueur à avoir trois de ses marques alignées horizontalement, verticalement ou diagonalement remporte la partie. Si toutes les cases sont remplies et qu'aucun joueur n'a trois marques alignées, la partie est nulle.

👀 Aperçu

Aperçu du jeu de Morpion

🎯 Tâches

Dans ce projet, vous apprendrez :

  • Comment créer un plateau de jeu et l'initialiser avec des cases vides.
  • Comment implémenter des fonctions pour effacer l'écran, afficher le plateau de jeu et vérifier si la partie est terminée.
  • Comment déterminer le gagnant de la partie.
  • Comment implémenter la boucle principale du jeu pour permettre aux joueurs de jouer tour à tour et d'interagir avec le jeu.

🏆 Réalisations

Après avoir terminé ce projet, vous serez en mesure de :

  • Créer et manipuler des tableaux en C.
  • Utiliser des boucles et des conditions pour implémenter la logique du jeu.
  • Interagir avec l'utilisateur via l'interface en ligne de commande.
  • Organiser le code en fonctions pour une meilleure modularité et lisibilité.

Créer les fichiers du projet

Tout d'abord, créez un nouveau fichier nommé tictactoe.c et ouvrez-le dans votre éditeur de code préféré.

cd ~/project
touch tictactoe.c

Définir des constantes

Maintenant, nous devons écrire le code C. La première étape consiste à inclure les fichiers d'en-tête :

#include <stdio.h>
#include <stdbool.h>

Déclarez la taille du plateau :

char board[3][3];

Initialiser le plateau de jeu

Initialisez le plateau de jeu avec des cases vides.

void initializeBoard() {
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            board[i][j] = ' ';
        }
    }
}

La première boucle for est une boucle externe qui utilise la variable i pour itérer de 0 à 2, représentant le nombre de lignes sur le plateau de jeu. La deuxième boucle for est une boucle interne qui utilise la variable j pour itérer de 0 à 2, représentant le nombre de colonnes sur le plateau de jeu à son tour.

board[i][j] = ' ' Dans la boucle interne, définit le contenu des cases de la ligne i et de la colonne j du plateau de jeu sur le caractère espace (' '). Cela signifie que l'ensemble du plateau de jeu est initialisé à un état vide, aucun joueur n'ayant joué sur le plateau.

Effacer l'écran après chaque tour

Implémentez une fonction pour effacer l'écran après chaque tour.

void clearScreen() {
    printf("\033[H\033[J");
}

La fonction clearScreen est principalement utilisée pour effacer le contenu du terminal ou de l'écran de la console afin d'effacer l'état et la sortie du jeu précédents à la fin de chaque tour. Cela se fait en imprimant une séquence d'échappement spéciale sur un flux de sortie standard (généralement une fenêtre de terminal) qui efface le contenu textuel de l'écran.

printf("\033[H\033[J") utilise des séquences d'échappement ANSI :

  • \033 est la représentation octale du caractère d'échappement ASCII, qui représente le début de la séquence.
  • [H indique de déplacer le curseur dans le coin supérieur gauche de l'écran, ce qui équivaut à positionner le curseur sur la première ligne et la première colonne de l'écran.
  • [J signifie effacer l'écran. Il effacera tout le contenu textuel après la position du curseur, y compris l'état et la sortie du jeu précédents.

Cela signifie que chaque fois que la fonction clearScreen est appelée, elle effacera le contenu de l'écran du terminal ou de la console actuel afin d'afficher le nouvel état du jeu avant la prochaine session de jeu, ce qui donne une interface plus propre.

Afficher le plateau de jeu

Créez la fonction printBoard pour afficher visuellement l'état actuel du plateau de jeu à l'écran, permettant au joueur de comprendre la position des pièces sur le plateau. Il s'agit d'une partie du jeu utilisée dans les jeux de morpion pour montrer l'état du jeu.

void printBoard() {
    printf("\n");
    printf("  1   2   3\n");
    printf("1 %c | %c | %c\n", board[0][0], board[0][1], board[0][2]);
    printf("  ---------\n");
    printf("2 %c | %c | %c\n", board[1][0], board[1][1], board[1][2]);
    printf("  ---------\n");
    printf("3 %c | %c | %c\n", board[2][0], board[2][1], board[2][2]);
}

Vérifier si le jeu est terminé

Implémentez une fonction appelée isGameOver pour déterminer si le jeu de morpion est terminé et retourner une valeur booléenne (true ou false).

bool isGameOver() {
    // Check rows
    for (int i = 0; i < 3; i++) {
        if (board[i][0]!= ' ' && board[i][0] == board[i][1] && board[i][0] == board[i][2]) {
            return true;
        }
    }

    // Check columns
    for (int j = 0; j < 3; j++) {
        if (board[0][j]!= ' ' && board[0][j] == board[1][j] && board[0][j] == board[2][j]) {
            return true;
        }
    }

    // Check diagonals
    if (board[0][0]!= ' ' && board[0][0] == board[1][1] && board[0][0] == board[2][2]) {
        return true;
    }
    if (board[0][2]!= ' ' && board[0][2] == board[1][1] && board[0][2] == board[2][0]) {
        return true;
    }

    // Check for a draw
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if (board[i][j] == ' ') {
                return false;
            }
        }
    }

    return true;
}

Vérifier si une ligne a un gagnant : Si les trois cases d'une ligne sont occupées par le même joueur, il y a un gagnant et la fonction retourne true.

Vérifier si une colonne a un gagnant : Si les trois cases d'une colonne sont occupées par le même joueur, il y a un gagnant et la fonction retourne true.

Vérifier si il y a un gagnant sur la diagonale : Si les trois cases de n'importe quelle diagonale sont occupées par le même joueur, il y a un gagnant et la fonction retourne true.

Vérifier s'il y a match nul : Enfin, la fonction vérifie si toutes les cases ont été occupées, mais qu'il n'y a pas de gagnant. Si c'est le cas, le jeu est un match nul et la fonction retourne true.

Déterminer le gagnant

Une fonction nommée getWinner est définie. Son but est de déterminer s'il y a un gagnant dans un jeu de morpion et de retourner le symbole du gagnant (X ou O), ou un espace (' ') s'il n'y a pas de gagnant.

char getWinner() {
    // Check rows
    for (int i = 0; i < 3; i++) {
        if (board[i][0]!= ' ' && board[i][0] == board[i][1] && board[i][0] == board[i][2]) {
            return board[i][0];
        }
    }

    // Check columns
    for (int j = 0; j < 3; j++) {
        if (board[0][j]!= ' ' && board[0][j] == board[1][j] && board[0][j] == board[2][j]) {
            return board[0][j];
        }
    }

    // Check diagonals
    if (board[0][0]!= ' ' && board[0][0] == board[1][1] && board[0][0] == board[2][2]) {
        return board[0][0];
    }
    if (board[0][2]!= ' ' && board[0][2] == board[1][1] && board[0][2] == board[2][0]) {
        return board[0][2];
    }

    return ' '; // No winner
}

Implémenter la boucle principale du jeu

Écrivez la boucle principale du jeu pour permettre aux joueurs de jouer à tour de rôle et d'interagir avec le jeu.

int main() {
    initializeBoard();
    int currentPlayer = 1;

    while (1) {
        clearScreen();
        printf("Current board state:\n");
        printBoard();

        int row, col;
        printf("Player %d, please enter a row and column (e.g., 1 2):", currentPlayer);

        while (scanf("%d %d", &row, &col)!= 2) {
            printf("Invalid input, please try again: ");
            while (getchar()!= '\n');
        }

        if (row < 1 || row > 3 || col < 1 || col > 3 || board[row - 1][col - 1]!= ' ') {
            printf("Invalid move, please try again.\n");
        } else {
            if (currentPlayer == 1) {
                board[row - 1][col - 1] = 'X';
                currentPlayer = 2;
            } else {
                board[row - 1][col - 1] = 'O';
                currentPlayer = 1;
            }
        }

        if (isGameOver()) {
            clearScreen();
            printf("Game over!\n");
            printBoard();
            char winner = getWinner();
            if (winner!= ' ') {
                printf("Player %c wins!\n", winner);
            } else {
                printf("It's a draw!\n");
            }
            break;
        }
    }

    return 0;
}

Appelez la fonction initializeBoard pour initialiser le plateau de jeu, en définissant toutes les cases sur des espaces.

Créez une variable entière currentPlayer pour suivre de qui est le tour. Le paramètre initial est 1, indiquant le joueur 1.

Dans la boucle principale while (1) :

  • Appelez la fonction clearScreen pour effacer l'écran afin que l'affichage soit actualisé après chaque tour.
  • Appelez la fonction printBoard pour afficher le plateau de jeu actuel.

Saisie du joueur : Demandez au joueur actuel d'entrer les coordonnées de ligne et de colonne via la fonction scanf, par exemple Player 1, please enter a row and column (e.g., 1 2):. Si la saisie est invalide (pas deux entiers), le message Invalid input, please try again: est affiché et le tampon d'entrée est vidé jusqu'à obtenir une saisie valide.

Validation de la saisie : Ensuite, vérifiez que les coordonnées de ligne et de colonne saisies sont valides (comprises entre 1 et 3) et que la position sélectionnée est un espace. Si la saisie est invalide ou si la position sélectionnée est déjà occupée, le message Invalid move, please try again. est affiché et le joueur est invité à saisir à nouveau.

Placement du pion : Si la saisie est valide, le code place un X ou un O à la position correspondante sur le plateau de jeu en fonction du joueur actuel (1 ou 2).

Détection de la fin du jeu : Le code appelle ensuite la fonction isGameOver() pour vérifier si le jeu est terminé. Si le jeu se termine, l'écran est effacé et un message indiquant que le jeu est terminé est affiché, y compris le gagnant (le cas échéant) ou un match nul.

Résultat du jeu : Si un gagnant est déterminé, le code affichera Player X wins! ou Player O wins!, selon le joueur gagnant. Si aucun gagnant n'est déterminé, le code affichera It's a draw! pour indiquer un match nul.

Compiler et exécuter le projet

Exécutez la commande gcc pour compiler :

cd ~/project
gcc -o tictactoe tictactoe.c
./tictactoe

Démonstration du jeu de morpion

Résumé

Félicitations! Vous avez créé avec succès un simple jeu de morpion en langage C. Les joueurs peuvent jouer à tour de rôle et marquer leurs positions sur une grille de 3x3. Le jeu vérifie s'il y a un gagnant ou un match nul après chaque tour et affiche le résultat en conséquence. Ce projet simple illustre les concepts de base de la programmation en C et peut servir de point de départ pour le développement de jeux plus complexes.

✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer✨ Vérifier la solution et pratiquer