Actualisation du mainactivity

This commit is contained in:
2026-03-19 10:07:24 +01:00
parent 7302412a37
commit eb7ceec902
41 changed files with 2301 additions and 8 deletions
+67 -8
View File
@@ -1,6 +1,7 @@
package sae.chuzzle; package sae.chuzzle;
import android.app.Activity; import android.app.Activity;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
@@ -10,8 +11,15 @@ import android.widget.TextView;
public class MainActivity extends Activity implements View.OnClickListener { public class MainActivity extends Activity implements View.OnClickListener {
private Controleur controleur; private Controleur controleur;
private Button btnJouer; private Button btnJouer;
private Button btnMenu;
private boolean hardMode;
private EtatJeu etatJeu;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@@ -19,33 +27,79 @@ public class MainActivity extends Activity implements View.OnClickListener {
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
// --- Modèle --- // --- Modèle ---
long graine = getIntent().getLongExtra("graine", System.currentTimeMillis()); long graine = getIntent().getLongExtra("graine", System.currentTimeMillis());
boolean hardMode = getSharedPreferences("chuzzle_prefs", MODE_PRIVATE) hardMode = getSharedPreferences("chuzzle_prefs", MODE_PRIVATE)
.getBoolean("hard_mode", false); .getBoolean("hard_mode", false);
boolean daltonien = getSharedPreferences("chuzzle_prefs", MODE_PRIVATE) boolean daltonien = getSharedPreferences("chuzzle_prefs", MODE_PRIVATE)
.getBoolean("daltonien", false); .getBoolean("daltonien", false);
EtatJeu etatJeu = new EtatJeu(graine, hardMode); etatJeu = new EtatJeu(graine, hardMode);
// --- Restauration si retour de pause ---
if (savedInstanceState != null) {
etatJeu.restaurerEtat(savedInstanceState);
}
// --- Vue --- // --- Vue ---
VueGrille vueGrille = findViewById(R.id.vueGrille); VueGrille vueGrille = findViewById(R.id.vueGrille);
vueGrille.definirModeDaltonien(daltonien); vueGrille.definirModeDaltonien(daltonien);
// --- Controleur --- // --- Controleur ---
btnJouer = findViewById(R.id.btnJouer); btnJouer = findViewById(R.id.btnJouer);
btnJouer.setOnClickListener(this); btnJouer.setOnClickListener(this);
btnMenu = findViewById(R.id.btnMenu);
btnMenu.setOnClickListener(this);
controleur = new Controleur( controleur = new Controleur(
this, this,
etatJeu, etatJeu,
vueGrille, vueGrille,
(TextView) findViewById(R.id.tvScore), graine,
(TextView) findViewById(R.id.tvCoups), (TextView) findViewById(R.id.tvScore),
(TextView) findViewById(R.id.tvCoups),
(RadioButton) findViewById(R.id.rbLigne), (RadioButton) findViewById(R.id.rbLigne),
(RadioButton) findViewById(R.id.rbDroite), (RadioButton) findViewById(R.id.rbDroite),
(Spinner) findViewById(R.id.spinnerIndex), (Spinner) findViewById(R.id.spinnerIndex),
btnJouer btnJouer,
hardMode
); );
// --- Gestion tactile ---
GestionnaireTactile gestionnaireTactile =
new GestionnaireTactile(vueGrille, etatJeu, controleur);
vueGrille.setOnTouchListener(gestionnaireTactile);
// --- Logique Hard mode ---
if (hardMode) {
// TODO: Ajouter la nouvelle fonctionnalité pour le hard mode ici (en remplacement du timer)
}
}
// -
//
// -
// CYCLE DE VIE
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (etatJeu != null) {
etatJeu.sauvegarderEtat(outState);
}
if (controleur != null) {
controleur.sauvegarderEtat(outState);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
} }
@Override @Override
@@ -53,5 +107,10 @@ public class MainActivity extends Activity implements View.OnClickListener {
if (v == btnJouer) { if (v == btnJouer) {
controleur.gererCoupJoueur(); controleur.gererCoupJoueur();
} }
if (v == btnMenu) {
etatJeu.forcerFinDePartie();
Intent intent = new Intent(this, MenuActivity.class);
startActivity(intent);
}
} }
} }
BIN
View File
Binary file not shown.
@@ -0,0 +1,26 @@
package sae.chuzzle;
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 <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("sae.chuzzle", appContext.getPackageName());
}
}
+41
View File
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="sae.chuzzle">
<application
android:allowBackup="true"
android:label="Chuzzle"
android:theme="@android:style/Theme.Light.NoTitleBar">
<!-- Point d'entrée : le menu principal -->
<activity android:name=".MenuActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Partie avec graine : retour arrière = MenuActivity -->
<activity
android:name=".SeedActivity"
android:parentActivityName=".MenuActivity"/>
<!-- Options : retour arrière = MenuActivity -->
<activity
android:name=".OptionsActivity"
android:parentActivityName=".MenuActivity"/>
<!-- Jeu : retour arrière = MenuActivity -->
<activity
android:name=".MainActivity"
android:parentActivityName=".MenuActivity"/>
<!-- Fin de partie : retour arrière = MenuActivity -->
<activity
android:name=".FinPartieActivity"
android:parentActivityName=".MenuActivity"/>
</application>
</manifest>
@@ -0,0 +1,133 @@
package sae.chuzzle;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
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;
private final RadioButton rbLigne;
private final RadioButton rbDroite;
private final Spinner spinnerIndex;
private final Button btnJouer;
// Hard Mode
private final boolean hardMode;
// -
// CONSTRUCTEUR
public Controleur(Activity activite, EtatJeu etatJeu, VueGrille vueGrille,
long graine,
TextView tvScore, TextView tvCoups,
RadioButton rbLigne, RadioButton rbDroite,
Spinner spinnerIndex, Button btnJouer,
boolean hardMode) {
this.activite = activite;
this.etatJeu = etatJeu;
this.vueGrille = vueGrille;
this.graine = graine;
this.tvScore = tvScore;
this.tvCoups = tvCoups;
this.rbLigne = rbLigne;
this.rbDroite = rbDroite;
this.spinnerIndex = spinnerIndex;
this.btnJouer = btnJouer;
this.hardMode = hardMode;
initialiserSpinner();
rafraichirAffichage();
}
// -
// INITIALISATION
private void initialiserSpinner() {
String[] indices = {"0", "1", "2", "3", "4", "5"};
ArrayAdapter<String> adaptateur = new ArrayAdapter<>(
activite,
android.R.layout.simple_spinner_item,
indices
);
adaptateur.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerIndex.setAdapter(adaptateur);
}
// -
// GESTION DU COUP
public void gererCoupJoueur() {
boolean estLigne = rbLigne.isChecked();
int index = spinnerIndex.getSelectedItemPosition();
int sens;
if (rbDroite.isChecked()) {
sens = +1;
} else {
sens = -1;
}
boolean accepte = etatJeu.appliquerCoup(estLigne, index, sens);
if (!accepte) {
Toast.makeText(activite, "Coup invalide !", Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(activite, "Coup valide !", Toast.LENGTH_SHORT).show();
rafraichirAffichage();
verifierFinDePartie();
}
// -
// FIN DE PARTIE
public void verifierFinDePartie() {
if (etatJeu.estTerminee()) {
Intent intent = new Intent(activite, FinPartieActivity.class);
intent.putExtra("score", etatJeu.obtenirScore());
intent.putExtra("nbCoups", etatJeu.obtenirNbCoups());
intent.putExtra("graine", graine);
activite.startActivity(intent);
}
}
// -
// MISE A JOUR DE LA VUE
public void rafraichirAffichage() {
tvScore.setText("Score : " + etatJeu.obtenirScore());
tvCoups.setText("Coups : " + etatJeu.obtenirNbCoups());
vueGrille.definirGrille(etatJeu.obtenirGrille());
vueGrille.definirVerrous(etatJeu.obtenirVerrous());
if (etatJeu.estTerminee()) {
btnJouer.setEnabled(false);
}
}
public void sauvegarderEtat(Bundle out) {
// Nettoyé de la logique d'objectifs
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,50 @@
package sae.chuzzle;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
public class FinPartieActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fin_partie);
// Récupérer les données passées par le Controleur
int score = getIntent().getIntExtra("score", 0);
int nbCoups = getIntent().getIntExtra("nbCoups", 0);
long graine = getIntent().getLongExtra("graine", 0L);
// Afficher les données
TextView tvScore = findViewById(R.id.tvFinScore);
TextView tvCoups = findViewById(R.id.tvFinCoups);
TextView tvGraine = findViewById(R.id.tvFinGraine);
tvScore.setText(String.valueOf(score));
tvCoups.setText(String.valueOf(nbCoups));
tvGraine.setText(String.valueOf(graine));
// Bouton retour au menu
Button btnMenu = findViewById(R.id.btnFinMenu);
btnMenu.setOnClickListener(v -> {
Intent intent = new Intent(this, MenuActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
});
}
// -
// RETOUR ARRIERE = menu principal
@Override
public void onBackPressed() {
Intent intent = new Intent(this, MenuActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}
}
@@ -0,0 +1,140 @@
package sae.chuzzle;
import android.view.MotionEvent;
import android.view.View;
public class GestionnaireTactile implements View.OnTouchListener {
private static final int NB_LIGNES = EtatJeu.NB_LIGNES;
private static final int NB_COLONNES = EtatJeu.NB_COLONNES;
private static final float SEUIL_DIRECTION_PX = 10f;
private final VueGrille vueGrille;
private final EtatJeu etatJeu;
private final Controleur controleur;
private float touchDebutX, touchDebutY;
private int ligneTouchee, colonneTouchee;
private Boolean estLigne;
private int indexGlissement;
private float decalagePx;
private float tailleCase;
public GestionnaireTactile(VueGrille vueGrille,
EtatJeu etatJeu,
Controleur controleur) {
this.vueGrille = vueGrille;
this.etatJeu = etatJeu;
this.controleur = controleur;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (etatJeu.estTerminee()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
tailleCase = calculerTailleCase();
gererDebut(event);
return true;
case MotionEvent.ACTION_MOVE:
gererMouvement(event);
return true;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
gererFin(event.getAction() == MotionEvent.ACTION_UP);
return true;
}
return false;
}
private void gererDebut(MotionEvent event) {
touchDebutX = event.getX();
touchDebutY = event.getY();
estLigne = null;
decalagePx = 0f;
float margeGauche = (vueGrille.getWidth() - tailleCase * NB_COLONNES) / 2f;
float margeHaut = (vueGrille.getHeight() - tailleCase * NB_LIGNES) / 2f;
ligneTouchee = (int) ((touchDebutY - margeHaut) / tailleCase);
colonneTouchee = (int) ((touchDebutX - margeGauche) / tailleCase);
ligneTouchee = Math.max(0, Math.min(NB_LIGNES - 1, ligneTouchee));
colonneTouchee = Math.max(0, Math.min(NB_COLONNES - 1, colonneTouchee));
}
private void gererMouvement(MotionEvent event) {
float dx = event.getX() - touchDebutX;
float dy = event.getY() - touchDebutY;
if (estLigne == null) {
if (Math.abs(dx) > SEUIL_DIRECTION_PX || Math.abs(dy) > SEUIL_DIRECTION_PX) {
estLigne = Math.abs(dx) >= Math.abs(dy);
if (estLigne) {
indexGlissement = ligneTouchee;
} else {
indexGlissement = colonneTouchee;
}
} else {
return;
}
}
if (estLigne) {
decalagePx = dx;
} else {
decalagePx = dy;
}
// Affiche le glissement réel du doigt (permet la rotation multi-cases)
vueGrille.definirGlissement(estLigne, indexGlissement, decalagePx);
}
private void gererFin(boolean estRelachement) {
if (estLigne == null) {
vueGrille.annulerGlissement();
return;
}
if (tailleCase <= 1f) {
vueGrille.annulerGlissement();
estLigne = null;
return;
}
// Arrondi au nombre de cases le plus proche (permet ±1, ±2, ±3…)
int nbCases = (int) Math.round(decalagePx / tailleCase);
if (nbCases != 0 && estRelachement) {
boolean accepte = etatJeu.appliquerCoup(estLigne, indexGlissement, nbCases);
if (accepte) {
controleur.rafraichirAffichage();
controleur.verifierFinDePartie();
}
}
vueGrille.annulerGlissement();
estLigne = null;
}
private float calculerTailleCase() {
float l = vueGrille.getWidth();
float h = vueGrille.getHeight();
if (l == 0 || h == 0) {
return 1f;
}
return Math.min(l / NB_COLONNES, h / NB_LIGNES);
}
}
@@ -0,0 +1,116 @@
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.RadioButton;
import android.widget.Spinner;
import android.widget.TextView;
public class MainActivity extends Activity implements View.OnClickListener {
private Controleur controleur;
private Button btnJouer;
private Button btnMenu;
private boolean hardMode;
private EtatJeu etatJeu;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// --- Modèle ---
long graine = getIntent().getLongExtra("graine", System.currentTimeMillis());
hardMode = getSharedPreferences("chuzzle_prefs", MODE_PRIVATE)
.getBoolean("hard_mode", false);
boolean daltonien = getSharedPreferences("chuzzle_prefs", MODE_PRIVATE)
.getBoolean("daltonien", false);
etatJeu = new EtatJeu(graine, hardMode);
// --- Restauration si retour de pause ---
if (savedInstanceState != null) {
etatJeu.restaurerEtat(savedInstanceState);
}
// --- Vue ---
VueGrille vueGrille = findViewById(R.id.vueGrille);
vueGrille.definirModeDaltonien(daltonien);
// --- Controleur ---
btnJouer = findViewById(R.id.btnJouer);
btnJouer.setOnClickListener(this);
btnMenu = findViewById(R.id.btnMenu);
btnMenu.setOnClickListener(this);
controleur = new Controleur(
this,
etatJeu,
vueGrille,
graine,
(TextView) findViewById(R.id.tvScore),
(TextView) findViewById(R.id.tvCoups),
(RadioButton) findViewById(R.id.rbLigne),
(RadioButton) findViewById(R.id.rbDroite),
(Spinner) findViewById(R.id.spinnerIndex),
btnJouer,
hardMode
);
// --- Gestion tactile ---
GestionnaireTactile gestionnaireTactile =
new GestionnaireTactile(vueGrille, etatJeu, controleur);
vueGrille.setOnTouchListener(gestionnaireTactile);
// --- Logique Hard mode ---
if (hardMode) {
// TODO: Ajouter la nouvelle fonctionnalité pour le hard mode ici (en remplacement du timer)
}
}
// -
//
// -
// CYCLE DE VIE
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (etatJeu != null) {
etatJeu.sauvegarderEtat(outState);
}
if (controleur != null) {
controleur.sauvegarderEtat(outState);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
public void onClick(View v) {
if (v == btnJouer) {
controleur.gererCoupJoueur();
}
if (v == btnMenu) {
etatJeu.forcerFinDePartie();
Intent intent = new Intent(this, MenuActivity.class);
startActivity(intent);
}
}
}
@@ -0,0 +1,44 @@
package sae.chuzzle;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MenuActivity extends Activity implements View.OnClickListener {
private Button btnNouvellePartie;
private Button btnPartieGraine;
private Button btnOptions;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
btnNouvellePartie = findViewById(R.id.btnNouvellePartie);
btnPartieGraine = findViewById(R.id.btnPartieGraine);
btnOptions = findViewById(R.id.btnOptions);
btnNouvellePartie.setOnClickListener(this);
btnPartieGraine.setOnClickListener(this);
btnOptions.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v == btnNouvellePartie) {
long graine = System.currentTimeMillis();
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("graine", graine);
startActivity(intent);
} else if (v == btnPartieGraine) {
Intent intent = new Intent(this, SeedActivity.class);
startActivity(intent);
} else if (v == btnOptions) {
Intent intent = new Intent(this, OptionsActivity.class);
startActivity(intent);
}
}
}
@@ -0,0 +1,58 @@
package sae.chuzzle;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
public class OptionsActivity extends Activity
implements CompoundButton.OnCheckedChangeListener, View.OnClickListener {
private SharedPreferences prefs;
private CheckBox checkDaltonien;
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);
checkDaltonien = findViewById(R.id.checkDaltonien);
checkHard = findViewById(R.id.checkHard);
btnRetour = findViewById(R.id.btnBack);
checkDaltonien.setChecked(prefs.getBoolean("daltonien", false));
checkHard.setChecked(prefs.getBoolean("hard_mode", false));
checkDaltonien.setOnCheckedChangeListener(this);
checkHard.setOnCheckedChangeListener(this);
btnRetour.setOnClickListener(this);
}
@Override
public void onCheckedChanged(CompoundButton bouton, boolean estCoche) {
if (bouton == checkDaltonien) {
prefs.edit().putBoolean("daltonien", estCoche).apply();
} else if (bouton == checkHard) {
prefs.edit().putBoolean("hard_mode", estCoche).apply();
}
}
@Override
public void onClick(View v) {
if (v == btnRetour) {
Intent intent = new Intent(this, MenuActivity.class);
startActivity(intent);
}
}
}
@@ -0,0 +1,67 @@
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);
}
}
@@ -0,0 +1,307 @@
package sae.chuzzle;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.NonNull;
public class VueGrille extends View {
// =========================================================
// Constantes
// =========================================================
private static final int NB_LIGNES = 6;
private static final int NB_COLONNES = 6;
private static final int NB_TYPES = 7;
/** Symboles pour le mode daltonien, un par type. */
private static final String[] SYMBOLES = {"", "", "", "", "", "", ""};
// =========================================================
// Données métier
// =========================================================
/** Grille reçue depuis MainActivity (tableau brut). */
private int[][] grille = new int[NB_LIGNES][NB_COLONNES];
/** Verrous reçus depuis MainActivity. */
private boolean[][] verrous = new boolean[NB_LIGNES][NB_COLONNES];
private boolean modeDaltonien = false;
// =========================================================
// État de l'animation de glissement
// =========================================================
/**
* true = on anime une ligne,
* false = on anime une colonne,
* null = pas d'animation en cours.
*/
private Boolean animEstLigne = null;
/** Index de la ligne ou colonne en cours de glissement. */
private int animIndex = 0;
/**
* Décalage courant en pixels (positif = droite/bas,
* négatif = gauche/haut).
*/
private float animDecalagePx = 0f;
// =========================================================
// Outils de dessin
// =========================================================
private final Paint pinceauCase = new Paint();
private final Paint pinceauSymbole = new Paint();
// =========================================================
// Constructeurs
// =========================================================
public VueGrille(Context contexte) {
super(contexte);
initPinceaux();
}
public VueGrille(Context context, AttributeSet attrs) {
super(context, attrs);
initPinceaux();
}
private void initPinceaux() {
pinceauCase.setAntiAlias(true);
pinceauCase.setStyle(Paint.Style.FILL);
pinceauSymbole.setAntiAlias(true);
pinceauSymbole.setColor(0xFF000000);
pinceauSymbole.setTextAlign(Paint.Align.CENTER);
}
// =========================================================
// API publique
// =========================================================
/**
* Reçoit une copie de la grille depuis MainActivity.
* VueGrille ne sait pas d'où viennent ces données,
* elle sait juste les dessiner.
*/
public void definirGrille(int[][] nouvelleGrille) {
for (int l = 0; l < NB_LIGNES; l++) {
System.arraycopy(nouvelleGrille[l], 0, grille[l], 0, NB_COLONNES);
}
invalidate();
}
public void definirModeDaltonien(boolean actif) {
this.modeDaltonien = actif;
invalidate();
}
public void definirVerrous(boolean[][] nouveauxVerrous) {
for (int l = 0; l < NB_LIGNES; l++) {
System.arraycopy(nouveauxVerrous[l], 0, verrous[l], 0, NB_COLONNES);
}
invalidate();
}
// =========================================================
// API animation de glissement (appelée par GestionnaireTactile)
// =========================================================
/**
* Déclenche l'animation de glissement en temps réel.
*
* @param estLigne true = on déplace une ligne, false = une colonne
* @param index index de la ligne ou colonne (0-based)
* @param decalagePx décalage courant en pixels (peut être négatif)
*/
public void definirGlissement(boolean estLigne, int index, float decalagePx) {
this.animEstLigne = estLigne;
this.animIndex = index;
this.animDecalagePx = decalagePx;
invalidate();
}
/**
* Annule l'animation de glissement et revient à l'affichage normal.
*/
public void annulerGlissement() {
this.animEstLigne = null;
invalidate();
}
// =========================================================
// Dessin
// =========================================================
@Override
protected void onDraw(@NonNull Canvas canvas) {
super.onDraw(canvas);
int largeur = getWidth();
int hauteur = getHeight();
float tailleCase = Math.min(
largeur / (float) NB_COLONNES,
hauteur / (float) NB_LIGNES
);
float margeGauche = (largeur - tailleCase * NB_COLONNES) / 2f;
float margeHaut = (hauteur - tailleCase * NB_LIGNES) / 2f;
pinceauSymbole.setTextSize(tailleCase * 0.4f);
for (int ligne = 0; ligne < NB_LIGNES; ligne++) {
for (int colonne = 0; colonne < NB_COLONNES; colonne++) {
// --------------------------------------------------
// Calcul de l'offset d'animation pour cette case
// --------------------------------------------------
float offsetX = 0f;
float offsetY = 0f;
if (animEstLigne != null) {
if (animEstLigne && ligne == animIndex) {
// Décalage horizontal de toute la ligne
offsetX = animDecalagePx;
} else if (!animEstLigne && colonne == animIndex) {
// Décalage vertical de toute la colonne
offsetY = animDecalagePx;
}
}
// --------------------------------------------------
// Position de base de la case
// --------------------------------------------------
float x1 = margeGauche + colonne * tailleCase + 6 + offsetX;
float y1 = margeHaut + ligne * tailleCase + 6 + offsetY;
float x2 = margeGauche + (colonne + 1) * tailleCase - 6 + offsetX;
float y2 = margeHaut + (ligne + 1) * tailleCase - 6 + offsetY;
// --------------------------------------------------
// Dessin avec wrap-around (la case qui sort d'un
// côté réapparaît de l'autre côté)
// --------------------------------------------------
dessinerCase(canvas, ligne, colonne, x1, y1, x2, y2,
tailleCase, margeGauche, margeHaut, offsetX, offsetY);
}
}
}
/**
* Dessine une case à la position donnée.
* Si la case sort des bords (wrap-around), elle est aussi dessinée
* du côté opposé de la grille.
*/
private void dessinerCase(Canvas canvas,
int ligne, int colonne,
float x1, float y1, float x2, float y2,
float tailleCase,
float margeGauche, float margeHaut,
float offsetX, float offsetY) {
int type = grille[ligne][colonne];
// Bornage de la grille (en pixels)
float borneGaucheGrille = margeGauche;
float bordDroiteGrille = margeGauche + NB_COLONNES * tailleCase;
float borneHautGrille = margeHaut;
float bordBasGrille = margeHaut + NB_LIGNES * tailleCase;
// Largeur totale de la ligne / hauteur totale de la colonne en pixels
float largeurGrille = NB_COLONNES * tailleCase;
float hauteurGrille = NB_LIGNES * tailleCase;
// Dessine la case principale
dessinerRectCase(canvas, type, ligne, colonne, x1, y1, x2, y2);
// Wrap-around horizontal (pour les lignes)
if (offsetX != 0f) {
float wrapX1 = x1, wrapX2 = x2;
if (x2 > bordDroiteGrille) {
// La case déborde à droite → réapparaît à gauche
wrapX1 = x1 - largeurGrille;
wrapX2 = x2 - largeurGrille;
dessinerRectCase(canvas, type, ligne, colonne, wrapX1, y1, wrapX2, y2);
} else if (x1 < borneGaucheGrille) {
// La case déborde à gauche → réapparaît à droite
wrapX1 = x1 + largeurGrille;
wrapX2 = x2 + largeurGrille;
dessinerRectCase(canvas, type, ligne, colonne, wrapX1, y1, wrapX2, y2);
}
}
// Wrap-around vertical (pour les colonnes)
if (offsetY != 0f) {
float wrapY1 = y1, wrapY2 = y2;
if (y2 > bordBasGrille) {
// La case déborde en bas → réapparaît en haut
wrapY1 = y1 - hauteurGrille;
wrapY2 = y2 - hauteurGrille;
dessinerRectCase(canvas, type, ligne, colonne, x1, wrapY1, x2, wrapY2);
} else if (y1 < borneHautGrille) {
// La case déborde en haut → réapparaît en bas
wrapY1 = y1 + hauteurGrille;
wrapY2 = y2 + hauteurGrille;
dessinerRectCase(canvas, type, ligne, colonne, x1, wrapY1, x2, wrapY2);
}
}
}
/**
* Dessine le rectangle coloré d'une case + verrou + symbole daltonien.
*/
private void dessinerRectCase(Canvas canvas, int type,
int ligne, int colonne,
float x1, float y1, float x2, float y2) {
// Couleur de fond
definirCouleur(type);
canvas.drawRoundRect(x1, y1, x2, y2, 20, 20, pinceauCase);
// Assombrir si verrouillée
if (verrous[ligne][colonne]) {
pinceauCase.setARGB(120, 0, 0, 0);
canvas.drawRoundRect(x1, y1, x2, y2, 20, 20, pinceauCase);
}
float cx = (x1 + x2) / 2f;
float cy = (y1 + y2) / 2f
- (pinceauSymbole.descent() + pinceauSymbole.ascent()) / 2f;
// Symbole daltonien
if (modeDaltonien) {
canvas.drawText(SYMBOLES[type % NB_TYPES], cx, cy, pinceauSymbole);
}
// Cadenas par-dessus si verrouillée
if (verrous[ligne][colonne]) {
canvas.drawText("🔒", cx, cy, pinceauSymbole);
}
}
// =========================================================
// Utilitaire privé
// =========================================================
private void definirCouleur(int type) {
switch (type % NB_TYPES) {
case 0: pinceauCase.setARGB(255, 200, 200, 200); break;
case 1: pinceauCase.setARGB(255, 255, 105, 180); break;
case 2: pinceauCase.setARGB(255, 90, 230, 200); break;
case 3: pinceauCase.setARGB(255, 100, 170, 255); break;
case 4: pinceauCase.setARGB(255, 255, 220, 90); break;
case 5: pinceauCase.setARGB(255, 255, 140, 90); break;
case 6: pinceauCase.setARGB(255, 255, 90, 90); break;
}
}
}
@@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>
@@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:padding="48dp"
android:background="#1A1A2E">
<!-- Titre -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Partie terminée !"
android:textSize="36sp"
android:textStyle="bold"
android:textColor="#E94560"
android:gravity="center"
android:layout_marginBottom="48dp"/>
<!-- Score -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Score"
android:textSize="16sp"
android:textColor="#AAAACC"
android:gravity="center"/>
<TextView
android:id="@+id/tvFinScore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textSize="52sp"
android:textStyle="bold"
android:textColor="#FFFFFF"
android:gravity="center"
android:layout_marginBottom="32dp"/>
<!-- Nombre de coups -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Coups joués"
android:textSize="16sp"
android:textColor="#AAAACC"
android:gravity="center"/>
<TextView
android:id="@+id/tvFinCoups"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textSize="36sp"
android:textStyle="bold"
android:textColor="#FFFFFF"
android:gravity="center"
android:layout_marginBottom="32dp"/>
<!-- Graine -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Graine de la partie"
android:textSize="14sp"
android:textColor="#AAAACC"
android:gravity="center"/>
<TextView
android:id="@+id/tvFinGraine"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textSize="20sp"
android:textColor="#E2C94E"
android:gravity="center"
android:layout_marginBottom="48dp"/>
<!-- Bouton retour au menu -->
<Button
android:id="@+id/btnFinMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Retour au menu"
android:textSize="18sp"
android:backgroundTint="#E94560"
android:textColor="#FFFFFF"
android:padding="16dp"/>
</LinearLayout>
+97
View File
@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/tvScore"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Score : 0"
android:textSize="18sp"
android:textStyle="bold"/>
<TextView
android:id="@+id/tvCoups"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Coups : 0"
android:textSize="18sp"/>
<Button
android:id="@+id/btnMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Menu"/>
<sae.chuzzle.VueGrille
android:id="@+id/vueGrille"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<RadioGroup
android:id="@+id/rgChoix"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rbLigne"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Ligne"
android:checked="true"/>
<RadioButton
android:id="@+id/rbColonne"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Colonne"/>
</RadioGroup>
<Spinner
android:id="@+id/spinnerIndex"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<RadioGroup
android:id="@+id/rgSens"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rbDroite"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Droite / Bas (+1)"
android:checked="true"/>
<RadioButton
android:id="@+id/rbGauche"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Gauche / Haut (-1)"/>
</RadioGroup>
<Button
android:id="@+id/btnJouer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Jouer"/>
</LinearLayout>
+38
View File
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:padding="48dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Chuzzle"
android:textSize="48sp"
android:textStyle="bold"
android:gravity="center"
android:layout_marginBottom="64dp"/>
<Button
android:id="@+id/btnNouvellePartie"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Nouvelle Partie"
android:layout_marginBottom="16dp"/>
<Button
android:id="@+id/btnPartieGraine"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Partie avec Graine"
android:layout_marginBottom="16dp"/>
<Button
android:id="@+id/btnOptions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Options"/>
</LinearLayout>
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="48dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Options"
android:textSize="32sp"
android:textStyle="bold"
android:gravity="center"
android:layout_marginBottom="64dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_marginBottom="32dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Mode daltonien (symboles)"
android:textSize="18sp"/>
<CheckBox
android:id="@+id/checkDaltonien"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleX="1.5"
android:scaleY="1.5"
android:layout_marginEnd="16dp"
android:minWidth="48dp"
android:minHeight="48dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Hard mode (verrous)"
android:textSize="18sp"/>
<CheckBox
android:id="@+id/checkHard"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleX="1.5"
android:scaleY="1.5"
android:layout_marginEnd="16dp"
android:minWidth="48dp"
android:minHeight="48dp"/>
</LinearLayout>
<Button
android:id="@+id/btnBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Retour"
android:layout_marginTop="32dp">
</Button>
</LinearLayout>
+39
View File
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:padding="48dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Entrez une graine"
android:textSize="24sp"
android:gravity="center"
android:layout_marginBottom="32dp"/>
<EditText
android:id="@+id/etGraine"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Ex : 12345"
android:inputType="number"
android:layout_marginBottom="32dp"/>
<Button
android:id="@+id/btnJouer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Jouer"/>
<Button
android:id="@+id/btnBack"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Retour"
android:layout_marginTop="32dp"/>
</LinearLayout>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.Chuzzle" parent="@android:style/Theme.Light.NoTitleBar" />
</resources>
+5
View File
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>
+3
View File
@@ -0,0 +1,3 @@
<resources>
<string name="app_name">RealChuzzle</string>
</resources>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.Chuzzle" parent="@android:style/Theme.Light.NoTitleBar" />
</resources>
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample backup rules file; uncomment and customize as necessary.
See https://developer.android.com/guide/topics/data/autobackup
for details.
Note: This file is ignored for devices older than API 31
See https://developer.android.com/about/versions/12/backup-restore
-->
<full-backup-content>
<!--
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="device.xml"/>
-->
</full-backup-content>
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample data extraction rules file; uncomment and customize as necessary.
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
for details.
-->
<data-extraction-rules>
<cloud-backup>
<!-- TODO: Use <include> and <exclude> to control what is backed up.
<include .../>
<exclude .../>
-->
</cloud-backup>
<!--
<device-transfer>
<include .../>
<exclude .../>
</device-transfer>
-->
</data-extraction-rules>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
</PreferenceScreen>
@@ -0,0 +1,17 @@
package sae.chuzzle;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}