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 :

Free Automatons with State and Transitions : soumission d'un projet


Sujet :

C++

Mode arborescent

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Par défaut Free Automatons with State and Transitions : soumission d'un projet
    Bonjour,

    Je viens ici pour vous présenter un code que j'ai fait, et qui va beaucoup me servir sous peu. C'est une classe d'automates générique. Les choix de conceptions sont surement à discuter (comme toujours), et je veux volontiers en discuter, mais il faudra des arguments forts pour que je remanie la partie conceptuelle (bon commencé comme ça, je vais avoir beaucoup de retour...). Entre parenthèses, j'ai pour projet ensuite de m'en servir pour proposer librement des automates de gestion multi-écrans, IA, météo, animations, etc dans les jeux vidéos 2D, d'où le nom.

    Ce qui m'intéresse surtout, ce sont les remarques sur la propreté du code, sur les choses que j'aurais pas du faire (comme les _ en début de donnée membre (3DArchi me l'a rappelé déjà), ce que je peux encore faire pour améliorer les performences, pour améliorer la sécurité d'utilisation (je suppose que mon code n'est pas du tout exception-safe, mais je maitrise assez mal le sujet), etc...

    je veux rendre ce projet irréprochable. Je compte sur vous pour me dire tout ce qui ne va pas


    le tout est en pièce jointe, mais pour les moins courageux, je montre le main que j'ai joint pour tester la bête


    Le main n'est là que pour illustrer
    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
     
    #include <iostream>
    #include "Automaton.hpp"
    #include <map>
     
    using namespace std;
    using namespace FAST;
     
    typedef State<string> SInt;
    typedef Transition<string> TInt;
     
     
    int main()
    {
     
        Automaton<string> Automate1("Automate 1");
     
        Automate1.NewState(new SInt("Etat Initial", initialState));
        Automate1.NewState(new SInt("Etat 2",       intermediaryState));
        Automate1.NewState(new SInt("Etat 3",       intermediaryState));
        Automate1.NewState(new SInt("Etat 4",       intermediaryState));
        Automate1.NewState(new SInt("Etat 5",       finalState));
     
        Automate1.NewTransitionForState("Etat Initial", new TInt("touche haut","transition vers l'etat numero 2"),   Automate1.GetStateByName("Etat 2"));
        Automate1.NewTransitionForState("Etat Initial", new TInt("touche bas","transition vers l'etat numero 3"),    Automate1.GetStateByName("Etat 3"));
        Automate1.NewTransitionForState("Etat 2",       new TInt("touche gauche","transition vers l'etat numero 4"), Automate1.GetStateByName("Etat 4"));
        Automate1.NewTransitionForState("Etat 3",       new TInt("touche droite","transition vers l'etat numero 5"), Automate1.GetStateByName("Etat 5"));
        Automate1.NewTransitionForState("Etat 4",       new TInt("touche gauche","transition vers l'etat numero 5"), Automate1.GetStateByName("Etat 5"));
        Automate1.NewTransitionForState("Etat 4",       new TInt("touche bas","transition vers l'etat numero 1"),    Automate1.GetStateByName("Etat Initial"));
     
        int compteur = 0;
        cout << "->";
        while(Automate1.GetCurrentState()->GetType() != finalState)
        {
            cout << Automate1.GetCurrentState()->GetName() <<"(";
            const std::string& currentStateName = std::string(Automate1.GetCurrentState()->GetName());
            if (currentStateName == "Etat Initial")
            {
                compteur++;
                if (compteur==10)
                {
                    cout << Automate1.GetCurrentState()->GetTransitionByName("transition vers l'etat numero 3")->GetValue();
                    Automate1.UpdateState(Automate1.GetCurrentState()->GetTransitionByName("transition vers l'etat numero 3"));
                }
                else
                {
                    cout << Automate1.GetCurrentState()->GetTransitionByName("transition vers l'etat numero 2")->GetValue();
                    Automate1.UpdateState(Automate1.GetCurrentState()->GetTransitionByName("transition vers l'etat numero 2"));
                }
            }
            else if (currentStateName == "Etat 2")
            {
                cout << Automate1.GetCurrentState()->GetTransitionByName("transition vers l'etat numero 4")->GetValue();
                Automate1.UpdateState(Automate1.GetCurrentState()->GetTransitionByName("transition vers l'etat numero 4"));
            }
            else if (currentStateName == "Etat 3")
            {
                cout << Automate1.GetCurrentState()->GetTransitionByName("transition vers l'etat numero 5")->GetValue();
                Automate1.UpdateState(Automate1.GetCurrentState()->GetTransitionByName("transition vers l'etat numero 5"));
            }
            else if (currentStateName == "Etat 4")
            {
                cout << Automate1.GetCurrentState()->GetTransitionByName("transition vers l'etat numero 1")->GetValue();
                Automate1.UpdateState(Automate1.GetCurrentState()->GetTransitionByName("transition vers l'etat numero 1"));
            }
            else
                cout << "Etat non reconnu" << endl;
     
                cout << ") ->";
        }
        cout << Automate1.GetCurrentState()->GetName() << endl;
     
        return 0;
    }

    Pour les perfs, je précise que je suis en mode debug, donc ça peut être beaucoup mieux en release je pense (mais je ne constate aucun changement personnellement, à part la taille de l'éxécutable) : le main fait passé un automate dans 30 états en 29ms (chez moi) et 47ms (au boulot)

    je pose un bout de code plus concret pour ceux qui n'ont pas le temps :

    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
     
    #ifndef AUTOMATON_HPP
    #define AUTOMATON_HPP
     
    #include <vector>
    #include "State.hpp"
     
     
    namespace FAST
    {
     
     
     
    template<typename T>
    class Automaton
    {
        public :
            typedef std::vector<State<T>*> T_statesVector;
     
            Automaton(const std::string& name_, const T_statesVector& statesVector_ = std::vector<State<T>*>());
            ~Automaton();
     
            void NewState(State<T>* state_);
     
            const State<T>* GetCurrentState() const;
            State<T>* GetCurrentState();
            void UpdateState(Transition<T>* transition_);
     
            void NewTransitionForCurrentState(Transition<T>* transition_, State<T>* stateReached_);
            void NewTransitionForState(const std::string& name_, Transition<T>* transition_, State<T>* stateReached_);
     
            const State<T>* GetStateByName(const std::string& name_) const;
            State<T>* GetStateByName(const std::string& name_);
     
     
            const std::string& GetName() const;
            std::string& GetName();
            void SetName(const std::string& name_);
     
        private :
            T_statesVector _statesVector;
            std::string _name;
            State<T>* _currentState;
     
    };
     
    template<typename T>
    Automaton<T>::Automaton(const std::string& name_, const T_statesVector& statesVector_) :
    _statesVector(statesVector_),
    _name(name_),
    _currentState(NULL)
    {
     
    }
     
    template<typename T>
    Automaton<T>::~Automaton()
    {
     
    }
     
    template<typename T>
    void Automaton<T>::NewState(State<T>* state_)
    {
        _statesVector.push_back(state_);
        if (_currentState == NULL)
            _currentState = state_;
    }
     
    template<typename T>
    const State<T>* Automaton<T>::GetCurrentState() const
    {
        return _currentState;
    }
     
    template<typename T>
    State<T>* Automaton<T>::GetCurrentState()
    {
        return _currentState;
    }
     
    template<typename T>
    const State<T>* Automaton<T>::GetStateByName(const std::string& name_) const
    {
        typename T_statesVector::iterator it;
        for(it=_statesVector.begin(); it=! _statesVector.end(); ++it)
        {
            if ((*it)->GetName() == name_)
                return it;
        }
        return NULL;
    }
     
    template<typename T>
    State<T>* Automaton<T>::GetStateByName(const std::string& name_)
    {
        typename T_statesVector::iterator it;
        for(it=_statesVector.begin(); it!= _statesVector.end(); ++it)
        {
            if ((*it)->GetName() == name_)
                return *it;
        }
        return NULL;
    }
     
    template<typename T>
    void Automaton<T>::UpdateState(Transition<T>* transition_)
    {
        if (_currentState->GetTransitionByName(transition_->GetName()) != NULL)
            _currentState = _currentState->GetStateReachedByTransition(transition_->GetName());
    }
     
    template<typename T>
    void Automaton<T>::NewTransitionForCurrentState(Transition<T>* transition_, State<T>* stateReached_)
    {
        _currentState.NewTransition(transition_, stateReached_);
    }
     
    template<typename T>
    void Automaton<T>::NewTransitionForState(const std::string& name_, Transition<T>* transition_, State<T>* stateReached_)
    {
        typename T_statesVector::iterator it;
        for(it=_statesVector.begin(); it!= _statesVector.end(); ++it)
        {
            if ((*it)->GetName() == name_)
                (*it)->NewTransition(transition_, stateReached_);
        }
    }
     
    template<typename T>
    const std::string& Automaton<T>::GetName() const
    {
        return _name;
    }
     
    template<typename T>
    std::string& Automaton<T>::GetName()
    {
        return _name;
    }
     
    template<typename T>
    void Automaton<T>::SetName(const std::string& name_)
    {
        _name = name_;
    }
     
     
     
    }
    Fichiers attachés Fichiers attachés

Discussions similaires

  1. Réponses: 2
    Dernier message: 04/06/2009, 11h31
  2. [C#] Calendar Popup with TextBox and Image?
    Par Nadaa dans le forum ASP.NET
    Réponses: 15
    Dernier message: 04/02/2009, 11h59
  3. Indy TIdFTP : Please login with USER and PASS.
    Par sinfoni dans le forum Composants VCL
    Réponses: 3
    Dernier message: 19/03/2008, 08h15

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