[c++] demineur sous console

Description

Simple jeu de Démineur qui tourne sous la console.
Je ne l'ai pas du tout optimisé, je voulais juste mettre en application mes quelques connaissances en C++.
Essayez de toujours envoyer une réponse en majuscules à la console ;)

Source / Exemple :


//******************
//*FICHIER MAIN.CPP*
//******************
#include <iostream>
#include <ctime> // Obligatoire
#include <cstdlib> // Obligatoire
#include <string>
#include "fonctions.hh"
#include <fstream>
#include <sstream>
#include <cmath>
#include <vector>
#include <algorithm>

void header()
{
std::cout << "\t\t\t    *************************\n"
             "\t\t\t    *\t     Demineur       *\n"
             "\t\t\t    *\t        By          *\n"
             "\t\t\t    *\t       Zenoo        *\n"
             "\t\t\t    *************************\n" << std::endl;
}

std::string stockagePseudo(std::string nomJoueur)
{
    std::cout << std::endl;
    std::cout << "        ****************************************************************\n"
                 "        *                                                              *\n"
                 "        *                                                              *\n"
                 "        *                                                              *\n"
                 "        *                                                              *\n"
                 "        *                                                              *\n"
                 "        *                                                              *\n"
                 "        *      **      **      **      **      **      **      **      *\n"
                 "        **   **  **  **  Entrez votre pseudo (3 lettres) **  **  **  ***\n"
                 "        *  **      **      **      **      **      **      **      **  *\n"
                 "        *                                                              *\n"
                 "        *                                                              *\n"
                 "        *                                                              *\n"
                 "        *                                                              *\n"
                 "        *                                                              *\n"
                 "        *                                                              *\n"
                 "        ****************************************************************\n" << std::endl;
    std::cin >> nomJoueur;
    std::cout << std::endl;
    return nomJoueur;
}

void menu()
{
    std::cout << "        ****************************************************************\n"
                 "        *                                                              *\n"
                 "        *      **      **      **      **      **      **      **      *\n"
                 "        **   **  **  **  **  **  1. Nouvelle partie  **  **  **  **  ***\n"
                 "        *  **      **      **      **      **      **      **      **  *\n"
                 "        *                                                              *\n"
                 "        *                                                              *\n"
                 "        *      **      **      **      **      **      **      **      *\n"
                 "        **   **  **  **  **  **  2. Regles du jeu**  **  **  **  **  ***\n"
                 "        *  **      **      **      **      **      **      **      **  *\n"
                 "        *                                                              *\n"
                 "        *                                                              *\n"
                 "        *      **      **      **      **      **      **      **      *\n"
                 "        **   **  **  **  **  **  3. Scores*  **  **  **  **  **  **  ***\n"
                 "        *  **      **      **      **      **      **      **      **  *\n"
                 "        *                                                              *\n"
                 "        ****************************************************************\n" << std::endl;
}

void nouveauJeu(int positions[12][12], int positionsIf[12][12]) //positions = chiffres de la grille. positionsIf = vérif si joueur a déjà découvert des cases
{
    std::string nomJoueur("---");
    header();
    nomJoueur = stockagePseudo(nomJoueur);

    //INITIALISATION DES VARIABLES ALEATOIRES
    for (int i(0) ; i<12 ; ++i)
    {
        for (int j(0) ; j<12 ; ++j)
        {
            positions[i][j] = 0;        //Grille initialisée
        }
    }

    int const nbBombes(10);
    int bomb1[nbBombes];
    int bomb2[nbBombes];
    for (int i(0) ; i<10 ; ++i) //Choix des coordonnées des 10 bombes
    {
        bomb1[i] = ((rand() % 9)+1);
        bomb2[i] = ((rand() % 9)+1);
    }

    for (int i(0) ; i<10 ; ++i) // Remplit environnement des 10 bombes
    {
        for (int n(1) ; n<11 ; ++n)
        {
            for (int m(1) ; m<10 ; ++m)
            {
                if (bomb1[i] == m && bomb2[i] == n)
                {
                    ++positions[m-1][n-1];
                    ++positions[m-1][n];
                    ++positions[m-1][n+1];
                    ++positions[m][n-1];
                    positions[m][n]=9;
                    ++positions[m][n+1];
                    ++positions[m+1][n-1];
                    ++positions[m+1][n];
                    ++positions[m+1][n+1];
                }
            }
        }
    }

    for (int i(0) ; i<12 ; ++i)
    {
        for (int j(0) ; j<12 ; ++j)
        {
            positionsIf[i][j] = 0;   //INITIALISATION. Si = 1, on dévoile la case soncernée (sera modifiée par la suite)
        }
    }

    //INITIALISATION DE DIVERSES VARIABLES UTILISEES DANS LA BOUCLE
    std::string reponse("rien");
    bool gain(true); // Si false, perdu
    std::string ligneChoisie("null");  //Servira à stocker la ligne choisie par le joueur
    std::string colonneChoisie("null"); // Servira à stocker la colonne choisie par le joueur
    int ligneChoisieInt(0), colonneChoisieInt(0);
    std::string alphabet("ABCDEFGHIJ"), alphabetMin("abcdefghij"); // Servira à faire le passage entre lettres/chiffres
    int compteurCasesDevoilees(0), pointsGagnes(0);

        //DEBUT BOUCLE AFFICHAGE TABLEAUX EVOLUTION DEMINEUR
    while (gain)
    {
        //INTERFACE GRAPHIQUE
        header();
        std::cout << "        ****************************************************************" << std::endl;
        std::cout << "        *                                                              *" << std::endl;
        std::cout << "        *                      A B C D E F G H I J                     *" << std::endl;
        //Affichage des 10 lignes
        for (int j(10) ; j>0 ; --j)
        {
            if (j == 10)
            {
                std::cout << "        *                   " << j << " ";
            }
            else
            {
                std::cout << "        *                   " << j << "  ";
            }

            for (int i(1) ; i<11 ; ++i)
            {
                affichage(i, j, positions, positionsIf);
                std::cout << " ";
            }
            std::cout << "                    *" << std::endl;
        }
        std::cout << "        *                                                              *" << std::endl;
        std::cout << "        *                                                              *" << std::endl;
        std::cout << "        *                                                              *" << std::endl;
        std::cout << "        ****************************************************************" << std::endl;

        //Si choix précédent = bombe
        if (positions[colonneChoisieInt][ligneChoisieInt] >= 9)
        {
            // Comptage des points
            for (int i(1) ; i<11 ; ++i)
            {
                for (int j(1) ; j<11 ; ++j)
                {
                   if (positionsIf[i][j] == 1)
                   {
                       pointsGagnes += 1000;
                   }
                }
            }
            std::cout << " Perdu ! Vous avez gagne " << pointsGagnes << " points !" << std::endl;
            gain = (false);

            //Stockage du score
            std::string const fichier("scores.txt");
            std::ofstream flux1(fichier.c_str(), std::ios::app);

            if (flux1) //
            {
                flux1 << nomJoueur << " - " << pointsGagnes << std::endl;
            }
            else
            {
                std::cout << "ERREUR: Impossible d'ouvrir le fichier." << std::endl;
            }
        }
        else
        {
            //Si tout le tableau (sauf les bombes) a été dévoilé.
            compteurCasesDevoilees = 0;
            for (int i(1) ; i<11 ; ++i)
            {
                for (int j(1) ; j<11 ; ++j)
                {
                    if (positionsIf[i][j] == 1)
                    {
                        ++compteurCasesDevoilees;
                    }
                }
            }
            if (compteurCasesDevoilees == 92)
            {
                std::cout << "Bravo, vous avez gagne avec 92.000 points !";
                gain = (false);
                pointsGagnes = 92000;

                //Stockage du score
                std::string const fichier("scores.txt");
                std::ofstream flux1(fichier.c_str(), std::ios::app);

                if (flux1)
                {
                    flux1 << nomJoueur << " - " << pointsGagnes << std::endl;
                }
                else
                {
                    std::cout << "ERREUR: Impossible d'ouvrir le fichier." << std::endl;
                }

            }
            else
            {
                // Choix du joueur
                std::cout << "Jouez. (de la forme A1, a1, d10 ou D10)" << std::endl;
                std::cin >> reponse;

                //Reconnaissance de la ligne choisie
                ligneChoisie = reponse.substr(1);

                if (ligneChoisie[0] == 0 )
                {
                    ligneChoisie = ligneChoisie.substr(1);
                }
                else if (ligneChoisie == "10")
                {
                    ligneChoisie = "10";
                }
                else
                {
                    std::cout << "Choix incorrect." << std::endl;
                }

                //Reconnaissance de la colonne choisie
                std::string stringI("null"); // Equivalent de (int i) en string
                int j; // = i+1
                for (int i(0) ; i<10 ; ++i)
                {
                    j = i + 1;
                    stringI = convertInt(j);
                    if (reponse[0] == alphabet[i] || reponse[0] == alphabetMin[i])
                    {
                        colonneChoisie = stringI;
                    }
                }

                colonneChoisieInt=convertString(colonneChoisie);
                ligneChoisieInt=convertString(ligneChoisie);
                // Le prochain tableau affichera la case choisie, car dans le tableau positionsIf, une valeur 1 correspond à un affichage du tableau positions au lieu d'un #.
                positionsIf[colonneChoisieInt][ligneChoisieInt] = 1;
            }
        }
    }
}

void options()
{
    header();
    std::cout << "        ****************************************************************" << std::endl;
    std::cout << "        *                             REGLES                           *" << std::endl;
    std::cout << "        *                                                              *" << std::endl;
    std::cout << "        * Le principe est simple. Comme son nom l'indique, le but du   *" << std::endl;
    std::cout << "        * jeu est de deminer le terrain, symbolise par une grille.     *" << std::endl;
    std::cout << "        * Une fois qu'une zone est decouverte il est possible de       *" << std::endl;
    std::cout << "        * deduire la position des mines par rapport aux indications    *" << std::endl;
    std::cout << "        * chiffrees donnees par les cases mises a jour. En effet ces   *" << std::endl;
    std::cout << "        * cases sont numerotees de 1 a 8. Ce chiffre indique le nombre *" << std::endl;
    std::cout << "        * de mines se trouvant dans les 8 cases entourant celle        *" << std::endl;
    std::cout << "        * contentant le chiffre. De cette maniere on peut (en théorie  *" << std::endl;
    std::cout << "        * du moins) finir le jeu.                                      *" << std::endl;
    std::cout << "        * La partie est terminee lorque vous avez decouvert toutes les *" << std::endl;
    std::cout << "        * mines du terrain, ou si vous avez malencontreusement pose la *" << std::endl;
    std::cout << "        * souris sur une case minee !                                  *" << std::endl;
    std::cout << "        *                                                              *" << std::endl;
    std::cout << "        ****************************************************************" << std::endl;

}

//Affichage des scores
void scores()
{
    //Comptage nb lignes dans fichier scores.txt
    int nbLignes(0);
    nbLignes = nombreLignes();

    int repeto(0); // Variable de répétition dans boucle while
    std::string transit("null"); // variable temporaire
    std::vector<int> tabPoints(nbLignes); // tableau pour stocker les points indiqués dans scores.txt

    //Lecture de scores.txt et copie des points dans le tableau
    std::ifstream chemin("scores.txt");
    if (chemin)
    {
        while(getline(chemin, transit))
        {
            tabPoints[repeto] = convertString(transit.substr(6));
            ++repeto;
        }
    }
    else
    {
        std::cout << "ERREUR: Impossible d'ouvrir le fichier en lecture. (1)" << std::endl;
    }

    //Tableau trié du plus petit au plus grand.
    std::sort (tabPoints.begin(), tabPoints.end());
    //STOCKAGE DES PSEUDOS
    std::string transit2("null"); //Variable de transit
    std::string tabPseudos[nbLignes];
    repeto = 0;
    std::ifstream chemin2("scores.txt");
    if (chemin2)
    {
        while(getline(chemin2, transit2))
        {
            tabPseudos[repeto] = transit2.substr(0,3);
            ++repeto;
        }
    }
    else
    {
        std::cout << "ERREUR: Impossible d'ouvrir le fichier en lecture. (2)" << std::endl;
    }

    //RATTACHEMENT DES PSEUDOS AUX SCORES CORRESPONDANTS
    std::string transit3("null"); // Variable temporaire
    repeto = 0;
    int substrTransit3(0);
    if (chemin)
    {
        while(getline(chemin, transit3))
        {
            substrTransit3 = convertString(transit3.substr(6)); // subsTransit3 = Points de la ligne lue

            for (int i(nbLignes) ; i>0 ; --i)
            {
                if (tabPoints[i] == substrTransit3)
                {
                    tabPseudos[repeto] = transit3.substr(0,3); // Si points de la ligne lue correspondent aux points de la ligne i du tableau des scores, alors on associe le pseudo de la ligne lue au score.
                }
            }
            ++repeto;
        }
    }

    header();
    std::cout << "        ****************************************************************\n"
              << "        *                                                              *\n"
              << "        *      **      **      **      **      **      **      **      *\n"
              << "        **   **  **  **  **  **  **  *SCORES **  **  **  **  **  **  ***\n"
              << "        *  **      **      **      **      **      **      **      **  *\n";
    for (int i(1) ; i<11 ; ++i)
    {
        if (i ==10)
        {
            std::cout << "        *                        " << i << ". " << tabPseudos[nbLignes-i] << " - " << tabPoints[nbLignes-i] << "                       *\n";
        }
        else
        {
            std::cout << "        *                        " << i << ". " << tabPseudos[nbLignes-i] << " - " << tabPoints[nbLignes-i] << "                        *\n";
        }
    }
    std::cout << "        *                                                              *\n"
              << "        ****************************************************************\n" << std::endl;
}

int main()
{
    int const taillepositionsi(12);
    int positions[taillepositionsi][taillepositionsi]; // chiffres de la grille du démineur
    int positionsIf[taillepositionsi][taillepositionsi]; // 1 ou 0, suivant l'utilisation du joueur

    srand(time(0));
    int boucleMenu(0);
    std::string choix("0");

    while (boucleMenu==0) //Repeat de la page d'accueil
    {
        std::cout << std::endl;
        header();
        menu();
        std::cin >> choix;
        std::cin.ignore();

        if (choix=="1")
        {
            boucleMenu=1;
            nouveauJeu(positions, positionsIf);  // Affichage du démineur
            std::cout << " Tapez 0 pour retourner au menu." << std::endl;
            std::cin >> boucleMenu;
        }
        else if (choix=="2")
        {
            boucleMenu=2;
            options();
            std::cout << " Tapez 0 pour retourner au menu." << std::endl;
            std::cin >> boucleMenu;
        }
        else if (choix=="3")
        {
            boucleMenu=3;
            scores();
            std::cout << " Tapez 0 pour retourner au menu." << std::endl;
            std::cin >> boucleMenu;
        }
    }

    return 0;
}

//***********************
//*FICHIER FONCTIONS.CPP*
//***********************
#include "fonctions.hh"

void affichage(int x, int y, int positions[12][12], int positionsIf[12][12])
{

    std::string valeur("0");
    int valeurDouble; // = valeur
    if (positionsIf[x][y] == 0) //Joueur n'a pas encore vérifié cette case
    {
        valeur = "#";
    }
    else if (positionsIf[x][y] == 1) // Joueur a déjà vérifié la case
    {
        valeur = convertInt(positions[x][y]);
    }
    valeurDouble = convertString(valeur);
    if (valeurDouble >= 9)
    {
        valeur = "°";
    }

    std::cout << valeur;
}

std::string convertInt(int number)
{
   std::stringstream ss;//create a stringstream
   ss << number;//add number to the stream
   return ss.str();//return a string with the contents of the stream
}
int convertString (std::string texte)
{
    int entier(0); // Entier de sortie

    std::stringstream convert(texte); // stringstream used for the conversion initialized with the contents of Text

    if ( !(convert >> entier) )//give the value to Result using the characters in the string
    entier = 0;//if that fails set Result to 0
    return entier;
}

int nombreLignes ()
{
    int nombre(0);
    std::ifstream chemin("scores.txt");
    if(chemin)
    {
         //L'ouverture s'est bien passée. On peut donc lire

        std::string lignes;     //Une variable pour stocker les lignes

        while(getline(chemin, lignes))    //Tant qu'on n'est pas a la fin, on lit
        {
            ++nombre;
        }
    }
    else
    {
        std::cout << "ERREUR: Impossible d'ouvrir le fichier en lecture." << std::endl;
    }
    return nombre;
}

//**********************
//*FICHIER FONCTIONS.HH*
//**********************
#ifndef FONCTIONS_H_INCLUDED
#define FONCTIONS_H_INCLUDED
#include <iostream>
#include <ctime> // Obligatoire
#include <cstdlib> // Obligatoire
#include <string>
#include <fstream>
#include <sstream>
#include <cmath>
#include <vector>

//Gère l'affichage du dièse ou du chiffre
void affichage(int x, int y, int positions[12][12], int positionsIf[12][12]);

//Convertit les entiers en strings
std::string convertInt(int number);

//Convertir les strings en entiers
int convertString(std::string texte);

//Compte nombre lignes dans un fichier
int nombreLignes ();

#endif // FONCTIONS_H_INCLUDED

Conclusion :


J'attends vos améliorations :)

N'hésitez surtout pas à m'aider à alléger mon code !

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.