diff --git a/Partie_3/.vscode/c_cpp_properties.json b/Partie_3/.vscode/c_cpp_properties.json
new file mode 100644
index 0000000000000000000000000000000000000000..c2098a2d0c4b96621c02cb4e33bc58231ccffc1d
--- /dev/null
+++ b/Partie_3/.vscode/c_cpp_properties.json
@@ -0,0 +1,18 @@
+{
+  "configurations": [
+    {
+      "name": "linux-gcc-x64",
+      "includePath": [
+        "${workspaceFolder}/**"
+      ],
+      "compilerPath": "/usr/bin/gcc",
+      "cStandard": "${default}",
+      "cppStandard": "${default}",
+      "intelliSenseMode": "linux-gcc-x64",
+      "compilerArgs": [
+        ""
+      ]
+    }
+  ],
+  "version": 4
+}
\ No newline at end of file
diff --git a/Partie_3/.vscode/launch.json b/Partie_3/.vscode/launch.json
new file mode 100644
index 0000000000000000000000000000000000000000..7f873a9001f36511d308c7bfb198f7e8789586d0
--- /dev/null
+++ b/Partie_3/.vscode/launch.json
@@ -0,0 +1,24 @@
+{
+  "version": "0.2.0",
+  "configurations": [
+    {
+      "name": "C/C++ Runner: Debug Session",
+      "type": "cppdbg",
+      "request": "launch",
+      "args": [],
+      "stopAtEntry": false,
+      "externalConsole": false,
+      "cwd": "/home/padi/Tรฉlรฉchargements",
+      "program": "/home/padi/Tรฉlรฉchargements/build/Debug/outDebug",
+      "MIMode": "gdb",
+      "miDebuggerPath": "gdb",
+      "setupCommands": [
+        {
+          "description": "Enable pretty-printing for gdb",
+          "text": "-enable-pretty-printing",
+          "ignoreFailures": true
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/Partie_3/.vscode/settings.json b/Partie_3/.vscode/settings.json
new file mode 100644
index 0000000000000000000000000000000000000000..3e5eb956e1aac2b053a4d09e761fcc26bb2b106e
--- /dev/null
+++ b/Partie_3/.vscode/settings.json
@@ -0,0 +1,59 @@
+{
+  "C_Cpp_Runner.cCompilerPath": "gcc",
+  "C_Cpp_Runner.cppCompilerPath": "g++",
+  "C_Cpp_Runner.debuggerPath": "gdb",
+  "C_Cpp_Runner.cStandard": "",
+  "C_Cpp_Runner.cppStandard": "",
+  "C_Cpp_Runner.msvcBatchPath": "",
+  "C_Cpp_Runner.useMsvc": false,
+  "C_Cpp_Runner.warnings": [
+    "-Wall",
+    "-Wextra",
+    "-Wpedantic",
+    "-Wshadow",
+    "-Wformat=2",
+    "-Wcast-align",
+    "-Wconversion",
+    "-Wsign-conversion",
+    "-Wnull-dereference"
+  ],
+  "C_Cpp_Runner.msvcWarnings": [
+    "/W4",
+    "/permissive-",
+    "/w14242",
+    "/w14287",
+    "/w14296",
+    "/w14311",
+    "/w14826",
+    "/w44062",
+    "/w44242",
+    "/w14905",
+    "/w14906",
+    "/w14263",
+    "/w44265",
+    "/w14928"
+  ],
+  "C_Cpp_Runner.enableWarnings": true,
+  "C_Cpp_Runner.warningsAsError": false,
+  "C_Cpp_Runner.compilerArgs": [],
+  "C_Cpp_Runner.linkerArgs": [],
+  "C_Cpp_Runner.includePaths": [],
+  "C_Cpp_Runner.includeSearch": [
+    "*",
+    "**/*"
+  ],
+  "C_Cpp_Runner.excludeSearch": [
+    "**/build",
+    "**/build/**",
+    "**/.*",
+    "**/.*/**",
+    "**/.vscode",
+    "**/.vscode/**"
+  ],
+  "C_Cpp_Runner.useAddressSanitizer": false,
+  "C_Cpp_Runner.useUndefinedSanitizer": false,
+  "C_Cpp_Runner.useLeakSanitizer": false,
+  "C_Cpp_Runner.showCompilationTime": false,
+  "C_Cpp_Runner.useLinkTimeOptimization": false,
+  "C_Cpp_Runner.msvcSecureNoWarnings": false
+}
\ No newline at end of file
diff --git a/Partie_3/pom.xml b/Partie_3/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7cb8921635687777cf25035757163633f56ebad6
--- /dev/null
+++ b/Partie_3/pom.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>ch.hepia</groupId>
+    <artifactId>Java_Card_Game</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <name>Java_Card_Game</name>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <maven.compiler.source>20</maven.compiler.source>
+        <maven.compiler.target>20</maven.compiler.target>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.11</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-controls</artifactId>
+            <version>19</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
+            <plugins>
+                <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
+                <plugin>
+                    <artifactId>maven-clean-plugin</artifactId>
+                    <version>3.1.0</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>3.8.0</version>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <version>2.22.1</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-javadoc-plugin</artifactId>
+                    <version>3.4.1</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>exec-maven-plugin</artifactId>
+                    <version>3.1.0</version>
+                    <executions>
+                        <execution>
+                            <goals>
+                                <goal>java</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                    <configuration>
+                        <mainClass>ch.hepia.App</mainClass>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+</project>
\ No newline at end of file
diff --git a/Partie_3/src/main/java/ch/hepia/App.java b/Partie_3/src/main/java/ch/hepia/App.java
new file mode 100644
index 0000000000000000000000000000000000000000..000bcecbb346a9016299fff04596f095524bc727
--- /dev/null
+++ b/Partie_3/src/main/java/ch/hepia/App.java
@@ -0,0 +1,118 @@
+package ch.hepia;
+
+import java.util.Scanner;
+
+public class App {
+
+    // Scanner will be used all along to take user inputs in the terminal
+    public static final Scanner in = new Scanner(System.in);
+
+    // All Color choices to be used in terminal prints
+    public static final String ANSI_RESET = "\u001B[0m";
+    public static final String ANSI_BLACK = "\u001B[30m";
+    public static final String ANSI_RED = "\u001B[31m";
+    public static final String ANSI_GREEN = "\u001B[32m";
+    public static final String ANSI_YELLOW = "\u001B[33m";
+    public static final String ANSI_BLUE = "\u001B[34m";
+    public static final String ANSI_PURPLE = "\u001B[35m";
+    public static final String ANSI_CYAN = "\u001B[36m";
+    public static final String ANSI_WHITE = "\u001B[37m";
+
+    public static void BlackJack() {
+
+        System.out.print("\033[H\033[2J");
+        System.out.flush();
+
+        System.out.println("*~-~* " + App.ANSI_RED + "BlackJack" + App.ANSI_RESET + " *~-~*\n");
+
+        int numPlayers;
+        int startMoney;
+
+        // Ask the number of players until a valide answer is given
+        while (true) {
+
+            System.out.print("How many players ? ");
+
+            // Check that the input is an valid int
+            while (!App.in.hasNextInt()) {
+                System.out.println(
+                        App.ANSI_YELLOW + "Please enter a valid number for the number of players." + App.ANSI_RESET);
+                System.out.print("How many players ? ");
+                App.in.next();
+            }
+
+            numPlayers = App.in.nextInt();
+
+            // Player count must be between 1 and 7
+            if (numPlayers >= 1 && numPlayers <= 7) {
+                System.out.print("");
+                break;
+            } else {
+                System.out.println(
+                        App.ANSI_YELLOW + "Please enter a number of players between 1 and 7." + App.ANSI_RESET);
+            }
+        }
+
+        // Ask the start money count for each players until a valide answer is given
+        while (true) {
+
+            System.out.print("How much money do you start with ? ");
+
+            // Check that the input is an valid int
+            while (!App.in.hasNextInt()) {
+                System.out.println(App.ANSI_YELLOW + "Please enter a valid number for your Money." + App.ANSI_RESET);
+                System.out.print("How much money do you start with ? ");
+                App.in.next();
+            }
+
+            startMoney = App.in.nextInt();
+
+            // Starting money must be more or equal to minimum bid amount
+            if (startMoney >= 10) {
+                System.out.print("");
+                break;
+            } else {
+                System.out.println(App.ANSI_YELLOW + "Please enter an amount above 10." + App.ANSI_RESET);
+            }
+        }
+
+        // Create a new game
+        GameManager BlackJack = new GameManager(numPlayers, startMoney);
+
+        boolean GameOver = false;
+
+        // Game run's in 3 Phases :
+        // Phase 1 (StartTurn):
+        // Ask the player how much he wan't to bid
+        // Phase 2 (PlayTurn):
+        // Ask the player for all his interactions with this cards
+        // Phase 3 (ResolveTurn):
+        // Make the Dealer pick cards
+        // Do all the math for the player gains and losses
+        // Check if the player can continue et prepare for the next round
+        while (!GameOver) {
+            BlackJack.StartTurn();
+            BlackJack.PlayTurn();
+            GameOver = BlackJack.ResolveTurn();
+        }
+
+        // The player has less than the minimum bid amount allowed = Game Over
+
+        System.out.print("\033[H\033[2J");
+        System.out.flush();
+
+        System.out.println("*~-~* " + App.ANSI_RED + "BlackJack" + App.ANSI_RESET + " *~-~*\n");
+
+        System.out.println(App.ANSI_PURPLE + "Game Over !" + App.ANSI_RESET);
+
+        App.in.close();
+    }
+
+    public static void main(String[] args) {
+
+        // Play 1 BlackJack Game
+        BlackJack();
+
+    }
+
+}
diff --git a/Partie_3/src/main/java/ch/hepia/Carte.java b/Partie_3/src/main/java/ch/hepia/Carte.java
new file mode 100644
index 0000000000000000000000000000000000000000..62822203bf0183413c004347b06fb1605f0dc9e6
--- /dev/null
+++ b/Partie_3/src/main/java/ch/hepia/Carte.java
@@ -0,0 +1,86 @@
+package ch.hepia;
+
+enum COULEUR {
+    coeur,
+    carreau,
+    pique,
+    trefle
+}
+
+public class Carte {
+
+    final private COULEUR couleur;
+    final private int rang;
+    final private int force;
+
+    private static final int NOMBRE_DE_RANGS = 13;
+
+    String[][] playingCards = {
+            { "๐ŸƒŸ", "๐Ÿ‚ฑ", "๐Ÿ‚ฒ", "๐Ÿ‚ณ", "๐Ÿ‚ด", "๐Ÿ‚ต", "๐Ÿ‚ถ", "๐Ÿ‚ท", "๐Ÿ‚ธ", "๐Ÿ‚น", "๐Ÿ‚บ", "๐Ÿ‚ป", "๐Ÿ‚ฝ", "๐Ÿ‚พ" },
+            { "๐ŸƒŸ", "๐Ÿƒ", "๐Ÿƒ‚", "๐Ÿƒƒ", "๐Ÿƒ„", "๐Ÿƒ…", "๐Ÿƒ†", "๐Ÿƒ‡", "๐Ÿƒˆ", "๐Ÿƒ‰", "๐ŸƒŠ", "๐Ÿƒ‹", "๐Ÿƒ", "๐ŸƒŽ" },
+            { "๐ŸƒŸ", "๐Ÿ‚ก", "๐Ÿ‚ข", "๐Ÿ‚ฃ", "๐Ÿ‚ค", "๐Ÿ‚ฅ", "๐Ÿ‚ฆ", "๐Ÿ‚ง", "๐Ÿ‚จ", "๐Ÿ‚ฉ", "๐Ÿ‚ช", "๐Ÿ‚ซ", "๐Ÿ‚ญ", "๐Ÿ‚ฎ" },
+            { "๐ŸƒŸ", "๐Ÿƒ‘", "๐Ÿƒ’", "๐Ÿƒ“", "๐Ÿƒ”", "๐Ÿƒ•", "๐Ÿƒ–", "๐Ÿƒ—", "๐Ÿƒ˜", "๐Ÿƒ™", "๐Ÿƒš", "๐Ÿƒ›", "๐Ÿƒ", "๐Ÿƒž" }
+    };
+
+    public Carte(COULEUR couleur, int rang) {
+
+        if (rang < 0 || rang > NOMBRE_DE_RANGS) {
+            throw new IllegalArgumentException("Carte invalide : rang incorrect");
+        }
+
+        this.couleur = couleur;
+        this.rang = rang;
+
+        if (rang <= 10) {
+            this.force = rang;
+        } else {
+            this.force = 10;
+        }
+
+    }
+
+    public COULEUR getCouleur() {
+
+        return this.couleur;
+
+    }
+
+    public int getRang() {
+
+        return this.rang;
+
+    }
+
+    public int getForce() {
+
+        return this.force;
+
+    }
+
+    public String getNomCouleur() {
+
+        String[] NOMS_COULEURS = { "โ™ฅ", "โ™ฆ", "โ™ ", "โ™ฃ" };
+        return NOMS_COULEURS[couleur.ordinal()];
+
+    }
+
+    public String getNomRang() {
+
+        String[] NOMS_RANGS = { "Joker", "As", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Valet", "Dame", "Roi" };
+        return NOMS_RANGS[rang];
+
+    }
+
+    public String getNomComplet() {
+        if (getRang() == 0) {
+
+            return "๐ŸƒŸ";
+
+        } else {
+
+            return playingCards[couleur.ordinal()][rang];
+
+        }
+    }
+
+}
diff --git a/Partie_3/src/main/java/ch/hepia/GameManager.java b/Partie_3/src/main/java/ch/hepia/GameManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed86be6a73e16e88492deccb74b6770ca3e3d353
--- /dev/null
+++ b/Partie_3/src/main/java/ch/hepia/GameManager.java
@@ -0,0 +1,414 @@
+package ch.hepia;
+
+import java.util.ArrayList;
+
+public class GameManager {
+
+    private JeudeCarte Deck;
+    private ArrayList<Joueur> Players;
+    private JoueurCroupier Dealer;
+    private int Step;
+
+    public GameManager(int nbPlayer, int startMoney) {
+
+        // Create a new BlackJack Deck of card (6 x 52 cards game)
+        this.Deck = new JeudeCarte(new Paquet(6, 52));
+
+        this.Players = new ArrayList<>();
+
+        // First Player is always the humain
+        this.Players.add(new JoueurHumain(Deck, startMoney));
+
+        // All other are controlled by the computer
+        if (nbPlayer > 1) {
+            for (int x = 1; x < nbPlayer; x++) {
+                this.Players.add(new JoueurOrdinateur(Deck, startMoney));
+            }
+        }
+
+        this.Dealer = new JoueurCroupier(Deck);
+    }
+
+    // Phase 1 (StartTurn):
+    // Ask the player how much he wan't to bid
+    public void StartTurn() {
+
+        this.Step = 0;
+
+        System.out.print("\033[H\033[2J");
+        System.out.flush();
+
+        System.out.println("*~-~* " + App.ANSI_RED + "BlackJack" + App.ANSI_RESET + " *~-~*\n");
+
+        double bet;
+
+        System.out.println("Money : " + App.ANSI_BLUE + this.Players.get(0).GetMoney() + App.ANSI_RESET);
+
+        // Ask the bid amount until a valide answer is given
+        while (true) {
+
+            System.out.print("How much do you want to bet (Min. 10) ? ");
+
+            // Check that the input is an valid double
+            while (!App.in.hasNextDouble()) {
+                System.out.println(App.ANSI_YELLOW + "Please enter a valid number to bet." + App.ANSI_RESET);
+                System.out.print("How much do you want to bet (Min. 10) ?");
+                App.in.next();
+            }
+
+            bet = App.in.nextDouble();
+
+            // Check if the player has enough money to place the bid
+            if (bet <= this.Players.get(0).GetMoney()) {
+
+                // Check if the minimum bid amount it cleared
+                if (bet < 10) {
+                    System.out.println(App.ANSI_YELLOW + "Minimum bid amount is 10." + App.ANSI_RESET);
+                } else {
+                    break;
+                }
+
+            } else {
+                System.out.println(App.ANSI_YELLOW + "You don't have enough money." + App.ANSI_RESET);
+            }
+        }
+
+        // Set the player bid for this turn
+        Players.get(0).SetBet(bet, 0);
+    }
+
+    // Phase 2 (PlayTurn):
+    // Ask the player for all his interactions with this cards
+    public void PlayTurn() {
+
+        boolean EndTurn = false, CanSplit = false, CanInsure = false, CanDouble = false, CanDraw = false;
+
+        // Continue interacting with the player until all actions have been taken on all
+        // his hands
+        while (!EndTurn) {
+
+            char choice = 'x';
+
+            // Go thew all hands of the player
+            for (int HandNb = 0; HandNb < this.Players.get(0).GetNbHands(); HandNb++) {
+
+                CanSplit = false;
+                CanInsure = false;
+                CanDouble = false;
+                CanDraw = false;
+                choice = 'x';
+
+                System.out.print("\033[H\033[2J");
+                System.out.flush();
+
+                System.out.println("*~-~* " + App.ANSI_RED + "BlackJack" + App.ANSI_RESET + " *~-~*\n");
+
+                // Show the remaining amount of cards in the deck
+                System.out.println(
+                        "Cards in Deck : " + App.ANSI_GREEN + this.Deck.GetNbCards() + App.ANSI_RESET + "\n");
+
+                // Dealer has only 1 card in his hand at this point in time
+                System.out
+                        .println("Dealer Strength : " + App.ANSI_PURPLE + this.Dealer.GetStrength(0) + App.ANSI_RESET);
+
+                // Show the dealer hand
+                this.Dealer.ShowHands();
+
+                // Show the current player balance
+                System.out.println("\nMoney : " + App.ANSI_BLUE + this.Players.get(0).GetMoney() + App.ANSI_RESET);
+
+                // Check if the player has put down an insurance
+                if (this.Players.get(0).HasInsured()) {
+                    System.out.println(
+                            "Insured : " + App.ANSI_BLUE + this.Players.get(0).GetInsured() + App.ANSI_RESET);
+                }
+
+                // Show the hand number of the player
+                System.out
+                        .println("Bet on Hand " + App.ANSI_GREEN + (HandNb + 1) + App.ANSI_RESET + " : " + App.ANSI_BLUE
+                                + this.Players.get(0).GetBet(HandNb) + App.ANSI_RESET);
+
+                // Show the hand strength of the player
+                // 99 = BlackJack
+                // >21 = Busted
+                // <=21 = show the strength
+                System.out
+                        .print("Strength of Hand " + App.ANSI_GREEN + (HandNb + 1) + App.ANSI_RESET + " : "
+                                + App.ANSI_PURPLE);
+                if (this.Players.get(0).GetStrength(HandNb) == 99) {
+                    System.out.println("BlackJack" + App.ANSI_RESET);
+                } else if (this.Players.get(0).GetStrength(HandNb) > 21) {
+                    System.out.println(
+                            this.Players.get(0).GetStrength(HandNb) + App.ANSI_RED + " [BUSTED]" + App.ANSI_RESET);
+                } else {
+                    System.out.println(this.Players.get(0).GetStrength(HandNb) + App.ANSI_RESET);
+                }
+
+                // Show the player hand
+                this.Players.get(0).ShowHand(HandNb);
+
+                // Choices for player
+                System.out.println("\n--- " + App.ANSI_GREEN + "Choices" + App.ANSI_RESET + " ---\n");
+
+                // Insurance
+                // Can only insure if it's the first thing that the players does
+                // AND
+                // That he hasn't already insured during this round
+                if (this.Step == 0 && this.Dealer.HasOnlyAs()
+                        && !this.Players.get(0).HasInsured()) {
+                    CanInsure = true;
+                    System.out.println(App.ANSI_BLUE + "[i]" + App.ANSI_RESET + " Insurance against Dealer");
+                }
+
+                // Split
+                // Can only split if this hand can be split (if it wasn't already split AND if
+                // the 2 cards have the same strength)
+                // AND
+                // if we have less that 3 hands already (Max 2 splits)
+                // AND
+                // if the player has enough money
+                if (this.Players.get(0).CanSplit(HandNb)
+                        && this.Players.get(0).GetNbHands() < 3
+                        && this.Players.get(0).GetBet(HandNb) <= this.Players.get(0).GetMoney()) {
+                    CanSplit = true;
+                    System.out.println(App.ANSI_BLUE + "[s]" + App.ANSI_RESET + " Split your Hand");
+                }
+
+                // Double
+                // Can only double if this hand wasn't already doubled
+                // AND
+                // if the hand has only 2 cards
+                // AND
+                // if the hand is not a BlackJack
+                // AND
+                // if the player has enough money
+                if (!this.Players.get(0).HasDoubled(HandNb)
+                        && this.Players.get(0).GetNbCards(HandNb) == 2
+                        && this.Players.get(0).GetStrength(HandNb) != 99
+                        && this.Players.get(0).GetBet(HandNb) <= this.Players.get(0).GetMoney()) {
+                    CanDouble = true;
+                    System.out.println(App.ANSI_BLUE + "[d]" + App.ANSI_RESET + " Double your Hand");
+                }
+
+                // Draw a Card (Hit)
+                // Can NOT draw if this hand was doubled AND has already 3 cards
+                // AND
+                // if the hand has been splitted with a pair of Asses
+                // AND
+                // if the player has a BlackJack
+                // AND
+                // if the strength of the hand is more than 21
+                if (!(this.Players.get(0).HasDoubled(HandNb) && this.Players.get(0).GetNbCards(HandNb) == 3)
+                        && !(this.Players.get(0).HasSplit(HandNb)
+                                && this.Players.get(0).GetCardStrength(HandNb, 0) == 1)
+                        && this.Players.get(0).GetStrength(HandNb) < 21) {
+                    CanDraw = true;
+                    System.out.println(App.ANSI_BLUE + "[h]" + App.ANSI_RESET + " Hit");
+                }
+
+                // Keep (Stand)
+                System.out.println(App.ANSI_BLUE + "[k]" + App.ANSI_RESET + " Keep current Hand");
+
+                // Ask for the player choice until a valide one is given
+                while (true) {
+                    System.out.print("> ");
+
+                    choice = App.in.next().charAt(0);
+
+                    // Choices are checked with available one for confirmation
+                    if ((choice == 'i' && CanInsure) || (choice == 's' && CanSplit) || (choice == 'd' && CanDouble)
+                            || (choice == 'h' && CanDraw)
+                            || choice == 'k') {
+                        break;
+                    } else {
+                        System.out.println(App.ANSI_YELLOW + "Please enter a valid choice." + App.ANSI_RESET);
+                    }
+                }
+
+                // Hit
+                if (choice == 'h') {
+                    this.Players.get(0).DrawCard(HandNb, this.Deck);
+                    // Go back 1 hand to stay on the same hand in the for loop
+                    HandNb--;
+                }
+                // Split
+                else if (choice == 's') {
+                    this.Players.get(0).Split(HandNb, this.Deck);
+                    // Go back 1 hand to stay on the same hand in the for loop
+                    HandNb--;
+                }
+                // Double
+                else if (choice == 'd') {
+                    this.Players.get(0).Double(HandNb, this.Deck);
+                    // Go back 1 hand to stay on the same hand in the for loop
+                    HandNb--;
+                }
+
+                Step++;
+            }
+
+            // Insure
+            if (choice == 'i') {
+                this.Players.get(0).Insure();
+                EndTurn = false;
+            }
+            // If this point is reached (and not because of the insurance), all hands have
+            // been played
+            else {
+                EndTurn = true;
+            }
+        }
+
+    }
+
+    // Phase 3 (ResolveTurn):
+    // Make the Dealer pick cards
+    // Do all the math for the player gains and losses
+    // Check if the player can continue et prepare for the next round
+    public boolean ResolveTurn() {
+
+        // Dealer draws card until he hits 17 or more
+        while (this.Dealer.GetStrength(0) <= 17) {
+            this.Dealer.DrawCard(0, this.Deck);
+        }
+
+        System.out.print("\033[H\033[2J");
+        System.out.flush();
+
+        System.out.println("*~-~* " + App.ANSI_RED + "BlackJack" + App.ANSI_RESET + " *~-~*\n");
+
+        // Show the remaining amount of cards in the deck
+        System.out.println(
+                "Cards in Deck : " + App.ANSI_GREEN + this.Deck.GetNbCards() + App.ANSI_RESET + "\n");
+
+        // Show the hand strength of the dealer
+        // 99 = BlackJack
+        // >21 = Busted
+        // <=21 = show the strength
+        System.out.print("Dealer Score : " + App.ANSI_PURPLE);
+        if (this.Dealer.GetStrength(0) == 99) {
+            System.out.println("BlackJack" + App.ANSI_RESET);
+        } else if (this.Dealer.GetStrength(0) > 21) {
+            System.out.println(this.Dealer.GetStrength(0) + App.ANSI_RED + " [BUSTED]" + App.ANSI_RESET);
+        } else {
+            System.out.println(this.Dealer.GetStrength(0) + App.ANSI_RESET);
+        }
+
+        // Show the dealers hand
+        this.Dealer.ShowHands();
+
+        // Check if the player has put down an insurance
+        if (this.Players.get(0).HasInsured()) {
+            System.out.println(
+                    "Insured : " + App.ANSI_BLUE + this.Players.get(0).GetInsured() + App.ANSI_RESET);
+        }
+
+        // Go thew all hands of the player
+        for (int HandNb = 0; HandNb < this.Players.get(0).GetNbHands(); HandNb++) {
+
+            System.out.println("\nHand " + App.ANSI_GREEN + (HandNb + 1) + App.ANSI_RESET + " :");
+
+            // Show to bet amount of the hand
+            System.out.println("\tBet : " + App.ANSI_BLUE + this.Players.get(0).GetBet(HandNb) + App.ANSI_RESET);
+
+            // Show strength of the hand of the player
+            // 99 = BlackJack
+            // >21 = Busted
+            // <=21 = show the strength
+            System.out.print("\tStrength : " + App.ANSI_PURPLE);
+            if (this.Players.get(0).GetStrength(HandNb) == 99) {
+                System.out.println("BlackJack" + App.ANSI_RESET);
+            } else if (this.Players.get(0).GetStrength(HandNb) > 21) {
+                System.out.println(
+                        this.Players.get(0).GetStrength(HandNb) + App.ANSI_RED + " [BUSTED]" + App.ANSI_RESET);
+            } else {
+                System.out.println(this.Players.get(0).GetStrength(HandNb) + App.ANSI_RESET);
+            }
+
+            // Show and apply gains and losses
+            System.out.print("\tResult : ");
+            // If the player is Busted (strength > 21 but not BlackJack (99))
+            if (this.Players.get(0).GetStrength(HandNb) > 21 && this.Players.get(0).GetStrength(HandNb) != 99) {
+                // Show player loss
+                System.out.println(App.ANSI_RED + "-" + this.Players.get(0).GetBet(HandNb) + App.ANSI_RESET);
+            }
+            // If it's a Draw
+            else if (this.Dealer.GetStrength(0) == this.Players.get(0).GetStrength(HandNb)) {
+                // Player get's back his bet
+                System.out.println(App.ANSI_BLUE + "ยฑ0" + App.ANSI_RESET);
+                this.Players.get(0).AddMoney(this.Players.get(0).GetBet(HandNb));
+            }
+            // If the player has done a BlackJack
+            else if (this.Players.get(0).GetStrength(HandNb) == 99) {
+                // Player gets payed 1.5 to 1
+                System.out.println(App.ANSI_GREEN + "+" + (this.Players.get(0).GetBet(HandNb) * 1.5) + App.ANSI_RESET);
+                this.Players.get(0).AddMoney(this.Players.get(0).GetBet(HandNb) * 2.5);
+            }
+            // If the Dealer is Busted (strength > 21 but not BlackJack (99))
+            else if (this.Dealer.GetStrength(0) > 21 && this.Dealer.GetStrength(0) != 99) {
+                // Player wins and get payed 1 to 1
+                System.out.println(App.ANSI_GREEN + "+" + this.Players.get(0).GetBet(HandNb) + App.ANSI_RESET);
+                this.Players.get(0).AddMoney(this.Players.get(0).GetBet(HandNb) * 2);
+            }
+            // If the Dealer has a better score
+            else if (this.Players.get(0).GetStrength(HandNb) < this.Dealer.GetStrength(0)) {
+                // Show player loss
+                System.out.println(App.ANSI_RED + "-" + this.Players.get(0).GetBet(HandNb) + App.ANSI_RESET);
+            }
+            // If the Player has a better score
+            else if (this.Players.get(0).GetStrength(HandNb) > this.Dealer.GetStrength(0)) {
+                // Player wins and get payed 1 to 1
+                System.out.println(App.ANSI_GREEN + "+" + this.Players.get(0).GetBet(HandNb) + App.ANSI_RESET);
+                this.Players.get(0).AddMoney(this.Players.get(0).GetBet(HandNb) * 2);
+            }
+
+        }
+
+        // Check if the player had insurance
+        if (this.Players.get(0).HasInsured()) {
+
+            System.out.print("Insurance : ");
+
+            // If the Dealer did a BackJack
+            if (this.Dealer.GetStrength(0) == 99) {
+                // Player gets payed back 2 to 1
+                System.out.println(App.ANSI_GREEN + "+" + (this.Players.get(0).GetInsured() * 3) + App.ANSI_RESET);
+                this.Players.get(0).AddMoney(this.Players.get(0).GetInsured() * 3);
+            } else {
+                // Show player loss
+                System.out.println(App.ANSI_RED + "-" + (this.Players.get(0).GetInsured()) + App.ANSI_RESET);
+            }
+        }
+
+        // Show the final player balance
+        System.out.println("\nMoney : " + App.ANSI_BLUE + this.Players.get(0).GetMoney() + App.ANSI_RESET);
+
+        System.out.print("> ");
+
+        // Wait for a simple input of the player
+        try {
+            System.in.read();
+        } catch (Exception e) {
+        }
+
+        // If the player has less than the minimum bid amount allowed
+        if (this.Players.get(0).GetMoney() <= 10) {
+            return true;
+        }
+
+        // If more thn 75% of the Deck has been used, reshuffle all cards. In our case:
+        // simply recreate a new deck
+        if (this.Deck.GetNbCards() < 78) {
+            this.Deck = new JeudeCarte(new Paquet(6, 52));
+        }
+
+        // Reset all hands
+        this.Dealer.Reset(this.Deck);
+        for (Joueur Player : this.Players) {
+            Player.Reset(this.Deck);
+        }
+
+        return false;
+    }
+
+}
diff --git a/Partie_3/src/main/java/ch/hepia/Hand.java b/Partie_3/src/main/java/ch/hepia/Hand.java
new file mode 100644
index 0000000000000000000000000000000000000000..9b5ffe0560fd90cd470596fb89ae514e328d221b
--- /dev/null
+++ b/Partie_3/src/main/java/ch/hepia/Hand.java
@@ -0,0 +1,216 @@
+package ch.hepia;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+public class Hand implements Comparable<Hand> {
+
+    private ArrayList<Carte> Hand;
+    private double Bet;
+    private boolean Splitted;
+    private boolean Doubled;
+
+    public Hand(Carte... cartes) {
+
+        this.Hand = new ArrayList<>();
+
+        for (Carte carte : cartes) {
+
+            Hand.add(carte);
+
+        }
+
+        this.Splitted = false;
+        this.Doubled = false;
+        this.Bet = 0;
+    }
+
+    public Hand(JeudeCarte game, int nb) {
+
+        this.Hand = new ArrayList<>();
+
+        this.DrawCardFromGame(game, nb);
+
+        this.Splitted = false;
+        this.Doubled = false;
+    }
+
+    public boolean HasDoubled() {
+        return this.Doubled;
+    }
+
+    public void Double() {
+        this.Doubled = true;
+        this.Bet *= 2;
+    }
+
+    public boolean HasSplit() {
+        return this.Splitted;
+    }
+
+    public void Splitted() {
+        this.Splitted = true;
+    }
+
+    public int NbCard() {
+        return this.Hand.size();
+    }
+
+    public void SetBet(double amount) {
+        if (amount < 0) {
+            throw new RuntimeException("Can't bet negative amount of money.");
+        }
+
+        this.Bet = amount;
+    }
+
+    public double GetBet() {
+        return this.Bet;
+    }
+
+    public Carte GetCarte(int cardNb) {
+        return this.Hand.get(cardNb);
+    }
+
+    public void AddCardToHand(Carte... cartes) {
+
+        for (Carte carte : cartes) {
+
+            this.Hand.add(carte);
+
+        }
+    }
+
+    public void RemoveCardFromHand(Carte... cartes) {
+
+        for (Carte carte : cartes) {
+
+            this.Hand.remove(carte);
+
+        }
+    }
+
+    public void DrawCardFromGame(JeudeCarte game) {
+
+        this.AddCardToHand(game.GetTopCarteOfGame());
+
+        game.RemoveCarteFromGame(game.GetTopCarteOfGame());
+
+    }
+
+    public void DrawCardFromGame(JeudeCarte game, int nb) {
+
+        for (int x = 0; x < nb; x++) {
+            this.DrawCardFromGame(game);
+        }
+
+    }
+
+    public void SortHand() {
+
+        Collections.sort(Hand, new Comparator<Carte>() {
+
+            public int compare(Carte carte1, Carte carte2) {
+
+                int comparaisonCouleur = carte1.getCouleur().compareTo(carte2.getCouleur());
+
+                if (comparaisonCouleur == 0) {
+
+                    return Integer.compare(carte1.getRang(), carte2.getRang());
+
+                } else {
+
+                    return comparaisonCouleur;
+                }
+            }
+
+        });
+
+    }
+
+    public int GetStrength() {
+
+        int force = 0;
+        int as = 0;
+
+        // Add strength of cards and count how much Asses there is
+        for (Carte carte : Hand) {
+            if (carte.getForce() == 1) {
+                as++;
+            }
+            force += carte.getForce();
+        }
+
+        // Test how many Asses we can but to 11 without going over 21
+        while (force < 21 && as > 0) {
+            force += 10;
+
+            as--;
+
+            if (force > 21) {
+                force -= 10;
+                as = 0;
+            }
+        }
+
+        // Edge Case = BlackJack
+        // Check if a 21 is a BlackJack (As + 10) or a combination of 3 cards
+        // (simple 21)
+        if (force == 21) {
+
+            boolean isAs = false;
+            boolean is10 = false;
+            boolean isOther = false;
+
+            for (Carte carte : Hand) {
+
+                switch (carte.getForce()) {
+                    case 1:
+                        isAs = true;
+                        break;
+                    case 10:
+                        is10 = true;
+                        break;
+                    default:
+                        isOther = true;
+                        break;
+                }
+            }
+
+            if (isAs && is10 && !isOther) {
+                return 99;
+            }
+        }
+
+        return force;
+    }
+
+    public void ShowHand() {
+
+        for (Carte carte : Hand) {
+
+            System.out.print(carte.getNomComplet() + " ");
+
+        }
+
+        System.out.println("");
+    }
+
+    // Not used but asked for Part 2
+    @Override
+    public int compareTo(Hand otherHand) {
+
+        int Hand_1_Strength = this.GetStrength();
+        int Hand_2_Strength = otherHand.GetStrength();
+
+        if (Hand_1_Strength > Hand_2_Strength) {
+            return 1;
+        } else if (Hand_1_Strength < Hand_2_Strength) {
+            return -1;
+        } else {
+            return 0;
+        }
+
+    }
+}
diff --git a/Partie_3/src/main/java/ch/hepia/JeudeCarte.java b/Partie_3/src/main/java/ch/hepia/JeudeCarte.java
new file mode 100644
index 0000000000000000000000000000000000000000..e6bd3c6c42211a33e64b76c4d0fb0f31767038cf
--- /dev/null
+++ b/Partie_3/src/main/java/ch/hepia/JeudeCarte.java
@@ -0,0 +1,123 @@
+package ch.hepia;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class JeudeCarte {
+
+    private List<Carte> jeuDeCartes;
+
+    public JeudeCarte(int nb) {
+
+        jeuDeCartes = new ArrayList<>();
+
+        for (COULEUR couleur : COULEUR.values()) {
+
+            for (int rang = 7; rang <= (nb / 4) + 6; rang++) {
+
+                if (rang > 13) {
+                    jeuDeCartes.add(new Carte(couleur, rang - 13));
+                } else {
+                    jeuDeCartes.add(new Carte(couleur, rang));
+                }
+
+            }
+
+        }
+
+        if (nb % 4 != 0) {
+
+            for (int x = 0; x < nb % 4; x++) {
+
+                jeuDeCartes.add(new Carte(COULEUR.carreau, 0));
+
+            }
+        }
+
+        Collections.sort(jeuDeCartes, new Comparator<Carte>() {
+
+            public int compare(Carte carte1, Carte carte2) {
+
+                int comparaisonCouleur = carte1.getCouleur().compareTo(carte2.getCouleur());
+
+                if (comparaisonCouleur == 0) {
+
+                    return Integer.compare(carte1.getRang(), carte2.getRang());
+
+                } else {
+
+                    return comparaisonCouleur;
+                }
+            }
+
+        });
+
+    }
+
+    public JeudeCarte(Paquet paquet) {
+
+        jeuDeCartes = new ArrayList<>();
+
+        List<JeudeCarte> paquets = paquet.getPaquet();
+
+        for (JeudeCarte deck : paquets) {
+            List<Carte> cartes = deck.getCartes();
+            jeuDeCartes.addAll(cartes);
+        }
+
+    }
+
+    public List<Carte> getCartes() {
+        return this.jeuDeCartes;
+    }
+
+    public Carte GetTopCarteOfGame() {
+
+        return this.jeuDeCartes.get(0);
+
+    }
+
+    public void AddCarteToGame(Carte... cartes) {
+
+        for (Carte carte : cartes) {
+
+            this.jeuDeCartes.add(carte);
+
+        }
+    }
+
+    public void RemoveCarteFromGame(Carte... cartes) {
+
+        for (Carte carte : cartes) {
+
+            this.jeuDeCartes.remove(carte);
+
+        }
+    }
+
+    public void shuffle() {
+
+        Collections.shuffle(jeuDeCartes);
+
+    }
+
+    public int GetNbCards() {
+        return this.jeuDeCartes.size();
+    }
+
+    public void ShowPaquet() {
+
+        System.out.println("------- Paquet -------");
+
+        for (Carte carte : jeuDeCartes) {
+
+            System.out.println(carte.getNomComplet());
+
+        }
+
+        System.out.println("----------------------");
+    }
+
+}
diff --git a/Partie_3/src/main/java/ch/hepia/Joueur.java b/Partie_3/src/main/java/ch/hepia/Joueur.java
new file mode 100644
index 0000000000000000000000000000000000000000..07d998787b9dcc9e0d5ba4435b31a4ed382085cb
--- /dev/null
+++ b/Partie_3/src/main/java/ch/hepia/Joueur.java
@@ -0,0 +1,754 @@
+package ch.hepia;
+
+import java.util.ArrayList;
+
+interface Joueur {
+
+    // Set the Play strategy
+    public void SetStrategy();
+
+    // Add amount of money to the player balance
+    public void AddMoney(double amount);
+
+    // Remove amount of money from the player balance
+    public void RemoveMoney(double amount);
+
+    // Get the current balance of the player
+    public double GetMoney();
+
+    // Set bet amount on specific player hand
+    public void SetBet(double amount, int handNb);
+
+    // Get the bet amount from specific hand
+    public double GetBet(int handNb);
+
+    // Draw 1 card in specific hand from specific Deck
+    public void DrawCard(int handNb, JeudeCarte Jeu);
+
+    // Get a specific card strength from a specific hand
+    public int GetCardStrength(int handNb, int cardNb);
+
+    // Get number of cards in specific hand
+    public int GetNbCards(int handNb);
+
+    // Show specific hand in terminal
+    public void ShowHand(int handNb);
+
+    // Show all hands in terminal
+    public void ShowHands();
+
+    // Get the number of hands of the player
+    public int GetNbHands();
+
+    // Get the strength of a specific hand
+    public int GetStrength(int handNb);
+
+    // Double the bet on specific hand
+    public void Double(int handNb, JeudeCarte Jeu);
+
+    // Check if a specific hand has been doubled
+    public boolean HasDoubled(int handNb);
+
+    // Check if a specific hand can be split
+    public boolean CanSplit(int handNb);
+
+    // Split a specific hand
+    public void Split(int handNb, JeudeCarte Jeu);
+
+    // Check if a specific hand was splitted
+    public boolean HasSplit(int handNb);
+
+    // Insure the player
+    public void Insure();
+
+    // Get player insured amount
+    public double GetInsured();
+
+    // Has the player insured himself
+    public boolean HasInsured();
+
+    // Reset player for next turn
+    public void Reset(JeudeCarte Jeu);
+}
+
+// Human Player
+class JoueurHumain implements Joueur {
+
+    private ArrayList<Hand> Hands;
+    private double Money;
+    private double Insurance;
+    private boolean Insured;
+
+    public JoueurHumain(JeudeCarte Jeu, int Money) {
+
+        this.Hands = new ArrayList<>();
+
+        // At creation, player get's 1 hand with 2 cards
+        this.Hands.add(new Hand(Jeu, 2));
+
+        this.Hands.get(0).SetBet(0);
+
+        this.Money = Money;
+        this.Insurance = 0;
+        this.Insured = false;
+    }
+
+    public void SetStrategy() {
+        // Human player has no strategy
+        throw new RuntimeException("Humain Player has no Strategy.");
+    }
+
+    public void AddMoney(double amount) {
+
+        // Check if the amount is positif and that it will not create an Overflow
+        if (amount < 0) {
+            throw new RuntimeException("Can't add negative amount of Money.");
+        } else if (this.Money > 0 && this.Money + amount < 0) {
+            throw new RuntimeException("Money Overflow.");
+        }
+
+        // Add money to current balance
+        this.Money += amount;
+    }
+
+    public void RemoveMoney(double amount) {
+
+        // Check if the amount is positif and that it will not create an Underflow
+        if (amount < 0) {
+            throw new RuntimeException("Can't subtract negative amount of Money.");
+        } else if (this.Money < 0 && this.Money + amount > 0) {
+            throw new RuntimeException("Money Underflow.");
+        }
+
+        // Remove money from current balance
+        this.Money -= amount;
+    }
+
+    public double GetMoney() {
+        return this.Money;
+    }
+
+    public void SetBet(double amount, int handNb) {
+
+        // Check if the amount is positif
+        if (amount <= 0) {
+            throw new RuntimeException("Can't bet a negative or null amount.");
+        }
+        // Check if the player has enough money in his balance
+        else if (amount > this.Money) {
+            throw new RuntimeException("Can't bet more than the Money you have.");
+        }
+
+        // Check if the hand ID is valide
+        if (handNb < 0 || handNb > Hands.size()) {
+            throw new RuntimeException("Hand number not valid.");
+        }
+
+        // Remove amount from player balance
+        this.Money -= amount;
+
+        // Set bet on player hand
+        this.Hands.get(handNb).SetBet(amount);
+    }
+
+    public double GetBet(int handNb) {
+
+        // Check if the hand ID is valide
+        if (handNb < 0 || handNb > Hands.size()) {
+            throw new RuntimeException("Hand number not valid.");
+        }
+
+        // Get the bet amount on this hand
+        return this.Hands.get(handNb).GetBet();
+    }
+
+    public void DrawCard(int handNb, JeudeCarte Jeu) {
+
+        // Check if the hand ID is valide
+        if (handNb < 0 || handNb > Hands.size()) {
+            throw new RuntimeException("Hand number not valid.");
+        }
+
+        // Draw 1 card from of Deck in hand
+        this.Hands.get(handNb).DrawCardFromGame(Jeu);
+    }
+
+    public int GetCardStrength(int handNb, int cardNb) {
+        return this.Hands.get(handNb).GetCarte(cardNb).getForce();
+    }
+
+    public int GetNbCards(int handNb) {
+        return this.Hands.get(handNb).NbCard();
+    }
+
+    public void ShowHand(int handNb) {
+
+        // Check if the hand ID is valide
+        if (handNb < 0 || handNb > Hands.size()) {
+            throw new RuntimeException("Hand number not valid.");
+        }
+
+        // Show hand in terminal
+        this.Hands.get(handNb).ShowHand();
+    }
+
+    public void ShowHands() {
+
+        // Go threw all hands
+        for (Hand hand : this.Hands) {
+
+            // Show the hand in terminal
+            hand.ShowHand();
+        }
+    }
+
+    public int GetNbHands() {
+        return this.Hands.size();
+    }
+
+    public int GetStrength(int handNb) {
+
+        // If the strength is a BlackJack
+        // AND
+        // The hand was splitted
+        // OR
+        // It's not the 1rst hand
+        // OR
+        // There are more than 2 cards in the hand
+        if (this.Hands.get(handNb).GetStrength() == 99
+                && (this.Hands.get(handNb).HasSplit() || handNb != 0 || this.Hands.get(handNb).NbCard() != 2)) {
+            // Than it is not a BlackJack but a simple 21
+            return 21;
+        } else {
+            return this.Hands.get(handNb).GetStrength();
+        }
+
+    }
+
+    public void Double(int handNb, JeudeCarte Jeu) {
+
+        // Remove bet amount from money
+        this.RemoveMoney(this.Hands.get(handNb).GetBet());
+
+        // Double the bet in the hand
+        this.Hands.get(handNb).Double();
+
+        // If hte player doubles a hand he must draw 1 card
+        this.Hands.get(handNb).DrawCardFromGame(Jeu);
+    }
+
+    public boolean HasDoubled(int handNb) {
+        return this.Hands.get(handNb).HasDoubled();
+    }
+
+    public boolean CanSplit(int handNb) {
+
+        // Hand can be split
+        // If it hasn't already been spit with an As
+        // AND
+        // if the 2 cards are the same
+        // AND
+        // if there is only 2 cards in the hands
+        if (!(this.Hands.get(handNb).HasSplit() && this.Hands.get(handNb).GetCarte(0).getForce() == 1)
+                && this.Hands.get(handNb).GetCarte(0).getForce() == this.Hands.get(handNb).GetCarte(1).getForce()
+                && this.Hands.get(handNb).NbCard() == 2) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public void Split(int handNb, JeudeCarte Jeu) {
+
+        // Player can only have 3 hands
+        if (this.Hands.size() == 3) {
+            throw new RuntimeException("Max number of splits.");
+        }
+
+        // Get the 2nd card of the hand we want to split
+        Carte card = this.Hands.get(handNb).GetCarte(1);
+
+        // Create a new hand with this card in it
+        this.Hands.add(new Hand(card));
+
+        // Remove the card from the 1rst hand
+        this.Hands.get(handNb).RemoveCardFromHand(card);
+
+        // Set the hand as splitted
+        this.Hands.get(handNb).Splitted();
+
+        // Set the new hand as splitted
+        this.Hands.get(this.Hands.size() - 1).Splitted();
+
+        // Set the bet of the new hand to the same as the splitted hand
+        this.Hands.get(this.Hands.size() - 1).SetBet(this.Hands.get(handNb).GetBet());
+
+        // Remove the money from the player balance
+        this.RemoveMoney(this.Hands.get(handNb).GetBet());
+
+        // Draw 1 card in each hands
+        this.Hands.get(handNb).DrawCardFromGame(Jeu);
+        this.Hands.get(this.Hands.size() - 1).DrawCardFromGame(Jeu);
+    }
+
+    public boolean HasSplit(int handNb) {
+        return this.Hands.get(handNb).HasSplit();
+    }
+
+    public void Insure() {
+
+        this.Insured = true;
+
+        // Set the insurance the half the bet of the only player hand
+        this.Insurance = this.Hands.get(0).GetBet() / 2;
+
+        // Remove the insurance from the player balance
+        this.RemoveMoney(this.Insurance);
+    }
+
+    public double GetInsured() {
+        return this.Insurance;
+    }
+
+    public boolean HasInsured() {
+        return this.Insured;
+    }
+
+    public void Reset(JeudeCarte Jeu) {
+
+        this.Insured = false;
+
+        // Reset hands
+        this.Hands = new ArrayList<>();
+
+        // Draw 2 card from Deck
+        this.Hands.add(new Hand(Jeu, 2));
+
+        this.Hands.get(0).SetBet(0);
+    }
+}
+
+// Computer Player
+class JoueurOrdinateur implements Joueur {
+
+    private ArrayList<Hand> Hands;
+    private double Money;
+    private double Insurance;
+    private boolean Insured;
+
+    public JoueurOrdinateur(JeudeCarte Jeu, int Money) {
+
+        this.Hands = new ArrayList<>();
+
+        // At creation, player get's 1 hand with 2 cards
+        Hands.add(new Hand(Jeu, 2));
+
+        Hands.get(0).SetBet(0);
+
+        this.Money = Money;
+        this.Insurance = 0;
+        this.Insured = false;
+    }
+
+    public void SetStrategy() {
+        // TODO
+        // Will be implemented in Part 3 of the project
+    }
+
+    public void AddMoney(double amount) {
+
+        // Check if the amount is positif and that it will not create an Overflow
+        if (amount < 0) {
+            throw new RuntimeException("Can't add negative amount of Money.");
+        } else if (this.Money > 0 && this.Money + amount < 0) {
+            throw new RuntimeException("Money Overflow.");
+        }
+
+        // Add amount from current player balance
+        this.Money += amount;
+    }
+
+    public void RemoveMoney(double amount) {
+
+        // Check if the amount is positif and that it will not create an Underflow
+        if (amount < 0) {
+            throw new RuntimeException("Can't subtract negative amount of Money.");
+        } else if (this.Money < 0 && this.Money + amount > 0) {
+            throw new RuntimeException("Money Underflow.");
+        }
+
+        // Remove amount from current player balance
+        this.Money -= amount;
+    }
+
+    public double GetMoney() {
+        return this.Money;
+    }
+
+    public void SetBet(double amount, int handNb) {
+
+        // Check if the amount is positif
+        if (amount <= 0) {
+            throw new RuntimeException("Can't bet a negative or null amount.");
+        }
+        // Check if the player has enough money in his balance
+        else if (amount > this.Money) {
+            throw new RuntimeException("Can't bet more than the Money you have.");
+        }
+
+        // Check if the hand ID is valide
+        if (handNb < 0 || handNb > Hands.size()) {
+            throw new RuntimeException("Hand number not valid.");
+        }
+
+        // Remove amount from player balance
+        this.Money -= amount;
+
+        // Set bet on player hand
+        this.Hands.get(handNb).SetBet(amount);
+    }
+
+    public double GetBet(int handNb) {
+
+        // Check if the hand ID is valide
+        if (handNb < 0 || handNb > Hands.size()) {
+            throw new RuntimeException("Hand number not valid.");
+        }
+
+        // Get the bet amount on this hand
+        return this.Hands.get(handNb).GetBet();
+    }
+
+    public void DrawCard(int handNb, JeudeCarte Jeu) {
+
+        // Check if the hand ID is valide
+        if (handNb < 0 || handNb > Hands.size()) {
+            throw new RuntimeException("Hand number not valid.");
+        }
+
+        // Draw 1 card from of Deck in hand
+        this.Hands.get(handNb).DrawCardFromGame(Jeu);
+    }
+
+    public int GetCardStrength(int handNb, int cardNb) {
+        return this.Hands.get(handNb).GetCarte(cardNb).getForce();
+    }
+
+    public int GetNbCards(int handNb) {
+        return this.Hands.get(handNb).NbCard();
+    }
+
+    public void ShowHand(int handNb) {
+
+        // Check if the hand ID is valide
+        if (handNb < 0 || handNb > Hands.size()) {
+            throw new RuntimeException("Hand number not valid.");
+        }
+
+        // Show hand in terminal
+        this.Hands.get(handNb).ShowHand();
+    }
+
+    public void ShowHands() {
+
+        // Go threw all hands
+        for (Hand hand : this.Hands) {
+
+            // Show the hand in terminal
+            hand.ShowHand();
+        }
+    }
+
+    public int GetNbHands() {
+        return this.Hands.size();
+    }
+
+    public int GetStrength(int handNb) {
+
+        // If the strength is a BlackJack
+        // AND
+        // The hand was splitted
+        // OR
+        // It's not the 1rst hand
+        // OR
+        // There are more than 2 cards in the hand
+        if (this.Hands.get(handNb).GetStrength() == 99
+                && (this.Hands.get(handNb).HasSplit() || handNb != 0 || this.Hands.get(handNb).NbCard() != 2)) {
+            // Than it is not a BlackJack but a simple 21
+            return 21;
+        } else {
+            return this.Hands.get(handNb).GetStrength();
+        }
+
+    }
+
+    public void Double(int handNb, JeudeCarte Jeu) {
+
+        // Remove bet amount from money
+        this.RemoveMoney(this.Hands.get(handNb).GetBet());
+
+        // Double the bet in the hand
+        this.Hands.get(handNb).Double();
+
+        // If hte player doubles a hand he must draw 1 card
+        this.Hands.get(handNb).DrawCardFromGame(Jeu);
+    }
+
+    public boolean HasDoubled(int handNb) {
+        return this.Hands.get(handNb).HasDoubled();
+    }
+
+    public boolean CanSplit(int handNb) {
+
+        // Hand can be split
+        // If it hasn't already been spit with an As
+        // AND
+        // if the 2 cards are the same
+        // AND
+        // if there is only 2 cards in the hands
+        if (!(this.Hands.get(handNb).HasSplit() && this.Hands.get(handNb).GetCarte(0).getForce() == 1)
+                && this.Hands.get(handNb).GetCarte(0).getForce() == this.Hands.get(handNb).GetCarte(1).getForce()
+                && this.Hands.get(handNb).NbCard() == 2) {
+            return true;
+        }
+
+        return false;
+    }
+
+    public void Split(int handNb, JeudeCarte Jeu) {
+
+        // Player can only have 3 hands
+        if (this.Hands.size() == 3) {
+            throw new RuntimeException("Max number of splits.");
+        }
+
+        // Get the 2nd card of the hand we want to split
+        Carte card = this.Hands.get(handNb).GetCarte(1);
+
+        // Create a new hand with this card in it
+        this.Hands.add(new Hand(card));
+
+        // Remove the card from the 1rst hand
+        this.Hands.get(handNb).RemoveCardFromHand(card);
+
+        // Set the hand as splitted
+        this.Hands.get(handNb).Splitted();
+
+        // Set the new hand as splitted
+        this.Hands.get(this.Hands.size() - 1).Splitted();
+
+        // Set the bet of the new hand to the same as the splitted hand
+        this.Hands.get(this.Hands.size() - 1).SetBet(this.Hands.get(handNb).GetBet());
+
+        // Remove the money from the player balance
+        this.RemoveMoney(this.Hands.get(handNb).GetBet());
+
+        // Draw 1 card in each hands
+        this.Hands.get(handNb).DrawCardFromGame(Jeu);
+        this.Hands.get(this.Hands.size() - 1).DrawCardFromGame(Jeu);
+    }
+
+    public boolean HasSplit(int handNb) {
+        return this.Hands.get(handNb).HasSplit();
+    }
+
+    public void Insure() {
+
+        this.Insured = true;
+
+        // Set the insurance the half the bet of the only player hand
+        this.Insurance = this.Hands.get(0).GetBet() / 2;
+
+        // Remove the insurance from the player balance
+        this.RemoveMoney(this.Insurance);
+    }
+
+    public double GetInsured() {
+        return this.Insurance;
+    }
+
+    public boolean HasInsured() {
+        return this.Insured;
+    }
+
+    public void Reset(JeudeCarte Jeu) {
+
+        this.Insured = false;
+
+        // Reset hands
+        this.Hands = new ArrayList<>();
+
+        // Draw 2 card from Deck
+        this.Hands.add(new Hand(Jeu, 2));
+
+        this.Hands.get(0).SetBet(0);
+    }
+}
+
+// Dealer
+class JoueurCroupier implements Joueur {
+
+    private Hand Hand;
+
+    public JoueurCroupier(JeudeCarte Jeu) {
+        this.Hand = new Hand(Jeu, 1);
+    }
+
+    public void SetStrategy() {
+        // Dealer has no strategy
+        throw new RuntimeException("Dealer has no Strategy.");
+    }
+
+    public void AddMoney(double amount) {
+        // Dealer has infinite amount of money
+        throw new RuntimeException("Dealer has no Money.");
+    }
+
+    public void RemoveMoney(double amount) {
+        // Dealer has infinite amount of money
+        throw new RuntimeException("Dealer has no Money.");
+    }
+
+    public double GetMoney() {
+        // Dealer has infinite amount of money
+        throw new RuntimeException("Dealer has no Money.");
+    }
+
+    public void SetBet(double amount, int handNb) {
+        // Dealer doesn't bet
+        throw new RuntimeException("Dealer doesn't Bet.");
+    }
+
+    public double GetBet(int handNb) {
+        // Dealer doesn't bet
+        throw new RuntimeException("Dealer doesn't Bet.");
+    }
+
+    public void DrawCard(int handNb, JeudeCarte Jeu) {
+
+        // Dealer has only 1 hand
+        if (handNb != 0) {
+            throw new RuntimeException("Dealer has only 1 hand.");
+        }
+
+        // Draw 1 card from of Deck in hand
+        this.Hand.DrawCardFromGame(Jeu);
+    }
+
+    public int GetCardStrength(int handNb, int cardNb) {
+        return this.Hand.GetCarte(cardNb).getForce();
+    }
+
+    public int GetNbCards(int handNb) {
+        return this.Hand.NbCard();
+    }
+
+    public void ShowHand(int handNb) {
+
+        // Dealer has only 1 hand
+        if (handNb != 0) {
+            throw new RuntimeException("Dealer has only 1 hand.");
+        }
+
+        // Show hand in terminal
+        this.Hand.ShowHand();
+    }
+
+    public void ShowHands() {
+
+        // Show hand in terminal (only 1 for the Dealer)
+        this.Hand.ShowHand();
+    }
+
+    public int GetNbHands() {
+
+        // Dealer has only 1 hand
+        return 1;
+    }
+
+    public int GetStrength(int handNb) {
+
+        // Dealer has only 1 hand
+        if (handNb != 0) {
+            throw new RuntimeException("Bank has only 1 hand.");
+        }
+
+        // If the strength is a BlackJack
+        // AND
+        // The hand was splitted
+        // OR
+        // It's not the 1rst hand
+        // OR
+        // There are more than 2 cards in the hand
+        if (this.Hand.GetStrength() == 99
+                && (this.Hand.HasSplit() || handNb != 0 || this.Hand.NbCard() != 2)) {
+            // Than it is not a BlackJack but a simple 21
+            return 21;
+        } else {
+            return this.Hand.GetStrength();
+        }
+
+    }
+
+    public void Double(int handNb, JeudeCarte Jeu) {
+        // Dealer does not bet
+        throw new RuntimeException("Dealer can't Double.");
+    }
+
+    public boolean HasDoubled(int handNb) {
+        // Dealer does not bet
+        throw new RuntimeException("Dealer can't Double.");
+    }
+
+    public boolean CanSplit(int handNb) {
+        // Dealer can't split
+        throw new RuntimeException("Dealer can't Split.");
+    }
+
+    public void Split(int handNb, JeudeCarte Jeu) {
+        // Dealer can't split
+        throw new RuntimeException("Dealer can't Split.");
+
+    }
+
+    public boolean HasSplit(int handNb) {
+        // Dealer can't split
+        throw new RuntimeException("Dealer can't split.");
+    }
+
+    public void Insure() {
+        // Dealer can't insure himself against himself
+        throw new RuntimeException("Dealer can't get Insurance.");
+    }
+
+    public double GetInsured() {
+        // Dealer can't insure himself against himself
+        throw new RuntimeException("Dealer can't get Insurance.");
+    }
+
+    public boolean HasInsured() {
+        // Dealer can't insure himself against himself
+        throw new RuntimeException("Dealer can't get Insurance.");
+
+    }
+
+    public void Reset(JeudeCarte Jeu) {
+
+        // Create a new hand with 1 card
+        this.Hand = new Hand(Jeu, 1);
+    }
+
+    // Check if the Dealer only has an As in this hand (for Insurance)
+    public boolean HasOnlyAs() {
+
+        // If the first card in hand is an As
+        // AND
+        // There is only 1 card in the hand
+        if (this.Hand.GetCarte(0).getNomRang() == "As" && this.Hand.NbCard() == 1) {
+            return true;
+        }
+
+        return false;
+    }
+
+}
diff --git a/Partie_3/src/main/java/ch/hepia/Paquet.java b/Partie_3/src/main/java/ch/hepia/Paquet.java
new file mode 100644
index 0000000000000000000000000000000000000000..43311c54e7d597eb450df72bd20fe2100d251e49
--- /dev/null
+++ b/Partie_3/src/main/java/ch/hepia/Paquet.java
@@ -0,0 +1,25 @@
+package ch.hepia;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public class Paquet {
+
+    private List<JeudeCarte> paquet;
+
+    public Paquet(int nb_paquet, int nb_carte) {
+
+        paquet = new ArrayList<>();
+
+        for (int i = 0; i < nb_paquet; ++i) {
+            JeudeCarte jeuDeCarte = new JeudeCarte(nb_carte);
+            jeuDeCarte.shuffle();
+            paquet.add(jeuDeCarte);
+        }
+
+    }
+
+    public List<JeudeCarte> getPaquet() {
+        return paquet;
+    }
+}
diff --git a/Partie_3/src/test/java/ch/hepia/CarteTest.java b/Partie_3/src/test/java/ch/hepia/CarteTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..f1ac133fe7f7a24190d80d303fd27399edda526f
--- /dev/null
+++ b/Partie_3/src/test/java/ch/hepia/CarteTest.java
@@ -0,0 +1,49 @@
+package ch.hepia;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+
+public class CarteTest {
+
+    @Test
+    public void testGetCouleur() {
+        Carte carte = new Carte(COULEUR.coeur, 2);
+        assertEquals(COULEUR.coeur, carte.getCouleur());
+    }
+
+    @Test
+    public void testGetRang() {
+        Carte carte = new Carte(COULEUR.carreau, 7);
+        assertEquals(7, carte.getRang());
+    }
+
+    @Test
+    public void testGetForce() {
+        Carte carte = new Carte(COULEUR.trefle, 12, 10);
+        assertEquals(10, carte.getForce());
+    }
+
+    @Test
+    public void testGetNomCouleur() {
+        Carte carte = new Carte(COULEUR.coeur, 0);
+        assertEquals("Coeur", carte.getNomCouleur());
+    }
+
+    @Test
+    public void testGetNomRang() {
+        Carte carte = new Carte(COULEUR.coeur, 2);
+        assertEquals("2", carte.getNomRang());
+    }
+
+    @Test
+    public void testGetNomComplet() {
+        Carte carte = new Carte(COULEUR.carreau, 12);
+        assertEquals("Dame de Carreau", carte.getNomComplet());
+    }
+
+    @Test
+    public void testGetNomComplet_2() {
+        Carte carte = new Carte(COULEUR.carreau, 0);
+        assertEquals("Joker", carte.getNomComplet());
+    }
+}
\ No newline at end of file
diff --git a/Partie_3/target/classes/ch/hepia/App.class b/Partie_3/target/classes/ch/hepia/App.class
new file mode 100644
index 0000000000000000000000000000000000000000..7b2a1df8e106d74a6b78784c9f545cf4350d308a
Binary files /dev/null and b/Partie_3/target/classes/ch/hepia/App.class differ
diff --git a/Partie_3/target/classes/ch/hepia/COULEUR.class b/Partie_3/target/classes/ch/hepia/COULEUR.class
new file mode 100644
index 0000000000000000000000000000000000000000..c38a76f38b5f56aec3100849ad749e77c1255bcd
Binary files /dev/null and b/Partie_3/target/classes/ch/hepia/COULEUR.class differ
diff --git a/Partie_3/target/classes/ch/hepia/Carte.class b/Partie_3/target/classes/ch/hepia/Carte.class
new file mode 100644
index 0000000000000000000000000000000000000000..bb77e1a2cf2b2c55d68d07f73a271f6ad870f1c6
Binary files /dev/null and b/Partie_3/target/classes/ch/hepia/Carte.class differ
diff --git a/Partie_3/target/classes/ch/hepia/GameManager.class b/Partie_3/target/classes/ch/hepia/GameManager.class
new file mode 100644
index 0000000000000000000000000000000000000000..deab1ca162c602940cf4df190de3e8751b0ad034
Binary files /dev/null and b/Partie_3/target/classes/ch/hepia/GameManager.class differ
diff --git a/Partie_3/target/classes/ch/hepia/Hand$1.class b/Partie_3/target/classes/ch/hepia/Hand$1.class
new file mode 100644
index 0000000000000000000000000000000000000000..e2750c39ec1ee0ffda4f715b78a572443a2da898
Binary files /dev/null and b/Partie_3/target/classes/ch/hepia/Hand$1.class differ
diff --git a/Partie_3/target/classes/ch/hepia/Hand.class b/Partie_3/target/classes/ch/hepia/Hand.class
new file mode 100644
index 0000000000000000000000000000000000000000..a5d795896fe3549efa725a1873962850a6211e6f
Binary files /dev/null and b/Partie_3/target/classes/ch/hepia/Hand.class differ
diff --git a/Partie_3/target/classes/ch/hepia/JeudeCarte$1.class b/Partie_3/target/classes/ch/hepia/JeudeCarte$1.class
new file mode 100644
index 0000000000000000000000000000000000000000..e87f2ad85071fb1b622c4a955974eae6caf97a63
Binary files /dev/null and b/Partie_3/target/classes/ch/hepia/JeudeCarte$1.class differ
diff --git a/Partie_3/target/classes/ch/hepia/JeudeCarte.class b/Partie_3/target/classes/ch/hepia/JeudeCarte.class
new file mode 100644
index 0000000000000000000000000000000000000000..7c84a24a016f03fff7d97c2fd8eab208948f7fbf
Binary files /dev/null and b/Partie_3/target/classes/ch/hepia/JeudeCarte.class differ
diff --git a/Partie_3/target/classes/ch/hepia/Joueur.class b/Partie_3/target/classes/ch/hepia/Joueur.class
new file mode 100644
index 0000000000000000000000000000000000000000..5e4728e620596c8ce4d971e1d94e4d16b7f6bac8
Binary files /dev/null and b/Partie_3/target/classes/ch/hepia/Joueur.class differ
diff --git a/Partie_3/target/classes/ch/hepia/JoueurCroupier.class b/Partie_3/target/classes/ch/hepia/JoueurCroupier.class
new file mode 100644
index 0000000000000000000000000000000000000000..1a117b2e6248aecff4b395b75018848c471b8526
Binary files /dev/null and b/Partie_3/target/classes/ch/hepia/JoueurCroupier.class differ
diff --git a/Partie_3/target/classes/ch/hepia/JoueurHumain.class b/Partie_3/target/classes/ch/hepia/JoueurHumain.class
new file mode 100644
index 0000000000000000000000000000000000000000..733a8e929c37ad44af07e0311c79cabaeee685a9
Binary files /dev/null and b/Partie_3/target/classes/ch/hepia/JoueurHumain.class differ
diff --git a/Partie_3/target/classes/ch/hepia/JoueurOrdinateur.class b/Partie_3/target/classes/ch/hepia/JoueurOrdinateur.class
new file mode 100644
index 0000000000000000000000000000000000000000..b83e6a0bea0dd6f64078eaf509636401c3c5324e
Binary files /dev/null and b/Partie_3/target/classes/ch/hepia/JoueurOrdinateur.class differ
diff --git a/Partie_3/target/classes/ch/hepia/Paquet.class b/Partie_3/target/classes/ch/hepia/Paquet.class
new file mode 100644
index 0000000000000000000000000000000000000000..79dc7afd66ab47cc77bb82fcf6c5682425eccc23
Binary files /dev/null and b/Partie_3/target/classes/ch/hepia/Paquet.class differ
diff --git a/Partie_3/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/Partie_3/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000000000000000000000000000000000000..814b85978aca0dc13df7846ffc2a5d7617a2ea2d
--- /dev/null
+++ b/Partie_3/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,7 @@
+ch/hepia/Hand.class
+ch/hepia/JeudeCarte.class
+ch/hepia/Carte.class
+ch/hepia/App.class
+ch/hepia/COULEUR.class
+ch/hepia/Hand$1.class
+ch/hepia/Paquet.class
diff --git a/Partie_3/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/Partie_3/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000000000000000000000000000000000000..8643c6b1229fa6a0b75a7a07c874984c3b9ad5f8
--- /dev/null
+++ b/Partie_3/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,7 @@
+/home/padi/Git/java-card-game/Partie_2/src/main/java/ch/hepia/Hand.java
+/home/padi/Git/java-card-game/Partie_2/src/main/java/ch/hepia/Carte.java
+/home/padi/Git/java-card-game/Partie_2/src/main/java/ch/hepia/Joueur.java
+/home/padi/Git/java-card-game/Partie_2/src/main/java/ch/hepia/GameManager.java
+/home/padi/Git/java-card-game/Partie_2/src/main/java/ch/hepia/App.java
+/home/padi/Git/java-card-game/Partie_2/src/main/java/ch/hepia/Paquet.java
+/home/padi/Git/java-card-game/Partie_2/src/main/java/ch/hepia/JeudeCarte.java
diff --git a/Partie_3/target/test-classes/ch/hepia/CarteTest.class b/Partie_3/target/test-classes/ch/hepia/CarteTest.class
new file mode 100644
index 0000000000000000000000000000000000000000..655456ed1f9c7073c51fefd5a6f05ec8d78d542b
Binary files /dev/null and b/Partie_3/target/test-classes/ch/hepia/CarteTest.class differ