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 !
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.