Vous le savez certainement, pour progresser en informatique, il faut pratiquer le plus possible. C'est en forgeant qu'on devient forgeron. Malheureusement il est parfois difficile de trouver des exercices pour travailler un point particulier du langage.
Ce topic a pour but de vous proposer un ensemble d'exercices qui approfondissent des aspects du merveilleux langage qu'est le C++.
Comment ça marche ?
Chacun peut, si l'envie l'en prend, proposer un exercice sur ce topic. Si l'exercice est bien présenté (lisible, et non pas un pavé en fouillis), un lien vers lui sera alors ajouté à ce premier post, de telle sorte qu'il sera aisément accessible.
Je veux proposer un exercice, comment faire ?
Il vous suffit de poster un message sur ce topic, composé uniquement de l'exercice. Penser à respecter les conseils suivants.
Chaque exercice devra être composé de :
Un nom (par lequel il sera identifié) ;
Un groupe, un sujet (pour le classer et accéder plus facilement aux exercices intéressants);
Un énoncé, qui devra être clair et net ;
Les plus :
Un exercice découpé en niveau;
Un exercice sur un sujet encore jamais abordé par les autres exercices;
Une solution proposée dans un autre message (voir plus bas).
Les moins :
Une orthographe déplorable;
Une absence de présentation (le zCode est là pour vous !);
Un énième exercice sur le même sujet;
Un exercice aussi simple qu'un "Hello, World!" : il faut quand même devoir réfléchir un minimum !
Il est à noter que le niveau de difficulté sera apprécié par nos soins, vous n'avez donc pas à en mettre pour proposer vos exercices.
Je souhaite proposer une solution, comment faire ?
Chacun peut proposer la solution à un exercice sur ce topic en postant un message constitué uniquement de la solution. Si elle est bien présentée, un lien vers elle sera alors ajouté à ce premier post, de telle sorte qu'il sera aisément accessible.
Il n'y a pas qu'une seule solution possible ! Vous pouvez parfaitement proposer une solution à un exercice qui en possède déjà une à condition d'être différente de celles déjà proposées !
Chaque solution devra être obligatoirement composée de :
un titre la présentant comme telle;
un lien vers l'exercice en question;
le code source de votre solution qui doit impérativement être compilable et commenté;
des explications sur la correction
la mention [C++11] si vous utilisez cette dernière version du langage
Les composants suivants sont facultatifs mais appréciés :
si l'exercice est découpé en niveau, une solution découpée elle aussi en niveaux;
des conseils pédagogiques;
des idées pour "aller plus loin";
la liste des propriétés du C++11 utilisée.
Les points négatifs :
Une orthographe déplorable;
Une absence de présentation (le zCode est là pour vous !);
Une énième solution sur le même exercice.
Les exercices
Voilà (enfin !) les exercices, classés par sujet. Les exercices de difficulté ? n'ont pas encore été notés. Les noms de langages entre parenthèse à côté d'un lien (ex: (Java)) indique que l'exercice a été proposé sur un autre sujet initialement prévu pour un autre langage, mais dont nous avons estimé que les explications étaient compréhensibles pour un programmeur C++; demandez de l'aide sur ce sujet si vous voulez avoir une réponse en C++ .
Actuellement, ce sont germino et Equinoxe qui s'occupent de ce topic. Ils tiennent régulièrement à jour ce sujet
Vous pouvez les aider en donnant votre avis sur ce sujet ou tout simplement en faisant les exercices dont la difficulté n'a pas été évaluée afin justement de les évaluer correctement
Note : les exercices proposés par Nanoc proviennent d'un sujet lui appartenant.
germino : suppression de la partie Général et répartition de ses composants.
germino : ajout d'un lien vers le sujet méta.
germino : clarification de l'emplacement des exercices.
oui en effet c'est le terme exacte du site du zéro . Moi je me croyait entrain de coder .
A part ca, le plus important c'est de faire des nouveau exos en sortes de concours, et donc faire que l'on envoi les réponses à Exercice cpp ?
Equinoxe : Corrigé la typo (Polinômes >>> Polynômes) annoncée par lmghs.
Equinoxe : Modifié le format de la difficulté, por éviter qu'elle soit considérée comme une note de "qualité".
Equinoxe : Envoyé l'image de difficulté (source) :
Le but de cet exercice est de réaliser le célèbre jeu de Tic-Tac-Toe (appelé Morpion par les incultes ). Si vous ne connaissez pas les règles : Go Wikipédia
Le jeu devra être jouable à 2 joueurs. Les joueurs choisiront chacun leurs tours où placer leurs symboles ("X" pour le joueur 1 et "O" pour le joueur 2). Vous devrez gérer l'affichage d'une grille en console. Je vous propose déjà celle que j'ai utilisé (bien évidemment, vous n'êtes pas obliger de faire la même):
1|2|3
-+-+-
4|5|6
-+-+-
7|8|9
Puis au cours de la partie:
X|2|O
-+-+-
X|O|6
-+-+-
O|X|9
(Ici, le joueur 2 a gagné)
Solution possible
#include <iostream>
using namespace std;
void Printboard(); // Fonction qui affiche la grille
char cSquare[3][3] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'};
int main() {
int iPlayerTurn(1);
bool bGameOver(true);
// Boucle Principal
do {
// Affichage de la grille
Printboard();
// Symbole utilisé par les joueurs: Joueur1='X' Joueur2='O'
char cPlayerMark;
if (iPlayerTurn == 1) {
cPlayerMark = 'X';
} else {
cPlayerMark = 'O';
}
// Demande où le joueur souhaite placer son Symbole
cout << "Player" << iPlayerTurn << "'s move:" << endl;
bool bValidMove;
// Boucle jusqu'à ce que le placement soit valide
do {
char cNextMove;
cin >> cNextMove;
bValidMove = true;
// Vérifie la validité du placement
if (cNextMove == '1' && cSquare[0][0] == '1') {
cSquare[0][0] = cPlayerMark;
} else if (cNextMove == '2' && cSquare[0][1] == '2') {
cSquare[0][1] = cPlayerMark;
} else if (cNextMove == '3' && cSquare[0][2] == '3') {
cSquare[0][2] = cPlayerMark;
} else if (cNextMove == '4' && cSquare[1][0] == '4') {
cSquare[1][0] = cPlayerMark;
} else if (cNextMove == '5' && cSquare[1][1] == '5') {
cSquare[1][1] = cPlayerMark;
} else if (cNextMove == '6' && cSquare[1][2] == '6') {
cSquare[1][2] = cPlayerMark;
} else if (cNextMove == '7' && cSquare[2][0] == '7') {
cSquare[2][0] = cPlayerMark;
} else if (cNextMove == '8' && cSquare[2][1] == '8') {
cSquare[2][1] = cPlayerMark;
} else if (cNextMove == '9' && cSquare[2][2] == '9') {
cSquare[2][2] = cPlayerMark;
} else {
cout << "Invalid Move. Try again." << endl;
bValidMove = false;
}
} while (!bValidMove);
bGameOver = false;
bool bWinGame = true;
// Vérification pour savoir si le jeu est fini
if (cSquare[0][0] != '1') {
if (cSquare[0][1] == cSquare[0][0] && cSquare[0][2] == cSquare[0][0]) {
bGameOver = true;
}
if (cSquare[1][0] == cSquare[0][0] && cSquare[2][0] == cSquare[0][0]) {
bGameOver = true;
}
}
if (cSquare[1][1] != '5') {
if (cSquare[0][0] == cSquare[1][1] && cSquare[2][2] == cSquare[1][1]) {
bGameOver = true;
}
if (cSquare[0][1] == cSquare[1][1] && cSquare[2][1] == cSquare[1][1]) {
bGameOver = true;
}
if (cSquare[1][0] == cSquare[1][1] && cSquare[1][2] == cSquare[1][1]) {
bGameOver = true;
}
if (cSquare[0][2] == cSquare[1][1] && cSquare[2][0] == cSquare[1][1]) {
bGameOver = true;
}
}
if (cSquare[2][2] != '9') {
if (cSquare[0][2] == cSquare[2][2] && cSquare[1][2] == cSquare[2][2]) {
bGameOver = true;
}
if (cSquare[2][0] == cSquare[2][2] && cSquare[2][1] == cSquare[2][2]) {
bGameOver = true;
}
}
// Vérification si la grille est pleine (pas de vainqueurs)
if (cSquare[0][0] != '1' && cSquare[0][1] != '2' && cSquare[0][2] != '3' &&
cSquare[1][0] != '4' && cSquare[1][1] != '5' && cSquare[1][2] != '6' &&
cSquare[2][0] != '7' && cSquare[2][1] != '8' && cSquare[2][2] != '9' && !bGameOver)
{
bGameOver = true;
bWinGame = false;
}
if (bGameOver) {
// Affichage de la grille final
Printboard();
if (bWinGame) {
cout << "Player" << iPlayerTurn << " wins!" << endl;
} else {
cout << "Egalité" << endl;
}
cout << "Game Over!" << endl;
cout << "Play again (y/n)?" << endl;
char cPlayAgain;
cin >> cPlayAgain;
if (cPlayAgain == 'y') {
bGameOver = false;
// Remise à zéro de la grille
cSquare[0][0] = '1';
cSquare[0][1] = '2';
cSquare[0][2] = '3';
cSquare[1][0] = '4';
cSquare[1][1] = '5';
cSquare[1][2] = '6';
cSquare[2][0] = '7';
cSquare[2][1] = '8';
cSquare[2][2] = '9';
}
iPlayerTurn = 1;
} else {
// Changement de joueur
if (iPlayerTurn == 1) {
iPlayerTurn = 2;
} else {
iPlayerTurn = 1;
}
}
} while (!bGameOver);
return 0;
}
void Printboard() {
cout << cSquare[0][0] << "|" << cSquare[0][1] << "|" << cSquare[0][2] << endl;
cout << "-+-+-"<< endl;
cout << cSquare[1][0] << "|" << cSquare[1][1] << "|" << cSquare[1][2] << endl;
cout << "-+-+-"<< endl;
cout << cSquare[2][0] << "|" << cSquare[2][1] << "|" << cSquare[2][2] << endl;
}
Les explications sont dans le code.
PS : J'utilise des noms de variables en Anglais si cela pose problème, je modifierais mon code.
j'ai une idée d'exercice, une sorte de suite de l'exo "fractions" qui permet de gérer les réels (sous forme exacte et simplifiée) mais bon c'est peut être un peut dur pour un exo non ?
EDIT : comme je sais pas trop comment je pourais faire, je laisse juste l'idée et si quelqu'un veut l'exploiter, gogogo
Metallica-z80 ton code est horrible a lire, fait de petites fonctions qui exectuent chacune une tache bien precise. Le main n'est pas la pour contenir tout le programme et au lieu de faire ton:
if (...)
else if(...)
...
...
...
else
de malade tu peux faire une petite fonction et une boucle qui reproduirait exactement la meme chose et ne brulerait pas les yeux de ceux qui lisent ton code.
A la limite, l'OO n'est pas nécessaire, mais simplement déjà changer le code de "rien sur la case" pour ' ', et demander à l'utilisateur une position X, Y ; ça permettrait de :
- Simplifier la suite de "if"
- Clarifier l'affichage d'une partie en cours
De même, il serait possible de clarifier beaucoup de code. J'essaie de faire quelque chose de plutôt joli et je reviens.
@Dumpy: Laisser la réponse ici permettra d'avoir des conseils, et si la solution est bonne, d'avoir un lien pointant vers la solution. Bref, bénéfice pour tout le monde.
J'ai fini le TicTacToe, avec une solution qui me semble plus élégante (la lourdeur étant principalement dans la gestion de la fin de partie) :
#include <iostream>
#include <vector>
typedef std::vector<char> line;
typedef std::vector<line> board;
void display (const board & b);
char the_winner(const board & b);
int main(int, char**) {
char player = 'X', winner;
board tic_tac_toe(3, line(3, ' '));
display(tic_tac_toe);
while ((winner = the_winner(tic_tac_toe)) == '?') {
int x = -1, y = -1;
while (x > 3 || x < 1 || y > 3 || y < 1 || tic_tac_toe[y - 1][x - 1] != ' ') {
std::cout << "Joueur " << player << ", où voulez-vous jouer ?" << std::endl;
std::cout << "X : ";
std::cin >> x;
std::cout << "Y : ";
std::cin >> y;
}
tic_tac_toe[y - 1][x - 1] = player;
display(tic_tac_toe);
player = (player == 'X' ? 'O' : 'X');
}
if (winner == '!') {
std::cout << "Match nul !" << std::endl;
} else {
std::cout << "Le gagnant est le joueur " << winner << " !" << std::endl;
}
return 0;
}
void display(const board & b) {
std::cout << " |1|2|3|" << std::endl;
std::cout << "-+-+-+-+" << std::endl;
std::cout << "1|" << b[0][0] << "|" << b[0][1] << "|" << b[0][2] << "|" << std::endl;
std::cout << "-+-+-+-+" << std::endl;
std::cout << "2|" << b[1][0] << "|" << b[1][1] << "|" << b[1][2] << "|" << std::endl;
std::cout << "-+-+-+-+" << std::endl;
std::cout << "3|" << b[2][0] << "|" << b[2][1] << "|" << b[2][2] << "|" << std::endl;
std::cout << "-+-+-+-+" << std::endl;
}
char the_winner(const board & b) {
char player;
bool found;
// Check lines
for (int l = 0 ; l < 3 ; ++l) { // l = numero de ligne
player = b[l][0];
found = true;
for (int c = 1 ; c < 3 ; ++c) { // c = numero de colonne
if (b[l][c] != player) {
found = false;
break;
}
}
if (found && player != ' ') {
return player;
}
}
// Check columns
for (int c = 0 ; c < 3 ; ++c) {
player = b[0][c];
found = true;
for (int l = 1 ; l < 3 ; ++l) {
if (b[l][c] != player) {
found = false;
break;
}
}
if (found && player != ' ') {
return player;
}
}
// Check diagonal topleft - bottomright
player = b[0][0];
found = true;
for (int i = 1 ; i < 3 ; ++i) {
if (b[i][i] != player) {
found = false;
break;
}
}
if (found && player != ' ') {
return player;
}
// Check diagonal topright - bottomleft
player = b[0][2];
found = true;
for (int i = 1 ; i < 3 ; ++i) {
if (b[i][2 - i] != player) {
found = false;
break;
}
}
if (found && player != ' ') {
return player;
}
// Check ex-aeco - if true, return '!'
found = true;
for (int l = 0 ; l < 3 ; ++l) {
for (int c = 0 ; c < 3 ; ++c) {
if (b[l][c] == ' ') {
found = false;
break;
}
}
if (!found) {
break;
}
}
if (found) {
return '!';
}
// Nothing - return '?'
return '?';
}
Edit : Petite précision : Pour la recherche du gagnant, j'ai préféré conserver un code générique, mais il est évident qu'un listage bruteforce-like pourrait également fonctionner.
@Dumpy:
Chiffre de César :
- La fonction UpToLow pourrait utiliser des caractères, plus compréhensibles que les codes hexa :
- Pourquoi interdire un décalage négatif ? Il pourrait être utilisé pour décrypter simplement.
- Même remarque pour les 'X' au niveau de la fonction crypter - et, d'ailleurs, tout le long du code.
- Il serait possible d'utiliser la fonctions tolower (cctype) pour simplifier le code de UpToLow, par exemple.
- Les lignes 22 à 45 sont vraiment tordues, pourquoi ne pas faire simplement :
char & c = texte[i]; // Référence pour propager automatiquement la modification
if (isupper(c)) c = (((c - 'A') + decalage) % 26) + 'A';
if (islower(c)) c = (((c - 'a') + decalage) % 26) + 'a';
if (isdigit(c)) c = (((c - '0') + decalage) % 10) + '0'; // Retirable, c'est pour crypter aussi les numeros
- La fonction decrypter devrait s'appeller casser
- Il devrait y avoir une fonction decrypter contenant uniquement : crypter(texte,-decalage);
Je dois malheureusement m'arrêter là pour ce soir, à bientôt !
moi ce que j'avait fait, (pour pas m'embéter) c'est un objet Grille, avec un char[3][3] en argument qui prend soit ' ', 'o', 'x'. et ensuite je l'affiche dedans, je fait une méthode qui test si l'utilisateur à gagné (peut largement gagner en performances car l'algoritgme est du style : "je test tout les cas un par un" )
mais sinon ca me paraît le bon plan de faire comme ca.
EDIT :
je l'ai refait (enfin juste la classe) en niveau très basique, le plus propre possible (et j'en ai souffert ) mais j'ai la flemme de coder le main pour le moment . Voici :
grille.h :
#ifndef GRILLE_H
#define GRILLE_H
#include <iostream>
class Grille
{
public:
Grille(char starting = 'o');// génère la grille remplit par défaut par les nombre 1, 2, 3, ..., 7, 8, 9
void afficher();// affiche la grille
void init();// initialise toute les cases de m_grille à ' '
bool playAt(int x, int y = -1);// soit les coordonnées de m_grille, soit un nombre entre 1 et 9
int won();// 0 si personne, 1 si o, 2 si x
char next();
private:
char m_grille[3][3];// la grille
char m_next;// le prochain "joueur" à jouer : 'o' ou 'x'
};
#endif
#include <iostream>
#include <cstdlib>
#include "grille.h"
using namespace std;
int main()
{
Grille g;
int choix = 0;
cout << "bienvenu dans ce Tix-Tac-Toe, voici la grille numérotée" << endl;
g.afficher();
g.init();
while(!g.won())
{
cout << "c'est à '" << g.next() << "' de jouer" << endl;
do
{
choix = 0;
cout << "quel est votre choix '" << g.next() << "' ?" << endl;
cin >> choix;
}while(!g.playAt(choix));
system("clear");// pas sur que c'est portable ...
g.afficher();
}
cout << ((g.won() == 2)?"'o'":"'x'") << "a gagné la partie" << endl;
return 0;
}
le main est absolument facile à faire (si quelqu'un veut le faire) il suffit de faire une boucle puis de faire jouer normalement en testant won() à chaques fois. Si won() = 1 : "'o' à gagné" et si won() = 2 : "'x' à gagné"
EDIT 2 : je devait PITETRE être fatigué mais ca marche tous juste pas (encore un piti pb), je règle ca tout de suite je réactualise le code précédent
EDIT 3 : voila, le seul problème, c'est si on autre choses qu'une lettre, il fait une boucle infinie sans faire le cin ...
Afin d'obtenir un code indépendant de tout Char-set. Et donc qui fonctionne aussi pour les non ascii.Mais je n'ai pas pris en compte les caractères non alpha, c'est réglable en 1 if.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles- ♡ Copying is an act of love.
Effectivement, comme on me l'a fait remarquer mon code est loin d'être le plus propre car je suis encore débutant (~1 mois). (cela reste tout de même une solution possible)
Sinon, merci d'avoir posté des solutions plus propre, ça me permettra sans doute de progresser, surtout en POO.
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Cours de C++ moderne
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.