diff --git a/Partie_3/.vscode/c_cpp_properties.json b/Partie_3_GFX/.vscode/c_cpp_properties.json
similarity index 100%
rename from Partie_3/.vscode/c_cpp_properties.json
rename to Partie_3_GFX/.vscode/c_cpp_properties.json
diff --git a/Partie_3/.vscode/launch.json b/Partie_3_GFX/.vscode/launch.json
similarity index 100%
rename from Partie_3/.vscode/launch.json
rename to Partie_3_GFX/.vscode/launch.json
diff --git a/Partie_3/.vscode/settings.json b/Partie_3_GFX/.vscode/settings.json
similarity index 100%
rename from Partie_3/.vscode/settings.json
rename to Partie_3_GFX/.vscode/settings.json
diff --git a/Partie_3/pom.xml b/Partie_3_GFX/pom.xml
similarity index 100%
rename from Partie_3/pom.xml
rename to Partie_3_GFX/pom.xml
diff --git a/Partie_3/save.csv b/Partie_3_GFX/save.csv
similarity index 100%
rename from Partie_3/save.csv
rename to Partie_3_GFX/save.csv
diff --git a/Partie_3/src/main/java/ch/hepia/App.java b/Partie_3_GFX/src/main/java/ch/hepia/App.java
similarity index 100%
rename from Partie_3/src/main/java/ch/hepia/App.java
rename to Partie_3_GFX/src/main/java/ch/hepia/App.java
diff --git a/Partie_3/src/main/java/ch/hepia/Carte.java b/Partie_3_GFX/src/main/java/ch/hepia/Carte.java
similarity index 100%
rename from Partie_3/src/main/java/ch/hepia/Carte.java
rename to Partie_3_GFX/src/main/java/ch/hepia/Carte.java
diff --git a/Partie_3/src/main/java/ch/hepia/GameManager.java b/Partie_3_GFX/src/main/java/ch/hepia/GameManager.java
similarity index 100%
rename from Partie_3/src/main/java/ch/hepia/GameManager.java
rename to Partie_3_GFX/src/main/java/ch/hepia/GameManager.java
diff --git a/Partie_3/src/main/java/ch/hepia/Hand.java b/Partie_3_GFX/src/main/java/ch/hepia/Hand.java
similarity index 100%
rename from Partie_3/src/main/java/ch/hepia/Hand.java
rename to Partie_3_GFX/src/main/java/ch/hepia/Hand.java
diff --git a/Partie_3/src/main/java/ch/hepia/JeudeCarte.java b/Partie_3_GFX/src/main/java/ch/hepia/JeudeCarte.java
similarity index 100%
rename from Partie_3/src/main/java/ch/hepia/JeudeCarte.java
rename to Partie_3_GFX/src/main/java/ch/hepia/JeudeCarte.java
diff --git a/Partie_3/src/main/java/ch/hepia/Joueur.java b/Partie_3_GFX/src/main/java/ch/hepia/Joueur.java
similarity index 100%
rename from Partie_3/src/main/java/ch/hepia/Joueur.java
rename to Partie_3_GFX/src/main/java/ch/hepia/Joueur.java
diff --git a/Partie_3/src/main/java/ch/hepia/Paquet.java b/Partie_3_GFX/src/main/java/ch/hepia/Paquet.java
similarity index 100%
rename from Partie_3/src/main/java/ch/hepia/Paquet.java
rename to Partie_3_GFX/src/main/java/ch/hepia/Paquet.java
diff --git a/Partie_3/src/main/java/ch/hepia/Save.java b/Partie_3_GFX/src/main/java/ch/hepia/Save.java
similarity index 100%
rename from Partie_3/src/main/java/ch/hepia/Save.java
rename to Partie_3_GFX/src/main/java/ch/hepia/Save.java
diff --git a/Partie_3/src/test/java/ch/hepia/JoueurTest.java b/Partie_3_GFX/src/test/java/ch/hepia/JoueurTest.java
similarity index 100%
rename from Partie_3/src/test/java/ch/hepia/JoueurTest.java
rename to Partie_3_GFX/src/test/java/ch/hepia/JoueurTest.java
diff --git a/Partie_3/target/classes/ch/hepia/App.class b/Partie_3_GFX/target/classes/ch/hepia/App.class
similarity index 100%
rename from Partie_3/target/classes/ch/hepia/App.class
rename to Partie_3_GFX/target/classes/ch/hepia/App.class
diff --git a/Partie_3/target/classes/ch/hepia/COULEUR.class b/Partie_3_GFX/target/classes/ch/hepia/COULEUR.class
similarity index 100%
rename from Partie_3/target/classes/ch/hepia/COULEUR.class
rename to Partie_3_GFX/target/classes/ch/hepia/COULEUR.class
diff --git a/Partie_3/target/classes/ch/hepia/Carte.class b/Partie_3_GFX/target/classes/ch/hepia/Carte.class
similarity index 100%
rename from Partie_3/target/classes/ch/hepia/Carte.class
rename to Partie_3_GFX/target/classes/ch/hepia/Carte.class
diff --git a/Partie_3/target/classes/ch/hepia/GameManager.class b/Partie_3_GFX/target/classes/ch/hepia/GameManager.class
similarity index 100%
rename from Partie_3/target/classes/ch/hepia/GameManager.class
rename to Partie_3_GFX/target/classes/ch/hepia/GameManager.class
diff --git a/Partie_3/target/classes/ch/hepia/Hand$1.class b/Partie_3_GFX/target/classes/ch/hepia/Hand$1.class
similarity index 100%
rename from Partie_3/target/classes/ch/hepia/Hand$1.class
rename to Partie_3_GFX/target/classes/ch/hepia/Hand$1.class
diff --git a/Partie_3/target/classes/ch/hepia/Hand.class b/Partie_3_GFX/target/classes/ch/hepia/Hand.class
similarity index 100%
rename from Partie_3/target/classes/ch/hepia/Hand.class
rename to Partie_3_GFX/target/classes/ch/hepia/Hand.class
diff --git a/Partie_3/target/classes/ch/hepia/JeudeCarte$1.class b/Partie_3_GFX/target/classes/ch/hepia/JeudeCarte$1.class
similarity index 100%
rename from Partie_3/target/classes/ch/hepia/JeudeCarte$1.class
rename to Partie_3_GFX/target/classes/ch/hepia/JeudeCarte$1.class
diff --git a/Partie_3/target/classes/ch/hepia/JeudeCarte.class b/Partie_3_GFX/target/classes/ch/hepia/JeudeCarte.class
similarity index 100%
rename from Partie_3/target/classes/ch/hepia/JeudeCarte.class
rename to Partie_3_GFX/target/classes/ch/hepia/JeudeCarte.class
diff --git a/Partie_3/target/classes/ch/hepia/Joueur.class b/Partie_3_GFX/target/classes/ch/hepia/Joueur.class
similarity index 100%
rename from Partie_3/target/classes/ch/hepia/Joueur.class
rename to Partie_3_GFX/target/classes/ch/hepia/Joueur.class
diff --git a/Partie_3/target/classes/ch/hepia/JoueurCroupier.class b/Partie_3_GFX/target/classes/ch/hepia/JoueurCroupier.class
similarity index 100%
rename from Partie_3/target/classes/ch/hepia/JoueurCroupier.class
rename to Partie_3_GFX/target/classes/ch/hepia/JoueurCroupier.class
diff --git a/Partie_3/target/classes/ch/hepia/JoueurHumain.class b/Partie_3_GFX/target/classes/ch/hepia/JoueurHumain.class
similarity index 100%
rename from Partie_3/target/classes/ch/hepia/JoueurHumain.class
rename to Partie_3_GFX/target/classes/ch/hepia/JoueurHumain.class
diff --git a/Partie_3/target/classes/ch/hepia/JoueurOrdinateur.class b/Partie_3_GFX/target/classes/ch/hepia/JoueurOrdinateur.class
similarity index 100%
rename from Partie_3/target/classes/ch/hepia/JoueurOrdinateur.class
rename to Partie_3_GFX/target/classes/ch/hepia/JoueurOrdinateur.class
diff --git a/Partie_3/target/classes/ch/hepia/Paquet.class b/Partie_3_GFX/target/classes/ch/hepia/Paquet.class
similarity index 100%
rename from Partie_3/target/classes/ch/hepia/Paquet.class
rename to Partie_3_GFX/target/classes/ch/hepia/Paquet.class
diff --git a/Partie_3/target/classes/ch/hepia/Save.class b/Partie_3_GFX/target/classes/ch/hepia/Save.class
similarity index 100%
rename from Partie_3/target/classes/ch/hepia/Save.class
rename to Partie_3_GFX/target/classes/ch/hepia/Save.class
diff --git a/Partie_3/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/Partie_3_GFX/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
similarity index 100%
rename from Partie_3/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
rename to Partie_3_GFX/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
diff --git a/Partie_3/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/Partie_3_GFX/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
similarity index 100%
rename from Partie_3/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
rename to Partie_3_GFX/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
diff --git a/Partie_3/target/test-classes/ch/hepia/JoueurTest.class b/Partie_3_GFX/target/test-classes/ch/hepia/JoueurTest.class
similarity index 100%
rename from Partie_3/target/test-classes/ch/hepia/JoueurTest.class
rename to Partie_3_GFX/target/test-classes/ch/hepia/JoueurTest.class
diff --git a/Partie_3_Terminal/.vscode/c_cpp_properties.json b/Partie_3_Terminal/.vscode/c_cpp_properties.json
new file mode 100644
index 0000000000000000000000000000000000000000..c2098a2d0c4b96621c02cb4e33bc58231ccffc1d
--- /dev/null
+++ b/Partie_3_Terminal/.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_Terminal/.vscode/launch.json b/Partie_3_Terminal/.vscode/launch.json
new file mode 100644
index 0000000000000000000000000000000000000000..7f873a9001f36511d308c7bfb198f7e8789586d0
--- /dev/null
+++ b/Partie_3_Terminal/.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_Terminal/.vscode/settings.json b/Partie_3_Terminal/.vscode/settings.json
new file mode 100644
index 0000000000000000000000000000000000000000..1152b26c4f7b3e09717bc55acb4ffa24c81ecc42
--- /dev/null
+++ b/Partie_3_Terminal/.vscode/settings.json
@@ -0,0 +1,60 @@
+{
+  "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,
+  "java.configuration.updateBuildConfiguration": "interactive"
+}
\ No newline at end of file
diff --git a/Partie_3_Terminal/pom.xml b/Partie_3_Terminal/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a8dc63e3d7322b47fbfe43c3739f9655dca1814a
--- /dev/null
+++ b/Partie_3_Terminal/pom.xml
@@ -0,0 +1,82 @@
+<?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.13.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <version>5.9.1</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.openjfx</groupId>
+            <artifactId>javafx-controls</artifactId>
+            <version>19</version>
+        </dependency>
+        <dependency>
+            <groupId>com.opencsv</groupId>
+            <artifactId>opencsv</artifactId>
+            <version>5.9</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_Terminal/save.csv b/Partie_3_Terminal/save.csv
new file mode 100644
index 0000000000000000000000000000000000000000..f481abffdbc7df4d1718d6dcc2639b0a4f25b9de
--- /dev/null
+++ b/Partie_3_Terminal/save.csv
@@ -0,0 +1,3 @@
+Human,100.0,0
+Player_1,190.0,1
+Player_2,305.0,1
diff --git a/Partie_3_Terminal/src/main/java/ch/hepia/App.java b/Partie_3_Terminal/src/main/java/ch/hepia/App.java
new file mode 100644
index 0000000000000000000000000000000000000000..b99e87fcaf53d954cec2092e1548f78da9934187
--- /dev/null
+++ b/Partie_3_Terminal/src/main/java/ch/hepia/App.java
@@ -0,0 +1,187 @@
+package ch.hepia;
+
+import java.io.File;
+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;
+        int computerStrategy = 1;
+        boolean loadSave = false;
+        String filePath = "save.csv";
+
+        File f = new File(filePath);
+
+        // Check if a save file exists
+        if (f.exists() && !f.isDirectory()) {
+
+            char choice = 'x';
+
+            System.out.print("Do you want to load last game save (y/n) ? ");
+
+            while (true) {
+
+                choice = App.in.next().charAt(0);
+
+                // Choices are checked with available one for confirmation
+                if (choice == 'y' || choice == 'n') {
+                    break;
+                } else {
+                    System.out.println(App.ANSI_YELLOW + "Please enter a valid choice." + App.ANSI_RESET);
+                }
+            }
+
+            if (choice == 'y') {
+                loadSave = true;
+            }
+        }
+
+        GameManager BlackJack;
+
+        if (loadSave) {
+
+            // Load save to create game
+            Save Game = new Save();
+
+            BlackJack = new GameManager(Game.loadMoney(), Game.loadStrategy());
+
+        } else {
+            // 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);
+                }
+            }
+
+            // Ask if the Computer players should be smart of not
+            if (numPlayers > 1) {
+                while (true) {
+
+                    System.out.print("Should the Compter players be [1] Smart or [2] Stupid ? ");
+
+                    // Check that the input is an valid int
+                    while (!App.in.hasNextInt()) {
+                        System.out
+                                .println(App.ANSI_YELLOW + "Please enter a valid choice." + App.ANSI_RESET);
+                        System.out.print("Should the Compter players be [1] Smart or [2] Stupid ? ");
+                        App.in.next();
+                    }
+
+                    computerStrategy = App.in.nextInt();
+
+                    // Check if the value i s valide
+                    if (computerStrategy == 1 || computerStrategy == 2) {
+                        System.out.print("");
+                        break;
+                    } else {
+                        System.out.println(App.ANSI_YELLOW + "Please enter a valid choice." + App.ANSI_RESET);
+                    }
+                }
+            }
+
+            // Create a new game
+            BlackJack = new GameManager(numPlayers, startMoney, computerStrategy);
+        }
+
+        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_Terminal/src/main/java/ch/hepia/Carte.java b/Partie_3_Terminal/src/main/java/ch/hepia/Carte.java
new file mode 100644
index 0000000000000000000000000000000000000000..62822203bf0183413c004347b06fb1605f0dc9e6
--- /dev/null
+++ b/Partie_3_Terminal/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_Terminal/src/main/java/ch/hepia/GameManager.java b/Partie_3_Terminal/src/main/java/ch/hepia/GameManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..2cc3940f7e6485114af15f378c94242b079d1859
--- /dev/null
+++ b/Partie_3_Terminal/src/main/java/ch/hepia/GameManager.java
@@ -0,0 +1,755 @@
+package ch.hepia;
+
+import java.util.ArrayList;
+
+public class GameManager {
+
+    private JeudeCarte Deck;
+    private ArrayList<Joueur> Players;
+    private JoueurCroupier Dealer;
+    private int ComputerPlayers;
+    private int Step;
+
+    public GameManager(int nbPlayer, int startMoney, int computerStrategy) {
+
+        // 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));
+
+        this.ComputerPlayers = 0;
+
+        // All other are controlled by the computer
+        if (nbPlayer > 1) {
+            for (int x = 1; x < nbPlayer; x++) {
+                ComputerPlayers++;
+                this.Players.add(new JoueurOrdinateur(Deck, startMoney, computerStrategy));
+            }
+        }
+
+        this.Dealer = new JoueurCroupier(Deck);
+    }
+
+    public GameManager(ArrayList<Double> Money, ArrayList<Integer> Strategy) {
+
+        // 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, Money.get(0)));
+
+        this.ComputerPlayers = 0;
+
+        // All other are controlled by the computer
+        if (Money.size() > 1) {
+            for (int x = 1; x < Money.size(); x++) {
+                ComputerPlayers++;
+                this.Players.add(new JoueurOrdinateur(Deck, Money.get(x), Strategy.get(x)));
+            }
+        }
+
+        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);
+
+        // Set the Computer players bid for this turn
+        for (int x = 1; x <= this.ComputerPlayers; x++) {
+            Players.get(x).SetBet(10, 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);
+
+                // Show Computer Players hands
+                for (int x = 1; x <= this.ComputerPlayers; x++) {
+                    for (int HandNbComputer = 0; HandNbComputer < this.Players.get(x).GetNbHands(); HandNbComputer++) {
+                        System.out
+                                .print("\nComputer " + App.ANSI_GREEN + x + App.ANSI_RESET + ", Money " + App.ANSI_BLUE
+                                        + this.Players.get(x).GetMoney() + App.ANSI_RESET + ", Hand "
+                                        + App.ANSI_GREEN + HandNbComputer + App.ANSI_RESET + ", Bet " + App.ANSI_BLUE
+                                        + this.Players.get(x).GetBet(HandNbComputer) + App.ANSI_RESET + ", Strength "
+                                        + App.ANSI_PURPLE);
+                        if (this.Players.get(x).GetStrength(HandNbComputer) == 99) {
+                            System.out.println("BlackJack" + App.ANSI_RESET + " :");
+                        } else if (this.Players.get(x).GetStrength(HandNbComputer) > 21) {
+                            System.out.println(
+                                    this.Players.get(x).GetStrength(HandNbComputer) + App.ANSI_RED + " [BUSTED]"
+                                            + App.ANSI_RESET + " :");
+                        } else {
+                            System.out.println(this.Players.get(x).GetStrength(HandNbComputer) + App.ANSI_RESET + " :");
+                        }
+                        this.Players.get(x).ShowHand(HandNbComputer);
+                    }
+                }
+
+                // 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() {
+
+        // Computer Players take turn to play
+        for (int x = 1; x <= this.ComputerPlayers; x++) {
+
+            // Check there strategy
+            /*
+             * 1 = Smart
+             * 2 = Stupid
+             */
+            if (this.Players.get(x).GetStrategy() == 1) {
+
+                char[][][] Choices_2Cards = {
+                        {
+                                { 'S', 'T', 'T', 'T', 'T', 'T', 'T', 'R', 'R', 'R' },
+                                { 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T' },
+                                { 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T' },
+                                { 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T' },
+                                { 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T' },
+                                { 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'R' },
+                                { 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'R', 'R' },
+                                { 'R', 'T', 'T', 'T', 'T', 'T', 'T', 'S', 'R', 'R' },
+                                { 'R', 'T', 'T', 'T', 'T', 'T', 'R', 'R', 'R', 'R' },
+                                { 'R', 'T', 'T', 'T', 'T', 'R', 'R', 'R', 'R', 'R' },
+                        },
+                        {
+                                { 'S', 'T', 'T', 'T', 'T', 'T', 'R', 'R', 'R', 'R' },
+                                { 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T' },
+                                { 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'R' },
+                                { 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'R', 'R' },
+                                { 'T', 'T', 'T', 'T', 'D', 'T', 'T', 'R', 'R', 'R' },
+                                { 'T', 'T', 'T', 'T', 'T', 'T', 'R', 'R', 'R', 'R' },
+                                { 'R', 'T', 'T', 'T', 'T', 'R', 'S', 'R', 'R', 'R' },
+                                { 'R', 'T', 'T', 'T', 'R', 'R', 'R', 'S', 'R', 'R' },
+                                { 'R', 'T', 'T', 'R', 'R', 'R', 'R', 'R', 'S', 'R' },
+                                { 'R', 'T', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' },
+                        },
+                        {
+                                { 'S', 'T', 'T', 'T', 'T', 'D', 'D', 'R', 'R', 'R' },
+                                { 'T', 'T', 'T', 'T', 'T', 'T', 'D', 'D', 'D', 'T' },
+                                { 'T', 'T', 'T', 'T', 'T', 'D', 'D', 'D', 'T', 'R' },
+                                { 'T', 'T', 'T', 'T', 'D', 'D', 'D', 'T', 'R', 'R' },
+                                { 'T', 'T', 'T', 'D', 'D', 'D', 'T', 'R', 'R', 'R' },
+                                { 'D', 'T', 'D', 'D', 'D', 'S', 'R', 'R', 'R', 'R' },
+                                { 'D', 'D', 'D', 'D', 'T', 'R', 'S', 'R', 'R', 'R' },
+                                { 'R', 'D', 'D', 'T', 'R', 'R', 'R', 'S', 'R', 'R' },
+                                { 'R', 'D', 'T', 'R', 'R', 'R', 'R', 'R', 'S', 'R' },
+                                { 'R', 'T', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' },
+                        },
+                        {
+                                { 'S', 'T', 'T', 'D', 'D', 'D', 'D', 'R', 'R', 'R' },
+                                { 'T', 'S', 'T', 'T', 'T', 'T', 'D', 'D', 'D', 'R' },
+                                { 'T', 'T', 'S', 'T', 'T', 'D', 'D', 'D', 'R', 'R' },
+                                { 'D', 'T', 'T', 'T', 'D', 'D', 'D', 'R', 'R', 'R' },
+                                { 'D', 'T', 'T', 'D', 'D', 'D', 'R', 'R', 'R', 'R' },
+                                { 'D', 'T', 'D', 'D', 'D', 'S', 'R', 'R', 'R', 'R' },
+                                { 'D', 'D', 'D', 'D', 'R', 'R', 'S', 'R', 'R', 'R' },
+                                { 'R', 'D', 'D', 'R', 'R', 'R', 'R', 'S', 'R', 'R' },
+                                { 'R', 'D', 'R', 'R', 'R', 'R', 'R', 'R', 'S', 'R' },
+                                { 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' },
+                        },
+                        {
+                                { 'S', 'D', 'D', 'D', 'D', 'D', 'D', 'R', 'R', 'R' },
+                                { 'D', 'S', 'T', 'T', 'T', 'T', 'D', 'D', 'D', 'R' },
+                                { 'D', 'T', 'S', 'T', 'T', 'D', 'D', 'D', 'R', 'R' },
+                                { 'D', 'T', 'T', 'T', 'D', 'D', 'D', 'R', 'R', 'R' },
+                                { 'D', 'T', 'T', 'D', 'D', 'D', 'R', 'R', 'R', 'R' },
+                                { 'D', 'T', 'D', 'D', 'D', 'S', 'R', 'R', 'R', 'R' },
+                                { 'D', 'D', 'D', 'D', 'R', 'R', 'S', 'R', 'R', 'R' },
+                                { 'R', 'D', 'D', 'R', 'R', 'R', 'R', 'S', 'R', 'R' },
+                                { 'R', 'D', 'R', 'R', 'R', 'R', 'R', 'R', 'S', 'R' },
+                                { 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' },
+                        },
+                        {
+                                { 'S', 'D', 'D', 'D', 'D', 'D', 'D', 'R', 'R', 'R' },
+                                { 'D', 'S', 'T', 'T', 'T', 'T', 'D', 'D', 'D', 'R' },
+                                { 'D', 'T', 'S', 'T', 'T', 'D', 'D', 'D', 'R', 'R' },
+                                { 'D', 'T', 'T', 'T', 'D', 'D', 'D', 'R', 'R', 'R' },
+                                { 'D', 'T', 'T', 'D', 'D', 'D', 'R', 'R', 'R', 'R' },
+                                { 'D', 'T', 'D', 'D', 'D', 'S', 'R', 'R', 'R', 'R' },
+                                { 'D', 'D', 'D', 'D', 'R', 'R', 'S', 'R', 'R', 'R' },
+                                { 'R', 'D', 'D', 'R', 'R', 'R', 'R', 'S', 'R', 'R' },
+                                { 'R', 'D', 'R', 'R', 'R', 'R', 'R', 'R', 'S', 'R' },
+                                { 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R' },
+                        },
+                        {
+                                { 'S', 'T', 'T', 'T', 'T', 'T', 'R', 'R', 'R', 'R' },
+                                { 'T', 'S', 'T', 'T', 'T', 'T', 'T', 'D', 'D', 'T' },
+                                { 'T', 'T', 'S', 'T', 'T', 'T', 'D', 'D', 'T', 'T' },
+                                { 'T', 'T', 'T', 'T', 'T', 'D', 'D', 'T', 'T', 'T' },
+                                { 'T', 'T', 'T', 'T', 'D', 'D', 'T', 'T', 'T', 'T' },
+                                { 'T', 'T', 'T', 'D', 'D', 'T', 'T', 'T', 'T', 'T' },
+                                { 'R', 'T', 'D', 'D', 'T', 'T', 'S', 'T', 'T', 'R' },
+                                { 'R', 'D', 'D', 'T', 'T', 'T', 'T', 'S', 'R', 'R' },
+                                { 'R', 'D', 'T', 'T', 'T', 'T', 'T', 'R', 'R', 'R' },
+                                { 'R', 'T', 'T', 'T', 'T', 'T', 'R', 'R', 'R', 'R' },
+                        },
+                        {
+                                { 'S', 'T', 'T', 'T', 'T', 'T', 'R', 'R', 'R', 'R' },
+                                { 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'D', 'D', 'T' },
+                                { 'T', 'T', 'T', 'T', 'T', 'T', 'D', 'D', 'T', 'T' },
+                                { 'T', 'T', 'T', 'T', 'T', 'D', 'D', 'T', 'T', 'T' },
+                                { 'T', 'T', 'T', 'T', 'D', 'D', 'T', 'T', 'T', 'T' },
+                                { 'T', 'T', 'T', 'D', 'D', 'T', 'T', 'T', 'T', 'T' },
+                                { 'R', 'T', 'D', 'D', 'T', 'T', 'T', 'T', 'T', 'R' },
+                                { 'R', 'D', 'D', 'T', 'T', 'T', 'T', 'S', 'R', 'R' },
+                                { 'R', 'D', 'T', 'T', 'T', 'T', 'T', 'R', 'S', 'R' },
+                                { 'R', 'T', 'T', 'T', 'T', 'T', 'R', 'R', 'R', 'R' },
+                        },
+                        {
+                                { 'S', 'T', 'T', 'T', 'T', 'T', 'T', 'R', 'R', 'R' },
+                                { 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'D', 'D', 'T' },
+                                { 'T', 'T', 'T', 'T', 'T', 'T', 'D', 'D', 'T', 'T' },
+                                { 'T', 'T', 'T', 'T', 'T', 'D', 'D', 'T', 'T', 'T' },
+                                { 'T', 'T', 'T', 'T', 'D', 'D', 'T', 'T', 'T', 'T' },
+                                { 'T', 'T', 'T', 'D', 'D', 'T', 'T', 'T', 'T', 'R' },
+                                { 'T', 'T', 'D', 'D', 'T', 'T', 'T', 'T', 'R', 'R' },
+                                { 'R', 'D', 'D', 'T', 'T', 'T', 'T', 'S', 'R', 'R' },
+                                { 'R', 'D', 'T', 'T', 'T', 'T', 'R', 'R', 'S', 'R' },
+                                { 'R', 'T', 'T', 'T', 'T', 'R', 'R', 'R', 'R', 'R' },
+                        },
+                        {
+                                { 'S', 'T', 'T', 'T', 'T', 'T', 'T', 'R', 'R', 'R' },
+                                { 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'D', 'T' },
+                                { 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'D', 'T', 'T' },
+                                { 'T', 'T', 'T', 'T', 'T', 'T', 'D', 'T', 'T', 'T' },
+                                { 'T', 'T', 'T', 'T', 'T', 'D', 'T', 'T', 'T', 'R' },
+                                { 'T', 'T', 'T', 'T', 'D', 'T', 'T', 'T', 'R', 'R' },
+                                { 'T', 'T', 'T', 'D', 'T', 'T', 'T', 'R', 'R', 'R' },
+                                { 'R', 'T', 'D', 'T', 'T', 'T', 'R', 'S', 'R', 'R' },
+                                { 'R', 'D', 'T', 'T', 'T', 'R', 'R', 'R', 'R', 'R' },
+                                { 'R', 'T', 'T', 'T', 'R', 'R', 'R', 'R', 'R', 'R' },
+                        }
+                };
+
+                char[][] Choices_MoreThan2Cards = {
+                        { 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'T', 'R', 'R' },
+                        { 'T', 'T', 'D', 'D', 'T', 'R', 'R', 'R', 'R', 'R' },
+                        { 'T', 'D', 'D', 'D', 'T', 'R', 'R', 'R', 'R', 'R' },
+                        { 'T', 'D', 'D', 'D', 'R', 'R', 'R', 'R', 'R', 'R' },
+                        { 'T', 'D', 'D', 'D', 'R', 'R', 'R', 'R', 'R', 'R' },
+                        { 'T', 'D', 'D', 'D', 'R', 'R', 'R', 'R', 'R', 'R' },
+                        { 'T', 'T', 'D', 'D', 'T', 'T', 'T', 'T', 'T', 'R' },
+                        { 'T', 'T', 'D', 'D', 'T', 'T', 'T', 'T', 'T', 'R' },
+                        { 'T', 'T', 'D', 'D', 'T', 'T', 'T', 'T', 'R', 'R' },
+                        { 'T', 'T', 'T', 'D', 'T', 'T', 'T', 'R', 'R', 'R' }
+                };
+
+                char Choice = 'R';
+
+                // Go thew all the hands of the computer player
+                for (int HandNb = 0; HandNb < this.Players.get(x).GetNbHands(); HandNb++) {
+
+                    if (this.Players.get(x).GetNbCards(HandNb) == 2) {
+                        Choice = Choices_2Cards[this.Dealer.GetCardStrength(0, 0) - 1][this.Players.get(x)
+                                .GetCardStrength(HandNb, 0) - 1][this.Players.get(x).GetCardStrength(HandNb, 1) - 1];
+                    } else {
+                        if (this.Players.get(x).GetStrength(HandNb) <= 8) {
+                            Choice = Choices_MoreThan2Cards[this.Dealer.GetCardStrength(0, 0) - 1][0];
+                        } else if (this.Players.get(x).GetStrength(HandNb) == 9) {
+                            Choice = Choices_MoreThan2Cards[this.Dealer.GetCardStrength(0, 0) - 1][1];
+                        } else if (this.Players.get(x).GetStrength(HandNb) == 10) {
+                            Choice = Choices_MoreThan2Cards[this.Dealer.GetCardStrength(0, 0) - 1][2];
+                        } else if (this.Players.get(x).GetStrength(HandNb) == 11) {
+                            Choice = Choices_MoreThan2Cards[this.Dealer.GetCardStrength(0, 0) - 1][3];
+                        } else if (this.Players.get(x).GetStrength(HandNb) == 12) {
+                            Choice = Choices_MoreThan2Cards[this.Dealer.GetCardStrength(0, 0) - 1][4];
+                        } else if (this.Players.get(x).GetStrength(HandNb) == 13) {
+                            Choice = Choices_MoreThan2Cards[this.Dealer.GetCardStrength(0, 0) - 1][5];
+                        } else if (this.Players.get(x).GetStrength(HandNb) == 14) {
+                            Choice = Choices_MoreThan2Cards[this.Dealer.GetCardStrength(0, 0) - 1][6];
+                        } else if (this.Players.get(x).GetStrength(HandNb) == 15) {
+                            Choice = Choices_MoreThan2Cards[this.Dealer.GetCardStrength(0, 0) - 1][7];
+                        } else if (this.Players.get(x).GetStrength(HandNb) == 16) {
+                            Choice = Choices_MoreThan2Cards[this.Dealer.GetCardStrength(0, 0) - 1][8];
+                        } else if (this.Players.get(x).GetStrength(HandNb) >= 17) {
+                            Choice = Choices_MoreThan2Cards[this.Dealer.GetCardStrength(0, 0) - 1][9];
+                        }
+                    }
+
+                    if (Choice == 'T') {
+                        // Draw
+
+                        this.Players.get(x).DrawCard(HandNb, this.Deck);
+                        // Go back 1 hand to stay on the same hand in the for loop
+                        HandNb--;
+
+                    } else if (Choice == 'R') {
+                        // Stay
+
+                    } else if (Choice == 'D') {
+                        // Double
+
+                        this.Players.get(x).Double(HandNb, this.Deck);
+                        // Go back 1 hand to stay on the same hand in the for loop
+                        HandNb--;
+                    } else if (Choice == 'S') {
+                        // Split
+
+                        this.Players.get(x).Split(HandNb, this.Deck);
+                        // Go back 1 hand to stay on the same hand in the for loop
+                        HandNb--;
+                    }
+                }
+
+            } else if (this.Players.get(x).GetStrategy() == 2) {
+                while (this.Players.get(x).GetStrength(0) <= 15) {
+                    this.Players.get(x).DrawCard(0, this.Deck);
+                }
+            }
+        }
+
+        // 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);
+        }
+
+        // Apply Computer Players Loss/Win
+        for (int x = 1; x <= this.ComputerPlayers; x++) {
+            for (int HandNbComputer = 0; HandNbComputer < this.Players.get(x).GetNbHands(); HandNbComputer++) {
+                // If the player is Busted (strength > 21 but not BlackJack (99))
+                if (this.Players.get(x).GetStrength(HandNbComputer) > 21
+                        && this.Players.get(x).GetStrength(HandNbComputer) != 99) {
+                }
+                // If it's a Draw
+                else if (this.Dealer.GetStrength(0) == this.Players.get(x).GetStrength(HandNbComputer)) {
+                    // Player get's back his bet
+                    this.Players.get(x).AddMoney(this.Players.get(x).GetBet(HandNbComputer));
+                }
+                // If the player has done a BlackJack
+                else if (this.Players.get(x).GetStrength(HandNbComputer) == 99) {
+                    // Player gets payed 1.5 to 1
+                    this.Players.get(x).AddMoney(this.Players.get(x).GetBet(HandNbComputer) * 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
+                    this.Players.get(x).AddMoney(this.Players.get(x).GetBet(HandNbComputer) * 2);
+                }
+                // If the Dealer has a better score
+                else if (this.Players.get(x).GetStrength(HandNbComputer) < this.Dealer.GetStrength(0)) {
+                }
+                // If the Player has a better score
+                else if (this.Players.get(x).GetStrength(HandNbComputer) > this.Dealer.GetStrength(0)) {
+                    // Player wins and get payed 1 to 1
+                    this.Players.get(x).AddMoney(this.Players.get(x).GetBet(HandNbComputer) * 2);
+                }
+            }
+        }
+
+        // Show Computer Players hands
+        for (int x = 1; x <= this.ComputerPlayers; x++) {
+            for (int HandNbComputer = 0; HandNbComputer < this.Players.get(x).GetNbHands(); HandNbComputer++) {
+                System.out
+                        .print("\nComputer " + App.ANSI_GREEN + x + App.ANSI_RESET + ", Money " + App.ANSI_BLUE
+                                + this.Players.get(x).GetMoney() + App.ANSI_RESET + ", Hand "
+                                + App.ANSI_GREEN + HandNbComputer + App.ANSI_RESET + ", Bet " + App.ANSI_BLUE
+                                + this.Players.get(x).GetBet(HandNbComputer) + App.ANSI_RESET + ", Strength "
+                                + App.ANSI_PURPLE);
+                if (this.Players.get(x).GetStrength(HandNbComputer) == 99) {
+                    System.out.println("BlackJack" + App.ANSI_RESET + " :");
+                } else if (this.Players.get(x).GetStrength(HandNbComputer) > 21) {
+                    System.out.println(
+                            this.Players.get(x).GetStrength(HandNbComputer) + App.ANSI_RED + " [BUSTED]"
+                                    + App.ANSI_RESET + " :");
+                } else {
+                    System.out.println(this.Players.get(x).GetStrength(HandNbComputer) + App.ANSI_RESET + " :");
+                }
+                this.Players.get(x).ShowHand(HandNbComputer);
+            }
+        }
+
+        // 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);
+
+        // Show Choices
+        System.out.println("\n--- " + App.ANSI_GREEN + "Choices" + App.ANSI_RESET + " ---\n");
+
+        System.out.println(App.ANSI_BLUE + "[c]" + App.ANSI_RESET + " Continue");
+        System.out.println(App.ANSI_BLUE + "[s]" + App.ANSI_RESET + " Save & Quit");
+
+        char choice = 'x';
+
+        // 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 == 'c' || choice == 's') {
+                break;
+            } else {
+                System.out.println(App.ANSI_YELLOW + "Please enter a valid choice." + App.ANSI_RESET);
+            }
+        }
+
+        if (choice == 'c') {
+            // 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);
+            }
+        } else if (choice == 's') {
+
+            Save Game = new Save();
+            Game.save(this.Players, this.ComputerPlayers);
+
+            return true;
+        }
+
+        return false;
+    }
+
+}
diff --git a/Partie_3_Terminal/src/main/java/ch/hepia/Hand.java b/Partie_3_Terminal/src/main/java/ch/hepia/Hand.java
new file mode 100644
index 0000000000000000000000000000000000000000..9b5ffe0560fd90cd470596fb89ae514e328d221b
--- /dev/null
+++ b/Partie_3_Terminal/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_Terminal/src/main/java/ch/hepia/JeudeCarte.java b/Partie_3_Terminal/src/main/java/ch/hepia/JeudeCarte.java
new file mode 100644
index 0000000000000000000000000000000000000000..e6bd3c6c42211a33e64b76c4d0fb0f31767038cf
--- /dev/null
+++ b/Partie_3_Terminal/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_Terminal/src/main/java/ch/hepia/Joueur.java b/Partie_3_Terminal/src/main/java/ch/hepia/Joueur.java
new file mode 100644
index 0000000000000000000000000000000000000000..e69d341308e200397ff706a20aab3267e9d0019c
--- /dev/null
+++ b/Partie_3_Terminal/src/main/java/ch/hepia/Joueur.java
@@ -0,0 +1,761 @@
+package ch.hepia;
+
+import java.util.ArrayList;
+
+interface Joueur {
+
+    // Get the Computer Player Strategy
+    public int GetStrategy();
+
+    // 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, double 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 int GetStrategy() {
+        // 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;
+
+    /*
+     * 1 = Smart
+     * 2 = Stupid
+     */
+    private int Strategy;
+
+    public JoueurOrdinateur(JeudeCarte Jeu, double Money, int Strategy) {
+
+        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;
+
+        this.Strategy = Strategy;
+    }
+
+    public int GetStrategy() {
+        return this.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 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 int GetStrategy() {
+        // 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_Terminal/src/main/java/ch/hepia/Paquet.java b/Partie_3_Terminal/src/main/java/ch/hepia/Paquet.java
new file mode 100644
index 0000000000000000000000000000000000000000..43311c54e7d597eb450df72bd20fe2100d251e49
--- /dev/null
+++ b/Partie_3_Terminal/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_Terminal/src/main/java/ch/hepia/Save.java b/Partie_3_Terminal/src/main/java/ch/hepia/Save.java
new file mode 100644
index 0000000000000000000000000000000000000000..d66eaa2917f5d6490e862edd6cc920a6ecb9043b
--- /dev/null
+++ b/Partie_3_Terminal/src/main/java/ch/hepia/Save.java
@@ -0,0 +1,100 @@
+package ch.hepia;
+
+import com.opencsv.CSVWriter;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.List;
+
+public class Save {
+
+    public void save(ArrayList<Joueur> Players, int ComputerPlayers) {
+
+        String filePath = "save.csv";
+
+        File file = new File(filePath);
+
+        try {
+            // Create FileWriter object
+            FileWriter outputfile = new FileWriter(file);
+
+            // Create CSVWriter object filewriter
+            CSVWriter writer = new CSVWriter(outputfile, ',',
+                    CSVWriter.NO_QUOTE_CHARACTER,
+                    CSVWriter.DEFAULT_ESCAPE_CHARACTER,
+                    CSVWriter.DEFAULT_LINE_END);
+
+            String[] data = { "Human", Double.toString(Players.get(0).GetMoney()), "0" };
+
+            writer.writeNext(data);
+
+            for (int x = 1; x <= ComputerPlayers; x++) {
+
+                data[0] = "Player_" + x;
+                data[1] = Double.toString(Players.get(x).GetMoney());
+                data[2] = Integer.toString(Players.get(x).GetStrategy());
+
+                writer.writeNext(data);
+            }
+
+            // Closing writer connection
+            writer.close();
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    public ArrayList<Double> loadMoney() {
+
+        File file = new File("save.csv");
+
+        ArrayList<Double> Money = new ArrayList<>();
+
+        try {
+
+            List<String> lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
+
+            for (String string : lines) {
+
+                String[] array = string.split(",");
+
+                Money.add(Double.valueOf(array[1]));
+            }
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return Money;
+    }
+
+    public ArrayList<Integer> loadStrategy() {
+
+        File file = new File("save.csv");
+
+        ArrayList<Integer> Strategy = new ArrayList<>();
+
+        try {
+
+            List<String> lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
+
+            for (String string : lines) {
+
+                String[] array = string.split(",");
+
+                Strategy.add(Integer.valueOf(array[2]));
+            }
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return Strategy;
+    }
+}
diff --git a/Partie_3_Terminal/src/test/java/ch/hepia/JoueurTest.java b/Partie_3_Terminal/src/test/java/ch/hepia/JoueurTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..836b221b5da855987b44520d0ab78f2c53aad800
--- /dev/null
+++ b/Partie_3_Terminal/src/test/java/ch/hepia/JoueurTest.java
@@ -0,0 +1,302 @@
+package ch.hepia;
+
+import static org.junit.Assert.*;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+import org.junit.Test;
+
+public class JoueurTest {
+
+    @Test
+    public void testAddMoney() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(6, 52));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+        joueur.AddMoney(100);
+
+        assertEquals(100, joueur.GetMoney(), 0);
+    }
+
+    @Test
+    public void testAddZeroMoney() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(6, 52));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+        joueur.AddMoney(0);
+
+        assertEquals(0, joueur.GetMoney(), 0);
+    }
+
+    @Test
+    public void testAddNegativeMoney() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(6, 52));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+
+        assertThrows(RuntimeException.class, () -> joueur.AddMoney(-50));
+    }
+
+    @Test
+    public void testRemoveMoney() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(6, 52));
+        JoueurHumain joueur = new JoueurHumain(Deck, 100);
+        joueur.RemoveMoney(10);
+
+        assertEquals(90, joueur.GetMoney(), 0);
+    }
+
+    @Test
+    public void testRemoveZeroMoney() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(6, 52));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+        joueur.RemoveMoney(0);
+
+        assertEquals(0, joueur.GetMoney(), 0);
+    }
+
+    @Test
+    public void testRemoveNegativeMoney() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(6, 52));
+        JoueurHumain joueur = new JoueurHumain(Deck, 100);
+
+        assertThrows(RuntimeException.class, () -> joueur.RemoveMoney(-50));
+    }
+
+    @Test
+    public void testAddBet() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(6, 52));
+        JoueurHumain joueur = new JoueurHumain(Deck, 100);
+        joueur.SetBet(10, 0);
+
+        assertEquals(10, joueur.GetBet(0), 0);
+    }
+
+    @Test
+    public void testAddNegativeBet() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(6, 52));
+        JoueurHumain joueur = new JoueurHumain(Deck, 100);
+
+        assertThrows(RuntimeException.class, () -> joueur.SetBet(-10, 0));
+    }
+
+    @Test
+    public void testAddTooBigBet() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(6, 52));
+        JoueurHumain joueur = new JoueurHumain(Deck, 100);
+
+        assertThrows(RuntimeException.class, () -> joueur.SetBet(101, 0));
+    }
+
+    @Test
+    public void testAddBetWrongHand() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(6, 52));
+        JoueurHumain joueur = new JoueurHumain(Deck, 100);
+
+        assertThrows(RuntimeException.class, () -> joueur.SetBet(1, 1));
+    }
+
+    @Test
+    public void testGetBetWrongHand() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(6, 52));
+        JoueurHumain joueur = new JoueurHumain(Deck, 100);
+        joueur.SetBet(10, 0);
+
+        assertThrows(RuntimeException.class, () -> joueur.GetBet(1));
+    }
+
+    @Test
+    public void testDrawCard() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(6, 52));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+        joueur.DrawCard(0, Deck);
+
+        assertEquals(3, joueur.GetNbCards(0));
+    }
+
+    @Test
+    public void testDrawCardWrongHand() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(6, 52));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+
+        assertThrows(RuntimeException.class, () -> joueur.DrawCard(1, Deck));
+    }
+
+    @Test
+    public void testCardStrength() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(1, 2));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+
+        assertEquals(0, joueur.GetCardStrength(0, 0));
+    }
+
+    @Test
+    public void testCardStrengthWrongCard() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(1, 2));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+
+        assertThrows(RuntimeException.class, () -> joueur.GetCardStrength(0, 2));
+    }
+
+    @Test
+    public void testCardStrengthWrongHand() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(1, 2));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+
+        assertThrows(RuntimeException.class, () -> joueur.GetCardStrength(1, 0));
+    }
+
+    @Test
+    public void testCardCount() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(1, 2));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+
+        assertEquals(2, joueur.GetNbCards(0));
+    }
+
+    @Test
+    public void testCardCountWrongHand() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(1, 2));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+
+        assertThrows(RuntimeException.class, () -> joueur.GetNbCards(1));
+    }
+
+    @Test
+    public void testShowHand() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(1, 2));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+
+        ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream();
+        System.setOut(new PrintStream(outputStreamCaptor));
+
+        joueur.ShowHand(0);
+
+        System.setOut(System.out);
+        String printedOutput = outputStreamCaptor.toString().trim();
+
+        assertTrue(printedOutput.contains("๐ŸƒŸ ๐ŸƒŸ"));
+    }
+
+    @Test
+    public void testWrongShowHand() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(1, 2));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+
+        assertThrows(RuntimeException.class, () -> joueur.ShowHand(1));
+    }
+
+    @Test
+    public void testShowHands() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(1, 2));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+
+        ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream();
+        System.setOut(new PrintStream(outputStreamCaptor));
+
+        joueur.ShowHands();
+
+        System.setOut(System.out);
+        String printedOutput = outputStreamCaptor.toString().trim();
+
+        assertTrue(printedOutput.contains("๐ŸƒŸ ๐ŸƒŸ"));
+    }
+
+    @Test
+    public void testNumberHands() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(1, 2));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+
+        assertEquals(1, joueur.GetNbHands());
+    }
+
+    @Test
+    public void testHandStrength() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(1, 2));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+
+        assertEquals(0, joueur.GetStrength(0));
+    }
+
+    @Test
+    public void testWrongHandStrength() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(1, 2));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+
+        assertThrows(RuntimeException.class, () -> joueur.GetStrength(1));
+    }
+
+    @Test
+    public void testDoubled() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(1, 2));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+
+        assertEquals(false, joueur.HasDoubled(0));
+    }
+
+    @Test
+    public void testCanSplit() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(1, 2));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+
+        assertEquals(true, joueur.CanSplit(0));
+    }
+
+    @Test
+    public void testCantSplit() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(1, 3));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+
+        joueur.DrawCard(0, Deck);
+
+        assertEquals(false, joueur.CanSplit(0));
+    }
+
+    @Test
+    public void testSplit() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(1, 5));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+
+        joueur.Split(0, Deck);
+
+        assertEquals(true, joueur.HasSplit(0));
+    }
+
+    @Test
+    public void testSplitMax() {
+
+        JeudeCarte Deck = new JeudeCarte(new Paquet(1, 15));
+        JoueurHumain joueur = new JoueurHumain(Deck, 0);
+
+        joueur.Split(0, Deck);
+        joueur.Split(1, Deck);
+
+        assertThrows(RuntimeException.class, () -> joueur.Split(0, Deck));
+    }
+}
diff --git a/Partie_3_Terminal/target/classes/ch/hepia/App.class b/Partie_3_Terminal/target/classes/ch/hepia/App.class
new file mode 100644
index 0000000000000000000000000000000000000000..aad0e41606823ab879200272efe2f63852dccb72
Binary files /dev/null and b/Partie_3_Terminal/target/classes/ch/hepia/App.class differ
diff --git a/Partie_3_Terminal/target/classes/ch/hepia/COULEUR.class b/Partie_3_Terminal/target/classes/ch/hepia/COULEUR.class
new file mode 100644
index 0000000000000000000000000000000000000000..c582fd28bd308c74abcc31d7c543625ab96af75b
Binary files /dev/null and b/Partie_3_Terminal/target/classes/ch/hepia/COULEUR.class differ
diff --git a/Partie_3_Terminal/target/classes/ch/hepia/Carte.class b/Partie_3_Terminal/target/classes/ch/hepia/Carte.class
new file mode 100644
index 0000000000000000000000000000000000000000..f2e1b3556ab535a9579d8c800c12eb799aff3d01
Binary files /dev/null and b/Partie_3_Terminal/target/classes/ch/hepia/Carte.class differ
diff --git a/Partie_3_Terminal/target/classes/ch/hepia/GameManager.class b/Partie_3_Terminal/target/classes/ch/hepia/GameManager.class
new file mode 100644
index 0000000000000000000000000000000000000000..0ae3f3d24bc760587c947162801cc9ccb6df14b6
Binary files /dev/null and b/Partie_3_Terminal/target/classes/ch/hepia/GameManager.class differ
diff --git a/Partie_3_Terminal/target/classes/ch/hepia/Hand$1.class b/Partie_3_Terminal/target/classes/ch/hepia/Hand$1.class
new file mode 100644
index 0000000000000000000000000000000000000000..2214bf48295c2e99569934bb083314370d6c1499
Binary files /dev/null and b/Partie_3_Terminal/target/classes/ch/hepia/Hand$1.class differ
diff --git a/Partie_3_Terminal/target/classes/ch/hepia/Hand.class b/Partie_3_Terminal/target/classes/ch/hepia/Hand.class
new file mode 100644
index 0000000000000000000000000000000000000000..6e99640898ba7d7dacac297d9754b15afd0dc13e
Binary files /dev/null and b/Partie_3_Terminal/target/classes/ch/hepia/Hand.class differ
diff --git a/Partie_3_Terminal/target/classes/ch/hepia/JeudeCarte$1.class b/Partie_3_Terminal/target/classes/ch/hepia/JeudeCarte$1.class
new file mode 100644
index 0000000000000000000000000000000000000000..2735eb7c27de1aa52aa4584d2c1ef9d746a2b524
Binary files /dev/null and b/Partie_3_Terminal/target/classes/ch/hepia/JeudeCarte$1.class differ
diff --git a/Partie_3_Terminal/target/classes/ch/hepia/JeudeCarte.class b/Partie_3_Terminal/target/classes/ch/hepia/JeudeCarte.class
new file mode 100644
index 0000000000000000000000000000000000000000..ef19fe3892611f8ced9c139e6ced49f24319685c
Binary files /dev/null and b/Partie_3_Terminal/target/classes/ch/hepia/JeudeCarte.class differ
diff --git a/Partie_3_Terminal/target/classes/ch/hepia/Joueur.class b/Partie_3_Terminal/target/classes/ch/hepia/Joueur.class
new file mode 100644
index 0000000000000000000000000000000000000000..cec581d3b0582175934534582a999fa29a5d8288
Binary files /dev/null and b/Partie_3_Terminal/target/classes/ch/hepia/Joueur.class differ
diff --git a/Partie_3_Terminal/target/classes/ch/hepia/JoueurCroupier.class b/Partie_3_Terminal/target/classes/ch/hepia/JoueurCroupier.class
new file mode 100644
index 0000000000000000000000000000000000000000..1d0bb3797ec4281bcbc48e36763785c6e864c086
Binary files /dev/null and b/Partie_3_Terminal/target/classes/ch/hepia/JoueurCroupier.class differ
diff --git a/Partie_3_Terminal/target/classes/ch/hepia/JoueurHumain.class b/Partie_3_Terminal/target/classes/ch/hepia/JoueurHumain.class
new file mode 100644
index 0000000000000000000000000000000000000000..068028eff942eafbe3b36e821e7fc43a0fe1309b
Binary files /dev/null and b/Partie_3_Terminal/target/classes/ch/hepia/JoueurHumain.class differ
diff --git a/Partie_3_Terminal/target/classes/ch/hepia/JoueurOrdinateur.class b/Partie_3_Terminal/target/classes/ch/hepia/JoueurOrdinateur.class
new file mode 100644
index 0000000000000000000000000000000000000000..e8925bd7d60d537103d49935df82fae23c2b1f36
Binary files /dev/null and b/Partie_3_Terminal/target/classes/ch/hepia/JoueurOrdinateur.class differ
diff --git a/Partie_3_Terminal/target/classes/ch/hepia/Paquet.class b/Partie_3_Terminal/target/classes/ch/hepia/Paquet.class
new file mode 100644
index 0000000000000000000000000000000000000000..287773450d9a2e8fcd9120c796067e1f9f2a10cf
Binary files /dev/null and b/Partie_3_Terminal/target/classes/ch/hepia/Paquet.class differ
diff --git a/Partie_3_Terminal/target/classes/ch/hepia/Save.class b/Partie_3_Terminal/target/classes/ch/hepia/Save.class
new file mode 100644
index 0000000000000000000000000000000000000000..9573a2e368dea090dc72a1674ce1aa82a9c79b87
Binary files /dev/null and b/Partie_3_Terminal/target/classes/ch/hepia/Save.class differ
diff --git a/Partie_3_Terminal/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/Partie_3_Terminal/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000000000000000000000000000000000000..814b85978aca0dc13df7846ffc2a5d7617a2ea2d
--- /dev/null
+++ b/Partie_3_Terminal/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_Terminal/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/Partie_3_Terminal/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000000000000000000000000000000000000..aacaf9de67b552001c795abf890bbc4f2a439106
--- /dev/null
+++ b/Partie_3_Terminal/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,8 @@
+/home/padi/Git/java-card-game/Partie_3/src/main/java/ch/hepia/Paquet.java
+/home/padi/Git/java-card-game/Partie_3/src/main/java/ch/hepia/Joueur.java
+/home/padi/Git/java-card-game/Partie_3/src/main/java/ch/hepia/App.java
+/home/padi/Git/java-card-game/Partie_3/src/main/java/ch/hepia/Hand.java
+/home/padi/Git/java-card-game/Partie_3/src/main/java/ch/hepia/Carte.java
+/home/padi/Git/java-card-game/Partie_3/src/main/java/ch/hepia/GameManager.java
+/home/padi/Git/java-card-game/Partie_3/src/main/java/ch/hepia/JeudeCarte.java
+/home/padi/Git/java-card-game/Partie_3/src/main/java/ch/hepia/Save.java
diff --git a/Partie_3_Terminal/target/test-classes/ch/hepia/JoueurTest.class b/Partie_3_Terminal/target/test-classes/ch/hepia/JoueurTest.class
new file mode 100644
index 0000000000000000000000000000000000000000..6c1eb68d4853e00d11fada367c940922ce2fed72
Binary files /dev/null and b/Partie_3_Terminal/target/test-classes/ch/hepia/JoueurTest.class differ