M2103-TP9-EXO-0-Corrigé

/**
 *
 * @file   partied_echec.cpp
 *
 * @author M. Laporte
 *
 * @date   06/06/2019
 *
 * @brief  M2103 Testt 2 partie d'échec
 *
 **/

#include <vector>
#include <string>
#include <iostream>

 using namespace std;

namespace
{
    class Piece;

    #define classdef typedef
    classdef vector <Piece *> VPiece;
    enum Couleur {KBlanc, KNoir};
    enum Piece_t {KAucun, KRoi, KReine, KFou, KCavalier, KTour, KPion};
    vector <string> vNom {"", "Roi", "Reine", "Fou",
                          "Cavalier", "Tour", "Pion"};

    class Case;
    class Echiquier;
    class Joueur;

    class Piece
    {
      protected :
        Couleur  myCouleur;
        Piece_t  myNom;
        Case   * myCase;
        Joueur * myJoueur;
      public :
        Piece (Piece_t nom, Couleur couleur)
              : myCouleur (couleur), myNom (nom) {}

        Couleur getCouleur (void) const { return myCouleur; }
        Piece_t getNom     (void) const { return myNom; }
        Case *  getCase    (void) const { return myCase; }
        void setJoueur (Joueur * joueur) { myJoueur = joueur; }
        void setCase   (Case * laCase)   { myCase = laCase; }

        virtual bool operator () (Case * laCase) { return false; }
        virtual ~Piece (void) {}

    }; // Piece

    class Pion : public Piece
    {
      public :
        Pion (Piece_t nom, Couleur couleur) : Piece (nom, couleur)
        {}

        virtual bool operator () (Case * laCase) { return true; }
        virtual ~Pion (void) {}

    }; // Pion

    class Roi : public Piece
    {
      public :
        Roi (Piece_t nom, Couleur couleur) : Piece (nom, couleur) {}

        virtual bool operator () (Case * laCase) { return false; }
        virtual ~Roi (void) {}

    }; // Roi

    class Reine : public Piece
    {
      public :
        Reine (Piece_t nom, Couleur couleur) : Piece (nom, couleur) {}

        virtual bool operator () (Case * laCase) { return false; }
        virtual ~Reine (void) {}

    }; // Reine

    class Fou : public Piece
    {
      public :
        Fou (Piece_t nom, Couleur couleur) : Piece (nom, couleur) {}

        virtual bool operator () (Case * laCase) { return false; }
        virtual ~Fou (void) {}

    }; // Fou

    class Cavalier : public Piece
    {
      public :
        Cavalier (Piece_t nom, Couleur couleur) : Piece (nom, couleur) {}

        virtual bool operator () (Case * laCase) { return false; }
        virtual ~Cavalier (void) {}

    }; // Cavalier

    class Tour : public Piece
    {
      public :
        Tour (Piece_t nom, Couleur couleur) : Piece (nom, couleur) {}

        virtual bool operator () (Case * laCase) { return false; }
        virtual ~Tour (void) {}

    }; // Tour

    class Case
    {
        unsigned myLigne;
        unsigned myColonne;
        Piece  * myPiece;
      public :
        Case (unsigned ligne = 0, unsigned colonne = 0,
              Piece * piece = nullptr)
            : myLigne (ligne), myColonne (colonne), myPiece (piece) {}
        unsigned getLigne   (void) const      { return myLigne; }
        unsigned getColonne (void) const      { return myColonne; }
        Piece *  getPiece   (void) const      { return myPiece; }

        void     setPiece   (Piece * piece)   { myPiece  = piece; }

    }; // Case
    class Echiquier
    {
        vector <vector <Case>> myPlateau;
        vector <Piece>         myPieces;
        void addPions (Couleur couleur, unsigned numLigne)
        {
            for (unsigned col (0); col < myPlateau [numLigne].size ();
                 ++col)
            //for (Case & laCase : myPlateau [numLigne])
            {
                myPieces.push_back (Pion (KPion, couleur));
                myPieces.back().setCase (& (myPlateau [numLigne][col]));
                myPlateau [numLigne][col].setPiece (& (myPieces.back ()));
            }
        }// addPions()

      public :
        Echiquier (void)
        {
            myPlateau.resize (8);
            for (unsigned li (0); li < 8; ++li)
            {
                myPlateau [li].resize (8);
                for (unsigned col (0); col < 8; ++col)
                {
                    myPlateau [li][col] = Case (li, col);
                }
            }
            myPieces.reserve (32);
            // placer les pions
            addPions (KBlanc, 6);
            addPions (KNoir,  1);

            // placer les reines
            myPieces.push_back        (Reine (KReine, KNoir));
            myPieces.back().setCase   (& (myPlateau [0][3]));
            myPlateau [0][3].setPiece (& (myPieces.back ()));
            myPieces.push_back        (Reine (KReine, KBlanc));
            myPieces.back().setCase   (& (myPlateau [7][3]));
            myPlateau [7][3].setPiece (& (myPieces.back ()));

            // placer les rois
            myPieces.push_back        (Roi (KRoi, KNoir));
            myPieces.back().setCase   (& (myPlateau [0][4]));
            myPlateau [0][4].setPiece (& (myPieces.back ()));
            myPieces.push_back        (Roi (KRoi, KBlanc));
            myPieces.back().setCase   (& (myPlateau [7][4]));
            myPlateau [7][4].setPiece (& (myPieces.back ()));

            // placer les fous
            myPieces.push_back        (Fou (KFou, KNoir));
            myPieces.back().setCase   (& (myPlateau [0][2]));
            myPlateau [0][2].setPiece (& (myPieces.back ()));
            myPieces.push_back        (Fou (KFou, KBlanc));
            myPieces.back().setCase   (& (myPlateau [7][2]));
            myPlateau [7][2].setPiece (& (myPieces.back ()));

            myPieces.push_back        (Fou (KFou, KNoir));
            myPieces.back().setCase   (& (myPlateau [0][5]));
            myPlateau [0][5].setPiece (& (myPieces.back ()));
            myPieces.push_back        (Fou (KFou, KBlanc));
            myPieces.back().setCase   (& (myPlateau [7][5]));
            myPlateau [7][5].setPiece (& (myPieces.back ()));

            // placer les cavaliers
            myPieces.push_back        (Cavalier (KCavalier, KNoir));
            myPieces.back().setCase   (& (myPlateau [0][1]));
            myPlateau [0][1].setPiece (& (myPieces.back ()));
            myPieces.push_back        (Cavalier (KCavalier, KBlanc));
            myPieces.back().setCase   (& (myPlateau [7][1]));
            myPlateau [7][1].setPiece (& (myPieces.back ()));

            myPieces.push_back        (Cavalier (KCavalier, KNoir));
            myPieces.back().setCase   (& (myPlateau [0][6]));
            myPlateau [0][6].setPiece (& (myPieces.back ()));
            myPieces.push_back        (Cavalier (KCavalier, KBlanc));
            myPieces.back().setCase   (& (myPlateau [7][6]));
            myPlateau [7][6].setPiece (& (myPieces.back ()));

            // placer les tours
            myPieces.push_back        (Tour (KTour, KNoir));
            myPieces.back().setCase   (& (myPlateau [0][0]));
            myPlateau [0][0].setPiece (& (myPieces.back ()));
            myPieces.push_back        (Tour (KTour, KBlanc));
            myPieces.back().setCase   (& (myPlateau [7][0]));
            myPlateau [7][0].setPiece (& (myPieces.back ()));

            myPieces.push_back        (Tour (KTour, KNoir));
            myPieces.back().setCase   (& (myPlateau [0][7]));
            myPlateau [0][7].setPiece (& (myPieces.back ()));
            myPieces.push_back        (Tour (KTour, KBlanc));
            myPieces.back().setCase   (& (myPlateau [7][7]));
            myPlateau [7][7].setPiece (& (myPieces.back ()));

        } // Echiquier()

        VPiece getPieces (const Couleur & couleur) const
        {
            vector <Piece *> v;
            v.reserve (16);
            unsigned cpt = 0;
            for (vector <Case> vCase : myPlateau)
                for (Case laCase : vCase)
                {
                    if (laCase.getPiece () != nullptr)
                    {						//&&
                        if (laCase.getPiece ()->getCouleur () == couleur)
                            v.push_back (laCase.getPiece ());
                    }
                }
            return v;

        } // getPieces()

        Case * getCase (unsigned i, unsigned j)
        { return &(myPlateau[i][j]); }

    }; // Echiquier
    
    class Joueur
    {
        string myNom;
        VPiece myPieces;
        Echiquier * myPlateau;
      public :
        Joueur (const string & nom, const VPiece &vPieces,
                 Echiquier * plateau)
               : myNom (nom), myPieces (vPieces), myPlateau (plateau)  {}

        Piece * choisirPiece (void)
        {
            for (unsigned i (0); i < myPieces.size (); ++i)
                cout << i << ' ' << vNom [myPieces [i]->getNom ()]
                     << myPieces [i]->getNom ()
                     << ' ' << myPieces [i]->getCase ()->getLigne ()
                     << ' ' << myPieces [i]->getCase ()->getColonne ()
                     << endl;
            cout << "Quelle piece voulez-vous jouer ?";
            unsigned piece;
            cin >> piece;
            return myPieces [piece];

        } // choisirPiece()

        void move (Case * laCase, Piece * piece)
        {
            piece->getCase()->setPiece (nullptr);
            piece->setCase (laCase);
            laCase->setPiece (piece);

        } // move()

        void jouer (Piece * piece)
        {
            unsigned ligne;
            unsigned colonne;
            do
            {
                cout << "Où voulez-vous jouer "
                     << vNom [piece->getNom ()] << " ? "
                     << "Ligne Colonne ? ";
                cin >> ligne >> colonne;
            } while ((*piece)(myPlateau->getCase (ligne, colonne)));
            move (myPlateau->getCase (ligne, colonne), piece);


        } // jouer()

    }; // Joueur

    class Partie
    {
        Echiquier * myEchiquier;
        vector <Joueur *> myJoueurs;
      public :
        Partie (Joueur * j1, Joueur * j2, Echiquier * echiquier)
               : myEchiquier (echiquier)
        {
            myJoueurs.reserve (2);
            myJoueurs.push_back (j1);
            myJoueurs.push_back (j2);

            bool aJ2 = false;

            /*    */
            while (true)
            {
                Piece * piece = myJoueurs [aJ2]->choisirPiece ();
                myJoueurs [aJ2]->jouer (piece);
                aJ2 = ! aJ2;
                break;
            }
            /*     */
        } // Partie()

    }; // Partie

}// namespace
int main (void)
{
    Echiquier plateau;
    Joueur joueur1 ("Alain", plateau.getPieces (KBlanc), & plateau);
    Joueur joueur2 ("Marc",  plateau.getPieces (KNoir),  & plateau);

    Partie unePartie (& joueur1, & joueur2, & plateau);

    return 12;

} // main()

M2103-TP9-EXO-1

Créer le projet ReseauSocial.

Depuis C++11, C++ offre une bibliothèque ctime, qui permet de grossièrement gérer l’heure et la date. Cette bibliothèque reprend les structures du C, dans l’espace de nom std. Pour obtenir la date du jour, il faut procéder en 2 étapes. D’abord, récupérer le nombre de secondes écoulées depuis le 01/01/1970, à l’aide de la fonction time() de profil (simplifié)

time (time_t * t);

qui s’utilise comme suit :

time_t t; 
time (&t);

Ensuite,on transforme le time_t en une structure struct tm (rappel: struct classe où tout est publique par défaut) à l’aide de la fonction localtime() de profil

tm * localtime (time_t * t);

qui transforme t, le nombre de secondes écoulées depuis le 01/01/1970, en une tm et s’utilise comme suit :

tm local = * localtime (& t);

nous allons encapsuler cette struct tm dans la classe Date, comme sur le schéma UML suivant, de manière à interdire, à l’utilisateur qui utiliserait cette classe Date, l’accès aux attributs de la struct tm :

On ajoutera à cette classe Date un constructeur par défaut qui construit une Date avec la date du jour.

Travail demandé

Ecrire complètement les fichiers Date.h et Date.cpp qui contiennent respectivement les déclarations et les définitions de la classe Date correspondant au schéma et aux explications, dans l’espace de noms std.
Tester en ajoutant la fonction suivante à l’espace de noms anonyme de votre main.cpp :

    void testDate (void)
    {
        Date date;
        cout << "Aujourd'hui nous sommes le : " 
             << date.getDay () << ' ' << date.getMonth () << ' ' << date.getYear ()
             << " et il est " << date.getHour () << "h " << date.getMinute () 
             << "mn et " <

Petit problème, le mois est le mois dernier et l'année est n'importe quoi. Voici ce que dit le man sur les attributs mis en cause dans le struct tm :

           struct tm {
               int tm_sec;    /* Seconds (0-60) */
               int tm_min;    /* Minutes (0-59) */
               int tm_hour;   /* Hours (0-23) */
               int tm_mday;   /* Day of the month (1-31) */
               int tm_mon;    /* Month (0-11) */
               int tm_year;   /* Year - 1900 */
               int tm_wday;   /* Day of the week (0-6, Sunday = 0) */
               int tm_yday;   /* Day in the year (0-365, 1 Jan = 0) */
               int tm_isdst;  /* Daylight saving time * /
           };

Corriger dans les 2 accesseurs concernés et tester à nouveau.

M2103-TP9-EXO-1-Corrigé

Fichier Date.h

/**
 *
 * \file     Date.h
 *
 * \authors  M. Laporte
 *
 * \date     24/05/2018
 *
 * \version  V1.0
 *
 * \brief    Declaration de la classe Date
 *
 **/
#ifndef __DATE_H__
#define __DATE_H__

#include <ctime> // struct tm

namespace std
{
    class Date : public tm
    {
      public :
        Date (void);

        unsigned getYear   (void) const;
        unsigned getMonth  (void) const;
        unsigned getDay    (void) const;
        unsigned getHour   (void) const;
        unsigned getMinute (void) const;
        unsigned getSecond (void) const;

    }; // Date
} // std

#endif /* __DATE_H__ */

Fichier Date.cpp

/**
 *
 * \file     Date.cpp
 *
 * \authors  M. Laporte
 *
 * \date     24/05/2018
 *
 * \version  V1.0
 *
 * \brief    Definitions de la classe Date
 *
 **/

#include "date.h"
std::Date::Date (void)
{
    time_t whatTime;
    time (& whatTime);
    tm local;
    local = * localtime (&whatTime);
    tm_year = local.tm_year; 
    tm_mon  = local.tm_mon;
    tm_mday = local.tm_mday;
    tm_hour = local.tm_hour;
    tm_min  = local.tm_min;
    tm_sec  = local.tm_sec;

    //*this = * ((Date *) localtime (&whatTime));

    tm_year += 1900;
    tm_mon += 1;

}

unsigned std::Date::getYear   (void) const { return tm_year; }
unsigned std::Date::getMonth  (void) const { return tm_mon;  }
unsigned std::Date::getDay    (void) const { return tm_mday; }
unsigned std::Date::getHour   (void) const { return tm_hour; }
unsigned std::Date::getMinute (void) const { return tm_min;  }
unsigned std::Date::getSecond (void) const { return tm_sec;  }


M2103-TP9-EXO-2

Le but de ce qui suit est de traduire en C++ le schéma UML suivant :

Dans l’espace de noms anonyme du fichier main.cpp déclarer la classe Message, comme elle est décrite sur le schéma UML. Y ajouter un constructeur qui se contente de remplir myContent avec un paramètre correspondant, et myDate, avec la date courante (constructeur par défaut de Date). La fonction displayContent() affiche à l’écran le contenu du message. Vous intégrerez directement les définitions des fonctions dans la classe.
Dans l’espace de noms anonyme, insérer les différentes classes (exercices suivants), de haut en bas, dans l’ordre des exercices. Normalement, seules des déclarations de classes vides seront à ajouter. Lorsque cela sera nécessaire un embryon de classe sera fourni.

Ajouter à la classe l’accesseur à l’attribut myDate.

Dans l’espace de noms anomyme ajouter les fonctions displayDate() suivante :

    void displayDate (const Date & date)
    {
        cout << date.getDay () << ' ' << date.getMonth () << ' ' << date.getYear ();
    
    } // displayDate()

et displayHour() suivante :

    void displayHour (const Date & date)
    {
        cout << date.getHour () << "h " << date.getMinute () 
             << "mn et " <

Tester avec la fonction testMessage() suivante, également à incorporer à l'espace de noms anonyme du fichier main.cpp :

    void testMessage (void)
    {
        Message message ("salut");
        message.displayContent ();
        cout << " posté le : ";
        displayDate (message.getDate ());
        cout << " à ";
        displayHour (message.getDate ());
        cout << endl;

    } // testMessage()}

M2103-TP9-EXO-3

Dans l’espace de noms anonyme du fichier main.cpp déclarer la classe PublicMessage, comme elle est décrite sur le schéma UML.
La fonction add() se contente d’incrémenter de 1 myLikers (nombre de personnes qui aiment ce message).
Ajouter l’accesseur à myNbLikers.
Tester avec la fonction testPublicMessage() suivante, à incorporer également à l’espace de noms anonyme.

    void testPublicMessage (void)
    {
        PublicMessage message ("salut");
        message.displayContent ();
        cout << " posté le : ";
        displayDate (message.getDate ());
        cout << " à ";
        displayHour (message.getDate ());
        cout << endl;
        for (unsigned i(0); i < 5; ++i)
            message.add ();
        cout << "Nb de likers : " << message.getNbLikers (); << endl;

    } // testPublicMessage()

M2103-TP9-EXO-3-Corrigé

    class PublicMessage : public Message
    {
        unsigned myNbLikers;
      public :
        PublicMessage (const string & content)
           : Message (content), myNbLikers (0) {}

        unsigned getNbLikers (void) const { return myNbLikers; }

        void add (void) { ++ myNbLikers; }

    }; // PublicMessage

M2103-TP9-EXO-4

Dans l’espace de noms anonyme du fichier main.cpp déclarer la classe PrivateMessage, comme elle est décrite sur le schéma UML. Le constructeur a la tâche supplémentaire d’initialiser le lien avec l’User.
Ajouter l’accesseur à ce lien.

Tester avec la fonction testPrivateMessage() et la classe User provisoire suivantes, à incorporer également à l’espace de noms anonyme.

    class User
    {
       public :
       void sendMessage (const PrivateMessage & message)
       {
           message.displayContent ();
           cout << endl;
       } // sendMessage()
       void addFriend (User * oneFriend) { cout << "ajouté" << endl; }
       User * getFriend (unsigned i) const { cout << i << endl; return new User; }
       System * getSystem (void) const { cout << "système" << endl; return NULL; }
       void addMessage (const PrivateMessage & message) { message.displayContent (); cout << endl; }
       
    }; // User
    
    void testPrivateMessage (void)
    {
        User user;
        PrivateMessage message ("salut", & user);
        message.displayContent ();
        cout << " posté le : ";
        displayDate (message.getDate ());
        cout << " à ";
        displayHour (message.getDate ());
        cout << endl;
        message.getSender ()->getFriend (5);

    } // testPrivateMessage()