Soucis énumération

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour, je suis actuellement en train de réaliser un petit morpion pour tester la bibliothèque SFML mais je suis bloqué sur un point qui n'a apparemment pas de rapport avec cette bibliothèque.

Je possède 3 classes: Game, Board, BoardCase. Et une énumération qui me pose pas mal de soucis, CaseState, cette énumération défini les différents états d'une case. Dans ma classe BoardCase, j'ai une méthode setState(CaseState newState), et c'est cette méthode qui ne semble pas fonctionner.

Voici l'énumération:

1
2
3
4
5
6
7
8
9
class BoardCase{

    public:
    enum CaseState{
        ROUND,
        CROSS,
        EMPTY
    };
};

Et voici la méthode setState :

1
2
3
4
5
void BoardCase::setState(CaseState newState){
    std::cout << m_state << "-" << newState << std::endl;
    m_state = newState;
    std::cout << m_state << std::endl;
}

Lors de son appel, la console m'affiche : 2-1 puis 1. Mais une fois que j'essaye d'accéder à l'état à un autre endroit dans le code par la suite l'état est revenu sur EMPTY(2).

Voici l'appel de la fonction :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
bool Board::onClick(sf::Vector2i posi, BoardCase::CaseState state){
    std::cout << m_cases[0].getState() << std::endl;
    int i = 0;
    for(BoardCase caseB : m_cases){
        std::cout << m_cases[0].getState() << std::endl;
        if(caseB.isTouched(posi) && caseB.getState() == BoardCase::EMPTY){
            std::cout << m_cases[0].getState() << std::endl;
            caseB.setState(state);
            std::cout << m_cases[0].getState() << std::endl;
            return true;
        }
        i++;
    }
    return false;
}

Et l'appel de la méthode onClick :

1
if(m_board.onClick(coor, m_turnPlayer))

m_turnPlayer est un attribut (BoardCase::CaseState) et il vaut CaseState::CROSS.

Merci d'avance de votre aide.

+0 -0

Cette réponse a aidé l'auteur du sujet

Lu'!

Mieux vaut abandonner les énumérations au profit des enums fortement typés.

1
2
3
enum class Type /* : type de base */ { TRUC };

Type variable = Type::TRUC ;

Concernant ton problème, tu modifies des copies des cases, prends les par référence dans ton range-for.

PS : en C++, on parle plutôt de fonction membre que de méthodes (cf norme, messages des compilos, etc …). Une méthode étant théoriquement une fonction virtuelle.

PPS : Why setters and getters are evil ?

First : Always RTFM - "Tout devrait être rendu aussi simple que possible, mais pas plus." A.Einstein

+1 -0

Cette réponse a aidé l'auteur du sujet

Salut,

Dans ta fonction Board::onClick, ton range-based for ne doit pas simplement travailler sur une copie de chaque case, il faut que caseB fasse référence à une case de ton tableau m_cases (EDIT: Grillé sur ce point). Tu peux d'ailleurs utiliser auto, ça sera encore plus simple :

4
for(auto &caseB : m_cases)

Peut-être encore mieux, utilise la fonction std::replace_if qui fait tout le travail :

4
5
std::replace_if(m_cases.begin(), m_cases.end(), [&posi](const auto &caseB)
    { return caseB.isTouched(posi) && caseB.getState() == BoardCase::EMPTY; }, state);

Sinon en règle général, passe tes objets en paramètres par références (vers constantes si nécessaires) si ils sont plus lourds que les simples types arithmétiques. En général, on le fait lorsque le type est une classe/structure (et donc pas pour les énumérations par exemple).

1
bool Board::onClick(const sf::Vector2i &posi, BoardCase::CaseState state)

PS: Tu n'utilises pas ta variable i dans Board::onClick.

Édité par Olybri

+1 -0
Auteur du sujet

Merci beaucoup à vous, j'ai découvert ce type de for en java et je n'avais donc jamais eu de soucis de ce type, je vais me pencher sur ce que tu as écris Ksass`Peuk, pour les passages par référence je suis au courant, faut que je me réhabitue au C++. (Pour la variable i ce n'était qu'une variable pour tenter de debug.)

Édité par Chokocraft

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte