diff --git a/Makefile b/Makefile
index 60bf18c6b9ec624343e3f75955d1ea66f842cb78..94050e1291cae9ef7e33235cd260d31363dbd69d 100644
--- a/Makefile
+++ b/Makefile
@@ -10,16 +10,16 @@
 # Compiler for the AI: g++ >= 4.9
 CC = g++
 # JAVA ENVIRONMENT FOR THE GUI
-# Java compiler >= 1.8
-JAVAC = javac
-# Java jar utility
-JAR = jar
-# Java executable used for the run target >= 1.8
-JAVA = java
+# Java compiler >= 1.8 (usually javac)
+JAVAC := javac
+# Java jar utility (usually jar)
+JAR := jar
+# Java application launcher >= 1.8 (usually java)
+JAVA := java
 
 all: ai gui
 
-clean: aiclean guiclean
+clean: cleanai cleangui
 
 # ============================================ AI (C++) =============================================
 #Root directory for the AI module
@@ -47,8 +47,8 @@ AIOobjects=$(addprefix $(AIOutputDir)/, $(AISourceFile:.cpp=.o))
 
 # ==== RULES ====
 # Main rule for creating the executable
-ai: aioutputdir $(AIExecutable)
-aioutputdir:
+ai: $(AIOutputDir) $(AIExecutable)
+$(AIOutputDir):
 	mkdir -p $(AIOutputDir)
 
 $(AIExecutable): $(AIOobjects)
@@ -61,48 +61,68 @@ $(AIOutputDir)/%.o: %.cpp
 -include $(AIOobjects:.o=.d)
 
 # Deletes .o, .d and the executable
-aiclean:
+cleanai:
 	rm -f $(AIOutputDir)/*.o $(AIOutputDir)/*.d $(AIExecutable)
 
 # ============================================ GUI (Java) =============================================
-#Root directory of the GUI module
-GUIRoot = GUI
-# Output directory
-GUIOutputDir = $(GUIRoot)/bin
-# Name of the output jar
-GUIOutputJar = $(GUIOutputDir)/penguin.jar
-# Directory with all the java sources
-GUISourceDir = $(GUIRoot)/src
-vpath %.java $(GUISourceDir)
-# Path to the JSON lib
-GUIJSONJar = $(GUIRoot)/json-20160212.jar
-# Classes needed in the projet (in the form: package/className)
-GUIClasses = model/GameState model/Move model/Player model/Tile view/TileView controller/Controller controller/UpdateThread main/Main
-# Resources that will be included in the jar (they will be appended to the jar creation command. See man for the -C option that will allow to specify a relative path inside the jar)
-GUIJarResources = -C $(GUISourceDir) view/view.fxml -C $(GUISourceDir) resource/clic.wav -C $(GUISourceDir) resource/pingu_theme.wav
-
-# Output directory of compiled classes
-GUIClassesOutDir = $(GUIOutputDir)/classes
-# Classpath used for compiling
-GUICompileClasspath = $(GUIJSONJar):$(GUIClassesOutDir)
-# Classpath used for running
-GUIRunClasspath = $(GUIOutputJar):$(GUIJSONJar)
+GUIRoot := GUI
+# Output root directory
+GUIOutDir := $(GUIRoot)/out
+# Jar output file name
+GUIJarFile := $(GUIOutDir)/penguin.jar
+# Compiled classes output directory
+GUIOutClassDir := $(GUIOutDir)/classes
+# Sources root directory: all your sources will be under this directory (packages and classes)
+GUISrcDir := $(GUIRoot)/src
+# Packages that will be compiled and included in the jar: every class in these packages will be compiled, if you have classes in a package and in a subpackage as well you must specify both. Example: main package package/subpackage
+GUIPackages := main model view controller
+# Additional classes tha will be compiled and included in the jar: useful for packages that contains classes that you don't want to include. Otherwise, just use the Packages variable. Specify the path inside the source root WITH EXTENSION. Example: main/Main.java package/subpackage/MyClass.java
+GUIAdditionalClasses :=
+# Entry point (main class) for jar file. In the form package/subpackage/Class
+GUIJAREntryPoint := main.Main
+# Additional resources that will be copied in jar file. In the form -C path/to/the/parent/folder resource/path (resource/path will also be the path of the resourc inside the jar)
+GUIJARResources := -C $(GUISrcDir) resource/ -C $(GUISrcDir) view/view.fxml
+# Classpath option for compilation or execution: colon (:) separated list, must prepend -classpath flag. Example: -classpath Library.jar:Library/Include
+GUIClassPath := -classpath $(GUIRoot)/json-20160212.jar
+# Compiler additional flags
+GUIJAVACFlags :=
+# JAR additional flags
+GUIJARFlags :=
+# Run arguments
+GUIRunArgs := $(AIExecutable)
 
-# ==== RULES ====
-# Main rule for creating the jar of the GUI: it needs the output folder and all the compiled classes
-gui: guioutputdir $(addsuffix .class, $(GUIClasses))
-	$(JAR) cvfe $(GUIOutputJar) main.Main -C $(GUIClassesOutDir) ./ $(GUIJarResources)
-guioutputdir:
-	mkdir -p $(GUIOutputDir)
-
-# Rule for compiling a java class
-%.class: %.java guiclassesoutdir
-	$(JAVAC) -sourcepath $(GUISourceDir) -classpath $(GUICompileClasspath) -d $(GUIClassesOutDir)  $<
-guiclassesoutdir:
-	mkdir -p $(GUIClassesOutDir)
+
+# ========== AUTOMATICALLY GENERATED VARIABLES ==========
+# Searching for java files inside the $(Packages): for every package we search for java files and later we strip the leading source folder that is not necessary
+GUIClassesSources := $(patsubst $(GUISrcDir)/%, %, $(foreach package, $(GUIPackages), $(wildcard $(GUISrcDir)/$(package)/*.java)))
+GUIClassesSources := $(GUIClassesSources) $(GUIAdditionalClasses)
+# We tell make to search for java sources inside the source directory
+vpath %.java $(GUISrcDir)
+
+# ========== RULES ==========
+gui: $(GUIJarFile)
+
+# You need all compiled version of classes to make jar file
+$(GUIJarFile): $(addprefix $(GUIOutClassDir)/, $(GUIClassesSources:.java=.class)) $(GUIOutDir)
+	$(JAR) cvfe $(GUIJarFile) $(GUIJAREntryPoint) -C $(GUIOutClassDir) ./ $(GUIJARResources) $(GUIJARFlags)
+
+$(GUIOutDir):
+	mkdir -p $(GUIOutDir)
+
+# To compile a class you need the source code and the output folder
+$(GUIOutClassDir)/%.class: $(GUISrcDir)/%.java $(GUIOutClassDir)
+	$(JAVAC) -sourcepath $(GUISrcDir) -d $(GUIOutClassDir) $(GUIClassPath) $(GUIJAVACFlags) $<
+
+$(GUIOutClassDir):
+	mkdir -p $(GUIOutClassDir)
 
 run:
-	$(JAVA) -classpath $(GUIRunClasspath) main.Main $(AIExecutable)
+	@$(JAVA) $(GUIClassPath):$(GUIJarFile) main.Main $(GUIRunArgs)
+
+guicleanjar:
+	-rm -f $(GUIJarFile)
+
+guicleanclass:
+	-rm -f $(addprefix $(GUIOutClassDir)/, $(GUIClassesSources:.java=.class))
 
-guiclean:
-	rm -r $(GUIOutputDir)
+cleangui: guicleanjar guicleanclass