[C++11] Premier programme.
Salut les C++,
je débute vraiment avec le langage C++, environ depuis le début du moi de mai, et je suis loin de tout savoir sur le C++.
A noter que je pratique le C brute depuis plus de 2 ans et que j'ai débuter la programmation avec python il y a 5 ans.
Alors je vous présente, (enfin vous soumet a commenter (RFC)) mon premier mini programme.
Mais avant j'aimerai vous faire partager mon ressentis a propos du langage C++.
Alors m'étant renseigner avant de sauter le pas, il a été dit que le C++ n'est pas un C étendus objet.
Bon d'accord mais ca y ressemble quand ont regarde plus près: les classes n'étant rien d'autres que des structures (très) améliorées et les conteneurs ressemble au ensemble de données que l'on peut trouver en C (arbre, set, listes chainées, etc...)... Ca reste a débattre.
Ce qui me déplait avec le C++ c'est le nombre de mots clefs (keyword) et opérateurs que contient le langage je trouve qu'il y en a trop, chacun a son utilité mais il n'est pas facile de tous les retenir et surtout des exceptions d'utilisation de ceux -ci (je ne trouve pas d'exemple tellement je suis perdu).
Mais assez de bla bla, voici mon premier mini programme en C++:
Il s'agit d'une implémentation du jeu des tours de hanoi:
Au début du jeu sont empiler un nombre donné de disques sur un piquet a gauche, du plus grand en bas au plus petit en haut. Et il y a 2 autres piquets a la droite qui sont vide.
Le but du jeu est refaire une pile croissante sur un des deux piquets autres piquets.
+) En ne déplacant qu'un seule disque a la fois.
+) On ne peut pas empiler un disque plus grand sur un disque plus petit.
Le programme a la structure suivante:
2 classes: Tower et Game.
-+-> Tower.h
|
-+ -> Tower.cpp
|
-+-> Game_Tower.h
|
-+-> Game_Tower.cpp
|
-+-> main.cpp
Voici le fichier Tower.h
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
#ifndef TOWER_H
#define TOWER_H
#include <vector>
#include <string>
class Tower {
int upper_disc_index ;
int upper_disc_value ;
public :
/** Disc container. */
std::vector<int> disc ;
/** Maximum disc number set from the user. **/
int max_disc ;
/** DEBUG Identifier **/
std::string name ;
/** Constructors **/
Tower(int max, std::string n) ;
Tower() ;
/** getters. **/
int get_upper_disc_value() const ;
int get_upper_disc_index() const ;
/** Setters. **/
void set_upper_disc_value(int value) ;
void set_upper_disc_index(int index) ;
/** Check if game finish. **/
int disc_on_tower_count() const ;
/** Validity check. **/
bool is_entry_valid(int to_place_on) const ;
} ;
#endif |
Le fichier Tower.cpp:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
|
#ifndef TOWER_CPP
#define TOWER_CPP
#include "Tower.h"
#include <algorithm>
Tower::Tower(int max, std::string n) : name(n) {
max_disc=max ;
}
Tower::Tower() {} ;
int Tower::get_upper_disc_value() const {
/** Return the tower highest disc value.
**************************************/
return upper_disc_value ;
}
void Tower::set_upper_disc_value(int value) {
/** Set the tower highest disc value.
***********************************/
upper_disc_value=value ;
return ;
}
int Tower::get_upper_disc_index() const {
/** Return the index of the highest valid disc from the tower.
************************************************************/
return upper_disc_index ;
}
void Tower::set_upper_disc_index(int index) {
/** Set the index of the highest valid disc from the tower.
*********************************************************/
upper_disc_index = index ;
return ;
}
int Tower::disc_on_tower_count() const {
/** Count the number of disc onto a tower. **/
return max_disc-count(disc.begin(), disc.end(), 0) ;
}
bool Tower::is_entry_valid(int to_place_on) const {
/** Return if the given disc value is valid according the game rules:
* only a littler disc can be set on a bigger one.
*******************************************************************/
int upper_disc_value = get_upper_disc_value() ;
if ( upper_disc_value > to_place_on || upper_disc_value == 0 ) {
/** Okay or tower empty (=0). **/
return true ;
}
return false ;
}
#endif |
Le fichier Game_Tower.h:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
#ifndef HANOI_TOWER_GAME_H
#define HANOI_TOWER_GAME_H
#include "Tower.cpp"
class Game {
public :
/** The tree towers **/
Tower tower_1 ;
Tower tower_2 ;
Tower tower_3 ;
/** Contructor **/
Game(int max) ;
/** Move a disc onto another tower. **/
bool moving(Tower &from, Tower &to) ;
/** Check if the player win. **/
bool end_game(void) ;
/** Displaying method. **/
void display() ;
/** DEBUG function. **/
friend void display_debug(Game &g) ;
} ;
#endif |
Le fichier Game_Tower.cpp:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
|
#ifndef HANOI_TOWER_GAME_CPP
#define HANOI_TOWER_GAME_CPP
#include "Game_Tower.h"
#include <iostream>
#include <string>
void display_debug(Game &g) {
/** DEBUG function which display the disc values in columns representing the towers. **/
std::cout << std::endl ;
for (int c=0 ; c < g.tower_1.max_disc ; c++) {
std::cout << g.tower_1.max_disc-c << " -> " << g.tower_1.disc[c] << " " << g.tower_2.disc[c] << " " << g.tower_3.disc[c] << std::endl ;
}
std::cout << std::endl ;
}
/** Contructor: **/
Game::Game(int max) : tower_1(max,"tower 1"), tower_2(max,"tower 2"), tower_3(max,"tower 3") { }
bool Game::moving(Tower &from, Tower &to) {
/** Move a disc from a tower onto another if valid disc move. **/
if ( ! to.is_entry_valid(from.get_upper_disc_value())) {
return false ;
}
if (from.disc_on_tower_count() == 0) {
return false ;
}
int to_index = to.get_upper_disc_index() ;
int from_index = from.get_upper_disc_index() ;
/** Move disc: **/
to.disc.at( to_index-1 ) = from.disc.at( from_index ) ;
/** Adjust the indexes. **/
to.set_upper_disc_index(to_index - 1) ;
from.set_upper_disc_index(from_index+1) ;
/** Adjust the values. **/
to.set_upper_disc_value(to.disc.at( to.get_upper_disc_index() )) ;
if (from_index+1 < tower_1.max_disc-1) {
from.set_upper_disc_value( from.disc.at(from.get_upper_disc_index()) ) ;
}
else {
from.set_upper_disc_value(0) ;
}
/** Set the source disc on zero (=0 represent no disc). **/
from.disc.at(from_index) = 0 ;
return true ;
}
bool Game::end_game(void) {
/** Check if the player has terminate the game. **/
int max_disc= tower_1.max_disc ;
if (tower_2.get_upper_disc_value() == 1 && tower_2.disc_on_tower_count() == max_disc) {
return true ;
}
if (tower_3.get_upper_disc_value() == 1 && tower_3.disc_on_tower_count() == max_disc) {
return true ;
}
return false ;
}
void Game::display() {
/** Terminal game playground displaying method. **/
unsigned int max_disc = tower_1.max_disc ;
std::string line_begin_space(3,' ') ;
for (int c=0 ; c < 2 ; c++) {
std::cout << std::endl ;
}
/** We display the towers line after line. **/
for (int c=0 ; c < tower_1.max_disc ; c++) {
std::cout << line_begin_space ;
/** Tower 1: **/
/** Set the disc middle part (represent as '=' sign). **/
std::string side1(tower_1.disc[c],'=') ;
/** Compute the spaces to display. **/
std::string space1(max_disc-tower_1.disc[c]+max_disc/2,' ') ;
/** Set the disc borders or space if empty.**/
std::string side_left1(1, (tower_1.disc[c] == 0) ? ' ' : '<') ;
std::string side_right1(1, (tower_1.disc[c] == 0) ? ' ' : '>') ;
/** Display a line from the first tower. **/
std::cout << space1 << side_left1 << side1 << "!" << side1 << side_right1 << space1 ;
/** Tower 2: **/
/** Set the disc middle part (represent as '=' sign). **/
std::string side2(tower_2.disc[c],'=') ;
/** Compute the spaces to display. **/
std::string space2(max_disc-tower_2.disc[c]+max_disc/2,' ') ;
/** Set the disc borders or space if empty.**/
std::string side_left2(1, (tower_2.disc[c] == 0) ? ' ' : '<') ;
std::string side_right2(1, (tower_2.disc[c] == 0) ? ' ' : '>') ;
/** Display a line from the second tower. **/
std::cout << space2 << side_left2 << side2 << "!" << side2 << side_right2 << space2 ;
/** Tower 2: **/
/** Set the disc middle part (represent as '=' sign). **/
std::string side3(tower_3.disc[c],'=') ;
/** Compute the spaces to display. **/
std::string space3(max_disc-tower_3.disc[c]+max_disc/2,' ') ;
/** Set the disc borders or space if empty.**/
std::string side_left3(1, (tower_3.disc[c] == 0) ? ' ' : '<') ;
std::string side_right3(1, (tower_3.disc[c] == 0) ? ' ' : '>') ;
/** Display a line from the third tower. **/
std::cout << space3 << side_left3 << side3 << "!" << side3 << side_right3 << space3 ;
std::cout << std::endl ;
}
std::cout << std::endl ;
/** Finally we display a number reconizing the towers. **/
/** Compute the amount of space between 2 towers numbers. **/
std::string spaces_tower_side(max_disc+max_disc/2+1,' ') ;
std::cout << line_begin_space ;
for (int c=1 ; c <= 3 ; c++) {
/** Display the towers numbers under the towers. **/
std::cout << spaces_tower_side << c << spaces_tower_side ;
}
std::cout << std::endl ;
for (int c=0 ; c < 2 ; c++) {
std::cout << std::endl ;
}
return ;
}
#endif |
Le fichier main.cpp:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
|
#include <cstdlib>
#include "Game_Tower.cpp"
//#define DEBUG_MATRIX
/** Hanoi tower game:
* usage: game number_of_disc.
*
* To compil with:
*
* $ g++ -o game -Wall -Wextra -std=c++11
*
****************************************/
int main(int argc, char *argv[]) {
if (argc != 2) {
std::cout << "Usage: " << argv[0] << " number of disc" << std::endl ;
exit(EXIT_FAILURE) ;
}
int max_disc ;
if ((max_disc = atoi(argv[1])) <= 0) {
std::cout << "Usage: " << argv[0] << " number of disc" << std::endl ;
exit(EXIT_FAILURE) ;
}
Game game(max_disc) ;
for (int c = 1 ; c < max_disc+1 ; c++) {
/** We create a vector as an array of integer for every tower.
* Ordered at start:
* The biggest disc is down.
* And the littles index is the highest disc in the tower.
***********************************************************/
game.tower_1.disc.push_back(c) ; /** We fill the tower one. **/
game.tower_2.disc.push_back(0) ; /** We fill the tower two. **/
game.tower_3.disc.push_back(0) ; /** We fill the tower three. **/
}
/** We set the upper tower disc value at start. **/
game.tower_1.set_upper_disc_value(1) ;
game.tower_2.set_upper_disc_value(0) ;
game.tower_3.set_upper_disc_value(0) ;
/** We set the upper tower disc index at start. **/
game.tower_1.set_upper_disc_index(0) ;
game.tower_2.set_upper_disc_index(max_disc) ;
game.tower_3.set_upper_disc_index(max_disc) ;
bool end_game = false ;
int round_counter = 1 ;
while (!(end_game)) {
/** Game mainloop. **/
game.display() ;
#ifdef DEBUG_MATRIX
display_debug(game) ;
#endif
int from, to ;
std::cout << "Move From [1-3]...: " ;
while (! (std::cin >> from)) {
/** Getting the source disc moving tower. **/
if (from < 1 || from > 3) {
std::cout << "Invalid move !!!" << std::endl ;
continue ;
}
std::cout << "Invalid entry !!!" << std::endl ;
}
std::cout << "Move to [1-3]...: " ;
while (! (std::cin >> to)) {
/** Getting the destination disc moving tower. **/
if ((to < 1 || to > 3) || (from == to)) {
std::cout << "Invalid move !!!" << std::endl ;
continue ;
}
std::cout << "Invalid entry !!!" << std::endl ;
}
#ifdef DEBUG
std::cout << "From " << from << " To " << to << std::endl ;
#endif
switch (from) {
/** Process disc moving with errors catching. **/
case 1 :
if (to == 2) {
if (! game.moving(game.tower_1, game.tower_2) ) {
std::cout << "Invalid move !!!" << std::endl ;
}
else {
round_counter++ ;
}
}
else if (to == 3) {
if (! game.moving(game.tower_1, game.tower_3) ) {
std::cout << "Invalid move !!!" << std::endl ;
}
else {
round_counter++ ;
}
}
else {
std::cout << "Invalid move !!!" << std::endl ;
}
break ;
case 2 :
if (to == 1) {
if (! game.moving(game.tower_2, game.tower_1) ) {
std::cout << "Invalid move !!!" << std::endl ;
}
else {
round_counter++ ;
}
}
else if (to == 3) {
if (! game.moving(game.tower_2, game.tower_3) ) {
std::cout << "Invalid move !!!" << std::endl ;
}
else {
round_counter++ ;
}
}
else {
std::cout << "Invalid move !!!" << std::endl ;
}
break ;
case 3 :
if (to == 1) {
if (! game.moving(game.tower_3, game.tower_1) ) {
std::cout << "Invalid move !!!" << std::endl ;
}
else {
round_counter++ ;
}
}
else if (to == 2) {
if (! game.moving(game.tower_3, game.tower_2) ) {
std::cout << "Invalid move !!!" << std::endl ;
}
else {
round_counter++ ;
}
}
else {
std::cout << "Invalid move !!!" << std::endl ;
}
break ;
}
end_game=game.end_game() ;
}
game.display() ;
std::cout << "YOU WIN !!!" << std::endl ;
std::cout << "With " << max_disc << " disc in " << round_counter << " rounds !!!" << std::endl ;
return 0 ;
} |
Remarque: je n'ai pas réussis a mettre les instances de Tower de la classe Game dans un conteneur ce qui m'aurai arranger. Il y a avait une erreur quand je récupérais les vector "disc"...???? C'est peut-être du au faîte que Tower est une classe et c'est pour cela qu'il y a un constructeur sans argument déclaré qui ne sert a rien.
Je vous serai grandement reconnaisant de toute aide dans la quête du C++: conseils, conseils de lecture, remarque sur mon code, avis sur mon bout de code etc...
Je suis ouvert a tous et vous remercie pour vos éclaicissement.
Sur ceux bon C++ a vous.