diff --git a/.gitignore b/.gitignore index 42afabf..aa724b7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,15 @@ -/build \ No newline at end of file +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..8f9c6a1 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +Real Chuzzle \ No newline at end of file diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml new file mode 100644 index 0000000..4a53bee --- /dev/null +++ b/.idea/AndroidProjectSystem.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b86273d --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..682aaf8 --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,26 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/deviceManager.xml b/.idea/deviceManager.xml new file mode 100644 index 0000000..91f9558 --- /dev/null +++ b/.idea/deviceManager.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..639c779 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml new file mode 100644 index 0000000..f8051a6 --- /dev/null +++ b/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..b2c751a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..16660f1 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file 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.kts b/app/build.gradle.kts new file mode 100644 index 0000000..882d8c5 --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,42 @@ +plugins { + alias(libs.plugins.android.application) +} + +android { + namespace = "sae.chuzzle" + compileSdk { + version = release(36) + } + + defaultConfig { + applicationId = "sae.chuzzle" + minSdk = 24 + targetSdk = 36 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } +} + +dependencies { + + implementation(libs.activity) + testImplementation(libs.junit) + androidTestImplementation(libs.ext.junit) + androidTestImplementation(libs.espresso.core) +} \ No newline at end of file diff --git a/proguard-rules.pro b/app/proguard-rules.pro similarity index 100% rename from proguard-rules.pro rename to app/proguard-rules.pro diff --git a/src/androidTest/java/sae/chuzzle/ExampleInstrumentedTest.java b/app/src/androidTest/java/sae/chuzzle/ExampleInstrumentedTest.java similarity index 100% rename from src/androidTest/java/sae/chuzzle/ExampleInstrumentedTest.java rename to app/src/androidTest/java/sae/chuzzle/ExampleInstrumentedTest.java diff --git a/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml similarity index 97% rename from src/main/AndroidManifest.xml rename to app/src/main/AndroidManifest.xml index 34cdb93..63d5740 100644 --- a/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,41 +1,41 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/sae/chuzzle/Controleur.java b/app/src/main/java/sae/chuzzle/Controleur.java similarity index 97% rename from src/main/java/sae/chuzzle/Controleur.java rename to app/src/main/java/sae/chuzzle/Controleur.java index 74d2d82..6c96353 100644 --- a/src/main/java/sae/chuzzle/Controleur.java +++ b/app/src/main/java/sae/chuzzle/Controleur.java @@ -1,209 +1,209 @@ -package sae.chuzzle; - -import android.app.Activity; -import android.os.Bundle; -import android.view.View; -import android.widget.Button; -import android.widget.TextView; -import android.widget.Toast; - -public class Controleur { - - private final Activity activite; - private final EtatJeu etatJeu; - private final VueGrille vueGrille; - private final long graine; - - private final TextView tvScore; - private final TextView tvCoups; - - // Hard Mode logic - private final boolean hardMode; - private GestionnaireObjectifs gestionnaireObjectifs; - private Objectif objectifActuel; - private TextView tvObjectif; - private TextView tvNbObjectifs; - private TextView tvCles; - private Button btnReinitialisationObjectif; - private View layoutCles; - - public Controleur(Activity activite, EtatJeu etatJeu, VueGrille vueGrille, - long graine, TextView tvScore, TextView tvCoups, - boolean hardMode) { - - - - this.activite = activite; - this.etatJeu = etatJeu; - this.vueGrille = vueGrille; - this.graine = graine; - this.tvScore = tvScore; - this.tvCoups = tvCoups; - this.hardMode = hardMode; - - if (hardMode) { - this.gestionnaireObjectifs = new GestionnaireObjectifs(graine); - this.tvObjectif = activite.findViewById(R.id.tvObjectif); - this.tvNbObjectifs = activite.findViewById(R.id.tvNbObjectifs); - this.tvCles = activite.findViewById(R.id.tvCles); - this.layoutCles = activite.findViewById(R.id.layoutCles); - this.btnReinitialisationObjectif = activite.findViewById(R.id.btnReinitialisationObjectif); - - if (tvObjectif != null) tvObjectif.setVisibility(View.VISIBLE); - if (tvNbObjectifs != null) tvNbObjectifs.setVisibility(View.VISIBLE); - if (layoutCles != null) layoutCles.setVisibility(View.VISIBLE); - - - if (btnReinitialisationObjectif != null) { - btnReinitialisationObjectif.setOnClickListener(v -> reinitialiserObjectif()); - } - } - - - rafraichirAffichage(); - } - - - - /** - * Initialise l'objectif au début de la partie ou lors de la restauration. - */ - public void initialiserObjectif(Bundle savedState) { - if (!hardMode) return; - - gestionnaireObjectifs.restaurer(savedState); - objectifActuel = Objectif.restaurer(savedState); - - if (objectifActuel == null) { - objectifActuel = gestionnaireObjectifs.genererObjectif(); - } - rafraichirAffichage(); - } - - /** - * Gère la validation d'un coup réussi (mise à jour objectif, score, affichage). - * Centralise la logique pour être appelé par le bouton ET par le tactile. - */ - public void gererFinDeCoup() { - - // 1 clé tous les 5 coups - if (hardMode && etatJeu.obtenirNbCoups() % 5 == 0) { - gestionnaireObjectifs.ajouterCle(); - } - // --- Logique Hard Mode - if (hardMode && objectifActuel != null) { - // 1. Décrémenter les coups de l'objectif - objectifActuel.decrementerCoups(); - - // 2. Compter les séries de la couleur cible - int[] series = etatJeu.getSeriesParCouleurDernierCoup(); - objectifActuel.ajouterSeries(series[objectifActuel.getCouleur()]); - - // 3. Vérifier réussite ou échec - if (objectifActuel.estReussi()) { - - gestionnaireObjectifs.incrementerReussites(); - objectifActuel = gestionnaireObjectifs.genererObjectif(); - } else if (objectifActuel.estEchoue()) { - // Plus de coups disponibles et objectif non réussi -> fin de partie immédiate - Toast.makeText(activite, "Objectif échoué !", - Toast.LENGTH_SHORT - ).show(); - - etatJeu.forcerFinDePartie(); - - } - } - - rafraichirAffichage(); - verifierFinDePartie(); - } - - /** - * Tente de réinitialiser l'objectif en cours en consommant 3 clés. - * Affiche un Toast si le joueur n'a pas assez de clés. - */ - public void reinitialiserObjectif() { - if (!hardMode || gestionnaireObjectifs == null) return; - - if (gestionnaireObjectifs.consommerCles()) { - objectifActuel = gestionnaireObjectifs.genererObjectif(); - rafraichirAffichage(); - } else { - Toast.makeText(activite, "Pas assez de clés !", Toast.LENGTH_SHORT).show(); - } - } - - - /** - * Lancer l'écran de fin. - */ - public void verifierFinDePartie() { - int nbARetenir; - if (hardMode) { - nbARetenir = gestionnaireObjectifs.getNbObjectifsRealises(); - } else { - nbARetenir = 0; - } - - String description; - if (hardMode == true && objectifActuel != null) { - description = objectifActuel.getDescription(); - } else { - description = null; - } - - if (etatJeu.estTerminee()) { - FinPartieActivity.demarrer( - activite, - etatJeu.obtenirScore(), - etatJeu.obtenirNbCoups(), - graine, - nbARetenir, - description, - etatJeu.obtenirGrille(), - etatJeu.obtenirVerrous() - ); - } - } - - public void rafraichirAffichage() { - tvScore.setText("Score : " + etatJeu.obtenirScore()); - tvCoups.setText("Coups : " + etatJeu.obtenirNbCoups()); - vueGrille.definirGrille(etatJeu.obtenirGrille()); - vueGrille.definirVerrous(etatJeu.obtenirVerrous()); - - if (hardMode && objectifActuel != null) { - if (tvObjectif != null){ - tvObjectif.setText(objectifActuel.getDescription()); - } - if (tvNbObjectifs != null){ - tvNbObjectifs.setText("Objectifs réussis : " + gestionnaireObjectifs.getNbObjectifsRealises()); - } - - int nbCles = gestionnaireObjectifs.getNbCles(); - if (tvCles != null) { - tvCles.setText("🗝️ Clés : " + nbCles + " (Max 1)"); - } - if (btnReinitialisationObjectif != null) { - // Grisé si 0 clé - float alpha; - if (nbCles >= 1) { - alpha = 1f; // visible - } else { - alpha = 0.4f; // grisé - } - btnReinitialisationObjectif.setAlpha(alpha); - } - } - } - - public void sauvegarderEtat(Bundle out) { - if (hardMode) { - gestionnaireObjectifs.sauvegarder(out); - if (objectifActuel != null) { - objectifActuel.sauvegarder(out); - } - } - } +package sae.chuzzle; + +import android.app.Activity; +import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; +import android.widget.Toast; + +public class Controleur { + + private final Activity activite; + private final EtatJeu etatJeu; + private final VueGrille vueGrille; + private final long graine; + + private final TextView tvScore; + private final TextView tvCoups; + + // Hard Mode logic + private final boolean hardMode; + private GestionnaireObjectifs gestionnaireObjectifs; + private Objectif objectifActuel; + private TextView tvObjectif; + private TextView tvNbObjectifs; + private TextView tvCles; + private Button btnReinitialisationObjectif; + private View layoutCles; + + public Controleur(Activity activite, EtatJeu etatJeu, VueGrille vueGrille, + long graine, TextView tvScore, TextView tvCoups, + boolean hardMode) { + + + + this.activite = activite; + this.etatJeu = etatJeu; + this.vueGrille = vueGrille; + this.graine = graine; + this.tvScore = tvScore; + this.tvCoups = tvCoups; + this.hardMode = hardMode; + + if (hardMode) { + this.gestionnaireObjectifs = new GestionnaireObjectifs(graine); + this.tvObjectif = activite.findViewById(R.id.tvObjectif); + this.tvNbObjectifs = activite.findViewById(R.id.tvNbObjectifs); + this.tvCles = activite.findViewById(R.id.tvCles); + this.layoutCles = activite.findViewById(R.id.layoutCles); + this.btnReinitialisationObjectif = activite.findViewById(R.id.btnReinitialisationObjectif); + + if (tvObjectif != null) tvObjectif.setVisibility(View.VISIBLE); + if (tvNbObjectifs != null) tvNbObjectifs.setVisibility(View.VISIBLE); + if (layoutCles != null) layoutCles.setVisibility(View.VISIBLE); + + + if (btnReinitialisationObjectif != null) { + btnReinitialisationObjectif.setOnClickListener(v -> reinitialiserObjectif()); + } + } + + + rafraichirAffichage(); + } + + + + /** + * Initialise l'objectif au début de la partie ou lors de la restauration. + */ + public void initialiserObjectif(Bundle savedState) { + if (!hardMode) return; + + gestionnaireObjectifs.restaurer(savedState); + objectifActuel = Objectif.restaurer(savedState); + + if (objectifActuel == null) { + objectifActuel = gestionnaireObjectifs.genererObjectif(); + } + rafraichirAffichage(); + } + + /** + * Gère la validation d'un coup réussi (mise à jour objectif, score, affichage). + * Centralise la logique pour être appelé par le bouton ET par le tactile. + */ + public void gererFinDeCoup() { + + // 1 clé tous les 5 coups + if (hardMode && etatJeu.obtenirNbCoups() % 5 == 0) { + gestionnaireObjectifs.ajouterCle(); + } + // --- Logique Hard Mode + if (hardMode && objectifActuel != null) { + // 1. Décrémenter les coups de l'objectif + objectifActuel.decrementerCoups(); + + // 2. Compter les séries de la couleur cible + int[] series = etatJeu.getSeriesParCouleurDernierCoup(); + objectifActuel.ajouterSeries(series[objectifActuel.getCouleur()]); + + // 3. Vérifier réussite ou échec + if (objectifActuel.estReussi()) { + + gestionnaireObjectifs.incrementerReussites(); + objectifActuel = gestionnaireObjectifs.genererObjectif(); + } else if (objectifActuel.estEchoue()) { + // Plus de coups disponibles et objectif non réussi -> fin de partie immédiate + Toast.makeText(activite, "Objectif échoué !", + Toast.LENGTH_SHORT + ).show(); + + etatJeu.forcerFinDePartie(); + + } + } + + rafraichirAffichage(); + verifierFinDePartie(); + } + + /** + * Tente de réinitialiser l'objectif en cours en consommant 3 clés. + * Affiche un Toast si le joueur n'a pas assez de clés. + */ + public void reinitialiserObjectif() { + if (!hardMode || gestionnaireObjectifs == null) return; + + if (gestionnaireObjectifs.consommerCles()) { + objectifActuel = gestionnaireObjectifs.genererObjectif(); + rafraichirAffichage(); + } else { + Toast.makeText(activite, "Pas assez de clés !", Toast.LENGTH_SHORT).show(); + } + } + + + /** + * Lancer l'écran de fin. + */ + public void verifierFinDePartie() { + int nbARetenir; + if (hardMode) { + nbARetenir = gestionnaireObjectifs.getNbObjectifsRealises(); + } else { + nbARetenir = 0; + } + + String description; + if (hardMode == true && objectifActuel != null) { + description = objectifActuel.getDescription(); + } else { + description = null; + } + + if (etatJeu.estTerminee()) { + FinPartieActivity.demarrer( + activite, + etatJeu.obtenirScore(), + etatJeu.obtenirNbCoups(), + graine, + nbARetenir, + description, + etatJeu.obtenirGrille(), + etatJeu.obtenirVerrous() + ); + } + } + + public void rafraichirAffichage() { + tvScore.setText("Score : " + etatJeu.obtenirScore()); + tvCoups.setText("Coups : " + etatJeu.obtenirNbCoups()); + vueGrille.definirGrille(etatJeu.obtenirGrille()); + vueGrille.definirVerrous(etatJeu.obtenirVerrous()); + + if (hardMode && objectifActuel != null) { + if (tvObjectif != null){ + tvObjectif.setText(objectifActuel.getDescription()); + } + if (tvNbObjectifs != null){ + tvNbObjectifs.setText("Objectifs réussis : " + gestionnaireObjectifs.getNbObjectifsRealises()); + } + + int nbCles = gestionnaireObjectifs.getNbCles(); + if (tvCles != null) { + tvCles.setText("🗝️ Clés : " + nbCles + " (Max 1)"); + } + if (btnReinitialisationObjectif != null) { + // Grisé si 0 clé + float alpha; + if (nbCles >= 1) { + alpha = 1f; // visible + } else { + alpha = 0.4f; // grisé + } + btnReinitialisationObjectif.setAlpha(alpha); + } + } + } + + public void sauvegarderEtat(Bundle out) { + if (hardMode) { + gestionnaireObjectifs.sauvegarder(out); + if (objectifActuel != null) { + objectifActuel.sauvegarder(out); + } + } + } } \ No newline at end of file diff --git a/src/main/java/sae/chuzzle/EtatJeu.java b/app/src/main/java/sae/chuzzle/EtatJeu.java similarity index 96% rename from src/main/java/sae/chuzzle/EtatJeu.java rename to app/src/main/java/sae/chuzzle/EtatJeu.java index 2f52c75..619a6a5 100644 --- a/src/main/java/sae/chuzzle/EtatJeu.java +++ b/app/src/main/java/sae/chuzzle/EtatJeu.java @@ -1,279 +1,279 @@ -package sae.chuzzle; - -import android.os.Bundle; -import java.util.List; -import java.util.Random; - -/** - * Gère la session de jeu (score, coups, état de la partie) et délègue la - * manipulation - * physique de la grille à la classe Plateau. - */ -public class EtatJeu { - - private final Plateau plateau; - private final Random aleatoire; - private final boolean hardMode; - - private int score = 0; - private int nbCoups = 0; - private boolean partieTerminee = false; - - private final int[] seriesParCouleurDernierCoup = new int[Plateau.NB_TYPES]; - - public EtatJeu(long graine, boolean hardMode) { - this.aleatoire = new Random(graine); - this.hardMode = hardMode; - this.plateau = new Plateau(this.aleatoire); - } - - // --- Getters --- - - public int obtenirScore() { - return score; - } - - public int obtenirNbCoups() { - return nbCoups; - } - - public boolean estTerminee() { - return partieTerminee; - } - - public int[] getSeriesParCouleurDernierCoup() { - return seriesParCouleurDernierCoup; - } - - public int[][] obtenirGrille() { - return plateau.copierGrille(); - } - - public boolean[][] obtenirVerrous() { - // Copie manuelle pour respecter l'encapsulation - boolean[][] v = plateau.getVerrous(); - boolean[][] copie = new boolean[Plateau.NB_LIGNES][Plateau.NB_COLONNES]; - for (int l = 0; l < Plateau.NB_LIGNES; l++) { - System.arraycopy(v[l], 0, copie[l], 0, Plateau.NB_COLONNES); - } - return copie; - } - - // --- Actions --- - - public boolean appliquerCoup(boolean estLigne, int index, int sens) { - if (partieTerminee || plateau.estBloque(estLigne, index)) { - return false; - } - - int[][] sauvegarde = plateau.copierGrille(); - if (estLigne) { - plateau.decalerLigne(index, sens); - } else { - plateau.decalerColonne(index, sens); - } - - if (plateau.trouverSeries().isEmpty()) { - plateau.restaurerGrille(sauvegarde); - return false; - } - - nbCoups++; - resetSeriesDernierCoup(); - score += resoudreCascades(); - - plateau.ajouterVerrou(nbCoups); - if (hardMode) { - plateau.ajouterVerrou(nbCoups); - } - - if (!aUnCoupValide()) { - partieTerminee = true; - } - return true; - } - - private int resoudreCascades() { - int baseTotal = 0; - int nbSeriesTotal = 0; - List series = plateau.trouverSeries(); - - while (!series.isEmpty()) { - int[] result = traiterSeries(series); - baseTotal += result[0]; - nbSeriesTotal += result[1]; - - boolean[][] masque = creerMasque(series); - plateau.libererVerrous(masque); - plateau.faireTomber(masque); - - series = plateau.trouverSeries(); - } - - if (nbSeriesTotal == 0) { - return 0; - } - return (int) (baseTotal * (1.0 + (nbSeriesTotal - 1) * 0.5)); - } - - // --- Aide à la résolution - - /** - * Parcourt les séries détectées, calcule les points de base et compte le nombre - * de séries. - * Vérifie la couleur des cellules pour délimiter correctement les séries. - * - * int[2] : [0] = points de base, [1] = nombre de séries - */ - private int[] traiterSeries(List series) { - boolean[][] masque = creerMasque(series); - int[][] g = plateau.getGrille(); - int pts = 0; - int count = 0; - - // Horizontal - for (int l = 0; l < Plateau.NB_LIGNES; l++) { - int c = 0; - while (c < Plateau.NB_COLONNES) { - if (masque[l][c]) { - int type = g[l][c]; - int fin = c + 1; - while (fin < Plateau.NB_COLONNES && masque[l][fin] && g[l][fin] == type) { - fin++; - } - if (fin - c >= 3) { - pts += pointsPourLongueur(fin - c); - seriesParCouleurDernierCoup[type]++; - count++; - } - c = fin; - } else { - c++; - } - } - } - // Vertical - for (int c = 0; c < Plateau.NB_COLONNES; c++) { - int l = 0; - while (l < Plateau.NB_LIGNES) { - if (masque[l][c]) { - int type = g[l][c]; - int fin = l + 1; - while (fin < Plateau.NB_LIGNES && masque[fin][c] && g[fin][c] == type) { - fin++; - } - if (fin - l >= 3) { - pts += pointsPourLongueur(fin - l); - seriesParCouleurDernierCoup[type]++; - count++; - } - l = fin; - } else { - l++; - } - } - } - return new int[] { pts, count }; - } - - private int pointsPourLongueur(int n) { - if (n == 3) - return 8; - if (n == 4) - return 16; - if (n == 5) - return 32; - return 64; - } - - private boolean[][] creerMasque(List positions) { - boolean[][] m = new boolean[Plateau.NB_LIGNES][Plateau.NB_COLONNES]; - for (int[] p : positions) { - m[p[0]][p[1]] = true; - } - return m; - } - - private void resetSeriesDernierCoup() { - for (int i = 0; i < Plateau.NB_TYPES; i++) { - seriesParCouleurDernierCoup[i] = 0; - } - } - - public boolean aUnCoupValide() { - for (int i = 0; i < Plateau.NB_LIGNES; i++) { - if (plateau.estBloque(true, i)) { - continue; - } - for (int s = 1; s < Plateau.NB_COLONNES; s++) { - if (simulerCoup(true, i, s)) { - return true; - } - } - } - for (int j = 0; j < Plateau.NB_COLONNES; j++) { - if (plateau.estBloque(false, j)) { - continue; - } - for (int s = 1; s < Plateau.NB_LIGNES; s++) { - if (simulerCoup(false, j, s)) { - return true; - } - } - } - return false; - } - - private boolean simulerCoup(boolean estLigne, int idx, int s) { - int[][] save = plateau.copierGrille(); - if (estLigne) { - plateau.decalerLigne(idx, s); - } else { - plateau.decalerColonne(idx, s); - } - boolean ok = !plateau.trouverSeries().isEmpty(); - plateau.restaurerGrille(save); - return ok; - } - - public void forcerFinDePartie() { - partieTerminee = true; - } - - public void sauvegarderEtat(Bundle b) { - int[] g = new int[36]; - boolean[] v = new boolean[36]; - int[][] grid = plateau.getGrille(); - boolean[][] lk = plateau.getVerrous(); - for (int i = 0; i < Plateau.NB_LIGNES; i++) { - for (int j = 0; j < Plateau.NB_COLONNES; j++) { - g[i * Plateau.NB_LIGNES + j] = grid[i][j]; - v[i * Plateau.NB_LIGNES + j] = lk[i][j]; - } - } - b.putIntArray("grille", g); - b.putBooleanArray("verrous", v); - b.putInt("score", score); - b.putInt("nbCoups", nbCoups); - b.putBoolean("partieTerminee", partieTerminee); - } - - public void restaurerEtat(Bundle b) { - if (!b.containsKey("grille")) { - return; - } - int[] g = b.getIntArray("grille"); - boolean[] v = b.getBooleanArray("verrous"); - int[][] grid = plateau.getGrille(); - boolean[][] lk = plateau.getVerrous(); - for (int i = 0; i < Plateau.NB_LIGNES; i++) { - for (int j = 0; j < Plateau.NB_COLONNES; j++) { - grid[i][j] = g[i * Plateau.NB_LIGNES + j]; - lk[i][j] = v[i * Plateau.NB_LIGNES + j]; - } - } - score = b.getInt("score"); - nbCoups = b.getInt("nbCoups"); - partieTerminee = b.getBoolean("partieTerminee"); - } -} +package sae.chuzzle; + +import android.os.Bundle; +import java.util.List; +import java.util.Random; + +/** + * Gère la session de jeu (score, coups, état de la partie) et délègue la + * manipulation + * physique de la grille à la classe Plateau. + */ +public class EtatJeu { + + private final Plateau plateau; + private final Random aleatoire; + private final boolean hardMode; + + private int score = 0; + private int nbCoups = 0; + private boolean partieTerminee = false; + + private final int[] seriesParCouleurDernierCoup = new int[Plateau.NB_TYPES]; + + public EtatJeu(long graine, boolean hardMode) { + this.aleatoire = new Random(graine); + this.hardMode = hardMode; + this.plateau = new Plateau(this.aleatoire); + } + + // --- Getters --- + + public int obtenirScore() { + return score; + } + + public int obtenirNbCoups() { + return nbCoups; + } + + public boolean estTerminee() { + return partieTerminee; + } + + public int[] getSeriesParCouleurDernierCoup() { + return seriesParCouleurDernierCoup; + } + + public int[][] obtenirGrille() { + return plateau.copierGrille(); + } + + public boolean[][] obtenirVerrous() { + // Copie manuelle pour respecter l'encapsulation + boolean[][] v = plateau.getVerrous(); + boolean[][] copie = new boolean[Plateau.NB_LIGNES][Plateau.NB_COLONNES]; + for (int l = 0; l < Plateau.NB_LIGNES; l++) { + System.arraycopy(v[l], 0, copie[l], 0, Plateau.NB_COLONNES); + } + return copie; + } + + // --- Actions --- + + public boolean appliquerCoup(boolean estLigne, int index, int sens) { + if (partieTerminee || plateau.estBloque(estLigne, index)) { + return false; + } + + int[][] sauvegarde = plateau.copierGrille(); + if (estLigne) { + plateau.decalerLigne(index, sens); + } else { + plateau.decalerColonne(index, sens); + } + + if (plateau.trouverSeries().isEmpty()) { + plateau.restaurerGrille(sauvegarde); + return false; + } + + nbCoups++; + resetSeriesDernierCoup(); + score += resoudreCascades(); + + plateau.ajouterVerrou(nbCoups); + if (hardMode) { + plateau.ajouterVerrou(nbCoups); + } + + if (!aUnCoupValide()) { + partieTerminee = true; + } + return true; + } + + private int resoudreCascades() { + int baseTotal = 0; + int nbSeriesTotal = 0; + List series = plateau.trouverSeries(); + + while (!series.isEmpty()) { + int[] result = traiterSeries(series); + baseTotal += result[0]; + nbSeriesTotal += result[1]; + + boolean[][] masque = creerMasque(series); + plateau.libererVerrous(masque); + plateau.faireTomber(masque); + + series = plateau.trouverSeries(); + } + + if (nbSeriesTotal == 0) { + return 0; + } + return (int) (baseTotal * (1.0 + (nbSeriesTotal - 1) * 0.5)); + } + + // --- Aide à la résolution + + /** + * Parcourt les séries détectées, calcule les points de base et compte le nombre + * de séries. + * Vérifie la couleur des cellules pour délimiter correctement les séries. + * + * int[2] : [0] = points de base, [1] = nombre de séries + */ + private int[] traiterSeries(List series) { + boolean[][] masque = creerMasque(series); + int[][] g = plateau.getGrille(); + int pts = 0; + int count = 0; + + // Horizontal + for (int l = 0; l < Plateau.NB_LIGNES; l++) { + int c = 0; + while (c < Plateau.NB_COLONNES) { + if (masque[l][c]) { + int type = g[l][c]; + int fin = c + 1; + while (fin < Plateau.NB_COLONNES && masque[l][fin] && g[l][fin] == type) { + fin++; + } + if (fin - c >= 3) { + pts += pointsPourLongueur(fin - c); + seriesParCouleurDernierCoup[type]++; + count++; + } + c = fin; + } else { + c++; + } + } + } + // Vertical + for (int c = 0; c < Plateau.NB_COLONNES; c++) { + int l = 0; + while (l < Plateau.NB_LIGNES) { + if (masque[l][c]) { + int type = g[l][c]; + int fin = l + 1; + while (fin < Plateau.NB_LIGNES && masque[fin][c] && g[fin][c] == type) { + fin++; + } + if (fin - l >= 3) { + pts += pointsPourLongueur(fin - l); + seriesParCouleurDernierCoup[type]++; + count++; + } + l = fin; + } else { + l++; + } + } + } + return new int[] { pts, count }; + } + + private int pointsPourLongueur(int n) { + if (n == 3) + return 8; + if (n == 4) + return 16; + if (n == 5) + return 32; + return 64; + } + + private boolean[][] creerMasque(List positions) { + boolean[][] m = new boolean[Plateau.NB_LIGNES][Plateau.NB_COLONNES]; + for (int[] p : positions) { + m[p[0]][p[1]] = true; + } + return m; + } + + private void resetSeriesDernierCoup() { + for (int i = 0; i < Plateau.NB_TYPES; i++) { + seriesParCouleurDernierCoup[i] = 0; + } + } + + public boolean aUnCoupValide() { + for (int i = 0; i < Plateau.NB_LIGNES; i++) { + if (plateau.estBloque(true, i)) { + continue; + } + for (int s = 1; s < Plateau.NB_COLONNES; s++) { + if (simulerCoup(true, i, s)) { + return true; + } + } + } + for (int j = 0; j < Plateau.NB_COLONNES; j++) { + if (plateau.estBloque(false, j)) { + continue; + } + for (int s = 1; s < Plateau.NB_LIGNES; s++) { + if (simulerCoup(false, j, s)) { + return true; + } + } + } + return false; + } + + private boolean simulerCoup(boolean estLigne, int idx, int s) { + int[][] save = plateau.copierGrille(); + if (estLigne) { + plateau.decalerLigne(idx, s); + } else { + plateau.decalerColonne(idx, s); + } + boolean ok = !plateau.trouverSeries().isEmpty(); + plateau.restaurerGrille(save); + return ok; + } + + public void forcerFinDePartie() { + partieTerminee = true; + } + + public void sauvegarderEtat(Bundle b) { + int[] g = new int[36]; + boolean[] v = new boolean[36]; + int[][] grid = plateau.getGrille(); + boolean[][] lk = plateau.getVerrous(); + for (int i = 0; i < Plateau.NB_LIGNES; i++) { + for (int j = 0; j < Plateau.NB_COLONNES; j++) { + g[i * Plateau.NB_LIGNES + j] = grid[i][j]; + v[i * Plateau.NB_LIGNES + j] = lk[i][j]; + } + } + b.putIntArray("grille", g); + b.putBooleanArray("verrous", v); + b.putInt("score", score); + b.putInt("nbCoups", nbCoups); + b.putBoolean("partieTerminee", partieTerminee); + } + + public void restaurerEtat(Bundle b) { + if (!b.containsKey("grille")) { + return; + } + int[] g = b.getIntArray("grille"); + boolean[] v = b.getBooleanArray("verrous"); + int[][] grid = plateau.getGrille(); + boolean[][] lk = plateau.getVerrous(); + for (int i = 0; i < Plateau.NB_LIGNES; i++) { + for (int j = 0; j < Plateau.NB_COLONNES; j++) { + grid[i][j] = g[i * Plateau.NB_LIGNES + j]; + lk[i][j] = v[i * Plateau.NB_LIGNES + j]; + } + } + score = b.getInt("score"); + nbCoups = b.getInt("nbCoups"); + partieTerminee = b.getBoolean("partieTerminee"); + } +} diff --git a/src/main/java/sae/chuzzle/FinPartieActivity.java b/app/src/main/java/sae/chuzzle/FinPartieActivity.java similarity index 100% rename from src/main/java/sae/chuzzle/FinPartieActivity.java rename to app/src/main/java/sae/chuzzle/FinPartieActivity.java diff --git a/src/main/java/sae/chuzzle/FinPartieControleur.java b/app/src/main/java/sae/chuzzle/FinPartieControleur.java similarity index 100% rename from src/main/java/sae/chuzzle/FinPartieControleur.java rename to app/src/main/java/sae/chuzzle/FinPartieControleur.java diff --git a/src/main/java/sae/chuzzle/GestionnaireObjectifs.java b/app/src/main/java/sae/chuzzle/GestionnaireObjectifs.java similarity index 96% rename from src/main/java/sae/chuzzle/GestionnaireObjectifs.java rename to app/src/main/java/sae/chuzzle/GestionnaireObjectifs.java index 9f24c52..f304a84 100644 --- a/src/main/java/sae/chuzzle/GestionnaireObjectifs.java +++ b/app/src/main/java/sae/chuzzle/GestionnaireObjectifs.java @@ -1,102 +1,102 @@ -package sae.chuzzle; - -import android.os.Bundle; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -/** - * Gère la génération aléatoire et le comptage des objectifs. - */ -public class GestionnaireObjectifs { - private final Random random; - private int nbObjectifsRealises = 0; - private int nbCles = 0; - - public GestionnaireObjectifs(long graine) { - - this.random = new Random(graine); - } - - /** - * Génère un nouvel objectif en respectant les probabilités de difficulté. - */ - public Objectif genererObjectif() { - List pool = new ArrayList<>(); - int totalPoids = 0; - - // M (nbCoupsMax) entre 2 et 5. - // N (nbSeriesCible) tel que M - N >= 1 et N <= 3. - for (int m = 2; m <= 5; m++) { - for (int n = 1; n <= m - 1 && n <= 3; n++) { - // Probabilité inversement proportionnelle à la facilité (M-N). - // Plus (M-N) est petit, plus c'est dur. - int diff = m - n; - int poids = diff * diff; // On utilise le carré pour accentuer la différence de probabilité - - for (int color = 0; color < 7; color++) { - pool.add(new Objectif(color, n, m, poids)); - totalPoids += poids; - } - } - } - - if (totalPoids == 0) return null; - - int tirage = random.nextInt(totalPoids); - int cumul = 0; - for (Objectif obj : pool) { - cumul += obj.getPoids(); - if (tirage < cumul) { - return new Objectif(obj.getCouleur(), obj.getNbSeriesCible(), obj.getNbCoupsMax(), obj.getPoids()); - } - } - return pool.get(0); - } - - public void incrementerReussites() { - nbObjectifsRealises++; - // 1 clé gagnée tous les 2 objectifs réussis, maximum 1 clés en stock - if (nbObjectifsRealises % 2 == 0) { - ajouterCle(); - } - } - - public int getNbCles() { - return nbCles; - } - - public void ajouterCle() { - // Ajoute une clé maximum 1 en stock - nbCles = Math.min(nbCles + 1, 1); - } - - /** - * Consomme 1 clé pour réinitialiser l'objectif. - */ - public boolean consommerCles() { - if (nbCles >= 1) { - nbCles -= 1; - return true; - } - return false; - } - - public int getNbObjectifsRealises() { - - return nbObjectifsRealises; - } - - public void sauvegarder(Bundle out) { - out.putInt("nb_objectifs_total", nbObjectifsRealises); - out.putInt("nb_cles", nbCles); - } - - public void restaurer(Bundle in) { - if (in != null) { - nbObjectifsRealises = in.getInt("nb_objectifs_total", 0); - nbCles = in.getInt("nb_cles", 0); - } - } -} - +package sae.chuzzle; + +import android.os.Bundle; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +/** + * Gère la génération aléatoire et le comptage des objectifs. + */ +public class GestionnaireObjectifs { + private final Random random; + private int nbObjectifsRealises = 0; + private int nbCles = 0; + + public GestionnaireObjectifs(long graine) { + + this.random = new Random(graine); + } + + /** + * Génère un nouvel objectif en respectant les probabilités de difficulté. + */ + public Objectif genererObjectif() { + List pool = new ArrayList<>(); + int totalPoids = 0; + + // M (nbCoupsMax) entre 2 et 5. + // N (nbSeriesCible) tel que M - N >= 1 et N <= 3. + for (int m = 2; m <= 5; m++) { + for (int n = 1; n <= m - 1 && n <= 3; n++) { + // Probabilité inversement proportionnelle à la facilité (M-N). + // Plus (M-N) est petit, plus c'est dur. + int diff = m - n; + int poids = diff * diff; // On utilise le carré pour accentuer la différence de probabilité + + for (int color = 0; color < 7; color++) { + pool.add(new Objectif(color, n, m, poids)); + totalPoids += poids; + } + } + } + + if (totalPoids == 0) return null; + + int tirage = random.nextInt(totalPoids); + int cumul = 0; + for (Objectif obj : pool) { + cumul += obj.getPoids(); + if (tirage < cumul) { + return new Objectif(obj.getCouleur(), obj.getNbSeriesCible(), obj.getNbCoupsMax(), obj.getPoids()); + } + } + return pool.get(0); + } + + public void incrementerReussites() { + nbObjectifsRealises++; + // 1 clé gagnée tous les 2 objectifs réussis, maximum 1 clés en stock + if (nbObjectifsRealises % 2 == 0) { + ajouterCle(); + } + } + + public int getNbCles() { + return nbCles; + } + + public void ajouterCle() { + // Ajoute une clé maximum 1 en stock + nbCles = Math.min(nbCles + 1, 1); + } + + /** + * Consomme 1 clé pour réinitialiser l'objectif. + */ + public boolean consommerCles() { + if (nbCles >= 1) { + nbCles -= 1; + return true; + } + return false; + } + + public int getNbObjectifsRealises() { + + return nbObjectifsRealises; + } + + public void sauvegarder(Bundle out) { + out.putInt("nb_objectifs_total", nbObjectifsRealises); + out.putInt("nb_cles", nbCles); + } + + public void restaurer(Bundle in) { + if (in != null) { + nbObjectifsRealises = in.getInt("nb_objectifs_total", 0); + nbCles = in.getInt("nb_cles", 0); + } + } +} + diff --git a/src/main/java/sae/chuzzle/GestionnaireTactile.java b/app/src/main/java/sae/chuzzle/GestionnaireTactile.java similarity index 100% rename from src/main/java/sae/chuzzle/GestionnaireTactile.java rename to app/src/main/java/sae/chuzzle/GestionnaireTactile.java diff --git a/src/main/java/sae/chuzzle/MainActivity.java b/app/src/main/java/sae/chuzzle/MainActivity.java similarity index 100% rename from src/main/java/sae/chuzzle/MainActivity.java rename to app/src/main/java/sae/chuzzle/MainActivity.java diff --git a/src/main/java/sae/chuzzle/MainController.java b/app/src/main/java/sae/chuzzle/MainController.java similarity index 100% rename from src/main/java/sae/chuzzle/MainController.java rename to app/src/main/java/sae/chuzzle/MainController.java diff --git a/src/main/java/sae/chuzzle/MenuActivity.java b/app/src/main/java/sae/chuzzle/MenuActivity.java similarity index 100% rename from src/main/java/sae/chuzzle/MenuActivity.java rename to app/src/main/java/sae/chuzzle/MenuActivity.java diff --git a/src/main/java/sae/chuzzle/MenuController.java b/app/src/main/java/sae/chuzzle/MenuController.java similarity index 100% rename from src/main/java/sae/chuzzle/MenuController.java rename to app/src/main/java/sae/chuzzle/MenuController.java diff --git a/src/main/java/sae/chuzzle/Objectif.java b/app/src/main/java/sae/chuzzle/Objectif.java similarity index 96% rename from src/main/java/sae/chuzzle/Objectif.java rename to app/src/main/java/sae/chuzzle/Objectif.java index 5de6d1c..9e50e08 100644 --- a/src/main/java/sae/chuzzle/Objectif.java +++ b/app/src/main/java/sae/chuzzle/Objectif.java @@ -1,108 +1,108 @@ -package sae.chuzzle; - -import android.os.Bundle; - -/** - * Représente un objectif dynamique pour le mode Hard. - */ -public class Objectif { - private final int couleur; // Index de la couleur cible (0-6) - private final int nbSeriesCible; // Nombre de séries à réaliser - private final int nbCoupsMax; // Limite de coups à faire - private final int poids; // Probabilité d'apparition (poids pour le tirage) - - private int seriesRealisees = 0; - private int coupsRestants; - - public Objectif(int couleur, int nbSeries, int nbCoupsMax, int poids) { - this.couleur = couleur; - this.nbSeriesCible = nbSeries; - this.nbCoupsMax = nbCoupsMax; - this.coupsRestants = nbCoupsMax; - this.poids = poids; - } - - // Getters - public int getCouleur() { - return couleur; - } - public int getNbSeriesCible() { - - return nbSeriesCible; - } - public int getNbCoupsMax() { - return nbCoupsMax; - } - - public int getCoupsRestants() { - return coupsRestants; - - } - public int getPoids() { - return poids; - - } - - public void decrementerCoups() { - - if (coupsRestants > 0) coupsRestants--; - } - - public void ajouterSeries(int n) { - - this.seriesRealisees += n; - } - - public boolean estReussi() { - - return seriesRealisees >= nbSeriesCible; - } - - public boolean estEchoue() { - - return coupsRestants <= 0 && !estReussi(); - } - - public String getDescription() { - String nomCouleur = obtenirNomCouleur(couleur); - return "Éclatez " + nbSeriesCible + " fois des Chuzzle " + nomCouleur + - " en moins de " + nbCoupsMax + " coups (" + seriesRealisees + "/" + nbSeriesCible + - ").\nCoups restants : " + coupsRestants; - } - - private String obtenirNomCouleur(int c) { - switch (c) { - case 0: return "Gris"; - case 1: return "Rose"; - case 2: return "Vert"; - case 3: return "Bleu"; - case 4: return "Jaune"; - case 5: return "Orange"; - case 6: return "Rouge"; - default: return "Inconnue"; - } - } - - // Persistance pour la rotation d'écran - public void sauvegarder(Bundle out) { - out.putInt("obj_couleur", couleur); - out.putInt("obj_cible", nbSeriesCible); - out.putInt("obj_max", nbCoupsMax); - out.putInt("obj_restants", coupsRestants); - out.putInt("obj_realise", seriesRealisees); - out.putInt("obj_poids", poids); - } - - public static Objectif restaurer(Bundle in) { - if (in == null || !in.containsKey("obj_couleur")) return null; - Objectif obj = new Objectif( - in.getInt("obj_couleur"), - in.getInt("obj_cible"), - in.getInt("obj_max"), - in.getInt("obj_poids") - ); - obj.coupsRestants = in.getInt("obj_restants"); - obj.seriesRealisees = in.getInt("obj_realise"); - return obj; - } -} +package sae.chuzzle; + +import android.os.Bundle; + +/** + * Représente un objectif dynamique pour le mode Hard. + */ +public class Objectif { + private final int couleur; // Index de la couleur cible (0-6) + private final int nbSeriesCible; // Nombre de séries à réaliser + private final int nbCoupsMax; // Limite de coups à faire + private final int poids; // Probabilité d'apparition (poids pour le tirage) + + private int seriesRealisees = 0; + private int coupsRestants; + + public Objectif(int couleur, int nbSeries, int nbCoupsMax, int poids) { + this.couleur = couleur; + this.nbSeriesCible = nbSeries; + this.nbCoupsMax = nbCoupsMax; + this.coupsRestants = nbCoupsMax; + this.poids = poids; + } + + // Getters + public int getCouleur() { + return couleur; + } + public int getNbSeriesCible() { + + return nbSeriesCible; + } + public int getNbCoupsMax() { + return nbCoupsMax; + } + + public int getCoupsRestants() { + return coupsRestants; + + } + public int getPoids() { + return poids; + + } + + public void decrementerCoups() { + + if (coupsRestants > 0) coupsRestants--; + } + + public void ajouterSeries(int n) { + + this.seriesRealisees += n; + } + + public boolean estReussi() { + + return seriesRealisees >= nbSeriesCible; + } + + public boolean estEchoue() { + + return coupsRestants <= 0 && !estReussi(); + } + + public String getDescription() { + String nomCouleur = obtenirNomCouleur(couleur); + return "Éclatez " + nbSeriesCible + " fois des Chuzzle " + nomCouleur + + " en moins de " + nbCoupsMax + " coups (" + seriesRealisees + "/" + nbSeriesCible + + ").\nCoups restants : " + coupsRestants; + } + + private String obtenirNomCouleur(int c) { + switch (c) { + case 0: return "Gris"; + case 1: return "Rose"; + case 2: return "Vert"; + case 3: return "Bleu"; + case 4: return "Jaune"; + case 5: return "Orange"; + case 6: return "Rouge"; + default: return "Inconnue"; + } + } + + // Persistance pour la rotation d'écran + public void sauvegarder(Bundle out) { + out.putInt("obj_couleur", couleur); + out.putInt("obj_cible", nbSeriesCible); + out.putInt("obj_max", nbCoupsMax); + out.putInt("obj_restants", coupsRestants); + out.putInt("obj_realise", seriesRealisees); + out.putInt("obj_poids", poids); + } + + public static Objectif restaurer(Bundle in) { + if (in == null || !in.containsKey("obj_couleur")) return null; + Objectif obj = new Objectif( + in.getInt("obj_couleur"), + in.getInt("obj_cible"), + in.getInt("obj_max"), + in.getInt("obj_poids") + ); + obj.coupsRestants = in.getInt("obj_restants"); + obj.seriesRealisees = in.getInt("obj_realise"); + return obj; + } +} diff --git a/src/main/java/sae/chuzzle/OptionsActivity.java b/app/src/main/java/sae/chuzzle/OptionsActivity.java similarity index 96% rename from src/main/java/sae/chuzzle/OptionsActivity.java rename to app/src/main/java/sae/chuzzle/OptionsActivity.java index 82783fa..e68419e 100644 --- a/src/main/java/sae/chuzzle/OptionsActivity.java +++ b/app/src/main/java/sae/chuzzle/OptionsActivity.java @@ -1,31 +1,31 @@ -package sae.chuzzle; - -import android.app.Activity; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.widget.Button; -import android.widget.CheckBox; - -public class OptionsActivity extends Activity { - - private SharedPreferences prefs; - private CheckBox checkHard; - private Button btnRetour; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_options); - - prefs = getSharedPreferences("chuzzle_prefs", MODE_PRIVATE); - - checkHard = findViewById(R.id.checkHard); - btnRetour = findViewById(R.id.btnBack); - - checkHard.setChecked(prefs.getBoolean("hard_mode", false)); - - OptionsController controller = new OptionsController(this, prefs); - checkHard.setOnCheckedChangeListener(controller); - btnRetour.setOnClickListener(controller); - } -} +package sae.chuzzle; + +import android.app.Activity; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.widget.Button; +import android.widget.CheckBox; + +public class OptionsActivity extends Activity { + + private SharedPreferences prefs; + private CheckBox checkHard; + private Button btnRetour; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_options); + + prefs = getSharedPreferences("chuzzle_prefs", MODE_PRIVATE); + + checkHard = findViewById(R.id.checkHard); + btnRetour = findViewById(R.id.btnBack); + + checkHard.setChecked(prefs.getBoolean("hard_mode", false)); + + OptionsController controller = new OptionsController(this, prefs); + checkHard.setOnCheckedChangeListener(controller); + btnRetour.setOnClickListener(controller); + } +} diff --git a/src/main/java/sae/chuzzle/OptionsController.java b/app/src/main/java/sae/chuzzle/OptionsController.java similarity index 100% rename from src/main/java/sae/chuzzle/OptionsController.java rename to app/src/main/java/sae/chuzzle/OptionsController.java diff --git a/src/main/java/sae/chuzzle/Plateau.java b/app/src/main/java/sae/chuzzle/Plateau.java similarity index 100% rename from src/main/java/sae/chuzzle/Plateau.java rename to app/src/main/java/sae/chuzzle/Plateau.java diff --git a/src/main/java/sae/chuzzle/SeedActivity.java b/app/src/main/java/sae/chuzzle/SeedActivity.java similarity index 96% rename from src/main/java/sae/chuzzle/SeedActivity.java rename to app/src/main/java/sae/chuzzle/SeedActivity.java index fd82310..3146351 100644 --- a/src/main/java/sae/chuzzle/SeedActivity.java +++ b/app/src/main/java/sae/chuzzle/SeedActivity.java @@ -1,65 +1,65 @@ -package sae.chuzzle; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.view.View; -import android.widget.Button; -import android.widget.EditText; -import android.widget.Toast; - -public class SeedActivity extends Activity implements View.OnClickListener { - - private EditText etGraine; - private Button btnJouer; - - private Button btnRetour; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_seed); - - etGraine = findViewById(R.id.etGraine); - btnJouer = findViewById(R.id.btnJouer); - btnRetour = findViewById(R.id.btnBack); - - btnRetour.setOnClickListener(this); - - btnJouer.setOnClickListener(this); - } - - @Override - public void onClick(View v) { - if (v == btnJouer) { - lancerPartieAvecGraine(); - } - if (v == btnRetour) { - Intent intent = new Intent(this, MenuActivity.class); - startActivity(intent); - } - } - - private void lancerPartieAvecGraine() { - String texte = etGraine.getText().toString().trim(); - - if (texte.isEmpty()) { - Toast.makeText(this, "Veuillez entrer une graine.", - Toast.LENGTH_SHORT - ).show(); - return; - } - - long graine; - - try { - graine = Long.parseLong(texte); - } catch (NumberFormatException e) { - graine = texte.hashCode(); - } - - Intent intent = new Intent(this, MainActivity.class); - intent.putExtra("graine", graine); - startActivity(intent); - } +package sae.chuzzle; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +public class SeedActivity extends Activity implements View.OnClickListener { + + private EditText etGraine; + private Button btnJouer; + + private Button btnRetour; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_seed); + + etGraine = findViewById(R.id.etGraine); + btnJouer = findViewById(R.id.btnJouer); + btnRetour = findViewById(R.id.btnBack); + + btnRetour.setOnClickListener(this); + + btnJouer.setOnClickListener(this); + } + + @Override + public void onClick(View v) { + if (v == btnJouer) { + lancerPartieAvecGraine(); + } + if (v == btnRetour) { + Intent intent = new Intent(this, MenuActivity.class); + startActivity(intent); + } + } + + private void lancerPartieAvecGraine() { + String texte = etGraine.getText().toString().trim(); + + if (texte.isEmpty()) { + Toast.makeText(this, "Veuillez entrer une graine.", + Toast.LENGTH_SHORT + ).show(); + return; + } + + long graine; + + try { + graine = Long.parseLong(texte); + } catch (NumberFormatException e) { + graine = texte.hashCode(); + } + + Intent intent = new Intent(this, MainActivity.class); + intent.putExtra("graine", graine); + startActivity(intent); + } } \ No newline at end of file diff --git a/src/main/java/sae/chuzzle/VueGrille.java b/app/src/main/java/sae/chuzzle/VueGrille.java similarity index 100% rename from src/main/java/sae/chuzzle/VueGrille.java rename to app/src/main/java/sae/chuzzle/VueGrille.java diff --git a/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml similarity index 100% rename from src/main/res/drawable-v24/ic_launcher_foreground.xml rename to app/src/main/res/drawable-v24/ic_launcher_foreground.xml diff --git a/src/main/res/drawable/chaine.png b/app/src/main/res/drawable/chaine.png similarity index 100% rename from src/main/res/drawable/chaine.png rename to app/src/main/res/drawable/chaine.png diff --git a/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml similarity index 100% rename from src/main/res/drawable/ic_launcher_background.xml rename to app/src/main/res/drawable/ic_launcher_background.xml diff --git a/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml similarity index 100% rename from src/main/res/drawable/ic_launcher_foreground.xml rename to app/src/main/res/drawable/ic_launcher_foreground.xml diff --git a/src/main/res/layout/activity_fin_partie.xml b/app/src/main/res/layout/activity_fin_partie.xml similarity index 100% rename from src/main/res/layout/activity_fin_partie.xml rename to app/src/main/res/layout/activity_fin_partie.xml diff --git a/src/main/res/layout/activity_menu.xml b/app/src/main/res/layout/activity_menu.xml similarity index 100% rename from src/main/res/layout/activity_menu.xml rename to app/src/main/res/layout/activity_menu.xml diff --git a/src/main/res/layout/activity_seed.xml b/app/src/main/res/layout/activity_seed.xml similarity index 100% rename from src/main/res/layout/activity_seed.xml rename to app/src/main/res/layout/activity_seed.xml diff --git a/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml similarity index 100% rename from src/main/res/mipmap-anydpi-v26/ic_launcher.xml rename to app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml diff --git a/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml similarity index 100% rename from src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml rename to app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml diff --git a/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp similarity index 100% rename from src/main/res/mipmap-hdpi/ic_launcher.webp rename to app/src/main/res/mipmap-hdpi/ic_launcher.webp diff --git a/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp similarity index 100% rename from src/main/res/mipmap-hdpi/ic_launcher_round.webp rename to app/src/main/res/mipmap-hdpi/ic_launcher_round.webp diff --git a/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp similarity index 100% rename from src/main/res/mipmap-mdpi/ic_launcher.webp rename to app/src/main/res/mipmap-mdpi/ic_launcher.webp diff --git a/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp similarity index 100% rename from src/main/res/mipmap-mdpi/ic_launcher_round.webp rename to app/src/main/res/mipmap-mdpi/ic_launcher_round.webp diff --git a/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp similarity index 100% rename from src/main/res/mipmap-xhdpi/ic_launcher.webp rename to app/src/main/res/mipmap-xhdpi/ic_launcher.webp diff --git a/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp similarity index 100% rename from src/main/res/mipmap-xhdpi/ic_launcher_round.webp rename to app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp diff --git a/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp similarity index 100% rename from src/main/res/mipmap-xxhdpi/ic_launcher.webp rename to app/src/main/res/mipmap-xxhdpi/ic_launcher.webp diff --git a/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp similarity index 100% rename from src/main/res/mipmap-xxhdpi/ic_launcher_round.webp rename to app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp diff --git a/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp similarity index 100% rename from src/main/res/mipmap-xxxhdpi/ic_launcher.webp rename to app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp diff --git a/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp similarity index 100% rename from src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp rename to app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp diff --git a/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml similarity index 100% rename from src/main/res/values-night/themes.xml rename to app/src/main/res/values-night/themes.xml diff --git a/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml similarity index 100% rename from src/main/res/values/colors.xml rename to app/src/main/res/values/colors.xml diff --git a/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml similarity index 100% rename from src/main/res/values/strings.xml rename to app/src/main/res/values/strings.xml diff --git a/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml similarity index 100% rename from src/main/res/values/themes.xml rename to app/src/main/res/values/themes.xml diff --git a/src/main/res/xml/backup_rules.xml b/app/src/main/res/xml/backup_rules.xml similarity index 100% rename from src/main/res/xml/backup_rules.xml rename to app/src/main/res/xml/backup_rules.xml diff --git a/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml similarity index 100% rename from src/main/res/xml/data_extraction_rules.xml rename to app/src/main/res/xml/data_extraction_rules.xml diff --git a/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml similarity index 100% rename from src/main/res/xml/preferences.xml rename to app/src/main/res/xml/preferences.xml diff --git a/src/test/java/sae/chuzzle/ExampleUnitTest.java b/app/src/test/java/sae/chuzzle/ExampleUnitTest.java similarity index 100% rename from src/test/java/sae/chuzzle/ExampleUnitTest.java rename to app/src/test/java/sae/chuzzle/ExampleUnitTest.java diff --git a/build.gradle.kts b/build.gradle.kts index 882d8c5..3756278 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,42 +1,4 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - alias(libs.plugins.android.application) -} - -android { - namespace = "sae.chuzzle" - compileSdk { - version = release(36) - } - - defaultConfig { - applicationId = "sae.chuzzle" - minSdk = 24 - targetSdk = 36 - versionCode = 1 - versionName = "1.0" - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } -} - -dependencies { - - implementation(libs.activity) - testImplementation(libs.junit) - androidTestImplementation(libs.ext.junit) - androidTestImplementation(libs.espresso.core) + alias(libs.plugins.android.application) apply false } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..4387edc --- /dev/null +++ b/gradle.properties @@ -0,0 +1,21 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. For more details, visit +# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Enables namespacing of each library's R class so that its R class includes only the +# resources declared in the library itself and none from the library's dependencies, +# thereby reducing the size of the R class for that library +android.nonTransitiveRClass=true \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..9f3ec5d --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,22 @@ +[versions] +agp = "9.0.1" +junit = "4.13.2" +junitVersion = "1.3.0" +espressoCore = "3.7.0" +appcompat = "1.7.1" +material = "1.13.0" +activity = "1.12.4" +constraintlayout = "2.2.1" + +[libraries] +junit = { group = "junit", name = "junit", version.ref = "junit" } +ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } +espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } +appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } +material = { group = "com.google.android.material", name = "material", version.ref = "material" } +activity = { group = "androidx.activity", name = "activity", version.ref = "activity" } +constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" } + +[plugins] +android-application = { id = "com.android.application", version.ref = "agp" } + diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..8bdaf60 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..a96301f --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,9 @@ +#Tue Mar 24 19:40:20 CET 2026 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionSha256Sum=a17ddd85a26b6a7f5ddb71ff8b05fc5104c0202c6e64782429790c933686c806 +distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..ef07e01 --- /dev/null +++ b/gradlew @@ -0,0 +1,251 @@ +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH="\\\"\\\"" + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..db3a6ac --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH= + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..95e681f --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,24 @@ +pluginManagement { + repositories { + google { + content { + includeGroupByRegex("com\\.android.*") + includeGroupByRegex("com\\.google.*") + includeGroupByRegex("androidx.*") + } + } + mavenCentral() + gradlePluginPortal() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} + +rootProject.name = "Real Chuzzle" +include(":app") + \ No newline at end of file diff --git a/src/main/res/layout/activity_main.xml b/src/main/res/layout/activity_main.xml deleted file mode 100644 index efcd1e2..0000000 --- a/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - -