diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..0cc36ab849c2913a2b09e23419bdcb8627fa2693
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,371 @@
+extern crate rust_hepia_lib;
+
+const WIDTH: usize = 7;
+const HEIGHT: usize = 6;
+const RED_CHAR: char = 'X';
+const YELLOW_CHAR: char = 'O';
+
+#[derive(Copy, Clone, PartialEq)]
+enum Connect4Case {
+    Empty,
+    Red,
+    Yellow,
+}
+
+pub struct Connect4 {
+    board: [[Connect4Case; WIDTH]; HEIGHT],
+    game_mode: u8,
+    turn_count: u32,
+    last_col_played: usize,
+    width: usize,
+    height: usize,
+}
+
+impl Connect4 {
+    pub fn new() -> Connect4 {
+        if WIDTH < 4 || HEIGHT < 4 {
+            panic!("The connect 4 board is too short (WIDTH and HEIGHT must be at least 4)");
+        }
+        Connect4 {
+            board: [[Connect4Case::Empty; WIDTH]; HEIGHT],
+            game_mode: 0,
+            turn_count: 0,
+            last_col_played: 0,
+            width: WIDTH,
+            height: HEIGHT,
+        }
+    }
+
+    fn get_max_turn(&self) -> u32 {
+        (self.width as u32 * self.height as u32)
+    }
+
+    fn is_red_turn(&self) -> bool {
+        if self.turn_count % 2 == 1 {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    fn choose_game_mode() -> u8 {
+        let mut x: i32;
+        loop {
+            println!("Choose your game mode : (1) Player vs Player. (2) Player vs IA, easy. (3) Player vs IA, hard.");
+            x = rust_hepia_lib::read_int();
+            match x {
+                1 | 2 | 3 => return x as u8,
+                _ => println!("This is not a valid number"),
+            }
+        }
+    }
+
+    fn place_piece(&mut self, x: usize) -> bool {
+        if x >= self.width {
+            // si on veut placer une piece en dehors du tableau
+            return false;
+        }
+        if self.board[0 as usize][x] != Connect4Case::Empty {
+            // si la colonne est deja pleine
+            return false;
+        }
+        for i in 1..self.height {
+            if self.board[i][x] != Connect4Case::Empty {
+                // on place la nouelle piece au dessus de la plus haute piece de la colonne
+                self.board[i - 1][x] = if self.is_red_turn() {
+                    Connect4Case::Red
+                } else {
+                    Connect4Case::Yellow
+                };
+                return true;
+            }
+        }
+        self.board[self.height - 1][x] = if self.is_red_turn() {
+            // si la colonne est vide
+            Connect4Case::Red
+        } else {
+            Connect4Case::Yellow
+        };
+        return true;
+    }
+
+    fn choose_col(&self) -> usize {
+        let mut col: i32;
+
+        loop {
+            println!("Choose a column (1-{})", self.width);
+            col = rust_hepia_lib::read_int();
+            if col < 1 || col > self.width as i32 {
+                println!("This is not a valid column");
+            } else {
+                return (col - 1) as usize;
+            }
+        }
+    }
+
+    fn play_turn(&mut self) {
+        self.turn_count += 1;
+        println!(
+            "This is {}'s turn !!",
+            if self.is_red_turn() { RED_CHAR } else { YELLOW_CHAR }
+        );
+        if self.is_red_turn() || self.game_mode == 1 {
+            let mut col: usize;
+            loop {
+                col = self.choose_col();
+                if !self.place_piece(col) {
+                    println!("This is not a valid column");
+                } else {
+                    self.last_col_played = col;
+                    break;
+                }
+            }
+        } else if self.game_mode == 2 {
+            let x: usize = self.get_ia1_play();
+            self.place_piece(x);
+            self.last_col_played = x;
+        } else if self.game_mode == 3 {
+            let x: usize = self.get_ia2_play();
+            self.place_piece(x);
+            self.last_col_played = x;
+        }
+    }
+
+    fn get_ia1_play(&self) -> usize {
+        let mut col: usize;
+        let mut last_emp: Option<usize> = None;
+        loop {
+            col = rust_hepia_lib::gen(0, self.width as i32) as usize;
+            last_emp = self.get_last_empty(col);
+            if last_emp.is_some() {
+                return col;
+            }
+        }
+    }
+
+    fn get_ia2_play(&self) -> usize {
+        let mut x: Option<usize> = None;
+        let mut block_col: usize;
+        let mut last_emp: Option<usize> = None;
+
+        for i in 0..self.width {
+            last_emp = self.get_last_empty(i);
+            if last_emp.is_some() {
+                let y = last_emp.unwrap();
+                for j in 0..4 {
+                    if self.cnt_same_piece_line(i, y, Connect4Case::Yellow, j) >= 4 {
+                        return i;
+                    } else if self.cnt_same_piece_line(i, y, Connect4Case::Red, j) >= 4 {
+                        x = Some(i);
+                        block_col = i;
+                    }
+                }
+            }
+        }
+        if let Some(block_col) = x { // c'est dans une option car il ne pourrait ne pas y avoir de case a bloqué
+            return block_col;
+        } else {
+            return self.get_ia1_play();
+        }
+    }
+
+    fn get_last_empty(&self, col: usize) -> Option<usize> {
+        if self.board[self.height - 1][col] == Connect4Case::Empty { return Some(self.height - 1); }
+        if self.board[0][col] != Connect4Case::Empty { return None; }
+        for i in 1..self.height {
+            if self.board[i][col] != Connect4Case::Empty { return Some(i - 1); }
+        }
+        None
+    }
+
+    fn display(&self) {
+        for y in 0..self.height {
+            if y == 0 {
+                print!("┌─");
+                for _x in 1..self.width {
+                    print!("┬─");
+                }
+                println!("┐");
+            } else {
+                print!("├─");
+                for _x in 1..self.width {
+                    print!("┼─");
+                }
+                println!("┤");
+            }
+            for x in 0..self.width {
+                print!(
+                    "|{}",
+                    match self.board[y][x] {
+                        Connect4Case::Empty => ' ',
+                        Connect4Case::Red => RED_CHAR,
+                        Connect4Case::Yellow => YELLOW_CHAR,
+                    }
+                );
+                if x + 1 == self.width {
+                    print!("|");
+                }
+            }
+            println!();
+        }
+        print!("└─");
+        for _x in 1..self.width {
+            print!("┴─");
+        }
+        println!("┘");
+        for x in 1..self.width + 1 {
+            print!(" {0}", x);
+        }
+        println!();
+    }
+
+    /*fn is_won(&self) -> bool {
+        for y in 0..self.height {
+            for x in 0..self.width {
+                if self.board[y][x] != Connect4Case::Empty {
+                    if x + 3 < WIDTH {
+                        // verif horizontale
+                        if self.board[y][x + 1] == self.board[y][x]
+                            && self.board[y][x + 2] == self.board[y][x]
+                            && self.board[y][x + 3] == self.board[y][x]
+                        {
+                            return true;
+                        }
+                    }
+                    if y + 3 < HEIGHT {
+                        // verif verticale
+                        if self.board[y + 1][x] == self.board[y][x]
+                            && self.board[y + 2][x] == self.board[y][x]
+                            && self.board[y + 3][x] == self.board[y][x]
+                        {
+                            return true;
+                        }
+                    }
+                    if x + 3 < WIDTH && y + 3 < HEIGHT {
+                        // verif diagonale 1 : \
+                        if self.board[y + 1][x + 1] == self.board[y][x]
+                            && self.board[y + 2][x + 2] == self.board[y][x]
+                            && self.board[y + 3][x + 3] == self.board[y][x]
+                        {
+                            return true;
+                        }
+                    }
+                    if x >= 3 && y + 3 < HEIGHT {
+                        // verif diagonale 2 : /
+                        if self.board[y + 1][x - 1] == self.board[y][x]
+                            && self.board[y + 2][x - 2] == self.board[y][x]
+                            && self.board[y + 3][x - 3] == self.board[y][x]
+                        {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+        return false;
+    }*/
+
+    fn is_full(&self) -> bool {
+        if self.turn_count >= self.get_max_turn() {
+            true
+        } else {
+            false
+        }
+    }
+
+    fn last_play_won(&self) -> bool {
+        let mut i: usize = 0;
+
+        loop {
+            if self.board[i][self.last_col_played as usize] == Connect4Case::Empty {
+                i += 1;
+            } else {
+                break;
+            }
+        }
+        for j in 0..4 {
+            if self.cnt_same_piece_line(
+                self.last_col_played as usize,
+                i,
+                if self.is_red_turn() {
+                    Connect4Case::Red
+                } else {
+                    Connect4Case::Yellow
+                },
+                j,
+            ) >= 4
+            {
+                return true;
+            }
+        }
+        false
+    }
+
+    fn cnt_same_piece_line(&self, x: usize, y: usize, c: Connect4Case, dir: u8) -> u32 {
+        let i: u32;
+        i = self.cnt_same_piece_dir(x, y, c, dir)
+            + self.cnt_same_piece_dir(x, y, c, (dir + 4) % 8)
+            + 1;
+        i
+    }
+
+    fn cnt_same_piece_dir(&self, x: usize, y: usize, c: Connect4Case, dir: u8) -> u32 {
+        match dir {
+            0 => if y != 0 && self.board[y - 1][x] == c {
+                //north
+                return self.cnt_same_piece_dir(x, y - 1, c, dir) + 1;
+            },
+            1 => if x != self.width - 1 && y != 0 && self.board[y - 1][x + 1] == c {
+                //north-west
+                return self.cnt_same_piece_dir(x + 1, y - 1, c, dir) + 1;
+            },
+            2 => if x != self.width - 1 && self.board[y][x + 1] == c {
+                //west
+                return self.cnt_same_piece_dir(x + 1, y, c, dir) + 1;
+            },
+            3 => if x != self.width - 1 && y != self.height - 1 && self.board[y + 1][x + 1] == c {
+                //south-west
+                return self.cnt_same_piece_dir(x + 1, y + 1, c, dir) + 1;
+            },
+            4 => if y < self.height - 1 && self.board[y + 1][x] == c {
+                //south
+                return self.cnt_same_piece_dir(x, y + 1, c, dir) + 1;
+            },
+            5 => if x != 0 && y != self.height - 1 && self.board[y + 1][x - 1] == c {
+                //south-east
+                return self.cnt_same_piece_dir(x - 1, y + 1, c, dir) + 1;
+            },
+            6 => if x != 0 && self.board[y][x - 1] == c {
+                //east
+                return self.cnt_same_piece_dir(x - 1, y, c, dir) + 1;
+            },
+            7 => if x != 0 && y != 0 && self.board[y - 1][x - 1] == c {
+                //north-east
+                return self.cnt_same_piece_dir(x - 1, y - 1, c, dir) + 1;
+            },
+            _ => panic!{"Direction not valid"},
+        }
+        return 0;
+    }
+
+    pub fn play_game(&mut self) {
+        self.game_mode = Connect4::choose_game_mode();
+        self.display();
+        loop {
+            self.play_turn();
+            self.display();
+            if self.last_play_won() {
+                if self.is_red_turn() {
+                    println!("O won GG !");
+                } else {
+                    println!("X won, well played !");
+                }
+                break;
+            }
+            if self.is_full() {
+                println!("Draw, nobody won !");
+                break;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main.rs b/src/main.rs
index cd7c2fb626c599efe673ef248e02ae98ac822889..75de5ab2d1dcca3f6f2db5b1668544e8fb7e7b4b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,374 +1,6 @@
-extern crate rust_hepia_lib;
+extern crate tp5_connect4;
 
-const WIDTH: usize = 7;
-const HEIGHT: usize = 6;
-const RED_CHAR: char = 'X';
-const YELLOW_CHAR: char = 'O';
-
-#[derive(Copy, Clone, PartialEq)]
-enum Connect4Case {
-    Empty,
-    Red,
-    Yellow,
-}
-
-struct Connect4 {
-    board: [[Connect4Case; WIDTH]; HEIGHT],
-    game_mode: u8,
-    turn_count: u32,
-    last_col_played: usize,
-    width: usize,
-    height: usize,
-}
-
-impl Connect4 {
-    fn new() -> Connect4 {
-        if WIDTH < 4 || HEIGHT < 4 {
-            panic!("The connect 4 board is too short (WIDTH and HEIGHT must be at least 4)");
-        }
-        Connect4 {
-            board: [[Connect4Case::Empty; WIDTH]; HEIGHT],
-            game_mode: 0,
-            turn_count: 0,
-            last_col_played: 0,
-            width: WIDTH,
-            height: HEIGHT,
-        }
-    }
-
-    fn get_max_turn(&self) -> u32 {
-        (self.width as u32 * self.height as u32)
-    }
-
-    fn is_red_turn(&self) -> bool {
-        if self.turn_count % 2 == 1 {
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    fn choose_game_mode() -> u8 {
-        let mut x: i32;
-        loop {
-            println!("Choose your game mode : (1) Player vs Player. (2) Player vs IA, easy. (3) Player vs IA, hard.");
-            x = rust_hepia_lib::read_int();
-            match x {
-                1 | 2 | 3 => return x as u8,
-                _ => println!("This is not a valid number"),
-            }
-        }
-    }
-
-    fn place_piece(&mut self, x: usize) -> bool {
-        if x >= self.width {
-            // si on veut placer une piece en dehors du tableau
-            return false;
-        }
-        if self.board[0 as usize][x] != Connect4Case::Empty {
-            // si la colonne est deja pleine
-            return false;
-        }
-        for i in 1..self.height {
-            if self.board[i][x] != Connect4Case::Empty {
-                // on place la nouelle piece au dessus de la plus haute piece de la colonne
-                self.board[i - 1][x] = if self.is_red_turn() {
-                    Connect4Case::Red
-                } else {
-                    Connect4Case::Yellow
-                };
-                return true;
-            }
-        }
-        self.board[self.height - 1][x] = if self.is_red_turn() {
-            // si la colonne est vide
-            Connect4Case::Red
-        } else {
-            Connect4Case::Yellow
-        };
-        return true;
-    }
-
-    fn choose_col(&self) -> usize {
-        let mut col: i32;
-
-        loop {
-            println!("Choose a column (1-{})", self.width);
-            col = rust_hepia_lib::read_int();
-            if col < 1 || col > self.width as i32 {
-                println!("This is not a valid column");
-            } else {
-                return (col - 1) as usize;
-            }
-        }
-    }
-
-    fn play_turn(&mut self) {
-        self.turn_count += 1;
-        println!(
-            "This is {}'s turn !!",
-            if self.is_red_turn() { RED_CHAR } else { YELLOW_CHAR }
-        );
-        if self.is_red_turn() || self.game_mode == 1 {
-            let mut col: usize;
-            loop {
-                col = self.choose_col();
-                if !self.place_piece(col) {
-                    println!("This is not a valid column");
-                } else {
-                    self.last_col_played = col;
-                    break;
-                }
-            }
-        } else if self.game_mode == 2 {
-            let x: usize = self.get_ia1_play();
-            self.place_piece(x);
-            self.last_col_played = x;
-        } else if self.game_mode == 3 {
-            let x: usize = self.get_ia2_play();
-            self.place_piece(x);
-            self.last_col_played = x;
-        }
-    }
-
-    fn get_ia1_play(&self) -> usize {
-        let mut col: usize;
-        let mut last_emp: Option<usize> = None;
-        loop {
-            col = rust_hepia_lib::gen(0, self.width as i32) as usize;
-            last_emp = self.get_last_empty(col);
-            if last_emp.is_some() {
-                return col;
-            }
-        }
-    }
-
-    fn get_ia2_play(&self) -> usize {
-        let mut x: Option<usize> = None;
-        let mut block_col: usize;
-        let mut last_emp: Option<usize> = None;
-
-        for i in 0..self.width {
-            last_emp = self.get_last_empty(i);
-            if last_emp.is_some() {
-                let y = last_emp.unwrap();
-                for j in 0..4 {
-                    if self.cnt_same_piece_line(i, y, Connect4Case::Yellow, j) >= 4 {
-                        return i;
-                    } else if self.cnt_same_piece_line(i, y, Connect4Case::Red, j) >= 4 {
-                        x = Some(i);
-                        block_col = i;
-                    }
-                }
-            }
-        }
-        if let Some(block_col) = x {
-            return block_col;
-        } else {
-            return self.get_ia1_play();
-        }
-    }
-
-    fn get_last_empty(&self, col: usize) -> Option<usize> {
-        if self.board[self.height - 1][col] == Connect4Case::Empty { return Some(self.height - 1); }
-        if self.board[0][col] != Connect4Case::Empty { return None; }
-        for i in 1..self.height {
-            if self.board[i][col] != Connect4Case::Empty { return Some(i - 1); }
-        }
-        None
-    }
-
-    fn display(&self) {
-        for y in 0..self.height {
-            if y == 0 {
-                print!("┌─");
-                for _x in 1..self.width {
-                    print!("┬─");
-                }
-                println!("┐");
-            } else {
-                print!("├─");
-                for _x in 1..self.width {
-                    print!("┼─");
-                }
-                println!("┤");
-            }
-            for x in 0..self.width {
-                print!(
-                    "|{}",
-                    match self.board[y][x] {
-                        Connect4Case::Empty => ' ',
-                        Connect4Case::Red => RED_CHAR,
-                        Connect4Case::Yellow => YELLOW_CHAR,
-                    }
-                );
-                if x + 1 == self.width {
-                    print!("|");
-                }
-            }
-            println!();
-        }
-        print!("└─");
-        for _x in 1..self.width {
-            print!("┴─");
-        }
-        println!("┘");
-        for x in 1..self.width + 1 {
-            print!(" {0}", x);
-        }
-        println!();
-    }
-
-    /*fn is_won(&self) -> bool {
-        for y in 0..self.height {
-            for x in 0..self.width {
-                if self.board[y][x] != Connect4Case::Empty {
-                    if x + 3 < WIDTH {
-                        // verif horizontale
-                        if self.board[y][x + 1] == self.board[y][x]
-                            && self.board[y][x + 2] == self.board[y][x]
-                            && self.board[y][x + 3] == self.board[y][x]
-                        {
-                            return true;
-                        }
-                    }
-                    if y + 3 < HEIGHT {
-                        // verif verticale
-                        if self.board[y + 1][x] == self.board[y][x]
-                            && self.board[y + 2][x] == self.board[y][x]
-                            && self.board[y + 3][x] == self.board[y][x]
-                        {
-                            return true;
-                        }
-                    }
-                    if x + 3 < WIDTH && y + 3 < HEIGHT {
-                        // verif diagonale 1 : \
-                        if self.board[y + 1][x + 1] == self.board[y][x]
-                            && self.board[y + 2][x + 2] == self.board[y][x]
-                            && self.board[y + 3][x + 3] == self.board[y][x]
-                        {
-                            return true;
-                        }
-                    }
-                    if x >= 3 && y + 3 < HEIGHT {
-                        // verif diagonale 2 : /
-                        if self.board[y + 1][x - 1] == self.board[y][x]
-                            && self.board[y + 2][x - 2] == self.board[y][x]
-                            && self.board[y + 3][x - 3] == self.board[y][x]
-                        {
-                            return true;
-                        }
-                    }
-                }
-            }
-        }
-        return false;
-    }*/
-
-    fn is_full(&self) -> bool {
-        if self.turn_count >= self.get_max_turn() {
-            true
-        } else {
-            false
-        }
-    }
-
-    fn last_play_won(&self) -> bool {
-        let mut i: usize = 0;
-
-        loop {
-            if self.board[i][self.last_col_played as usize] == Connect4Case::Empty {
-                i += 1;
-            } else {
-                break;
-            }
-        }
-        for j in 0..4 {
-            if self.cnt_same_piece_line(
-                self.last_col_played as usize,
-                i,
-                if self.is_red_turn() {
-                    Connect4Case::Red
-                } else {
-                    Connect4Case::Yellow
-                },
-                j,
-            ) >= 4
-            {
-                return true;
-            }
-        }
-        false
-    }
-
-    fn cnt_same_piece_line(&self, x: usize, y: usize, c: Connect4Case, dir: u8) -> u32 {
-        let i: u32;
-        i = self.cnt_same_piece_dir(x, y, c, dir)
-            + self.cnt_same_piece_dir(x, y, c, (dir + 4) % 8)
-            + 1;
-        i
-    }
-
-    fn cnt_same_piece_dir(&self, x: usize, y: usize, c: Connect4Case, dir: u8) -> u32 {
-        match dir {
-            0 => if y != 0 && self.board[y - 1][x] == c {
-                //north
-                return self.cnt_same_piece_dir(x, y - 1, c, dir) + 1;
-            },
-            1 => if x != self.width - 1 && y != 0 && self.board[y - 1][x + 1] == c {
-                //north-west
-                return self.cnt_same_piece_dir(x + 1, y - 1, c, dir) + 1;
-            },
-            2 => if x != self.width - 1 && self.board[y][x + 1] == c {
-                //west
-                return self.cnt_same_piece_dir(x + 1, y, c, dir) + 1;
-            },
-            3 => if x != self.width - 1 && y != self.height - 1 && self.board[y + 1][x + 1] == c {
-                //south-west
-                return self.cnt_same_piece_dir(x + 1, y + 1, c, dir) + 1;
-            },
-            4 => if y < self.height - 1 && self.board[y + 1][x] == c {
-                //south
-                return self.cnt_same_piece_dir(x, y + 1, c, dir) + 1;
-            },
-            5 => if x != 0 && y != self.height - 1 && self.board[y + 1][x - 1] == c {
-                //south-east
-                return self.cnt_same_piece_dir(x - 1, y + 1, c, dir) + 1;
-            },
-            6 => if x != 0 && self.board[y][x - 1] == c {
-                //east
-                return self.cnt_same_piece_dir(x - 1, y, c, dir) + 1;
-            },
-            7 => if x != 0 && y != 0 && self.board[y - 1][x - 1] == c {
-                //north-east
-                return self.cnt_same_piece_dir(x - 1, y - 1, c, dir) + 1;
-            },
-            _ => panic!{"Direction not valid"},
-        }
-        return 0;
-    }
-
-    fn play_game(&mut self) {
-        self.game_mode = Connect4::choose_game_mode();
-        self.display();
-        loop {
-            self.play_turn();
-            self.display();
-            if self.last_play_won() {
-                if self.is_red_turn() {
-                    println!("O won GG !");
-                } else {
-                    println!("X won, well played !");
-                }
-                break;
-            }
-            if self.is_full() {
-                println!("Draw, nobody won !");
-                break;
-            }
-        }
-    }
-}
+use tp5_connect4::Connect4;
 
 fn main() {
     let mut c: Connect4 = Connect4::new();