diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..6dea5f6
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,39 @@
+plugins {
+ id 'com.android.application'
+}
+
+android {
+ namespace 'com.example.jmastermind'
+ compileSdk 33
+
+ defaultConfig {
+ applicationId "com.example.jmastermind"
+ minSdk 19
+ targetSdk 33
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+dependencies {
+
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'com.google.android.material:material:1.8.0'
+ implementation 'androidx.preference:preference:1.2.0'
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.5'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
+}
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/app/src/androidTest/java/com/example/jmastermind/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/example/jmastermind/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..9c546fc
--- /dev/null
+++ b/app/src/androidTest/java/com/example/jmastermind/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.example.jmastermind;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ assertEquals("com.example.jmastermind", appContext.getPackageName());
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9cfca2c
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/example/jmastermind/Deck/Deck.java b/app/src/main/java/com/example/jmastermind/Deck/Deck.java
new file mode 100644
index 0000000..0a0b903
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Deck/Deck.java
@@ -0,0 +1,17 @@
+package com.example.jmastermind.Deck;
+
+import java.util.List;
+
+public interface Deck {
+ /**
+ * Recuperer la combinaison stockés dans la class
+ * @return La combinaison du deck
+ * */
+ public abstract List getDeck();
+
+ /**
+ * Retourne la combinaison sous forme de chaine de caractere
+ * @return Une facon personnaliser d'afficher la combinaison (debug)
+ * */
+ public abstract String displayComb();
+}
diff --git a/app/src/main/java/com/example/jmastermind/Deck/DeckCheck.java b/app/src/main/java/com/example/jmastermind/Deck/DeckCheck.java
new file mode 100644
index 0000000..cd4e131
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Deck/DeckCheck.java
@@ -0,0 +1,108 @@
+package com.example.jmastermind.Deck;
+
+import android.graphics.Color;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+
+public class DeckCheck implements Deck {
+ private List deck;
+ private Deck lambda;
+ private Deck winner;
+
+ /**
+ * Permet de comparer une combinaison attaquante avec une combinaison gagnante
+ * @param lambda La combinaison attaquante
+ * @param winner La combinaison gagnante
+ * */
+ public DeckCheck(Deck lambda, Deck winner) {
+ this.deck = new LinkedList<>();
+ this.lambda = lambda;
+ this.winner = winner;
+ }
+
+ /**
+ * Lancement de la verification
+ * @return Le deck comprenant les pions de verification Noir et Blanc
+ * */
+ public Deck doCheck() {
+ this.deck = new LinkedList<>();
+ List winner = this.winner.getDeck();
+ List lambda = this.lambda.getDeck();
+
+ for(int i = 0; i <= winner.size()-1; i++) {
+ Integer win = winner.get(i);
+ Integer lam = lambda.get(i);
+
+ if(Objects.equals(win, lam)) {
+ this.deck.add(Color.BLACK);
+ } else {
+ if(winner.contains(lam)) {
+ this.deck.add(Color.WHITE);
+ } else {
+ this.deck.add(Color.GRAY);
+ }
+ }
+ }
+
+ Deck check = new DeckLambda(
+ this.deck.get(0),
+ this.deck.get(1),
+ this.deck.get(2),
+ this.deck.get(3)
+ );
+
+ return check;
+ }
+
+ @Override
+ public List getDeck() {
+ return this.deck;
+ }
+
+ @Override
+ public String displayComb() {
+ StringBuilder sb = new StringBuilder();
+
+ for(int i = 0; i <= this.deck.size()-1; i++) {
+ switch(this.deck.get(i)) {
+ case Color.BLACK: {
+ sb.append("Noir").append(", ");
+ break;
+ }
+
+ case Color.WHITE: {
+ sb.append("Blanc").append(", ");
+ break;
+ }
+
+ case Color.GRAY: {
+ sb.append("Gris").append(", ");
+ break;
+ }
+
+ case Color.GREEN: {
+ sb.append("Vert").append(", ");
+ break;
+ }
+
+ case Color.RED: {
+ sb.append("Rouge").append(", ");
+ break;
+ }
+
+ case Color.YELLOW: {
+ sb.append("Jaune").append(", ");
+ break;
+ }
+
+ case Color.BLUE: {
+ sb.append("Bleu").append(", ");
+ break;
+ }
+ }
+ }
+
+ return sb.toString();
+ }
+}
diff --git a/app/src/main/java/com/example/jmastermind/Deck/DeckLambda.java b/app/src/main/java/com/example/jmastermind/Deck/DeckLambda.java
new file mode 100644
index 0000000..4d57622
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Deck/DeckLambda.java
@@ -0,0 +1,75 @@
+package com.example.jmastermind.Deck;
+
+import android.graphics.Color;
+import java.util.LinkedList;
+import java.util.List;
+
+public class DeckLambda implements Deck{
+ List deck;
+
+ /**
+ * Composition de la combinaison attaquante
+ * @param c1 Couleur en int du Pion n1
+ * @param c2 Couleur en int du Pion n2
+ * @param c3 Couleur en int du Pion n3
+ * @param c4 Couleur en int du Pion n4
+ * */
+ public DeckLambda(Integer c1, Integer c2, Integer c3, Integer c4) {
+ this.deck = new LinkedList<>();
+ this.deck.add(c1);
+ this.deck.add(c2);
+ this.deck.add(c3);
+ this.deck.add(c4);
+ }
+
+ @Override
+ public List getDeck() {
+ return this.deck;
+ }
+
+ @Override
+ public String displayComb() {
+ StringBuilder sb = new StringBuilder();
+
+ for(int i = 0; i <= this.deck.size()-1; i++) {
+ switch(this.deck.get(i)) {
+ case Color.BLACK: {
+ sb.append("Noir").append(", ");
+ break;
+ }
+
+ case Color.WHITE: {
+ sb.append("Blanc").append(", ");
+ break;
+ }
+
+ case Color.GREEN: {
+ sb.append("Vert").append(", ");
+ break;
+ }
+
+ case Color.RED: {
+ sb.append("Rouge").append(", ");
+ break;
+ }
+
+ case Color.YELLOW: {
+ sb.append("Jaune").append(", ");
+ break;
+ }
+
+ case Color.BLUE: {
+ sb.append("Bleu").append(", ");
+ break;
+ }
+
+ case Color.GRAY: {
+ sb.append("Gris").append(", ");
+ break;
+ }
+ }
+ }
+
+ return sb.toString();
+ }
+}
diff --git a/app/src/main/java/com/example/jmastermind/Deck/DeckWinner.java b/app/src/main/java/com/example/jmastermind/Deck/DeckWinner.java
new file mode 100644
index 0000000..af1370f
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Deck/DeckWinner.java
@@ -0,0 +1,102 @@
+package com.example.jmastermind.Deck;
+
+import android.graphics.Color;
+import java.util.LinkedList;
+import java.util.List;
+
+public class DeckWinner implements Deck{
+ List deck;
+ Boolean isMulti;
+
+ /**
+ * Composition de la combinaison gagante
+ * @param c1 Couleur en int du Pion n1
+ * @param c2 Couleur en int du Pion n2
+ * @param c3 Couleur en int du Pion n3
+ * @param c4 Couleur en int du Pion n4
+ * */
+ public DeckWinner(Integer c1, Integer c2, Integer c3, Integer c4) {
+ this.deck = new LinkedList<>();
+ this.deck.add(c1);
+ this.deck.add(c2);
+ this.deck.add(c3);
+ this.deck.add(c4);
+ isMulti = false;
+ }
+
+ /**
+ * (Je suis conscient que ce n'est pos opti mais il sert a savoir si le jeux doit relancer la partie sur le mode multi ou solo)
+ * Composition de la combinaison gagante
+ * @param c1 Couleur en int du Pion n1
+ * @param c2 Couleur en int du Pion n2
+ * @param c3 Couleur en int du Pion n3
+ * @param c4 Couleur en int du Pion n4
+ * @param isMulti Toujours = a true
+ * */
+ public DeckWinner(Integer c1, Integer c2, Integer c3, Integer c4, Boolean isMulti) {
+ this.deck = new LinkedList<>();
+ this.deck.add(c1);
+ this.deck.add(c2);
+ this.deck.add(c3);
+ this.deck.add(c4);
+ this.isMulti = isMulti;
+ }
+
+ /**
+ * Renvoie vrai ou faux celon le boolean de isMulti
+ * */
+ public Boolean getIsMulti() {
+ return this.isMulti;
+ }
+
+ @Override
+ public List getDeck() {
+ return this.deck;
+ }
+
+ @Override
+ public String displayComb() {
+ StringBuilder sb = new StringBuilder();
+
+ for(int i = 0; i <= this.deck.size()-1; i++) {
+ switch(this.deck.get(i)) {
+ case Color.BLACK: {
+ sb.append("Noir").append(", ");
+ break;
+ }
+
+ case Color.WHITE: {
+ sb.append("Blanc").append(", ");
+ break;
+ }
+
+ case Color.GREEN: {
+ sb.append("Vert").append(", ");
+ break;
+ }
+
+ case Color.RED: {
+ sb.append("Rouge").append(", ");
+ break;
+ }
+
+ case Color.YELLOW: {
+ sb.append("Jaune").append(", ");
+ break;
+ }
+
+ case Color.BLUE: {
+ sb.append("Bleu").append(", ");
+ break;
+ }
+
+ case Color.GRAY: {
+ sb.append("Gris").append(", ");
+ break;
+ }
+ }
+ }
+
+ return sb.toString();
+ }
+}
diff --git a/app/src/main/java/com/example/jmastermind/Events/CanVoidEvent.java b/app/src/main/java/com/example/jmastermind/Events/CanVoidEvent.java
new file mode 100644
index 0000000..c39201d
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Events/CanVoidEvent.java
@@ -0,0 +1,28 @@
+package com.example.jmastermind.Events;
+
+import android.content.SharedPreferences;
+import android.widget.CompoundButton;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.preference.PreferenceManager;
+
+public class CanVoidEvent implements CompoundButton.OnCheckedChangeListener {
+ private AppCompatActivity context;
+ private SharedPreferences sp;
+ private SharedPreferences.Editor edit;
+ private String CAN_VOID = "canVoid";
+
+ public CanVoidEvent(AppCompatActivity context) {
+ this.context = context;
+ this.sp = PreferenceManager.getDefaultSharedPreferences(this.context);
+ this.edit = this.sp.edit();
+ this.edit.putBoolean(CAN_VOID, false);
+ this.edit.apply();
+ }
+
+ @Override
+ public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
+ this.edit.putBoolean(CAN_VOID, b);
+ this.edit.apply();
+ }
+}
diff --git a/app/src/main/java/com/example/jmastermind/Events/ColorSelectorEvent.java b/app/src/main/java/com/example/jmastermind/Events/ColorSelectorEvent.java
new file mode 100644
index 0000000..a6e6606
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Events/ColorSelectorEvent.java
@@ -0,0 +1,187 @@
+package com.example.jmastermind.Events;
+
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.util.Log;
+import android.view.View;
+import android.widget.TextView;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.preference.PreferenceManager;
+import com.example.jmastermind.Deck.Deck;
+import com.example.jmastermind.Deck.DeckCheck;
+import com.example.jmastermind.Deck.DeckLambda;
+import com.example.jmastermind.Deck.DeckWinner;
+import com.example.jmastermind.Game.Popup;
+import com.example.jmastermind.Geometrics.Circle;
+import com.example.jmastermind.R;
+import java.util.LinkedList;
+import java.util.List;
+
+public class ColorSelectorEvent extends View implements View.OnClickListener {
+ private boolean canVoid;
+ private AppCompatActivity context;
+ /**
+ * [0] = x
+ * [1] = y
+ * */
+ private int[] coords;
+ private DeckWinner winner;
+ private int tentative;
+
+ /**
+ * Evenement declanché lorsque le joueur selectionne une couleur
+ * @param context Le contexte de l'app
+ * @param winner La combinaison gagnante
+ * */
+ public ColorSelectorEvent(AppCompatActivity context, DeckWinner winner) {
+ super(context);
+ this.context = context;
+ this.winner = winner;
+ this.coords = new int[]{1, 1};
+ this.tentative = 10;
+
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this.context);
+ this.canVoid = sp.getBoolean("canVoid", false);
+
+ Log.d("test", this.canVoid + "");
+ }
+
+ /**
+ * Relier indirectement au bouton "Valider"
+ * Changer de ligne et lancer la verification des combinaisons
+ * */
+ public void goNext() {
+ List listOfColors = new LinkedList<>();
+
+ for(int i = 1; i <= 4; i++) {
+ int id = this.context.getResources()
+ .getIdentifier("normalCircle" + this.coords[0] + i, "id", this.context.getPackageName());
+ Circle c = this.context.findViewById(id);
+
+ listOfColors.add(c.getColor());
+ }
+
+ if(listOfColors.contains(Color.GRAY) && !this.canVoid) {
+ return;
+ }
+
+ Deck lambda = new DeckLambda(
+ listOfColors.get(0),
+ listOfColors.get(1),
+ listOfColors.get(2),
+ listOfColors.get(3)
+ );
+
+ DeckCheck checker = new DeckCheck(lambda, this.winner);
+ Deck checkerPions = checker.doCheck();
+ List checkColors = checkerPions.getDeck();
+ int countOfBlack = 0;
+
+ for(int i = 1; i <= 4; i++) {
+ int id = this.context.getResources()
+ .getIdentifier("checkCircle" + this.coords[0] + i, "id", this.context.getPackageName());
+ Circle c = this.context.findViewById(id);
+
+ c.setColor(checkColors.get(i-1));
+
+ if(checkColors.get(i-1) == Color.BLACK) {
+ countOfBlack++;
+ }
+ }
+
+ String[] opts = new String[] {
+ "Rejouer",
+ "Voir votre jeu",
+ "Retourner au menu"
+ };
+
+ this.tentative--;
+
+ if(countOfBlack == 4) {
+ Popup popup = new Popup(this.context, opts, this.winner.getIsMulti(), (10 - this.tentative));
+ popup.show();
+ } else if(this.tentative == 0) {
+ Popup popup = new Popup(this.context, opts, this.winner.getIsMulti(), -1);
+ popup.show();
+ }
+
+ TextView tx = (TextView) this.context.findViewById(R.id.counter);
+ tx.setText("Tentative rest. \n" + this.tentative);
+ tx.invalidate();
+
+ this.coords[1] = 1;
+ this.coords[0]++;
+ }
+
+ /**
+ * Relier indirectement au bouton "Effacer"
+ * Permet d'effacer la combinaison non validé par le joueur
+ * */
+ public void resetCombi() {
+ for(int i = 1; i <= this.coords[1]; i++) {
+ int id = this.context.getResources()
+ .getIdentifier("normalCircle" + this.coords[0] + i, "id", this.context.getPackageName());
+ Circle c = this.context.findViewById(id);
+
+ c.setColor(Color.GRAY);
+ }
+
+ this.coords[1] = 1;
+ }
+
+ @Override
+ public void onClick(View view) {
+ int idOfClickedColor = view.getId();
+ Circle circleClicked = (Circle) this.context.findViewById(idOfClickedColor);
+ int colorChoosed = circleClicked.getColor();
+
+ int id = this.context.getResources()
+ .getIdentifier("normalCircle" + this.coords[0] + this.coords[1], "id", this.context.getPackageName());
+ Circle c = this.context.findViewById(id);
+
+ switch(colorChoosed) {
+ case Color.RED: {
+ c.setColor(Color.RED);
+ break;
+ }
+
+ case Color.GREEN: {
+ c.setColor(Color.GREEN);
+ break;
+ }
+
+ case Color.BLUE: {
+ c.setColor(Color.BLUE);
+ break;
+ }
+
+ case Color.YELLOW: {
+ c.setColor(Color.YELLOW);
+ break;
+ }
+
+ case Color.BLACK: {
+ c.setColor(Color.BLACK);
+ break;
+ }
+
+ case Color.WHITE: {
+ c.setColor(Color.WHITE);
+ break;
+ }
+
+ case Color.GRAY: {
+ c.setColor(Color.GRAY);
+ break;
+ }
+
+ default: {
+ break;
+ }
+ }
+
+ if(this.coords[1] < 4) {
+ this.coords[1]++;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/jmastermind/Events/ControlEvent.java b/app/src/main/java/com/example/jmastermind/Events/ControlEvent.java
new file mode 100644
index 0000000..76f3150
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Events/ControlEvent.java
@@ -0,0 +1,40 @@
+package com.example.jmastermind.Events;
+
+import android.content.Intent;
+import android.view.View;
+import android.widget.Button;
+import androidx.appcompat.app.AppCompatActivity;
+import com.example.jmastermind.Game.Controller;
+import com.example.jmastermind.Menu.Menu;
+
+public class ControlEvent extends View implements View.OnClickListener {
+ private final AppCompatActivity context;
+ private Controller controller;
+
+ /**
+ * Event relier aux boutons "Valider" et "Effacer"
+ * @param context Le context
+ * @param controller Le controller du jeu
+ * */
+ public ControlEvent(AppCompatActivity context, Controller controller) {
+ super(context);
+ this.context = context;
+ this.controller = controller;
+ }
+
+ @Override
+ public void onClick(View view) {
+ int idOfButton = view.getId();
+ Button btnClicked = (Button) this.context.findViewById(idOfButton);
+ CharSequence text = btnClicked.getText();
+
+ if ("Valider".equals(text)) {
+ this.controller.viewValidate();
+ } else if ("Effacer".equals(text)) {
+ this.controller.viewReset();
+ } else if("Quitter".equals(text)) {
+ Intent i = new Intent(this.context, Menu.class);
+ this.context.startActivity(i);
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/jmastermind/Events/DefendCombiSelectorEvent.java b/app/src/main/java/com/example/jmastermind/Events/DefendCombiSelectorEvent.java
new file mode 100644
index 0000000..1943d21
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Events/DefendCombiSelectorEvent.java
@@ -0,0 +1,100 @@
+package com.example.jmastermind.Events;
+
+import android.graphics.Color;
+import android.view.View;
+import androidx.appcompat.app.AppCompatActivity;
+import com.example.jmastermind.Geometrics.Circle;
+import com.example.jmastermind.R;
+import java.util.LinkedList;
+import java.util.List;
+
+public class DefendCombiSelectorEvent implements View.OnClickListener{
+ private AppCompatActivity context;
+ private int pos;
+ private List refs;
+
+ public DefendCombiSelectorEvent(AppCompatActivity context) {
+ this.context = context;
+ this.refs = new LinkedList<>();
+ this.pos = 0;
+
+ this.refs.add(R.id.receiveOne);
+ this.refs.add(R.id.receiveTwo);
+ this.refs.add(R.id.receiveThree);
+ this.refs.add(R.id.receiveFour);
+ }
+
+ /**
+ * Remettre le compteur a zero si le joueur reset sa combinaison.
+ * */
+ public void reset() {
+ this.pos = 0;
+ }
+
+ /**
+ * Recuperer la combinaison
+ * @return La liste des couleurs choisit par le defenseur
+ * */
+ public List getCombinaison() {
+ if(this.pos == 4) {
+ List tmp = new LinkedList<>();
+
+ for(int i = 0; i <= this.pos-1; i++) {
+ Circle c = this.context.findViewById(this.refs.get(i));
+ tmp.add(c.getColor());
+ }
+
+ return tmp;
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void onClick(View view) {
+ if(this.pos <= 3) {
+ int id = view.getId();
+ Circle c = this.context.findViewById(id);
+ Integer chose = c.getColor();
+
+ Circle toModify = (Circle) this.context.findViewById(this.refs.get(this.pos));
+
+ switch(chose) {
+ case Color.BLACK: {
+ toModify.setColor(Color.BLACK);
+ break;
+ }
+
+ case Color.WHITE: {
+ toModify.setColor(Color.WHITE);
+ break;
+ }
+
+ case Color.GREEN: {
+ toModify.setColor(Color.GREEN);
+ break;
+ }
+ case Color.BLUE: {
+ toModify.setColor(Color.BLUE);
+ break;
+ }
+
+ case Color.RED: {
+ toModify.setColor(Color.RED);
+ break;
+ }
+
+ case Color.YELLOW: {
+ toModify.setColor(Color.YELLOW);
+ break;
+ }
+
+ default: {
+ break;
+ }
+ }
+
+ this.pos++;
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/jmastermind/Events/DefendValidateEvent.java b/app/src/main/java/com/example/jmastermind/Events/DefendValidateEvent.java
new file mode 100644
index 0000000..77d800b
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Events/DefendValidateEvent.java
@@ -0,0 +1,64 @@
+package com.example.jmastermind.Events;
+
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import androidx.appcompat.app.AppCompatActivity;
+import com.example.jmastermind.Game.Game;
+import com.example.jmastermind.Geometrics.Circle;
+import com.example.jmastermind.Menu.Menu;
+import com.example.jmastermind.R;
+import java.util.ArrayList;
+import java.util.List;
+
+public class DefendValidateEvent implements View.OnClickListener {
+ private DefendCombiSelectorEvent dce;
+ private AppCompatActivity context;
+
+ public DefendValidateEvent(AppCompatActivity context, DefendCombiSelectorEvent dce) {
+ this.context = context;
+ this.dce = dce;
+ }
+
+ @Override
+ public void onClick(View view) {
+ int idOfButton = view.getId();
+ Button btnClicked = (Button) this.context.findViewById(idOfButton);
+ CharSequence text = btnClicked.getText();
+
+ if ("Valider".equals(text)) {
+ if(this.dce.getCombinaison() != null) {
+ List defendColor = this.dce.getCombinaison();
+
+ // Merci StackOverflow: https://stackoverflow.com/questions/2091465/how-do-i-pass-data-between-activities-in-android-application
+ Bundle bundle = new Bundle();
+ ArrayList arr = new ArrayList<>(defendColor);
+ bundle.putIntegerArrayList("DefendCombi", arr);
+
+ Intent i = new Intent(this.context, Game.class);
+ i.putExtras(bundle);
+
+ this.context.startActivity(i);
+ }
+ } else if ("Effacer".equals(text)) {
+ Circle one = this.context.findViewById(R.id.receiveOne);
+ one.setColor(Color.GRAY);
+
+ Circle two = this.context.findViewById(R.id.receiveTwo);
+ two.setColor(Color.GRAY);
+
+ Circle three = this.context.findViewById(R.id.receiveThree);
+ three.setColor(Color.GRAY);
+
+ Circle four = this.context.findViewById(R.id.receiveFour);
+ four.setColor(Color.GRAY);
+
+ this.dce.reset();
+ } else if("Retour".equals(text)) {
+ Intent i = new Intent(this.context, Menu.class);
+ this.context.startActivity(i);
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/jmastermind/Events/MenuEvent.java b/app/src/main/java/com/example/jmastermind/Events/MenuEvent.java
new file mode 100644
index 0000000..8ea1588
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Events/MenuEvent.java
@@ -0,0 +1,32 @@
+package com.example.jmastermind.Events;
+
+import android.content.Intent;
+import android.media.MediaPlayer;
+import android.view.View;
+import androidx.appcompat.app.AppCompatActivity;
+
+public class MenuEvent implements View.OnClickListener {
+ private Class option;
+ private AppCompatActivity context;
+ private MediaPlayer mp;
+
+ /**
+ * Event lié au menu de depart
+ * @param context Le contexte
+ * @param option La class de l'activité a demarrer
+ * @param mp Couper le son d'une activite
+ * */
+ public MenuEvent(AppCompatActivity context, Class option, MediaPlayer mp) {
+ this.context = context;
+ this.option = option;
+ this.mp = mp;
+ }
+
+ @Override
+ public void onClick(View view) {
+ this.mp.stop();
+
+ Intent i = new Intent(this.context, this.option);
+ this.context.startActivity(i);
+ }
+}
diff --git a/app/src/main/java/com/example/jmastermind/Events/PopupEvent.java b/app/src/main/java/com/example/jmastermind/Events/PopupEvent.java
new file mode 100644
index 0000000..adafd20
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Events/PopupEvent.java
@@ -0,0 +1,83 @@
+package com.example.jmastermind.Events;
+
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.media.MediaPlayer;
+import android.view.View;
+import android.widget.Button;
+import androidx.appcompat.app.AppCompatActivity;
+import com.example.jmastermind.Game.ColorDefSelect;
+import com.example.jmastermind.Game.Popup;
+import com.example.jmastermind.Game.Game;
+import com.example.jmastermind.Menu.Menu;
+import com.example.jmastermind.R;
+
+public class PopupEvent implements DialogInterface.OnClickListener, View.OnClickListener {
+ private MediaPlayer mp;
+ private int tentative;
+ private AppCompatActivity context;
+ private Boolean isMulti;
+
+ /**
+ * Event lié au popup de fin de partie
+ * @param context Le context
+ * @param tentative Le nombre de tentative
+ * @param isMulti Le mode de jeu
+ * */
+ public PopupEvent(AppCompatActivity context, int tentative, MediaPlayer mp, Boolean isMulti) {
+ this.context = context;
+ this.tentative = tentative;
+ this.mp = mp;
+ this.isMulti = isMulti;
+ }
+
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ switch(i) {
+ case 0: {
+ this.mp.stop();
+
+ Intent a;
+
+ if(!this.isMulti) {
+ a = new Intent(this.context, Game.class);
+ } else {
+ a = new Intent(this.context, ColorDefSelect.class);
+ }
+
+ this.context.startActivity(a);
+ break;
+ }
+
+ case 1: {
+ this.mp.stop();
+ Button btn = (Button) this.context.findViewById(R.id.validate);
+ btn.setText("Finish HIM");
+ btn.setOnClickListener(this);
+
+ dialogInterface.cancel();
+ break;
+ }
+
+ case 2: {
+ this.mp.stop();
+ Intent c = new Intent(this.context, Menu.class);
+ this.context.startActivity(c);
+ break;
+ }
+ }
+ }
+
+
+ @Override
+ public void onClick(View view) {
+ String[] opts = new String[] {
+ "Rejouer",
+ "Voir votre jeu",
+ "Retourner au menu"
+ };
+
+ Popup pop = new Popup(this.context, opts, this.isMulti, this.tentative);
+ pop.show();
+ }
+}
diff --git a/app/src/main/java/com/example/jmastermind/Events/PrologueAnimation.java b/app/src/main/java/com/example/jmastermind/Events/PrologueAnimation.java
new file mode 100644
index 0000000..56ec3ac
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Events/PrologueAnimation.java
@@ -0,0 +1,33 @@
+package com.example.jmastermind.Events;
+
+import android.content.Intent;
+import android.media.MediaPlayer;
+import android.view.animation.Animation;
+import androidx.appcompat.app.AppCompatActivity;
+import com.example.jmastermind.Menu.Menu;
+
+public class PrologueAnimation implements Animation.AnimationListener {
+ private AppCompatActivity context;
+ private MediaPlayer mp;
+
+ public PrologueAnimation(AppCompatActivity context, MediaPlayer mp) {
+ this.context = context;
+ this.mp = mp;
+ }
+
+ @Override
+ public void onAnimationStart(Animation animation) {
+ }
+
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ this.mp.stop();
+ Intent i = new Intent(this.context, Menu.class);
+ this.context.startActivity(i);
+ }
+
+ @Override
+ public void onAnimationRepeat(Animation animation) {
+
+ }
+}
diff --git a/app/src/main/java/com/example/jmastermind/Game/ColorDefSelect.java b/app/src/main/java/com/example/jmastermind/Game/ColorDefSelect.java
new file mode 100644
index 0000000..1645edd
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Game/ColorDefSelect.java
@@ -0,0 +1,59 @@
+package com.example.jmastermind.Game;
+
+import android.graphics.Color;
+import android.os.Bundle;
+import android.widget.Button;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+import com.example.jmastermind.Events.DefendCombiSelectorEvent;
+import com.example.jmastermind.Events.DefendValidateEvent;
+import com.example.jmastermind.Geometrics.Circle;
+import com.example.jmastermind.R;
+
+public class ColorDefSelect extends AppCompatActivity {
+
+ /**
+ * Le jeu mode Multi
+ * */
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.defend);
+
+ DefendCombiSelectorEvent dce = new DefendCombiSelectorEvent(this);
+ DefendValidateEvent dve = new DefendValidateEvent(this, dce);
+
+ Circle red = (Circle) findViewById(R.id.selectRed);
+ red.setColor(Color.RED);
+ red.setOnClickListener(dce);
+
+ Circle blue = (Circle) findViewById(R.id.selectBlue);
+ blue.setColor(Color.BLUE);
+ blue.setOnClickListener(dce);
+
+ Circle yellow = (Circle) findViewById(R.id.selectYellow);
+ yellow.setColor(Color.YELLOW);
+ yellow.setOnClickListener(dce);
+
+ Circle green = (Circle) findViewById(R.id.selectGreen);
+ green.setColor(Color.GREEN);
+ green.setOnClickListener(dce);
+
+ Circle black = (Circle) findViewById(R.id.selectBlack);
+ black.setColor(Color.BLACK);
+ black.setOnClickListener(dce);
+
+ Circle white = (Circle) findViewById(R.id.selectWhite);
+ white.setColor(Color.WHITE);
+ white.setOnClickListener(dce);
+
+ Button validate = (Button) findViewById(R.id.selectValidate);
+ validate.setOnClickListener(dve);
+
+ Button reset = (Button) findViewById(R.id.selectReset);
+ reset.setOnClickListener(dve);
+
+ Button back = (Button) findViewById(R.id.selectBack);
+ back.setOnClickListener(dve);
+ }
+}
diff --git a/app/src/main/java/com/example/jmastermind/Game/Controller.java b/app/src/main/java/com/example/jmastermind/Game/Controller.java
new file mode 100644
index 0000000..83e099c
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Game/Controller.java
@@ -0,0 +1,63 @@
+package com.example.jmastermind.Game;
+
+import android.util.Log;
+import androidx.appcompat.app.AppCompatActivity;
+import com.example.jmastermind.Deck.DeckWinner;
+import com.example.jmastermind.Events.ColorSelectorEvent;
+import com.example.jmastermind.Events.ControlEvent;
+
+public class Controller {
+ private Vuew vuew;
+ private Model model;
+ private AppCompatActivity context;
+ private ColorSelectorEvent event;
+ private ControlEvent controlEvent;
+
+ /**
+ * Controlleur du jeu
+ * @param context Le contexte
+ * @param mode 0 Solo ou 1 multi
+ * */
+ public Controller(AppCompatActivity context, int mode, DeckWinner... win) {
+ this.context = context;
+
+ this.controlEvent = new ControlEvent(this.context, this);
+
+ this.model = new Model(this.context);
+ this.model.init();
+
+ if(mode == 0) {
+ this.model.genWinner();
+ DeckWinner winner = this.model.getWinner();
+ Log.d("COMBINAISON GAGNANTE", winner.displayComb());
+ this.event = new ColorSelectorEvent(this.context, winner);
+ } else {
+ Log.d("COMBINAISON GAGNANTE", win[0].displayComb());
+ this.event = new ColorSelectorEvent(this.context, win[0]);
+ }
+
+ this.vuew = new Vuew(
+ this.context,
+ this.model.getListOfNormalCircle(),
+ this.model.getListOfCheckCircle(),
+ this.event,
+ this.controlEvent
+ );
+
+ this.vuew.init();
+ }
+
+ /**
+ * Quand le joueur appuie sur "valider"
+ * */
+ public void viewValidate() {
+ this.event.goNext();
+ }
+
+ /**
+ * Quand le joueur appuie sur "effacer"
+ * */
+ public void viewReset() {
+ this.event.resetCombi();
+ }
+}
diff --git a/app/src/main/java/com/example/jmastermind/Game/Game.java b/app/src/main/java/com/example/jmastermind/Game/Game.java
new file mode 100644
index 0000000..a1ee73f
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Game/Game.java
@@ -0,0 +1,39 @@
+package com.example.jmastermind.Game;
+
+import android.content.Intent;
+import android.os.Bundle;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+import com.example.jmastermind.Deck.DeckWinner;
+import com.example.jmastermind.Menu.Menu;
+import com.example.jmastermind.R;
+import java.util.ArrayList;
+
+public class Game extends AppCompatActivity {
+ /**
+ * Le jeu mode SOLO
+ * */
+ public Game() {}
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.game);
+
+ Intent i = this.getIntent();
+ ArrayList combi = i.getIntegerArrayListExtra("DefendCombi");
+
+ if(combi != null) {
+ DeckWinner dw = new DeckWinner(combi.get(0), combi.get(1), combi.get(2), combi.get(3), true);
+ Controller controller = new Controller(this, 1, dw);
+ } else {
+ Controller controller = new Controller(this, 0);
+ }
+ }
+
+ @Override
+ public void onBackPressed() {
+ Intent i = new Intent(this, Menu.class);
+ this.startActivity(i);
+ }
+}
diff --git a/app/src/main/java/com/example/jmastermind/Game/Model.java b/app/src/main/java/com/example/jmastermind/Game/Model.java
new file mode 100644
index 0000000..eeb4acb
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Game/Model.java
@@ -0,0 +1,139 @@
+package com.example.jmastermind.Game;
+
+import android.graphics.Color;
+import android.view.View;
+import androidx.appcompat.app.AppCompatActivity;
+import com.example.jmastermind.Deck.DeckWinner;
+import com.example.jmastermind.Geometrics.Circle;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+public class Model extends View {
+ private List listOfNormalCircle;
+ private List listOfCheckCircle;
+ private DeckWinner winner;
+ private AppCompatActivity context;
+
+ /**
+ * Le model du jeu
+ * @param context Le contexte
+ * */
+ public Model(AppCompatActivity context) {
+ super(context);
+ this.context = context;
+ this.listOfNormalCircle = new LinkedList<>();
+ this.listOfCheckCircle = new LinkedList<>();
+ this.winner = null;
+ }
+
+ /**
+ * Genere une combinaison aleatoire
+ * */
+ public void genWinner() {
+ Integer[] color = new Integer[]{0, 0, 0, 0};
+
+ for(int i = 0; i <= 3; i++) {
+ Random rand = new Random();
+ int ran = rand.nextInt(6) + 1;
+
+ switch(ran) {
+ case 1: {
+ color[i] = Color.RED;
+ break;
+ }
+
+ case 2: {
+ color[i] = Color.YELLOW;
+ break;
+ }
+
+ case 3: {
+ color[i] = Color.BLUE;
+ break;
+ }
+
+ case 4: {
+ color[i] = Color.GREEN;
+ break;
+ }
+
+ case 5: {
+ color[i] = Color.WHITE;
+ break;
+ }
+
+ case 6: {
+ color[i] = Color.BLACK;
+ break;
+ }
+
+ case 7: {
+ color[i] = Color.GRAY;
+ break;
+ }
+
+ default: {
+ break;
+ }
+ }
+ }
+
+ this.winner = new DeckWinner(color[1], color[0], color[2], color[3]);
+ }
+
+ /**
+ * Recupere le deck gagant du jeu
+ * @return DeckWinner Le deck gagant du jeu
+ * */
+ public DeckWinner getWinner() {
+ return this.winner;
+ }
+
+ /**
+ * Demarrage du Model
+ * @return Si oui ou non ca a fonctionné
+ * */
+ public Boolean init() {
+ try {
+ for(int i = 1; i <= 10; i++) {
+ for(int j = 1; j <= 4; j++) {
+ int normalId = this.context.getResources().
+ getIdentifier("normalCircle" + i + j, "id", this.context.getPackageName());
+ Circle normal = this.context.findViewById(normalId);
+
+ int checkId = this.context.getResources()
+ .getIdentifier("checkCircle" + i + j, "id", this.context.getPackageName());
+ Circle check = this.context.findViewById(checkId);
+
+ this.listOfNormalCircle.add(normal);
+ this.listOfCheckCircle.add(check);
+ }
+ }
+
+ return true;
+ } catch(ArrayIndexOutOfBoundsException e) {
+ System.out.println("[!] Probleme lors de l'initiliation du model (ArrayIndexOutOfBoundsException).");
+ return false;
+ } catch(NullPointerException e) {
+ System.out.println("[!] Probleme lors de l'initiliation du model (NullPointerException).");
+ return false;
+ }
+ }
+
+ /**
+ * Recuperation des cercles normaux du jeu (id="normalCircleXY" du xml)
+ * @return La liste des references vers les cercles normaux
+ * */
+ public List getListOfNormalCircle() {
+ return this.listOfNormalCircle;
+ }
+
+ /**
+ * Recuperation des clercles de verification du jeu (noir et blanc) (id="checkCircleXY" du xml)
+ * @return La liste des references vers les cercles de verification
+ * */
+ public List getListOfCheckCircle() {
+ return this.listOfCheckCircle;
+ }
+}
diff --git a/app/src/main/java/com/example/jmastermind/Game/Popup.java b/app/src/main/java/com/example/jmastermind/Game/Popup.java
new file mode 100644
index 0000000..b95cba6
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Game/Popup.java
@@ -0,0 +1,42 @@
+package com.example.jmastermind.Game;
+
+import android.media.MediaPlayer;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatActivity;
+import com.example.jmastermind.Events.PopupEvent;
+import com.example.jmastermind.R;
+
+public class Popup extends AlertDialog.Builder {
+ private MediaPlayer mp;
+ private AppCompatActivity context;
+ private PopupEvent event;
+
+ /**
+ * Affiche la popup de fin de jeu
+ * @param context Le context
+ * @param options La liste des options (rejouer, ...)
+ * @param tentative Le nombre de tentatives
+ * */
+ public Popup(AppCompatActivity context, String[] options, Boolean isMulti, int... tentative) {
+ super(context);
+ this.context = context;
+ this.setCancelable(false);
+
+ if(tentative[0] > 0) {
+ this.mp = MediaPlayer.create(this.context, R.raw.winningsong);
+ this.mp.setLooping(true);
+ this.mp.start();
+
+ this.setTitle("Félicitation ! Vous avez gagner en : " + tentative[0] + " coup(s).");
+ } else {
+ this.mp = MediaPlayer.create(this.context, R.raw.loosegamesong);
+ this.mp.setLooping(true);
+ this.mp.start();
+
+ this.setTitle("Perdu !");
+ }
+
+ this.event = new PopupEvent(this.context, tentative[0], this.mp, isMulti);
+ this.setItems(options, this.event);
+ }
+}
diff --git a/app/src/main/java/com/example/jmastermind/Game/Vuew.java b/app/src/main/java/com/example/jmastermind/Game/Vuew.java
new file mode 100644
index 0000000..acd1ef0
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Game/Vuew.java
@@ -0,0 +1,98 @@
+package com.example.jmastermind.Game;
+
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.view.View;
+import android.widget.Button;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.preference.PreferenceManager;
+
+import com.example.jmastermind.Events.ColorSelectorEvent;
+import com.example.jmastermind.Events.ControlEvent;
+import com.example.jmastermind.Geometrics.Circle;
+import com.example.jmastermind.R;
+import java.util.List;
+
+public class Vuew {
+ private boolean canVoid;
+ private ColorSelectorEvent event;
+ private List normalCircle;
+ private List checkedCircle;
+ private AppCompatActivity context;
+ private ControlEvent controlEvent;
+
+ /**
+ * La vue du jeu
+ * @param context Le context
+ * @param normalCircle Les references vers les cercles normaux
+ * @param checkCircle Les references vers les cercles de verification
+ * @param event L'event de la selection de couleur
+ * @param controlEvent L'event vers les deux boutons Valider et Effacer
+ * */
+ public Vuew(AppCompatActivity context, List normalCircle, List checkCircle, ColorSelectorEvent event, ControlEvent controlEvent) {
+ this.context = context;
+ this.normalCircle = normalCircle;
+ this.checkedCircle = checkCircle;
+ this.event = event;
+ this.controlEvent = controlEvent;
+
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this.context);
+ this.canVoid = sp.getBoolean("canVoid", false);
+ }
+
+ /**
+ * Parametrage du plateau de jeu
+ * */
+ public Boolean init() {
+ try {
+ Circle yellow = (Circle) this.context.findViewById(R.id.yellow);
+ yellow.setColor(Color.YELLOW);
+ yellow.setOnClickListener(this.event);
+
+ Circle red = (Circle) this.context.findViewById(R.id.red);
+ red.setColor(Color.RED);
+ red.setOnClickListener(this.event);
+
+ Circle green = (Circle) this.context.findViewById(R.id.green);
+ green.setColor(Color.GREEN);
+ green.setOnClickListener(this.event);
+
+ Circle blue = (Circle) this.context.findViewById(R.id.blue);
+ blue.setColor(Color.BLUE);
+ blue.setOnClickListener(this.event);
+
+ Circle white = (Circle) this.context.findViewById(R.id.white);
+ white.setColor(Color.WHITE);
+ white.setOnClickListener(this.event);
+
+ Circle black = (Circle) this.context.findViewById(R.id.black);
+ black.setColor(Color.BLACK);
+ black.setOnClickListener(this.event);
+
+ Circle gray = (Circle) this.context.findViewById(R.id.gray);
+ if(this.canVoid) {
+ gray.setColor(Color.GRAY);
+ gray.setOnClickListener(this.event);
+ } else {
+ gray.setVisibility(View.GONE);
+ }
+
+ Button validate = (Button) this.context.findViewById(R.id.validate);
+ validate.setOnClickListener(this.controlEvent);
+
+ Button reset = (Button) this.context.findViewById(R.id.reset);
+ reset.setOnClickListener(this.controlEvent);
+
+ Button leave = (Button) this.context.findViewById(R.id.leave);
+ leave.setOnClickListener(this.controlEvent);
+
+ return true;
+ } catch(NullPointerException e) {
+ System.out.println("[!] Probleme lors de l'initiliation de la vue (NullPointerException).");
+ return false;
+ } catch(ArrayIndexOutOfBoundsException e) {
+ System.out.println("[!] Probleme lors de l'initiliation de la vue (ArrayIndexOutOfBoundsException).");
+ return false;
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/jmastermind/Geometrics/Circle.java b/app/src/main/java/com/example/jmastermind/Geometrics/Circle.java
new file mode 100644
index 0000000..7415775
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Geometrics/Circle.java
@@ -0,0 +1,57 @@
+package com.example.jmastermind.Geometrics;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.view.View;
+import androidx.annotation.Nullable;
+
+public class Circle extends View {
+ private Paint picasso;
+ private int color;
+ /**
+ * Les cercles du jeu "programmiser" en Java
+ * @param context Le context
+ * @param attrs Les attributs (notamment id)
+ * */
+ public Circle(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ this.color = Color.GRAY;
+ this.picasso = new Paint();
+ }
+ /**
+ * Recuperer la couleur du cercle
+ * @return La couleur du cercle en int
+ * */
+ public int getColor() {
+ return this.color;
+ }
+ /**
+ * Changer la couleur d'un cercle
+ * @param c La nouvelle couleur
+ * */
+ public void setColor(int c) {
+ this.color = c;
+ this.invalidate();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ int centerX = getWidth() / 2;
+ int centerY = getHeight() / 2;
+ int radius = Math.min(centerX, centerY);
+
+ this.picasso.setColor(this.color);
+ this.picasso.setStyle(Paint.Style.FILL);
+ canvas.drawCircle(centerX, centerY, radius-2, this.picasso);
+
+ int corail = Color.rgb(255, 127, 80);
+ this.picasso.setColor(corail);
+ this.picasso.setStyle(Paint.Style.STROKE);
+ this.picasso.setStrokeWidth(4f);
+ canvas.drawCircle(centerX, centerY, radius-3, this.picasso);
+ }
+}
diff --git a/app/src/main/java/com/example/jmastermind/Menu/Menu.java b/app/src/main/java/com/example/jmastermind/Menu/Menu.java
new file mode 100644
index 0000000..09044e3
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Menu/Menu.java
@@ -0,0 +1,53 @@
+package com.example.jmastermind.Menu;
+
+import android.media.MediaPlayer;
+import android.os.Bundle;
+import android.widget.Button;
+import android.widget.CheckBox;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+import com.example.jmastermind.Events.CanVoidEvent;
+import com.example.jmastermind.Events.MenuEvent;
+import com.example.jmastermind.Game.ColorDefSelect;
+import com.example.jmastermind.Game.Game;
+import com.example.jmastermind.Rules.Rules;
+import com.example.jmastermind.R;
+
+public class Menu extends AppCompatActivity {
+ private MediaPlayer mp;
+
+ /**
+ * Le menu du jeu
+ * */
+ public Menu() {}
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.menu);
+
+ this.mp = MediaPlayer.create(this, R.raw.menusong);
+ this.mp.setLooping(true);
+ this.mp.start();
+
+ CanVoidEvent cve = new CanVoidEvent(this);
+ CheckBox bc = (CheckBox) findViewById(R.id.canvoid);
+ bc.setChecked(false);
+ bc.setOnCheckedChangeListener(cve);
+
+ Button btnSoloGame = (Button) findViewById(R.id.robotselect);
+ btnSoloGame.setOnClickListener(new MenuEvent(this, Game.class, this.mp));
+
+ Button btnMultiGame = (Button) findViewById(R.id.jcjselect);
+ btnMultiGame.setOnClickListener(new MenuEvent(this, ColorDefSelect.class, this.mp));
+
+ Button btnRules = (Button) findViewById(R.id.rules);
+ btnRules.setOnClickListener(new MenuEvent(this, Rules.class, this.mp));
+ }
+
+ @Override
+ public void onBackPressed() {
+ this.mp.stop();
+ this.finishAffinity();
+ }
+}
diff --git a/app/src/main/java/com/example/jmastermind/Prologue.java b/app/src/main/java/com/example/jmastermind/Prologue.java
new file mode 100644
index 0000000..4e500ca
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Prologue.java
@@ -0,0 +1,67 @@
+package com.example.jmastermind;
+
+import androidx.appcompat.app.AppCompatActivity;
+import android.media.MediaPlayer;
+import android.os.Bundle;
+import android.view.animation.Animation;
+import android.view.animation.AnimationSet;
+import android.view.animation.LinearInterpolator;
+import android.view.animation.TranslateAnimation;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import com.example.jmastermind.Events.MenuEvent;
+import com.example.jmastermind.Events.PrologueAnimation;
+import com.example.jmastermind.Menu.Menu;
+
+public class Prologue extends AppCompatActivity {
+ private MediaPlayer mp;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.prologue);
+
+ this.mp = MediaPlayer.create(this, R.raw.prologuesong);
+ this.mp.setLooping(false);
+ this.mp.start();
+
+ LinearLayout prologue = (LinearLayout) findViewById(R.id.prologue);
+ prologue.setOnClickListener(new MenuEvent(this, Menu.class, this.mp));
+
+ TextView tx = (TextView) findViewById(R.id.prologuetext);
+
+ AnimationSet animationSet = new AnimationSet(true);
+ animationSet.setInterpolator(new LinearInterpolator());
+
+ TranslateAnimation animationUp = new TranslateAnimation(
+ Animation.RELATIVE_TO_SELF, 0f,
+ Animation.RELATIVE_TO_SELF, 0f,
+ Animation.RELATIVE_TO_SELF, 0f,
+ Animation.RELATIVE_TO_SELF, -1f
+ );
+ animationUp.setDuration(30000);
+ animationUp.setFillAfter(true);
+ animationSet.addAnimation(animationUp);
+
+ TranslateAnimation animationDown = new TranslateAnimation(
+ Animation.RELATIVE_TO_SELF, 0f,
+ Animation.RELATIVE_TO_SELF, 0f,
+ Animation.RELATIVE_TO_SELF, 1f,
+ Animation.RELATIVE_TO_SELF, 0f
+ );
+ animationDown.setDuration(30000);
+ animationDown.setFillAfter(true);
+ animationSet.addAnimation(animationDown);
+
+ PrologueAnimation pa = new PrologueAnimation(this, mp);
+ animationSet.setAnimationListener(pa);
+
+ tx.startAnimation(animationSet);
+ }
+
+ @Override
+ public void onBackPressed() {
+ this.mp.stop();
+ this.finishAffinity();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/jmastermind/Rules/Rules.java b/app/src/main/java/com/example/jmastermind/Rules/Rules.java
new file mode 100644
index 0000000..678f069
--- /dev/null
+++ b/app/src/main/java/com/example/jmastermind/Rules/Rules.java
@@ -0,0 +1,22 @@
+package com.example.jmastermind.Rules;
+
+import android.content.Intent;
+import android.os.Bundle;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+import com.example.jmastermind.Menu.Menu;
+import com.example.jmastermind.R;
+
+public class Rules extends AppCompatActivity {
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.rules);
+ }
+
+ @Override
+ public void onBackPressed() {
+ Intent i = new Intent(this, Menu.class);
+ this.startActivity(i);
+ }
+}
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/game.PNG b/app/src/main/res/drawable/game.PNG
new file mode 100644
index 0000000..9dc7f8e
Binary files /dev/null and b/app/src/main/res/drawable/game.PNG differ
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/logo.png b/app/src/main/res/drawable/logo.png
new file mode 100644
index 0000000..868a586
Binary files /dev/null and b/app/src/main/res/drawable/logo.png differ
diff --git a/app/src/main/res/drawable/rulesone.PNG b/app/src/main/res/drawable/rulesone.PNG
new file mode 100644
index 0000000..6ca78df
Binary files /dev/null and b/app/src/main/res/drawable/rulesone.PNG differ
diff --git a/app/src/main/res/drawable/space.png b/app/src/main/res/drawable/space.png
new file mode 100644
index 0000000..e333e17
Binary files /dev/null and b/app/src/main/res/drawable/space.png differ
diff --git a/app/src/main/res/font/text.ttf b/app/src/main/res/font/text.ttf
new file mode 100644
index 0000000..3033308
Binary files /dev/null and b/app/src/main/res/font/text.ttf differ
diff --git a/app/src/main/res/font/title.ttf b/app/src/main/res/font/title.ttf
new file mode 100644
index 0000000..96ddf00
Binary files /dev/null and b/app/src/main/res/font/title.ttf differ
diff --git a/app/src/main/res/layout/defend.xml b/app/src/main/res/layout/defend.xml
new file mode 100644
index 0000000..d61e683
--- /dev/null
+++ b/app/src/main/res/layout/defend.xml
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/game.xml b/app/src/main/res/layout/game.xml
new file mode 100644
index 0000000..13ccae8
--- /dev/null
+++ b/app/src/main/res/layout/game.xml
@@ -0,0 +1,889 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/menu.xml b/app/src/main/res/layout/menu.xml
new file mode 100644
index 0000000..d46b132
--- /dev/null
+++ b/app/src/main/res/layout/menu.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/prologue.xml b/app/src/main/res/layout/prologue.xml
new file mode 100644
index 0000000..73bc5e3
--- /dev/null
+++ b/app/src/main/res/layout/prologue.xml
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/rules.xml b/app/src/main/res/layout/rules.xml
new file mode 100644
index 0000000..f0d8ef9
--- /dev/null
+++ b/app/src/main/res/layout/rules.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v33/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v33/ic_launcher.xml
new file mode 100644
index 0000000..6f3b755
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v33/ic_launcher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..b2dfe3d
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..62b611d
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1b9a695
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9287f50
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9126ae3
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/raw/b_10145_1604357052963.unity3d b/app/src/main/res/raw/b_10145_1604357052963.unity3d
new file mode 100644
index 0000000..4f28bb2
Binary files /dev/null and b/app/src/main/res/raw/b_10145_1604357052963.unity3d differ
diff --git a/app/src/main/res/raw/loosegamesong.mp3 b/app/src/main/res/raw/loosegamesong.mp3
new file mode 100644
index 0000000..35d1525
Binary files /dev/null and b/app/src/main/res/raw/loosegamesong.mp3 differ
diff --git a/app/src/main/res/raw/menusong.mp3 b/app/src/main/res/raw/menusong.mp3
new file mode 100644
index 0000000..2613486
Binary files /dev/null and b/app/src/main/res/raw/menusong.mp3 differ
diff --git a/app/src/main/res/raw/prologuesong.mp3 b/app/src/main/res/raw/prologuesong.mp3
new file mode 100644
index 0000000..36b88ae
Binary files /dev/null and b/app/src/main/res/raw/prologuesong.mp3 differ
diff --git a/app/src/main/res/raw/winningsong.mp3 b/app/src/main/res/raw/winningsong.mp3
new file mode 100644
index 0000000..59a822a
Binary files /dev/null and b/app/src/main/res/raw/winningsong.mp3 differ
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..8c059b8
--- /dev/null
+++ b/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..c151fe8
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,12 @@
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #11FF00
+ #FFFFFFFF
+ #FF0000
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..40b86b4
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ JMastermind
+
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..4f5f90f
--- /dev/null
+++ b/app/src/main/res/values/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/backup_rules.xml b/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 0000000..fa0f996
--- /dev/null
+++ b/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 0000000..9ee9997
--- /dev/null
+++ b/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/test/java/com/example/jmastermind/ExampleUnitTest.java b/app/src/test/java/com/example/jmastermind/ExampleUnitTest.java
new file mode 100644
index 0000000..496ae0f
--- /dev/null
+++ b/app/src/test/java/com/example/jmastermind/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.example.jmastermind;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file