diff --git a/tp3/README.md b/tp3/README.md
index 674fbd6896fdc4355ab811800d303f497a4a3007..bdd457f7a5178f65a8fc3cad835c3fd7b55340e8 100644
--- a/tp3/README.md
+++ b/tp3/README.md
@@ -24,7 +24,11 @@ trait Decoder {
     fn decode(&self, message: &str) -> String;
 }
 ```
+
 ### 1.1.2. A first encoder
+
+On utilise une méthode pour transformer `message` de la bonne façon avant de retourner un `String` :
+
 ```rs
 impl Encoder for ToUpper {
     fn encode(&self, message: &str) -> String {
@@ -38,7 +42,11 @@ impl Encoder for ToLower {
     }
 }
 ```
+
 ### 1.1.3. Two traits for one type
+
+Pour encoder on parcours un à un les caractères de `message` en appliquant à chaque fois le shift, et inversement pour décoder :
+
 ```rs
 struct Caesar {
     shift: u8,
@@ -76,7 +84,11 @@ impl Decoder for Caesar {
     }
 }
 ```
+
 ### 1.1.4. Implement a trait for a foreign type
+
+Pour ajouter les fonctions `encode()` et `decode()` on a cette fois-ci implémenté le trait `CaesarExt` au type `str` :
+
 ```rs
 trait CaesarExt {
     /// Encode self using a Caesar's cypher with the given shift
@@ -98,6 +110,7 @@ impl CaesarExt for str {
 ```
 ## 1.2. Implementing common traits
 ### 1.2.1. à 1.2.4. Clone/Copy/Debug/PartialEq
+
 On peut gérer ces 4 cas simplement en utilisant `derive` :
 
 ```rs
@@ -115,6 +128,9 @@ enum Instruction {
 ```
 
 ### 1.2.5. Display
+
+On doit implémenter la méthode `fmt()` du trait `Display` :
+
 ```rs
 impl std::fmt::Display for Instruction {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -127,7 +143,11 @@ impl std::fmt::Display for Instruction {
     }
 }
 ```
+
 ### 1.2.6. FromStr
+
+On parcours `s` et on fabrique un `Instruction` en fonction de ce qui était contenu dedans :
+
 ```rs
 #[derive(Debug, PartialEq)]
 enum InstructionError {
@@ -178,6 +198,9 @@ impl std::str::FromStr for Instruction {
 }
 ```
 ### 1.2.7. TryFrom<&[u8]> for Instruction
+
+On construit un `Instruction` simplement avec un match :
+
 ```rs
 #[derive(Debug)]
 enum TryFromInstructionError {
@@ -218,7 +241,11 @@ impl TryFrom<&[u8]> for Instruction {
     }
 }
 ```
+
 ### 1.2.8. From<Instruction> for [u8; 9]
+
+Comme pour la question précédente on parcours le paramètre, mais cette fois en reprenant la logique de construction d'un `Instruction` à partir d'un `[u8; 9]` mais dans l'autre sens :
+
 ```rs
 impl From<Instruction> for [u8; 9] {
     fn from(inst: Instruction) -> Self {
@@ -249,12 +276,20 @@ impl From<Instruction> for [u8; 9] {
     }
 }
 ```
+
 ### 1.2.9. Tests
+
+Normalement les tests passent :
+
 ```shell
 cargo test
 ```
+
 # 2. Generics
 ## 2.1. Without trait bounds
+
+Pour chaque méthode on vérifie dans quel cas de `Either` l'on est et on retourne la bonne réponse :
+
 ```rs
 enum Either<L, R> {
     Left(L),
@@ -303,7 +338,11 @@ impl<L, R> Either<L, R> {
     }
 }
 ```
+
 ## 2.2. With trait bounds
+
+On utilise `where` pour préciser que les trait bounds. Pour encoder et décoder, on lit ce qui est sur le `reader` et pour chaque ligne on encode ou décode avec `encoder.encode()` ou `decoder.decode()`, puis on l'écrit sur le `writer` :
+
 ```rs
 use std::io::{BufRead, BufReader, BufWriter, Read, Write};
 
@@ -355,8 +394,11 @@ where
     }
 }
 ```
+
 # 3. Long exercise proposal
 
+On défini un trait `Game` générique :
+
 ```rs
 use std::io::{BufRead, BufReader, BufWriter, Read, Write};
 
@@ -372,6 +414,8 @@ trait Game {
 }
 ```
 
+On implémente Tic Tac Toe :
+
 ```rs
 #[derive(Clone, Copy, Debug, PartialEq)]
 enum TicTacToePlayer {
@@ -484,6 +528,8 @@ impl Game for TicTacToe {
 }
 ```
 
+On implémente aussi le jeu de Nim :
+
 ```rs
 #[derive(Clone, Copy, Debug, PartialEq)]
 enum NimGamePlayer {
@@ -541,6 +587,8 @@ impl Game for NimGame {
 }
 ```
 
+Grâce au fait que `Game` est générique, on peut avoir une seule méthode `play_game()` pour les deux jeux :
+
 ```rs
 fn play_game<G: Game>(mut game: G) {
     while !game.is_over() {
@@ -565,6 +613,8 @@ fn play_game<G: Game>(mut game: G) {
 }
 ```
 
+On peut choisir le mode en entrant 1 ou 2, puis pour Tic Tac Toe entrer les coordonnées sous la forme `row col` et pour Nim en entrant le nombre de cailloux et à chaque tour le nombre que l'on prend :
+
 ```rs
 fn main() {
     println!("\n--- Game engine demo ---");