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 :

Associations bouton/armes


Sujet :

C++

  1. #1
    Candidat au Club
    Inscrit en
    Juin 2008
    Messages
    1
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 1
    Points : 2
    Points
    2
    Par défaut Associations bouton/armes
    Hey tout le monde !

    Ça fait déjà quelques mois que je pratique du C++ mais je me considère encore assez débutant (du moins, j'ose penser que ma question est de l'ordre d'un débutant).

    En bref, j'ai des "responses" exécutées à chaque fois qu'un bouton est appuyé sur le menu (dans le jeu), ces réponses servent à donner des armes.

    Voici comment c'est pour le moment:

    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
    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
     
    if( response == "give_ak47" )
    {
    	self.pers[ "xkmod_primary" ] = "ak47_mp";
    	self setClientDvar( "xkmod_cac_primary", "menu_mp_weapons_ak47" );
    }
    else if( response == "give_commando" )
    {
    	self.pers[ "xkmod_primary" ] = "commando_mp";
    	self setClientDvar( "xkmod_cac_primary", "menu_mp_weapons_commando" );
    }
    else if( response == "give_galil" )
    {
    	self.pers[ "xkmod_primary" ] = "galil_mp";
    	self setClientDvar( "xkmod_cac_primary", "menu_mp_weapons_galil" );
    }
    else if( response == "give_enfield" )
    {
    	self.pers[ "xkmod_primary" ] = "enfield_mp";
    	self setClientDvar( "xkmod_cac_primary", "menu_mp_weapons_enfield" );
    }
    else if( response == "give_m14" )
    {
    	self.pers[ "xkmod_primary" ] = "m14_mp";
    	self setClientDvar( "xkmod_cac_primary", "menu_mp_weapons_m14" );
    }
    else if( response == "give_fnfal" )
    {
    	self.pers[ "xkmod_primary" ] = "fnfal_mp";
    	self setClientDvar( "xkmod_cac_primary", "menu_mp_weapons_fnfal" );
    }
    else if( response == "give_m16" )
    {
    	self.pers[ "xkmod_primary" ] = "m16_mp";
    	self setClientDvar( "xkmod_cac_primary", "menu_mp_weapons_m16" );
    }
    else if( response == "give_ak74u" )
    {
    	self.pers[ "xkmod_primary" ] = "ak74u_mp";
    	self setClientDvar( "xkmod_cac_primary", "menu_mp_weapons_ak74u" );
    }
    else if( response == "give_mp5k" )
    {
    	self.pers[ "xkmod_primary" ] = "mp5k_mp";
    	self setClientDvar( "xkmod_cac_primary", "menu_mp_weapons_mp5k" );
    }
    else if( response == "give_uzi" )
    {
    	self.pers[ "xkmod_primary" ] = "uzi_mp";
    	self setClientDvar( "xkmod_cac_primary", "menu_mp_weapons_uzi" );
    }
    else if( response == "give_ithaca" )
    {
    	self.pers[ "xkmod_primary" ] = "ithaca_mp";
    	self setClientDvar( "xkmod_cac_primary", "menu_mp_weapons_ithaca" );
    }
    else if( response == "give_l96a1" )
    {
    	self.pers[ "xkmod_primary" ] = "l96a1_mp";
    	self setClientDvar( "xkmod_cac_primary", "menu_mp_weapons_l96a1" );
    }
    else if( response == "give_l96a1b" )
    {
    	self.pers[ "xkmod_primary" ] = "l96a1_ir_mp";
    	self setClientDvar( "xkmod_cac_primary", "menu_mp_weapons_l96a1" );
    }
    else if( response == "give_cz75" )
    {
    	self.pers[ "xkmod_secondary" ] = "cz75_mp";
    	self setClientDvar( "xkmod_cac_secondary", "menu_mp_weapons_cz75" );
    }
    else if( response == "give_makarov" )
    {
    	self.pers[ "xkmod_secondary" ] = "makarov_mp";
    	self setClientDvar( "xkmod_cac_secondary", "menu_mp_weapons_makarov" );
    }
    else if( response == "give_m1911" )
    {
    	self.pers[ "xkmod_secondary" ] = "m1911_mp";
    	self setClientDvar( "xkmod_cac_secondary", "menu_mp_weapons_colt" );
    }
    else if( response == "give_python" )
    {
    	self.pers[ "xkmod_secondary" ] = "python_mp";
    	self setClientDvar( "xkmod_cac_secondary", "menu_mp_weapons_python" );
    }
    else if( response == "give_asp" )
    {
    	self.pers[ "xkmod_secondary" ] = "asp_mp";
    	self setClientDvar( "xkmod_cac_secondary", "menu_mp_weapons_asp" );
    }
    else if( response == "give_flash" )
    {
    	self.pers[ "xkmod_tactical" ] = "flash_grenade_mp";
    	self setClientDvar( "xkmod_cac_grenade", "hud_us_flashgrenade" );
    }
    else if( response == "give_smoke" )
    {
    	self.pers[ "xkmod_tactical" ] = "willy_pete_mp";
    	self setClientDvar( "xkmod_cac_grenade", "hud_willy_pete" );
    }
    else if( response == "camo_none" )
    {
    	self.pers[ "xkmod_camo" ] = "0";
    	self setClientDvar( "xkmod_cac_camo", "" );
    }
    else if( response == "camo_tiger" )
    {
    	self.pers[ "xkmod_camo" ] = "8";
    	self setClientDvar( "xkmod_cac_camo", "menu_mp_weapons_camo_tiger" );
    }
    else if( response == "camo_siberia" )
    {
    	self.pers[ "xkmod_camo" ] = "11";
    	self setClientDvar( "xkmod_cac_camo", "menu_mp_weapons_camo_siberia" );
    }
    else if( response == "camo_yukon" )
    {
    	self.pers[ "xkmod_camo" ] = "12";
    	self setClientDvar( "xkmod_cac_camo", "menu_mp_weapons_camo_yukon" );
    }
    else if( response == "camo_woodland" )
    {
    	self.pers[ "xkmod_camo" ] = "13";
    	self setClientDvar( "xkmod_cac_camo", "menu_mp_weapons_camo_wood" );
    }
    else if( response == "camo_red" )
    {
    	self.pers[ "xkmod_camo" ] = "3";
    	self setClientDvar( "xkmod_cac_camo", "menu_mp_weapons_camo_mass" );
    }
    else if( response == "camo_golden" )
    {
    	self.pers[ "xkmod_camo" ] = "15";
    	self setClientDvar( "xkmod_cac_camo", "menu_mp_weapons_camo_gold" );
    }

    Voilà, donc, je suis persuadé qu'il y a une meilleure façon de formuler tout ça afin de rendre le code plus "léger" (en évitant tous ces if/else if) étant donné que le "give_" est toujours présent.


    Bonne journée !

  2. #2
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2007
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2007
    Messages : 634
    Points : 407
    Points
    407
    Par défaut
    Citation Envoyé par XeroK Voir le message
    Voilà, donc, je suis persuadé qu'il y a une meilleure façon de formuler tout ça afin de rendre le code plus "léger" (en évitant tous ces if/else if) étant donné que le "give_" est toujours présent.


    Bonne journée !
    Salut, afin de rendre ton code plus léger et te permettre d'ajouter des armes plus facilement, tu pourrais utiliser une std::map dont la clé serait le nom de l'arme, ainsi tu aurais quelque chose du genre :

    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
    #ifndef __CLASSARM_H__
    # define __CLASSARM_H__
     
    #include <string>
     
    class ClassArm
    {
    	public:
    		ClassArm(std::string, std::string, std::string);
    		std::string getS1(void) const;
    		std::string getS2(void) const;
    		std::string getS3(void) const;
     
     
    	private:
    		std::string _s1;
    		std::string _s2;
    		std::string _s3;
    };
     
    #endif
    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
    #include "ClassArm.h"
     
    std::string ClassArm::getS1(void) const
    {
    	return (this->_s1);
    }
     
    std::string ClassArm::getS2(void) const
    {
    	return (this->_s2);
    }
     
    std::string ClassArm::getS3(void) const
    {
    	return (this->_s3);
    }
     
    ClassArm::ClassArm(std::string s1, std::string s2, std::string s3)
    {
    	this->_s1 = s1;
    	this->_s2 = s2;
    	this->_s3 = s3;
    }
    Enfin la logique :
    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
    #include <map>
    #include "ClassArm.h"
     
     
    int main(void)
    {
    	std::map<std::string, ClassArm> map;
     
    	map["ak47"] = ClassArm("ak47_mp", "xkmod_cac_primary", "menu_mp_weapons_ak47" );
    	map["commando"] = ClassArm("commando_mp", "xkmod_cac_primary", "menu_mp_weapons_commando" );
    	map["galil"] = ClassArm("galil_mp", "xkmod_cac_primary", "menu_mp_weapons_galil" );
     
    	std::string response = "ak47";
     
    	std::map<std::string, ClassArm>::iterator it;
    	it = map.find("give_" + response);
    	if (it != map.end())
    	{
    		self.pers[ "xkmod_primary" ] = it->second.getS1();
    		self setClientDvar( it->second.getS2(), it->second.getS3() );
    	}
     
    return (0);
    }
    Ainsi, tu a juste à rajouter une ligne dans la map pour gérer une nouvelle arme.

    Petit inconvénient, contrairement à des if / else if..., cette méthode utilise plus de mémoire car la map est remplie au "démarrage de l'application"

    NeoKript


    Edit :

    Ou même si toutes tes chaînes sony formatée correctement :
    - À partir de ta variable result, tu supprime le give_, tu obtient par exemple "ak47" que tu stocke dans une nouvelle variable name.
    - Et ensuite tu appelle directement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	self.pers[ "xkmod_primary" ] = name + "_mp";
    	self setClientDvar( "xkmod_cac_primary", "menu_mp_weapons_" + name );

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 25
    Points : 24
    Points
    24
    Par défaut
    Je pense que la meilleur alternative à une suite de if..else if est un switch.

    Tu ne gagne pas en terme de nombre de lignes de code mais c'est plus rapide.

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par Arch74 Voir le message
    Je pense que la meilleur alternative à une suite de if..else if est un switch.
    Outre le fait qu'un switch ne marche qu'avec un nombre très limité de types (dont les chaînes de caractères ne font pas partie), un switch a le même problème que les if, à savoir que les différentes alternatives sont codées en dur, et ne peuvent donc pas varier en fonction par exemple d'une fichier de configuration, d'une autre condition du jeu (au début je n'ai pas de lance roquette, puis j'en trouve un)...

    Une solution à base de map est donc probablement moins performante (et encore, s'il y a *beaucoup* d'armes, écrire les if correspondant à l'algo en O(log N) des map risque d'être assez casse-tête), mais elle me semble bien plus flexible. Et les endroits où la vitesse doit primer sur l'architecture du code sont assez rares dans un programme.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Un tableau statique tout simple me semble la meilleure solution :

    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
     
    typedef struct  s_weapon
    {
      char          *type;
      char          *xkmod;
      char          *dvar;
    }               t_weapon;
     
    int fill_weapon(std::string &response)
    {
      t_weapon      tab[] =
        {
          {"give_ak47", "ak47_mp", "menu_mp_weapons_ak47"},
          {"give_commando", "commando_mp", "menu_mp_weapons_commando"},
          {NULL, NULL, NULL}
        };
     
      for (int i = 0; tab[i].type != NULL; i++)
        {
          if (tab[i].type == response)
            {
              self.pers[ "xkmod_primary" ] = tab[i].xkmod;
              self.setClientDvar("xkmod_cac_primary", tab[i].dvar);
              return 1;
            }
        }
      return 0;
    }
    Je n'ai pas compilé mais l'idée est là, et elle devient encore plus puissante quand tu fais des tableaux de pointeurs sur fonction.

  6. #6
    Tulutu
    Invité(e)
    Par défaut
    Je me permets de poster ici, même si je ne connais pas un rayon en C++, donc c'est juste une idée de piste. Corrigez moi si je dis des bêtises.

    J'ai eu certains projets en tête qui nécessitaient le même genre de "choix multiples" demandant de bonnes performances.

    Effectivement avec autant de choix, le if et le switch (qui n'est optimisé que dans certains cas assez particuliers, d'après ce que j'ai lu), ne sont pas de bonnes options.

    La deuxième idée qui viendrait serait de faire une table, triée bien comme il faut, et de développer un algorithme qui cherche assez rapidement dans celle-ci (dichotomie je crois, ça doit pas être la seule possibilité).

    Mais j'ai également lu que l'on peut remplacer un énorme switch en utilisant le polymorphisme, je ne sais pas précisément comment il faut faire, ni si c'est bien otimisé, mais ça peut être intéressant (en plus le code est plus propre et plus maintenable.

    Si ces quelques idées peuvent aider...
    à bientôt

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par feydaykyn Voir le message
    Je n'ai pas compilé mais l'idée est là, et elle devient encore plus puissante quand tu fais des tableaux de pointeurs sur fonction.
    Et si tu apprends le C++, tu te rends compte que c'est encore plus puissant
    Sans blague, à la place de char*, regarde du côté de std::string. A la place des tableaux statiques, regarde du côté de std::vector ou std::array ou ici, std::map. Et à la place d'une boucle maison qui risque d'être buggé et répétitive, regarde du côté de std::find. Pour les pointeurs de fonctions, il faut probablement réviser les bases d'une structure/classe. De même s'intéresser aux foncteurs (puis std/boost::function/bind,etc., .... puis les lambdas) Les pointeurs de fonctions en C++, vraiment je n'en vois pas l'intérêt.


    Citation Envoyé par Tulutu Voir le message
    La deuxième idée qui viendrait serait de faire une table, triée bien comme il faut, et de développer un algorithme qui cherche assez rapidement dans celle-ci (dichotomie je crois, ça doit pas être la seule possibilité).
    Effectivtement, un vecteur de pair triée avec une recherche dichotomique peut être une alternative à un tableau associatif. Tout comme on aurait pu utiliser une table de hachage (std/tr1/boost::unordered_map). Ces différentes alternatives ont chacune leurs avantages et inconvénients. std::map reste très pertinent pour commencer.

    Citation Envoyé par Tulutu Voir le message
    Mais j'ai également lu que l'on peut remplacer un énorme switch en utilisant le polymorphisme,
    Oui, à condition que derrière les classes derrières aient un sens dans un héritage donnée. Ici, non. Il s'agit typiquement d'associer des données à une clé d'entrée. C'est pour cela que std::map reste la solution la plus lisible.

Discussions similaires

  1. Association bouton avec un raccourci clavier
    Par benn13 dans le forum Débuter
    Réponses: 2
    Dernier message: 13/04/2012, 15h10
  2. Case a cocher associer à bouton bascule
    Par Marcopololo dans le forum IHM
    Réponses: 4
    Dernier message: 03/07/2008, 14h03
  3. association bouton et lien hypertexte
    Par fattouch_squall dans le forum Balisage (X)HTML et validation W3C
    Réponses: 11
    Dernier message: 08/12/2007, 11h19
  4. [Souris] Associer un bouton de souris
    Par GLDavid dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 26/01/2006, 09h44
  5. associer un son à un bouton
    Par Mucsy dans le forum MFC
    Réponses: 7
    Dernier message: 19/12/2005, 22h17

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