# source_cell

id: 19bc2955f4524b20ac96f09f591765a3
name: 10
cell_type: markdown
checksum: 810c04226cda9f4619e3d6c4d644b336
notebook_id: 3d4f0337cfb14542bd75470f682b424a
source:
  ::::{admonition} Exercice 1 : Compilation séparée

  Annotez les quatre fichiers suivants en précisant leurs rôles
  respectifs et en indiquant où se trouvent entête, définition,
  documentation, tests et utilisation de la fonction `factorielle`.

  :::{literalinclude} factorielle.hpp
  :caption: factorielle.hpp
  :::

  :::{literalinclude} factorielle.cpp
  :caption: factorielle.cpp
  :::

  :::{literalinclude} factorielle-test.cpp
  :caption: factorielle-test.cpp
  :::

  {latexonly}`\clearpage`

  :::{literalinclude} factorielle-exemple.cpp
  :caption: factorielle-exemple.cpp
  :::

  ::::

  % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE

  {latexonly}`\bigskip`
  {latexonly}`\enlargethispage{8ex}`

  ## Graphiques

  En TP, nous utiliserons la bibliothèque `SFML` [^1], une bibliothèque
  largement utilisée facilitant le développement de jeux ou
  d'applications multimédias grâce à une grande panoplie de modules
  (fenêtrage, graphismes, audio, réseau, ...), principalement développée
  par Laurent Gomila. Nous allons nous en servir pour créer une fenêtre
  et dessiner dedans.

  La `SFML` n'étant pas immédiatement intuitive à utiliser, nous avons
  écrit une micro bibliothèque composée de quelques primitives pour vous
  simplifier les premiers pas. Cette bibliothèque, documentée dans
  `primitives.hpp`, a vocation à être la plus transparente possible. À
  vous de la lire en détail pour vous l'approprier et, par la suite,
  vous en passer.

  Voici un exemple de programme utilisant la `SFML` et notre
  bibliothèque `primitives` :

  :::{literalinclude} exemple-graphisme1.cpp
  :caption: exemple-graphisme1.cpp
  :::

  Notez dans cet exemple le nouveau type `RenderWindow` représentant une
  fenêtre et les fonctions `clear` pour effacer la fenêtre, `sleep` pour
  attendre un temps donné et `draw_point` (qui vient de
  `primitives.cpp`) pour dessiner un point.


id: d89db88cf36b416d9b9e773e56d98661
name: 20
cell_type: markdown
checksum: 1986e35cfea627cd75aaacb627e8ad3c
notebook_id: 3d4f0337cfb14542bd75470f682b424a
source:
  ::::{admonition} Exercice 2 : Premiers dessins

  En vous inspirant de l'exemple fourni, écrivez des instructions
  (fragments de programme) qui, respectivement,

  1.  dessinent un point noir (*Black*) de coordonnées $(418, 143)$;

      % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE

  2.  dessinent un segment blanc (*White*) reliant les
      points $(100, 200)$ et $(200, 200)$;

      % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE

  3.  dessinent un segment rouge (*Red*) reliant les points $(200, 300)$ et
      $(200, 400)$;

      % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE

  4.  dessinent le rectangle horizontal vide de contour rouge dont les sommets diagonaux
      sont $(200, 200)$ et $(400, 300)$;

      % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE

  5.  dessinent un rectangle horizontal plein noir dont les sommets
      diagonaux sont $(400, 150)$ et $(500, 200)$;

      % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE

  6.  dessinent un segment rouge reliant les points $(400, 300)$ et
      $(500, 400)$;

      % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE

  7.  dessinent un cercle noir de centre $(415, 145)$ et de rayon
      $10$;  
  	**Indication :** Utiliser les fonctions `cos` et `sin`.

      % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE

  8.  dessinent un disque jaune (*Yellow*) de centre $(700, 100)$ et de rayon
      $50$;  
  	**Indication :** Utiliser la définition d'un disque.

      % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE

  ::::


id: 3971cbfa18294d9482fd6efcb452f21c
name: 30
cell_type: markdown
checksum: be45863a53351171a30bb896289f3266
notebook_id: 3d4f0337cfb14542bd75470f682b424a
source:
  {latexonly}`\enlargethispage{2ex}`

  ::::{admonition} Exercice 3 : $\clubsuit$ Fonctions de dessin

  Notre bibliothèque `primitives` contient entre autres les fonctions
  suivantes :

      /** Affiche une ligne de couleur entre deux positions données
       * @param w une fenêtre ouverte dans laquelle dessiner
       * @param pos1 les coordonnées du premier point de la ligne
       * @param pos1 les coordonnées du dernier point de la ligne
       * @param color la couleur de la ligne
       */
      void draw_line (RenderWindow& w, Point pos1, Point pos2, Color color);

      /** Affiche un cercle coloré vide
       * @param w une fenêtre ouverte dans laquelle dessiner
       * @param center la position du centre du cercle
       * @param r le rayon du cercle
       * @param color la couleur du trait
       */
      void draw_circle (RenderWindow& w, Point center, int r, Color color);

      /** Affiche un cercle coloré plein 
       * @param w une fenêtre ouverte dans laquelle dessiner
       * @param center la position du centre du cercle
       * @param r le rayon du cercle
       * @param color la couleur du trait et du remplissage
       */
      void draw_filled_circle(RenderWindow& w, Point center, int r, Color color);

  À noter qu'elles prennent la fenêtre où dessiner comme premier
  paramètre (`w`). Le symbole `&` indique que cette fenêtre est passée
  par référence afin que les fonctions puissent la modifier. Vous pouvez
  essentiellement ignorer ce détail technique dont vous verrez les
  tenants et les aboutissants au deuxième semestre.

  Notez aussi les variables de type `Point`. Ces dernières représentent
  des coordonnées. On peut créer un point et accéder à ses coordonnées
  comme suit :

  ```
  Point p = {42, 2713};
  int x = p.x; // 42
  int y = p.y; // 2713
  ```

  Techniquement parlant, il s'agit d'un *enregistrement* (*struct* en
  anglais); vous en verrez les détails au deuxième semestre.

  Dans notre bibliothèque, ces fonctions sont implémentées via des
  appels directs à des fonctions de la `SFML`. Par exemple :

  :::{literalinclude} primitives.cpp
  :start-after: BEGIN draw_filled_circle
  :end-before: END draw_filled_circle
  :::

  1.  Réimplantez ces fonctions, en n'utilisant que des
      appels à `draw_point`.

      % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE

  ::::


id: 814422fa5355467c90d583e2c182e4b3
name: 40
cell_type: markdown
checksum: 09775fae68e86d2b7c93e81b29b3bbb4
notebook_id: 3d4f0337cfb14542bd75470f682b424a
source:
  ::::{admonition} Exercice 4 : Souris et Clavier

  Voici maintenant un fragment de programme interactif utilisant la
  `SFML` et notre bibliothèque `primitives` pour réagir à des actions
  avec la souris ou le clavier.

  :::{literalinclude} exemple-graphisme2.cpp
  :start-after: BEGIN
  :end-before: END
  :caption: exemple-graphisme2.cpp
  :::

  1.  En vous inspirant du programme précédent, écrivez un programme qui
      attend que l'utilisateur clique sur deux points de l'écran puis
      qui trace le segment les reliant.

      % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE

  2.  Écrivez un programme qui attend que l'utilisateur clique sur
      quatre points puis qui dessine le quadrilatère ayant ces quatre
      points comme sommets.

      % REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE

  3.  Écrivez un programme qui dessine des polygones de la façon
      suivante : l'utilisateur clique sur des points successifs. À
      chaque clic, le programme relie les deux derniers points. Si
      l'utilisateur clique près du point initial, le polygone se ferme,
      et le programme commence un nouveau polygone.
   
  	% REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE

  ::::

  [^1]: <https://www.sfml-dev.org>


id: fe9c2a0d4e9743438bf3ea26308bafb6
name: cell-bcde2b57c973b401
cell_type: markdown
checksum: 3b3a708181297bdd0dd91741ce41c103
notebook_id: 27ba8f78dcfb459886b03349aa80859d
source:
  :::{admonition} Notes aux enseignants

  Avec la compilation séparée, et surtout les graphismes, cette semaine
  est un peu technique. Il est très important de tester le TP en salle
  TP et sur JupyterHub.

  Il peut y avoir un problème de bibliothèque `libudev.so.0` manquante. Ce
  problème peut être contourné avec :

  ```shell
  mamba install -c conda-forge libudev
  cd $CONDA_PREFIX/lib
  ln -s libudev.so.1 libudev.so.0
  ```

  TODO 2023-2024:
  - [x] ajout SFML dans l'environnement
  - [ ] automatiser l'ajout du lien pour libudev (fait sur le hub)
  - [x] basculer à xcanvas
  - [x] utiliser la libsfml sur le hub maintenant que XFCE Desktop est
    disponible. Voir
    https://gitlab.dsi.universite-paris-saclay.fr/jupyterhub-paris-saclay/image/-/issues/8 .

  TODO 2024-2025:
  - [ ] Revoir les coordonnées dans l'exercice 2 du TD et
        premier-dessin.md pour réduire un peu la résolution.
  :::


id: b5c829be997d4aefa49d39097fdff111
name: cell-6d952c4decd8c707
cell_type: markdown
checksum: f117371d70884a7bf3ba7d2cd02a4af7
notebook_id: 27ba8f78dcfb459886b03349aa80859d
source:
  ## Objectifs pédagogiques

  Cette semaine, comme la précédente, notre objectif est de gérer de
  **« gros » programmes**, notamment pour continuer à vous préparer au
  projet. Nous avions eu un premier aperçu du concept de **modularité**,
  en découpant un programme en **fonctions**. Nous allons en rajouter
  une couche en découpant un programme en plusieurs fichiers, grâce à la
  **compilation séparée**. En prélude, nous discuterons le **cycle de
  vie d'un programme**, notamment pour clarifier ce qu'est la
  **compilation**.  Comme application nous utiliserons <!-- si les
  conditions techniques à distance nous le permettent !-->la
  **bibliothèque multimédia SFML** pour faire des dessins et des
  interfaces graphiques. Cela pourra servir pour certaines parties
  optionnelles du projet.

  En TD et TP, nous mettrons d'abord en application la compilation
  séparée, observant en détail un programme découpé en plusieurs
  fichiers, puis reproduisant le schéma pour découper un autre programme
  en plusieurs fichiers. Puis nous étudierons quelques exemples de
  programmes utilisant la bibliothèque SFML et nous en inspirerons pour
  programmer des dessins et interagir avec l'utilisateur.


id: 49b464c3cd8948568fa1eaf221993b52
name: cell-6d952c4decd8c706
cell_type: markdown
checksum: 66602a703f36c2f7e318dabbea427a84
notebook_id: 27ba8f78dcfb459886b03349aa80859d
source:
  ## [Cours](cours.md)

  - Cours : [Cycle de vie d'un programme](cours-cycle-de-vie-d-un-programme.md)
  - Cours : [Modularité et compilation séparée](cours-modularite.md)
  - Cours : [Digressions: surcharge, templates, espaces de noms](cours-digressions.md)
  - Cours : [Conclusion](cours-conclusion.md)


id: c5860d5c9fd54ce2b0800c4f21231dc3
name: cell-88edc2f254ba7294
cell_type: markdown
checksum: c14862eeb15c1d00c45129ecb04ba658
notebook_id: 27ba8f78dcfb459886b03349aa80859d
source:
  ### Exercice 1 : préliminaires : compilation séparée

  1.  Consultez le contenu des fichiers suivants : [factorielle.hpp](factorielle.hpp),
      [factorielle.cpp](factorielle.cpp), [factorielle-exemple.cpp](factorielle-exemple.cpp).

  2.  Compilez le programme entier en suivant les instructions suivantes.
      Commencez par compiler chacun des bouts de programme (fichiers `.cpp`).
      Pour cela on utilise l'option `-c` :
      ```shell
      clang++ -c factorielle.cpp
      clang++ -c factorielle-exemple.cpp
      ```

      Ceci nous a créé deux fichiers, `factorielle.o` et
      `factorielle-exemple.o` qui sont des bouts de programme binaires.
      Vérifiez avec `ls` que ces fichiers ont bien été créés.

      Combinez ensuite (en anglais: *link* pour «édition de liens»)
      ces deux bouts de programme de la façon suivante :
      ```shell
      clang++ factorielle.o factorielle-exemple.o -o factorielle-exemple
      ```

      Vérifiez avec `ls` que cette commande crée bien un exécutable
      `factorielle-exemple`.

  4.  Exécutez le programme `factorielle-exemple`.

  5.  Consultez le fichier [factorielle-test.cpp](factorielle-test.cpp).
      Créez un exécutable `factorielle-test` en adaptant les étapes
      ci-dessus, puis testez ce nouveau programme.

  6.  Une autre méthode pour compiler `factorielle-exemple` est de
      remplacer les trois commandes de la question (2) par la seule
      commande :
      ```shell
      clang++ factorielle.cpp factorielle-exemple.cpp -o factorielle-exemple
      ```

      Supprimez les fichiers `factorielle.o`, `factorielle-exemple.o` et
      `factorielle-exemple` de votre dossier avec `rm`. Testez alors la
      commande précédente. Quel(s) fichier(s) ont été créés ? En déduire
      les différences avec la méthode précédente. Selon le cas vous pourrez
      être amené à choisir l'une ou l'autre, notamment dans le projet.


id: 8c6e0863d2234203a708af3768c2d33c
name: cell-bcde2b57c973b400
cell_type: markdown
checksum: 4926713763b0e145f25516bd63ae0fdd
notebook_id: 27ba8f78dcfb459886b03349aa80859d
source:
  :::{admonition} Notes aux enseignants

  Erreurs fréquentes :
  - Faute d'orthographe à fibonacci (typiquement nombre de n ou nombre de c)
    qui fait que le fichier n'est pas trouvé.
  - Ne pas mettre l'include du `.hpp` dans tous les `.cpp` (ou inclure
    `factorielle.hpp` au lieu de `fibonacci.hpp`, ou mettre des `< >` au
    lieu des `" "`).
  - Faire un `.hpp` qui contient uniquement la documentation de la
    fonction mais pas son en-tête.
  - Certains laissent le lancement des tests dans le `main` de
    `fibonacci-exemple.cpp` ce qu'ils ne sont pas censés faire (cf. le
    modèle donné pour factorielle) et pose le problème de la déclaration
    de la fonction de test.
      
  :::


id: debc79fba2fb455aaa8be82fc5833587
name: cell-89f33130471fc08e
cell_type: markdown
checksum: 0aa22e643a0731f21a052d645349ad26
notebook_id: 27ba8f78dcfb459886b03349aa80859d
source:
  -   Ouvrez le fichier [fibonacci.cpp](fibonacci.cpp) et regardez son
      contenu. Remarquez que la fonction `main` mélange deux actions de
      nature très différente : d'une part lancer les tests de la
      fonction `fibonacci`, et d'autre part utiliser cette fonction pour
      interagir avec l'utilisateur. Ceci n'est pas très satisfaisant.

  -   Réorganisez le fichier [fibonacci.cpp](fibonacci.cpp) en plusieurs
      fichiers en suivant le modèle de l'exercice précédent. Il y aura
      donc quatre fichiers :
  	- [fibonacci.hpp](fibonacci.hpp),
      - [fibonacci.cpp](fibonacci.cpp),
      - [fibonacci-test.cpp](fibonacci-test.cpp),
      - [fibonacci-exemple.cpp](fibonacci-exemple.cpp).

      Faites attention à ne pas dupliquer de code.


id: f913bd4ceeda4049a594ccca0bb88392
name: cell-89f33130471fc08f
cell_type: markdown
checksum: ed2c4d1d7c8b563e2a33580c914aa9d6
notebook_id: 27ba8f78dcfb459886b03349aa80859d
source:
  -   Quels exécutables allez-vous construire? Pour chaque exécutable,
      quels fichiers allez-vous combiner pour l'obtenir ? Vérifiez
      pour chaque exécutable que chaque fonction utilisée (dont la
      fonction `main`) est définie une et une seule fois dans l'ensemble
      de fichiers correspondant.


id: 790f03412b8143428813e820a3fe968b
name: cell-89f33130471fc08g
cell_type: markdown
checksum: eb352fd592187fcac4ce19570c7bc952
notebook_id: 27ba8f78dcfb459886b03349aa80859d
source:
  -   Compilez chacun des deux programmes (test et exemple) grâce à la
      compilation séparée, exécutez les et vérifiez que tout fonctionne
      correctement. En cas d'erreur, lisez le message d'erreur puis
      comparez attentivement vos fichiers et commandes avec ceux donnés
      pour la fonction `factorielle` (si vous avez la feuille de TD sous
      la main, l'énoncé de l'exercice 1 permet de visualiser facilement
      tous les fichiers pour factorielle).

      Notez ci-dessous les commandes utilisées pour la compilation :


id: 2f65c76f25d34bbf8c790c6bac09840a
name: cell-96bafcc3c30ace6e
cell_type: markdown
checksum: 36737f42fbf6300e344e76a3b1301b30
notebook_id: 27ba8f78dcfb459886b03349aa80859d
source:
  ### Exercice 3 : Premiers graphiques avec Jupyter

  1.  Refaites l'exercice 2 du [TD](TD.md) en complétant la feuille
      [premier-dessin](premier-dessin.md). Implantez chacun des items
      en vérifiant à chaque fois le résultat.


id: 04c09513ec104b95acab08c880e708ee
name: cell-96bafcc3c30ace6g
cell_type: markdown
checksum: f94f35a5a86a6a9bbfa70e9f2ec5274c
notebook_id: 27ba8f78dcfb459886b03349aa80859d
source:
  :::::{attention} SFML et sessions graphiques

  Pour exécuter un programme utilisant la bibliothèque SFML, il est
  nécessaire d'être dans une ***interface graphique***; sinon, vous
  aurez une erreur comme :
  ```
  ./exemple-graphisme1 
  Failed to open X11 display; make sure the DISPLAY environment variable is set correctly
  ```
  (X11 est le gestionnaire de session graphique sous UNIX).

  ::::{admonition} Option 1 : Sur les ordinateurs des salles de TP

  Vous êtes automatiquement dans une session graphique. Vous n'avez donc
  rien de particulier à faire.

  ::::

  ::::{admonition} Option 2 : Avec le service JupyterHub@Paris-Saclay, depuis tout autre ordinateur ou tablette connectée à Internet
  :class: dropdown

  En parallèle de l'interface usuelle JupyterLab, vous pouvez lancer une
  interface graphique (dite XFCE Desktop) sur le même serveur. Vous
  pourrez ensuite basculer entre l'une et l'autre pour éditer et
  compiler vos programmes d'une part, et les exécuter d'autre part.

  <figure>

  <video src="https://nicolas.thiery.name/Enseignement/Info111/media/screencast-sfml-on-jupyterhub.webm"
         width="95%" controls
         alt="Vidéo: lancer un programme graphique SFML avec JupyterHub"
         />

  <figcaption>Vidéo : lancer un programme graphique SFML avec JupyterHub</figcaption>
  </figure>

  ::::

  ::::{admonition} Sur votre machine personnelle
  :class: dropdown

  L'installation, la configuration et l'utilisation de la SFML peut être
  un peu technique selon la configuration de votre ordinateur (système
  d'exploitation, environnement de développement, ...).  Nous donnons
  ici quelques pointeurs, mais après c'est à vous de fouiller la
  documentation, notamment sur le [site de la
  SFML](https://www.sfml-dev.org/index-fr.php) et de vous
  débrouiller. Dans le doute, utilisez plutôt une des deux options
  ci-dessus.

  La section « Salle de TP virtuelle » sur la [page logiciels du site du
  cours](https://nicolas.thiery.name/Enseignement/Info111/ComputerLab/README.html)
  donne des instructions pour installer JupyterLab, compilateur C++ et
  SFML. Sous GNU/Linux (Ubuntu, ...) cela devrait être suffisant pour
  travailler.

  Si vous souhaitez utiliser CodeBlocks, Visual Studio, ou tout autre
  environnement de développement intégré (IDE), il faudra configurer cet
  IDE pour utiliser la SFML. Plus encore que d'habitude, nous
  recommandons de compiler en ligne de commande dans le terminal.

  ::::

  :::::


id: 629ffbb79f744064bb46ea24ed3a3470
name: cell-96bafcc3c30ace6h
cell_type: markdown
checksum: a0ff90a81efe68e4975687391da8ddc6
notebook_id: 27ba8f78dcfb459886b03349aa80859d
source:
  1.  Ouvrez les fichiers [exemple-graphisme1.cpp](exemple-graphisme1.cpp)
      et [primitives.hpp](primitives.hpp) et consultez le premier.

  2.  Compilez ce programme depuis le terminal avec
      (en une seule ligne !) :
      ```shell
      info-111 compile exemple-graphisme1.cpp primitives.cpp -o exemple-graphisme1 -lsfml-system -lsfml-window -lsfml-graphics
      ```

      Explication : le code binaire de SFML est réparti dans trois
      bibliothèques `sfml-system`, `sfml-window` et `sfml-graphics`.
      Les arguments `-lsfml-system`, ... indiquent au compilateur de les
      lier au programme (`-l` pour *link*).

  3.  Lancez le programme obtenu avec :
      ```shell
      ./exemple-graphisme1
      ````
  	Vous obtenez une fenêtre blanche, avec un (tout petit!) point
      rouge un peu à gauche, près du bord haut.

  4.  Compilez le programme fourni
      [premier-dessin.cpp](premier-dessin.cpp)
      en adaptant la commande utilisée plus haut pour compiler
      [exemple-graphisme1.cpp](exemple-graphisme1.cpp).
      Complétez [premier-dessin.cpp](premier-dessin.cpp) à partir
      de la feuille [premier-dessin](premier-dessin.md). N'hésitez pas
      à changer la valeur de la variable `delai` pour voir le résultat
      s'afficher plus longtemps.


id: ef9770bb957d42e893ff368d4b316d0a
name: cell-00e5e7435133ed7c
cell_type: markdown
checksum: 633dad6d2fc40907647239a4c8b48e31
notebook_id: 27ba8f78dcfb459886b03349aa80859d
source:
  :::{admonition} Notes aux enseignants

  Certains élèves croient que le premier caractère de `-lsfml-*` est un
  $1$ alors qu'il s'agit d'un $\ell$ (c'est vrai que ce n'est pas
  forcément très clair mais cela se voit en comparant avec les autres
  caractères de la ligne : on voit que ce n'est pas exactement le même
  caractère que dans `info-111` mais que c'est le même que dans `sfml`).

  Certains élèves compilent le programme `premier-dessin.cpp` en oubliant
  l'option `-lsfml*`, ce qui crée plein d'erreurs.

  :::


id: b433d0d081b34fc0a21b4dc1173ec76e
name: cell-eaefcdbc75785adb
cell_type: markdown
checksum: cb4372b6a345f17e803ae8856124785f
notebook_id: 27ba8f78dcfb459886b03349aa80859d
source:
  ### Exercice 5 : Souris et clavier ♣

  1.  Pour vous donner une idée de l'utilisation de la SFML et
      de notre bibliothèque de primitives, lisez attentivement
      [primitives.hpp](primitives.hpp) et sa documentation.

  2.  Consultez ensuite [exemple-graphisme2.cpp](exemple-graphisme2.cpp)
      et [exemple-graphisme3.cpp](exemple-graphisme3.cpp) pour en voir
      des exemples d'utilisation.

  3.  Implantez l'exercice 4 du TD.

      <!-- Solutions dans le TD !-->


id: 15626365aeec4604946b1c22e0e3c304
name: cell-5858dbcffa05aed3
cell_type: markdown
checksum: 6bb1aa5b00f1758bbd44d55f54bc3ea6
notebook_id: 27ba8f78dcfb459886b03349aa80859d
source:
  ### Exercice 6 : Couche d'abstraction ♣

  Pour vous approprier la couche d'abstraction, consultez son
  implantation dans `primitives.cpp`. En vous inspirant de
  ce qui est déjà fait, complétez l'implantation de la fonction
  `draw_filled_rectangle` (documentée dans `primitives.hpp`).
  Vous pouvez vous aider de la
  [documentation en ligne de la SFML](https://www.sfml-dev.org/learn-fr.php).


id: 75aaf6cf1aa346749e45d4e9237e0bc4
name: cell-48f3d0b08106b27e
cell_type: markdown
checksum: d07cbe5dd5f6b305779f0b8a6d1128f3
notebook_id: 27ba8f78dcfb459886b03349aa80859d
source:
  ### Exercice 7_: Jeu du Yams ♣

  Reprenez le jeu du Yams du TP 6 en ajoutant une interface graphique.

  On affichera les dés (soit avec du texte, soit avec des points) dans
  la fenêtre. Revoyez [exemple-graphisme3.cpp](exemple-graphisme3.cpp)
  pour des fonctions rapides. L'utilisateur pourra cliquer sur les dés
  à combiner pour former une figure. (Utiliser par exemple `wait_mouse()`
  pour cliquer sur les dés, et `wait_keyboard()` pour valider.) Le nombre
  de points sera ensuite affiché.

  À vous de concevoir les fonctions à introduire pour décomposer le
  problème.


id: b195a7049a704fe99470ade04cdccf72
name: cell-db040b06c5a92102
cell_type: markdown
checksum: 7df12946868397e5fbe4bc994fb8d19c
notebook_id: 91d20baea24d4d7694ef930ea2d485d5
source:
  puis dessinons un point noir de coordonnées (418, 143). Ce point est
  tout petit, vous aurez peut-être un peu de mal à le distinguer :


id: 7d662f8b717b486abea929e86a983aa6
name: cell-db040b06c5a92103
cell_type: markdown
checksum: d8948ac8886182d90df0fb2bce302b52
notebook_id: 91d20baea24d4d7694ef930ea2d485d5
source:
  1.  Dessinez un segment blanc entre les points de coordonnées
      respsectives (100,200) et (200,200) :


id: 2b5ae238b90b49aaac63f5bbd4ddadef
name: cell-e77db2d9ed7265ac
cell_type: code
checksum: ce1d6a0deeef3221d1ea8d9afbd40bce
notebook_id: 91d20baea24d4d7694ef930ea2d485d5
source:
  // REMPLACEZ CETTE LIGNE ET LA SUIVANTE PAR VOTRE RÉPONSE
  throw std::runtime_error("À faire");
  window.display();


id: 55512cc6deb448dab4d38bb42557983b
name: cell-db040b06c5a92104
cell_type: markdown
checksum: 5da5ff8010119a35e52e9ba76dc3237d
notebook_id: 91d20baea24d4d7694ef930ea2d485d5
source:
  :::{tip} Astuce

  Pour éviter de monter et descendre constamment dans cette feuille,
  faites un clic droit sur le canvas et cliquez sur «Créer une nouvelle
  vue pour la sortie» (ou «Create new view for output»). Puis disposez
  la copie obtenue du canvas sur votre espace de travail de sorte à voir
  simultanément votre code et le canvas.

  :::


id: e03a9b5f3411476bb61974cd1594723b
name: cell-db040b06c5a92106
cell_type: markdown
checksum: 0791571f18f4df2c2bfecb5a3ba9c0ff
notebook_id: 91d20baea24d4d7694ef930ea2d485d5
source:
  3.  Dessinez un rectangle horizontal vide de sommets diagonaux
      (200,200) et (400,300) et de contour rouge :


id: 3652ee6feb33414eb54ea974d8daf378
name: cell-3606e0158c83309d
cell_type: code
checksum: 4c65f8e4cec21af229e5a44dd7063a03
notebook_id: 91d20baea24d4d7694ef930ea2d485d5
source:
  // REMPLACEZ CETTE LIGNE ET LA SUIVANTE PAR VOTRE RÉPONSE
  throw std::runtime_error("À faire");
  window.display()


id: bf43ec44b16748d1b5fbf8962e000396
name: cell-db040b06c5a92112
cell_type: markdown
checksum: ef878f93df33be50d5262273cefbc00a
notebook_id: 91d20baea24d4d7694ef930ea2d485d5
source:
  :::{attention}

  Comme vous l'avez constaté, les performances sont lamentables. C'est
  parce que nous avons abusé des canvas de HTML : alors que ceux-ci sont
  conçus pour du dessin vectoriel, nous approximons les figures
  vectorielles (lignes, triangles, ...) par des accumulations d'un très
  grand nombre de pixels (combien pour le triangle bleu?), sachant que
  chacun de ces pixels est en fait représenté en interne par un petit
  rectangle.

  En dehors de ce premier dessin -- dont l'objectif pédagogique était de
  faire un peu d'algorithmique -- il faut au contraire utiliser les
  primitives vectorielles fournies.

  :::


