IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

mini rpg c/c++


Sujet :

C++

  1. #41
    Membre régulier Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Points : 78
    Points
    78
    Par défaut
    oui mais cela voudrais dire qu'il peut sortir par n'importe quel endroit de la map donc pour contrôler le changement de map cela deviendrait peut-être plus complexe car il pourrait sortir par en haut comme en bas comme à droite ou encore à gauche

  2. #42
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    En effet. Si ça te fait peur, on peut garder les téléporteurs pour l'instant. Dans ce cas, il faut pouvoir en avoir plusieurs par map.

    Ensuite, pour savoir quel téléporteur est le bon, deux solutions: Soit les numéroter, soit les connaître uniquement par leurs coordonnées.

    Ce qui veut déjà dire que ta map doit être plus complexe qu'un simple tableau 2D: Il nous faut une structure à présent:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    struct SWarp {
    	/*ici les coord de départ sur la map courante*/
    	int sourceX;
    	int sourceY;
    	/*Ici, l'identification de la map de sortie: nom, coordonnées, etc.*/
    	int destMapX;
    	int destMapY;
    	/*ici les coordonnees d'arrive sur la map de sortie*/
    	int destX;
    	int destY;
    }
     
    struct SMap {
    	char tiles[10][20];
    	struct SWarp warps[8];
    	char titre[32];
    };
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    struct SMap allMaps[2] = {
    /*Salle (0; 0)*/
    {
    	{	"###################",
    		"#@                #",
    		"#                 #",
    		"#                 #",
    		"#                 #",
    		"#    :            #",
    		"#                 :",
    		"#        +        #",
    		"#                 #",
    		"###################" },
    	{
    		{  5,  5, ??, ??, ??, ?? }, /*Je ne sais pas où ça mène*/
    		{ 19,  6,  1,  0,  0,  6 }  /*La porte à droite*/
    	},
    	"Cuisine Ouest"
    },
    /*Salle (1; 0)*/
    {
    	{
    		"###################",
    		"#                 #",
    		"#                 #",
    		"#                 #",
    		"#       +         #",
    		"#                 #",
    		":                 #",
    		"#                 #",
    		"#                 #",
    		"###################" }, 
    	{
    		{  0,  6,  0,  0, 19,  6 }  /*La porte à gauche*/
    	},
    	"Cellier Est"
    };
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #43
    Membre régulier Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Points : 78
    Points
    78
    Par défaut
    Bon je vais me plonger dans le code et reviendrai vers vous si je ne comprends pas tout car à première vue je vois un peu mais il me reste des points d’interrogation en tout cas merci pour cette réponse

  4. #44
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Note que le champ titre n'est pas un champ nom. Sa valeur est uniquement vouée à être affichée, surtout pas à être utilisée en interne pour identifier la map. Si on veut identifier une map par son nom plutôt que ses coordonnées, il faudra lui donner un champ nom séparé.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #45
    Membre régulier Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Points : 78
    Points
    78
    Par défaut
    Alors voila j'ai deux questions peut-être bête je ne sais pas :

    1er pourquoi 1; 0 et non pas 0; 1 ?

    2eme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    {  5,  5, ??, ??, ??, ?? }, /*Je ne sais pas où ça mène*/
    		{ 19,  6,  1,  0,  0,  6 }  /*La porte à droite*/
    quand il tombe sur ça l’interprète t-il ou pas ?

  6. #46
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Citation Envoyé par devdeb91 Voir le message
    edit : voila peu prés ce que mon code donne pouvais me dire comment palier a se probleme ( les ':' sont les endroit ou on change de map j'en est mis deux pour que vous puissiez comprendre le probleme)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    char Map[2][10][20] = {"###################",
                           "#@                #",
                           "#                 #",
                           "#                 #",
                           "#                 #",
                           "#    :            #",
                           "#                 :",
                           "#        +        #",
                           "#                 #",
                           "###################",
                           "###################",
                           "#                 #",
                           "#                 #",
                           "#                 #",
                           "#       +         #",
                           "#                 #",
                           ":                 #",
                           "#                 #",
                           "#                 #",
                           "###################"
     
                       };
     
    bool Exit = false;
    int inmap = 0;
    int gamespeed = 200;
    int main()
    {
        int y, y2, x, x2;
        while(Exit == false)
        {
            system("cls");
            for(y = 0; y < 10; y++)
            {
                cout << Map[inmap][y] << endl ;
            }
     
            for(y = 0; y < 10; y++)
            {
                for(x = 0; x < 20; x++)
                {
                    switch(Map[inmap][y][x])
                    {
                    case '@':
                    {
                        if(GetAsyncKeyState(VK_UP) != 0)
                        {
                            y2 = y - 1;
                            switch(Map[inmap][y2][x])
                            {
                            case ' ':
                                Map[inmap][y][x] = ' ';
                                y--;
                                Map[inmap][y2][x] = '@';
                                break;
                            }
                        }
     
                        if(GetAsyncKeyState(VK_DOWN) != 0)
                        {
                            y2 = y + 1;
                            switch(Map[inmap][y2][x])
                            {
                            case ' ':
                                Map[inmap][y][x] = ' ';
                                y++;
                                Map[inmap][y2][x] = '@';
                                break;
                            }
                        }
     
                        if(GetAsyncKeyState(VK_LEFT) != 0)
                        {
                            x2 = x - 1;
                            switch(Map[inmap][y][x2])
                            {
                            case ' ':
                                Map[inmap][y][x] = ' ';
                                x--;
                                Map[inmap][y][x2] = '@';
                                break;
                            case ':':
                                Map[inmap][y][x] = ' ';
                                x = 17;
                                inmap--;
                                Map[inmap][y][x] = '@';
                                break;
                            }
                        }
     
                        if(GetAsyncKeyState(VK_RIGHT) != 0)
                        {
                            x2 = x + 1;
                            switch(Map[inmap][y][x2])
                            {
                            case ' ':
                                Map[inmap][y][x] = ' ';
                                x++;
                                Map[inmap][y][x2] = '@';
                                break;
                            case ':':
                                Map[inmap][y][x] = ' ';
                                x = 1;
                                inmap++;
                                Map[inmap][y][x] = '@';
                                break;
                            }
                        }
                    }
                    break;
                    }
                }
            }
            Sleep(gamespeed);
        }
        return 0;
    }
    quelques remarques:
    - tu ne devrais pas itérer sur toutes les cases d'une map pour trouver le joueur, tu peux stocker sa position. (Et si d'autres entités doivent bouger, tu peux stocker leurs position aussi.)
    - vu que tu bosses avec un affichage console pour le moment, tu devrais éviter de redessiner la map pour rien (quand rien ne bouge), ça évitera des scintillements.
    - utilise une enum pour différencier tes tiles.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    enum TileType {
      TT_EMPTY,
      TT_PLAYER,
      TT_WARP,
      etc...
    };
    ça t'évitera des erreurs du à des fautes de frappes et rendra le code plus clair. Tu auras juste à "convertir" ça lors de l'affichage, par exemple avec une fonction du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    inline char charFromTile(TileType tp) {
      switch(tp) {
      case TT_EMPTY: return ' ';
      case TT_PLAYER: return '@';
      etc..
    }
    edit:
    Citation Envoyé par devdeb91 Voir le message
    2eme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    {  5,  5, ??, ??, ??, ?? }, /*Je ne sais pas où ça mène*/
    		{ 19,  6,  1,  0,  0,  6 }  /*La porte à droite*/
    quand il tombe sur sa l’interprète t'il ou pas ?
    Si tu te poses la question des "??", non, c'est à toi de les remplacer par les bonnes valeurs

  7. #47
    Membre régulier Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Points : 78
    Points
    78
    Par défaut
    À première vue j'ai pas trop capté mais je vais relire et relire jusqu’à comprendre

    edit:

    Citation Envoyé par Iradrille Voir le message
    Si tu te poses la question des "??", non, c'est à toi de les remplacer par les bonnes valeurs
    non je pose la question avec les valeurs déjà entrées pas ceux avec les "??"

  8. #48
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Citation Envoyé par devdeb91 Voir le message
    non je pose la question avec les valeur deja entrer pas ceux avec les "??"
    Quand le joueur arrive sur une case, tu compare sa position avec les positions de départ dans la liste de wrap de la map, si tu trouves la position du joueur dans la liste alors tu le déplaces à la position d'arrivée dans la map d'arrivée.

  9. #49
    Membre régulier Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Points : 78
    Points
    78
    Par défaut
    Donc si je te suis bien quand je vais déplacer le joueur sur la case et que le programme va voir cela
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    { 19,  6,  1,  0,  0,  6 }  /*La porte à droite*/
    il va interpréter toute les informations et changer de map

  10. #50
    Membre régulier Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Points : 78
    Points
    78
    Par défaut
    bon alors je suis parti sur la structure de médinoc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    struct SWarp {
    	/*ici les coord de départ sur la map courante*/
    	int sourceX;
    	int sourceY;
    	/*ici, l'identification de la map de sortie: nom, coordonnées, etc.*/
    	int destMapX;
    	int destMapY;
    	/*ici les coordonnees d'arrive sur la map de sortie*/
    	int destX;
    	int destY;
    };
     
    struct SMap {
    	char tiles[10][20];
    	struct SWarp warps[8];
    	char titre[32];
    };
     
    struct SMap allMaps[2] = {
    /*Salle (0; 0)*/
    {
    	{	"###################",
    		"#@                #",
    		"#                 #",
    		"#                 #",
    		"#                 #",
    		"#                 #",
    		"#                 :",
    		"#        +        #",
    		"#                 #",
    		"###################" },
    	{
    		//{  5,  5, ??, ??, ??, ?? }, /*Je ne sais pas où ça mène*/
    		{ 19,  6,  1,  0,  0,  6 }  /*La porte à droite*/
    	},
    	"Cuisine Ouest"
    },
    /*Salle (1; 0)*/
    {
    	{
    		"###################",
    		"#                 #",
    		"#                 #",
    		"#                 #",
    		"#       +         #",
    		"#                 #",
    		":                 #",
    		"#                 #",
    		"#                 #",
    		"###################" },
    	{
    		{  0,  6,  0,  0, 19,  6 }  /*La porte à gauche*/
    	},
    	"Cellier Est"
    }
    };
    mais une chose reste en parti un peu flou donc si quelqu'un peu m'expliquer cela serai merveilleux. la parti flou est le changement de map je comprend pas tout ?

    edit : alors j'ai bidouiller un peu pour faire en sorte d'utiliser la structure et voila le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #include <iostream>
    #include <windows.h>
     
    using namespace std;
     
    struct SWarp {
    	/*ici les coord de départ sur la map courante*/
    	int sourceX;
    	int sourceY;
    	/*ici, l'identification de la map de sortie: nom, coordonnées, etc.*/
    	int destMapX;
    	int destMapY;
    	/*ici les coordonnees d'arrive sur la map de sortie*/
    	int destX;
    	int destY;
    };
     
    struct SMap {
    	char tiles[10][20];
    	struct SWarp warps[8];
    	char titre[32];
    };
     
    struct SMap allMaps[2] = {
    /*Salle (0; 0)*/
    {
    	{	"###################",
    		"#@                #",
    		"#                 #",
    		"#                 #",
    		"#                 #",
    		"#                 #",
    		"#                 :",
    		"#        +        #",
    		"#                 #",
    		"###################" },
    	{
    		//{  5,  5, ??, ??, ??, ?? }, /*Je ne sais pas où ça mène*/
    		{ 19,  6,  1,  0,  0,  6 }  /*La porte à droite*/
    	},
    	"Cuisine Ouest"
    },
    /*Salle (1; 0)*/
    {
    	{
    		"###################",
    		"#                 #",
    		"#                 #",
    		"#                 #",
    		"#       +         #",
    		"#                 #",
    		":                 #",
    		"#                 #",
    		"#                 #",
    		"###################" },
    	{
    		{  0,  6,  0,  0, 19,  6 }  /*La porte à gauche*/
    	},
    	"Cellier Est"
    }
    };
     
    bool Exit = false;
    int inmap = 0;
    int gamespeed = 200;
    int main()
    {
        int y, y2, x, x2;
        while(Exit == false)
        {
            system("cls");
            for(y = 0; y < 10; y++)
            {
                cout << allMaps[inmap].tiles[y] << endl ;
            }
     
            cout << allMaps[inmap].warps->sourceX << endl;
     
            for(y = 0; y < 10; y++)
            {
                for(x = 0; x < 20; x++)
                {
                    switch(allMaps[inmap].tiles[y][x])
                    {
                    case '@':
                        {
                            if(GetAsyncKeyState(VK_UP) != 0)
                            {
                                y2 = y - 1;
                                switch(allMaps[inmap].tiles[y2][x])
                                {
                                case ' ':
                                    allMaps[inmap].tiles[y][x] = ' ';
                                    y--;
                                    allMaps[inmap].tiles[y2][x] = '@';
                                    break;
                                }
                            }
     
                            if(GetAsyncKeyState(VK_DOWN) != 0)
                            {
                                y2 = y + 1;
                                switch(allMaps[inmap].tiles[y2][x])
                                {
                                case ' ':
                                    allMaps[inmap].tiles[y][x] = ' ';
                                    y++;
                                    allMaps[inmap].tiles[y2][x] = '@';
                                    break;
                                }
                            }
     
                            if(GetAsyncKeyState(VK_LEFT) != 0)
                            {
                                x2 = x - 1;
                                switch(allMaps[inmap].tiles[y][x2])
                                {
                                case ' ':
                                    allMaps[inmap].tiles[y][x] = ' ';
                                    x--;
                                    allMaps[inmap].tiles[y][x2] = '@';
                                    break;
                                case ':':
                                    inmap = allMaps[inmap].warps->destX;
                                    x = allMaps[inmap].warps->sourceX;
                                    y = allMaps[inmap].warps->sourceY;
                                    break;
                                }
                            }
     
                            if(GetAsyncKeyState(VK_RIGHT) != 0)
                            {
                                x2 = x + 1;
                                switch(allMaps[inmap].tiles[y][x2])
                                {
                                case ' ':
                                    allMaps[inmap].tiles[y][x] = ' ';
                                    x++;
                                    allMaps[inmap].tiles[y][x2] = '@';
                                    break;
                                case ':':
                                    inmap = allMaps[inmap].warps->destX;
                                    x = allMaps[inmap].warps->sourceX;
                                    y = allMaps[inmap].warps->sourceY;
                                    break;
                                }
                            }
                        }
                        break;
                    }
                }
                //Sleep(gamespeed);
            }
        }
        return 0;
    }
    seul petit bémol il ne change pas de map va savoir pourquoi je travail encore dessus n'hesiter pas a me dire si vous avez la raison du pourquoi merci

    edit : non finalement erreur de ma part il change bien de map juste petit probleme a regler encore je tiens au courant

  11. #51
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    D'abord, une petite correction...

    Contrairement à C, lorsque tu définis une structure, une union, une énumération ou une classe en C++, tu déclare automatiquement un type dont l'identifiant est celui de la structure, de l'union, de l'énumération ou de la classe en question.

    Il est donc tout à fait inutile de répéter le mot clé struct (ou enum, ou union ou encore class) lorsque tu veux utiliser le type en question comme membre d'une autre classe ou structure (ou union).
    le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct SMap {
    	char tiles[10][20];
    	struct SWarp warps[8];
    	char titre[32];
    };
    serait donc avantageusement remplacé par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct SMap {
    	char tiles[10][20];
    	SWarp warps[8];
    	char titre[32];
    };
    et le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct SMap allMaps[2] = { /*...*/
    peut (doit ) s'écrire sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     SMap allMaps[2] = { /*...*/
    et, dans la même veine, tant qu'on y est:
    avec le code
    tu force ta map à une taille fixe et définitive.

    Cela peut être une solution, mais je te donne mon billet qu'elle t'embêtera très rapidement, soit parce que tu voudra un jour créer un couloir de deux cases de large, soit parce que tu voudra un jour créer une "méga salle" de 20*40

    L'idéal est sans doute de fournir une valeur pour le nombre de colonnes et une autre le nombre de lignes, et de travailler avec un tableau de (nombre de lignes * nombre de colonnes) éléments.

    Il "suffit" de travailler avec la formule index = numéro de ligne * nombre de colonnes + numéro de colonnes pour récupérer l'index auquel correspond la case se trouvant à la ligne (numéro de ligne) et à la colonne (numéro de colonne).

    Si tu travailles avec la classe vector, fournie par le standard dans l'espace de noms std par simple inclusion du fichier d'en-tête <vector>, tu auras l'occasion de travailler avec des map de n'importe quelle taille sans avoir à t'inquiéter de quoi que ce soit en terme d'espace mémoire dynamique

    De même avec le code
    tu force chaque map à avoir systématiquement 8 téléporteurs, ni moins, ni (et surtout pas!!!!) plus.

    Cela peut finir par poser quelques problèmes : certaines map ont peut etre des portes, mais pas de télé-porteurs du tout, et tu pourrais même envisager une "salle des télé-porteurs" qui te permet d'accéder à n'importe quelle map existante, ou que sais-je, mais qui nécessite d'avoir bien plus de 8 télé-porteurs

    Encore une fois, le fait de pouvoir avoir "n'importe quel nombre de télé-porteurs" peut s'avérer intéressant, et la classe vector pourrait t'aider énormément à ce sujet

    Enfin, la ligne
    pose aussi problème, car elle place une limite tout à fait artificielle au nombre de caractères que tu peux afficher (en l’occurrence, 31 vu qu'il y a le '\0' terminal)

    Encore une fois, le standard vient à ta rescousse en fournissant la classe string, disponible dans l'espace de noms std par simple inclusion du fichier <string> qui est la classe à préférer à toute autre solution pour représenter une chaine de caractères.

    Au final, ta structure SMap devrait sans doute ressembler à quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    struct SMap {
            size_t rows;
            size_t cols
    	std::vector<unsigned char> tiles;
    	std::vector<SWrap> wraps;
    	std::string title;
            /* et, comme on peut travailler en orienté objets, on peut rajouter
             * une fonction membre qui renvoie le caractère qui se trouve en X,Y ;)
             */
           const unsigned char tileAt(size_t x, size_t y) const
           {return tiles_[y*cols + x];}
           /* et la même chose avec une Position (sait on jamais ;)) */
           const unsigned char tileAt(Position const & pos)
           {return tileAt(pos.x(), pos.y());}
    };
    En plus, le fait de coder les maps en "dur" (comprends: directement dans ton code) va te poser de très sérieux problèmes, dans le sens où tu devra systématiquement re compiler ton jeu chaque fois que tu voudra, par exemple, rajouter un mur ou une porte (et je ne te parle pas des problèmes que tu auras si tu veux carrément rajouter toute une map ).

    L'idéal est donc de prévoir, dés le départ, la possibilité de gérer un nombre quelconque de maps de dimensions quelconques et composées d'un nombre quelconque de télé-porteurs et de portes, et surtout, de faire en sorte de ne pas avoir à recompiler ton jeu pour que les changements soient pris en compte.

    Et pour cela, il n'y a pas 36 solutions : il faut passer par un (ou plusieurs) fichier(s) qui fournira (fourniront) toutes les indications que tu peux envisager.

    Mais, pour cela, il faut réfléchir un peu à la manière dont on va fournir toutes les informations, pour pouvoir déterminer comment on peut les charger (et pourquoi pas, les sauvegarder, si d'aventure tu décide de créer un "éditeur de cartes" )

    Le "monde" pourrait très bien etre subdivisé en différentes cartes selon un système proche de l'image ci-jointe sur laquelle chaque rectangle de couleur correspond à une carte particulière et les nombres séparés par des virgule (la première ligne dans chaque rectangle ) correspond aux coordonnées du coin supérieur gauche de la carte dans le monde. (Bon, ce n'est pas fait à l'échelle, mais ca te permettra de comprendre le principe )

    Si tu associe pour chaque carte les coordonnées et un nom de fichier, tu peux charger une bonne fois pour toute une table d'équivalence entre les coordonnées et le fichier qui correspond à la carte à laquelle tu dois accéder.

    Cela pourrait se faire avec un simple fichier texte proche de
    world.txt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    0 0 rouge.txt
    25 0 jaune.txt
    45 0 vert.txt
    0 25 gris.txt
    45 31 bleu.txt
    (j'ai choisi des noms de fichiers correspondant aux couleurs employées, mais tu peux choisir n'importe quoi hein )

    Chaque fois que tu réduis l'espace où "vivent les koalas" en créant une carte supplémentaire, il te "suffit" de rajouter les coordonnées de son coin supérieur gauche et le nom du fichier qui en donne la description. Simple et efficace

    Tu pourrait envisager charger cette liste sous la forme d'un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::map<Position, std::string> maplist;
    où la classe Position serait proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    class Position
    {
        public:
            Position(int x, int y):x_(x), y_(y){}
            int x() const{return x_;}
            int y() const{return y_;}
        private:
            int x_;
            int y_;
    };
    /* Pour pouvoir utiliser la std::map, on a besoin de l'opérateur de 
     *comparaison <
     *
     */
    bool oprtator <(Position const & first, Position const & second)
    {
        return first.x() < second.x() ||
                  (first.x() == second.x() && first.y() < second.y() );
    }
    /* et, tant qu'à faire, te l'opérateur de comparaison == (pour d'autres
     * usages ultérieurs, très certainement ;)
     */
    bool oprtator ==(Position const & first, Position const & second)
    {
        return first.x() == second.x() && first.y() == second.y() );
    }
    Le chargement pourrait prendre la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    void loadMapList(std::map<Position, std::string> & toFill)
    {
        std::ifstream ifs("world.txt");
        int x;
        int y;
        std::string filename;
        while(ifs>>x>>y>>filename)
        {
            toFill.insert(std::make_pair(Position(x,y),filename);
        }
    }
    int main()
    {
        std::map<Position, std::string> maplist;
        loadMapList(maplist) ;
        /* tout le reste vient ici ;) */
        return 0;
    }
    En fait, l'idée est simple: chaque fois que tu arrives sur un télé-porteur, tu cherches dans maplist (selon mon exemple) le nom du fichier qui correspond aux coordonnées destMapX et destMapY de la structure SWarp.

    Ce nom de fichier correspond au nom de fichier qu'il faut charger pour obtenir la carte en question

    Evidemment, ca signifie que tu dois prévoir un format qui permette de représenter une carte.

    Je te proposerais bien:
    sur la première ligne, le nombre de lignes et le nombre de colonnes qui composent la carte, séparés par un espace
    sur les (nombre de lignes) suivante, les (nombre de colonnes) qui correspondent à la topologie de la carte
    juste après, nous aurions le nombre de télé-porteurs suivi
    des informations relatives aux portes et télé-porteurs (après tout, y a pas des masses de différences entre les deux , et, enfin, le titre à afficher.

    En respectant les conventions de ton propre code, la carte rouge pourrait ressembler à quelque choses comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    50 25 // 50 linges, 25 colonnes
    ########################
    #                      #
    #                    # #
    ###                  # #
    #@#######            # #
    # #   # #            # !
    # # # # #            ###
    # # # #                #
    #   # # #              #
    ##### # #              #
    #   #   #              #
    # # #####              #
    # # #                  #
    ### ################# ##
    #   # #   #   #   # #  #
    # ##### # # # # # # #  #
    # #   # # # # # # # #  #
    # # # # # # # # # # #  #
    # # # # # # # # # # #  #
    # # # # # # # # # # #  #
    # # # # # # # # # # #  #
    # # # # # # # # # # #  #
    # # # # # # # # # # #  #
    # # # # # # # # # # #  #
    #   #   #   #   #   #  #
    ################## ### #
    #                      #
    #                      #
    #                      #
    #                      #
    #                      #
    #                      #
    #                      #
    #                      #
    #                      #
    #                      #
    #                      #
    #                      #
    #                      #
    #                      #
    #                      #
    #                      #
    #                      #
    #                      #
    #                      #
    #                      #
    #                      #
    #                      #
    #                      #
    ########################
    3 // 3 portes ou télé-porteurs
    25 6 25 0 6 0 //la porte en 6,25 mène à la carte jaune (25,0) en position 6,0
    2 5 45 31 50 50 // le télé-porteur en 2,5 mène à la carte bleue (45,31) en position 50,50
    5 50 0 50 5 0 // la porte en 5,50 mène à la carte grise (0, 50) en position 5,0
    desert
    (en fait, ce qui suit les // n'apparait pas dans le fichier, je les ai juste rajoutés pour que tu comprennes de quoi il s'agit

    Et tu aurais un code pour charger ta map proche de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    void loadMap(SMap & map, std::string const & filename)
    {
        map.tiles.clear(); //supprime les informations de la map précédante
        map.wraps.clear();
        stdifstream ifs(filename);
        size_t rows;
        size_t cols;
        ifs>>rows>>cols;
        for(size_t y = 0; y <rows; ++y)
        {
            for(size_t x = 0; x <cols; ++x)
            {
               char c;
               ifs>>c;
               map.tiles.push_back(c);
            }
        }
        int wrapCount;
        ifs>>wrapCount;
        for(int i = 0; i< wrapCount;++i)
        {
             SWrap wrap;
             ifs>>wrap.sourceX>>wrap.sourceY
                >>wrap.destMapX>>wrap.destMapY
                >>wrap.destX>>wrap.destY;
            map.wraps.push_back(wrap);
        }
        ifs>>map.title;
    }
    // modifions la fonction main pour commencer dans la carte rouge
     
    int main()
    {
        std::map<Position, std::string> maplist;
        loadMapList(maplist) ;
        auto it= maplist.find(Position(0,0));
        SMap map;
        loadMap(map, it.second);
        return 0;
    }
    NOTA: tu devras peut etre prévoir quelque chose pour valider le format du fichier que tu lis, histoire de t'assurer que les données lues soient correctes, mais je ne vais quand meme pas tout faire pour toi

    Bon, j’atteins de nouveau la taille d'un roman avec mon intervention, je vais donc m'arrêter là, histoire de te laisser le loisir de digérer tout cela

    Hope it helps
    Images attachées Images attachées  
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  12. #52
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Euh, je ne sais pas pourquoi, je me croyais en C...
    Quant aux zones de taille fixe, je raisonnais en termes de fichiers binaire et de localité mémoire totale (donc, pas de char*). Mais tu avais parfaitement raison sur le fait d'avoir besoin d'indiquer le nombre de téléporteurs.

    @devdeb91: C'est à toi d'écrire le code pour interpréter les téléporteurs; personnellement, j'avais juste défini la structure.
    Quand le joueur tombe sur un ':', le code doit parcourir la liste de warps de la map courante pour trouver le bon à partir de ses coordonnées (en gros, une bète recherche linéaire dans le tableau de 8). Puis, charger la map de destination si elle est différente, et déplacer le perso.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  13. #53
    Membre régulier Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Points : 78
    Points
    78
    Par défaut
    @koala01 :
    bon j'avoue que j'ai lâché en cours de route mais je vais relire et relire jusqu’à comprendre merci a toi

    edit : alors voila quelques questions toutes bêtes

    est on obliger de utiliser size_t peut on plutot ne pas utiliser int ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    const unsigned char tileAt(size_t x, size_t y) const
           {return tiles_[y*cols + x];}
    est on obliger de utiliser des unsigned et const car j'avoue ne jamais utiliser ceux la ?
    en quoi consiste les instruction entre {} car je n'est jamais vue cette façon de coder ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::map<Position, std::string> maplist;
     toFill.insert(std::make_pair(Position(x,y),filename);
    est il vraiment obliger des fonction comme map ou make_pair car j'avoue ne pas m'y connaitre au point de les connaitre a vrai dire c'est la première fois que je les vois

  14. #54
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    1. Size_t est le type conseillé pour les tailles et indices de tableau.
    2. Pour le coup des unsigned char, je ne suis pas convaincu. Pour const, oui tu vas l'utiliser, tu vas le voir tous les jours et tu vas apprendre à l'aimer. La const-correctness est indispensable quand on bosse ainsi à bas niveau, sans filet.
      • Par contre, un type de retour par valeur const, je ne vois pas trop à quoi ça sert.
    3. std::map est vachement utile. make_pair on peut peut-être s'en passer, je n'ai pas l'habitude de l'utiliser.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  15. #55
    Membre régulier Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Points : 78
    Points
    78
    Par défaut
    Dans ce cas la pourriez vous m'expliquer a quoi sert std::map car j'ai beau lire sur internet cela ne m'apporte pas grande info

  16. #56
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    std::map is a sorted associative container that contains key-value
    pairs with unique keys.
    Source: http://en.cppreference.com/w/cpp/container/map

    Qu'est-ce que tu ne comprends pas dans cette phrase?

    Un conteneur associatif associe une clee a une ou plusieurs valeur. Dans le cas de std::map, c'est une clee et une valeur.


    Citation Envoyé par Medinoc
    std::map est vachement utile. make_pair on peut peut-être s'en passer, je n'ai pas l'habitude de l'utiliser.
    make_pair() permet just de ne pas avoir a specifier les types des elements du constructeur de std::pair.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mon_index.insert( std::pair< int, std::string >( clee, valeur ) );
    deviens

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mon_index.insert( std::make_pair( clee, valeur ) );
    Ce qui est donc beaucoup plus facile a ecrire et lire dans du code generique, ou meme en general. Mais sinon ces deux codes sont equivalents (a ce que je sache).

  17. #57
    Membre régulier Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Points : 78
    Points
    78
    Par défaut
    Citation Envoyé par Klaim Voir le message
    Source: http://en.cppreference.com/w/cpp/container/map

    Qu'est-ce que tu ne comprends pas dans cette phrase?

    Un conteneur associatif associe une clee a une ou plusieurs valeur. Dans le cas de std::map, c'est une clee et une valeur.

    dans ce cas la
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::map<Position, std::string> maplist;
    position est la clé et étant une class

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class Position
    {
        public:
            Position(int x, int y):x_(x), y_(y){}
            int x() const{return x_;}
            int y() const{return y_;}
        private:
            int x_;
            int y_;
    };
    il associe sa a une chaine si je comprend bien ?

  18. #58
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Position
    {
        public:
            Position(int x, int y):x_(x), y_(y){}
            int x() const{return x_;}
            int y() const{return y_;}
        private:
            int x_;
            int y_;
    };
    Han s'te révélation *_*
    A chaque fois que je vois un post partant de sémantique d'entité vs sémantique de valeur je me sens con car c'est un concept fondamental, mais il y a quelques semaines / mois, j'avais jamais entendu ces 2 termes.

    Et la, en lisant ça, je me disais que j'aurais codé ça un peu différemment (sans vouloir relancer un énième débat sur les getters )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct Position {
       const int x, y;
       Position(int x, int y): x(x), y(y) { }
    };
    Bref je me rend compte qu'en fait même sans connaitre ces termes je faisait déjà la différence entre les 2, j'utilise des class pour les entités, des struct pour les valeurs.
    C'est une pratique courante ? (car j'ai forcément appris ça quelques part...)

    Citation Envoyé par devdeb91 Voir le message
    dans ce cas la
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::map<Position, std::string> maplist;
    position est la clé et étant une class
    il associe sa a une chaine si je comprend bien ?
    Voila, ici la Position est la position d'une map dans "le monde" (Ou une grande map, regroupant toute les autres), et le string est le nom du fichier contenant la définition de cette map.

  19. #59
    Membre régulier Avatar de devdeb91
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2013
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2013
    Messages : 246
    Points : 78
    Points
    78
    Par défaut
    oh merci iradrille tu est mon sauveur voila ce que j'attendais. Là ça parait plus clair mais largement plus clair ça m'enlève déjà un blocage

    edit: bon au point de paraitre lourd ( je vous l'accorde ) je vais quand même demander
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void loadMap(SMap & map, std::string const & filename)
    ici aussi map est utilisé mais pas de la même syntaxe donc comment je dois interprété cette ligne (en langage humain)

  20. #60
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    D'abord, excusez cette réponse tardive, mais, étant nouvellement papa, je passe encore pas mal de temps à l'hopital
    Citation Envoyé par devdeb91 Voir le message
    bon j'avoue que j'ai laché en cours de route mais je vais relire et relire jusqu'a comprendre merci a toi
    C'est le problème des romans, ils contiennent un tas d'informations qu'il faut arriver à digérer

    Mais n'hésite pas à demander des précision sur ce qui pose problème
    edit : alors voila quelque question toute bete
    est on obliger de utiliser size_t peut on plutot ne pas utiliser int ?
    En fait, size_t est un alias de type (un bête typedef en sommes ) sur un type non signé (donc dont la valeur minimal est 0) qui permet au minimum de représenter "n'importe quelle adresse accessible par le système".

    Comme il n'est vraiment pas conseillé d'utiliser un index négatif, le fait d'utiliser un entier non signé nous évite déjà ce genre de problème.

    De plus, size_t est le type que renvoient certaines fonctions membres de pas mal de classes de la S(T)L, comme size() pour les différentes collections ou encore find_X_X_X pour la std::string.

    Le fait d'utiliser directement le bon type pour chaque usage permet d'éviter:
    1. un avertissement du compilateur (s'il est bien réglé) qui pourrait en fait dégénérer en
    2. un problème du à un dépassement de valeur (si tu utilises un type dont la fourchette de valeur est inférieure à celle à laquelle tu veux la comparer, par exemple)
    Bref, cela t'évitera surement pas mal de soucis et de bugs "difficilement compréhensibles"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    const unsigned char tileAt(size_t x, size_t y) const
           {return tiles_[y*cols + x];}
    est on obliger de utiliser des unsigned et const car j'avoue ne jamais utiliser ceux la ?
    j'aurais pu renvoyer un char non unsigned, non const...

    Mais le const qui précède unsigned indique que le caractère renvoyé n'a pas vocation à être modifié.

    Cela ne change pas grand chose ici, mais le fait est que, si tu prends l'habitude de déclarer constant tout ce qui n'a pas vocation à être modifié, tu fera du compilateur ton meilleur allié car il se mettra à t'insulter chaque fois que tu te mettras dans une situation où ce qui n'a pas à être modifié risque de l'être

    Par contre, le const qui suit les parenthèses est particulièrement important parce qu'il indique au compilateur que cette fonction s'engage à ne pas modifier l'état de l'objet courent.

    Tu peux sans problème appeler ce genre de fonctions sur des objets non constants (comprends: modifiables), mais tu ne peut appeler que des fonctions membres qui ont pris cet engagement depuis des objets constants (les deux coté d'une même pièce, en fait, qui font que le compilateur se transforme en ton meilleur allié )
    en quoi consiste les instruction entre {} car je n'est jamais vue cette façon de coder ?
    Ben, c'est tout simple...

    tiles est un objet de type std::vector qui n'est (faisons simple ) qu'une collection de type "tableau d'éléments contigus en mémoire".

    Comme tous les tableaux d'élément contigus en mémoire, il est possible d'accéder à un élément donné sur base de son indice dans le tableau (sa "position" dans le tableau si tu préfères).

    Le fait est que le tableau n'a ici qu'une dimension, alors que tu l'aurais sans doute représenté sous la forme d'un tableau à deux dimensions.

    Il n'y a pas de problème quant au nombre d'éléments pour la simple et bonne raison qu'un tableau deux dimensions proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UnType tab2D[linges][colonnes];
    permet de représenter linges*colonnes éléments, et que cela reviens donc tout à fait au même que si l'on créait un tableau sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UnType tab1D[linges*colonnes];
    qui contient lui aussi linges*colonnes éléments.
    Seulement, voilà... tab2D (selon mon premier exemple) est en réalité un tableau de tableau, et c'est pour cela que l'on peut utiliser les deux opérateurs [] l'un à coté de l'autre alors que tab1D est... un tableau, sans plus, et on ne peut donc utiliser qu'un seul opérateur [].

    Par chance, il existe une formule très simple pour convertir l'un en l'autre car si tu veut récupérer l'élément qui se trouve à la Yeme ligne et à la Xeme colonne (l'équivalent de tab2D[Y][X]), il te suffit d'accéder à l'élément qui se trouve à l'indice Y*(nombre de colonnes) + X dans tab1D.

    Le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    {return tiles_[y*cols + x];}
    ne fait rien d'autre qu'appliquer cette formule

    Mais peut etre es tu surtout étonné de voir l'implémentation de la fonction membre directement dans la définition de la classe

    En fait, il faut savoir qu'il est totalement légal de le faire (sauf dans un cas particulier), et que je suis un peu flemmard par moment, mais que, en plus, cela a pour résultat de rendre implicitement la fonction inline (autrement dit: cela demande au compilateur de remplacer directement tous les appels à la fonction par le code de la fonction elle-même).

    Cela peut améliorer grandement les performances pour des fonctions très simples, mais le compilateur reste seul juge pour décider de l'opportunité de le faire... ou non.

    Dans le cas présent, la fonction est particulièrement simple (elle se traduit par une ou deux instruction(s) processeur(s) dans le code binaire exécutable) et on a donc la garantie qu'elle sera effectivement inlinée

    Je gagne donc sur les deux tableaux en travaillant de la sorte: je gagne un peu de performances et je me laisse aller à ma flemmardise naturelle en évitant d'avoir à créer un fichier *.cpp "juste pour cela"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::map<Position, std::string> maplist;
     toFill.insert(std::make_pair(Position(x,y),filename);
    est il vraiment obliger des fonction comme map ou make_pair car j'avoue ne pas m'i connaitre au point de les connaitre a vrai dire c'est la premiere fois que je l'est vois
    La fonction make_pair est juste une fonction que j'aime utiliser car elle permet de se faciliter la vie (autrement, tu dois toi-même créer une std :: pair avec les bons types et tout et tout... je trouve cela ch..ant, et moins lisible )
    Citation Envoyé par devdeb91 Voir le message
    dans ce cas la pourriez vous m'expliquer a quoi sert std::map car j'ai beau lire sur internet cela ne m'apporte pas grande info
    en fait map est une classe fournie par le standard, et non une fonction...

    C'est ce que l'on appelle un conteneur associatif qui associe une valeur (la std :: string) à une clé qui permet de retrouver très rapidement la valeur sur base de la clé.

    C'est en fait un arbre binaire équilibré, qui permet une recherche dichotomique qui fait que tu n'a, par exemple, besoin que de 8 comparaisons pour retrouver un élément parmi 255 éléments potentiels
    Citation Envoyé par devdeb91 Voir le message
    dans ce cas la
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::map<Position, std::string> maplist;
    position est la clé et étant une class

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class Position
    {
        public:
            Position(int x, int y):x_(x), y_(y){}
            int x() const{return x_;}
            int y() const{return y_;}
        private:
            int x_;
            int y_;
    };
    il associe sa a une chaine si je comprend bien ?
    Tout à fait
    Citation Envoyé par Iradrille Voir le message
    Han s'te révélation *_*
    A chaque fois que je vois un post partant de sémantique d'entité vs sémantique de valeur je me sens con car c'est un concept fondamental, mais il y a quelques semaines / mois, j'avais jamais entendu ces 2 termes.
    Ca ne m'étonne absolument pas.

    A part les cours de quelques pointures que l'on rencontre sur le forum, il y a très peu de cours (de langue francaise s'entend) où l'on en entende parler, pour être tout à fait honnête

    Et pourtant, cette distinction est particulièrement importante, car elle te permet de déterminer très rapidement ce que tu peux envisager de demander à tes différentes classes... ou non
    Et la, en lisant ça, je me disais que j'aurais codé ça un peu différemment (sans vouloir relancer un énième débat sur les getters )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct Position {
       const int x, y;
       Position(int x, int y): x(x), y(y) { }
    };
    Bref je me rend compte qu'en fait même sans connaitre ces termes je faisait déjà la différence entre les 2, j'utilise des class pour les entités, des struct pour les valeurs.
    C'est une manière de faire qui n'est pas sans fondement
    C'est une pratique courante ? (car j'ai forcément appris ça quelques part...)
    Parles tu de ma pratique ou de la tienne

    Sinon, je crois que c'est surtout une question d'habitude

    Personnellement, j'ai pris l'habitude de limiter l'utilisation des structures à deux domaines:
    1. les structures vides (qui sont, généralement destinée à servir de flag )
    2. les foncteurs, dont je suis très friand

    Et j'utilise les classes dés qu'il s'agit d'un type de donnée pour lesquels j’attends un certain nombre de services (fusse juste le fait de renvoyer la valeur d'un membre )

    Je tiens à préciser qu'il s'agit ici d'une habitude strictement personnelle (quoi que me semble-t-il régulièrement rencontrée ), qui n'est ni plus ni moins justifiable que n'importe quelle habitude du même type.

    Simplement, je trouve que cela permet d'avoir un code cohérent, dans lequel on invoque systématiquement une fonction au départ d'un objet pour en obtenir un service donné .

    Citation Envoyé par devdeb91 Voir le message
    edit: bon au point de paraitre lourd ( je vous l'accorde ) je vais quand meme demander
    Il n'y a jamais de question idiote, il n'y a que les réponses qui le soient

    Ceci dit, tu aurais peut etre pu trouver la réponse dans n'importe quel tutoriel correct

    Mais bon, je suis décidément trop bon, et donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void loadMap(SMap & map, std::string const & filename)
    ici aussi map est utilisé mais pas de la meme syntaxe donc comment je dois interprété cette ligne (en langage humain)
    Cette fonction ne renvoie rien et prend comme arguments
    1. une référence (non constante) sur un objet de type SMap qui sera connu sous le nom de map
    2. une référence constante sur un objet de type std ::string qui sera connu sous le nom de filename
    Alors, comme je présume que tu seras gras si je te laisse en plan avec cette explication, je vais être obligé d'aller un peu plus loin

    Mais, pour que l'explication ait un sens, il me faut commencer par rappeler un point essentiel:

    Sauf indication contraire, les arguments sont passés aux fonctions par singleton, et le passage par valeur occasionne la copie de la variable transmise.

    Le premier résultat est que si la fonction appelée modifie l'argument qu'elle reçoit par valeur, aucune des modifications qu'elle pourrait y apporter ne sera répercutée sur la variable qui a servi d'argument dans la fonction appelante.

    De plus, la copie peut etre particulièrement gourmande en ressource (quant elle est autorisée), tant du point de vue du temps nécessaire à la copie que du point de vue de la mémoire utilisée.

    Il fallait donc trouver le moyen d'éviter cette copie. En C, le seul moyen est de passer un pointeur. mais cela présente quelques désagréments (dont le moindre n'est pas le fait qu'un pointeur puisse être nul).

    En C++, on peut disposer de références. Une référence n'est jamais qu'un "alias" de l'objet auquel elle fait ... (référence ).

    L'énorme avantage (en dehors de la syntaxe pour la manipuler) de la référence est qu'elle référence d'office un objet qui existe (elle offre une garantie de non nullité )

    De plus, comme il s'agit d'un alias, toutes les modifications qui y seront apportées au niveau de la fonction appelée seront automatiquement répercutées dans la fonction appelante (tout comme tout ce qui arrive à devdeb91 t'arrive en réalité à toi ).

    Le deuxième avantage que les références ont sur les pointeurs, c'est qu'elle respectent la constante: si tu informes le compilateur que la référence n'a absolument pas vocation à être modifiée, il est en mesure de s'assurer que tu ne fais rien qui tente de la modifier, et de t'insulter dans le cas contraire.

    C'est la raison pour laquelle je passe la SMap sous la forme d'une référence car le but de la fonction est... de charger (donc de modifier) l'argument connu sous le nom de map, mais que je passe filename sous la forme d'une référence constante , parce qu'il n'y a strictement aucune raison que la fonction essayes de modifier le nom que je lui donne
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Création mini-rpg type bomberman
    Par joonhy dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 20/03/2015, 15h16
  2. mini rpg c++ le retour
    Par devdeb91 dans le forum Débuter
    Réponses: 50
    Dernier message: 14/02/2013, 20h31
  3. Mini RPG representation UML
    Par manserk dans le forum Débuter
    Réponses: 12
    Dernier message: 28/04/2011, 23h13
  4. [RAID] config mini pour mise en place RAID 10
    Par netah25 dans le forum Composants
    Réponses: 4
    Dernier message: 27/01/2005, 16h32
  5. Début de mini moteur 2d
    Par GaldorSP dans le forum DirectX
    Réponses: 8
    Dernier message: 27/12/2004, 14h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo