Derniere version du jeu

This commit is contained in:
lecointre
2026-04-12 16:40:07 +02:00
parent 43cc3c1145
commit 86ff392e75
7 changed files with 734 additions and 244 deletions
+107 -40
View File
@@ -1,24 +1,44 @@
import java.io.Serializable;
import java.util.Random;
/**
* Gère la logique principale du Démineur (le plateau de jeu).
* Initialise les cases, place les mines et contient l'algorithme de révélation.
*/
public class Grille implements Serializable {
/** Tableau à deux dimensions contenant toutes les cases du jeu. */
private Case[][] plateau;
/** Nombre total de lignes de la grille. */
private int lignes;
/** Nombre total de colonnes de la grille. */
private int colonnes;
/** Nombre total de mines cachées dans la grille. */
private int mines;
/** Indique si la partie est bloquée (gagnée ou perdue). */
private boolean partieTerminee;
public Grille(int l, int c, int m) {
this.lignes = l;
this.colonnes = c;
this.mines = m;
/**
* Constructeur de la grille.
* Crée le plateau, place les mines aléatoirement et calcule les voisins.
* @param nbLignes le nombre de lignes souhaité.
* @param nbColonnes le nombre de colonnes souhaité.
* @param nbMines le nombre de mines à placer.
*/
public Grille(int nbLignes, int nbColonnes, int nbMines) {
this.lignes = nbLignes;
this.colonnes = nbColonnes;
this.mines = nbMines;
this.partieTerminee = false;
this.plateau = new Case[this.lignes][this.colonnes];
for (int i = 0; i < this.lignes; i++) {
for (int j = 0; j < this.colonnes; j++) {
this.plateau[i][j] = new Case();
for (int ligne = 0; ligne < this.lignes; ligne++) {
for (int colonne = 0; colonne < this.colonnes; colonne++) {
this.plateau[ligne][colonne] = new Case();
}
}
@@ -26,18 +46,47 @@ public class Grille implements Serializable {
calculerVoisins();
}
/**
* Récupère le nombre de lignes de la grille.
* @return le nombre de lignes.
*/
public int getLignes() { return this.lignes; }
/**
* Récupère le nombre de colonnes de la grille.
* @return le nombre de colonnes.
*/
public int getColonnes() { return this.colonnes; }
public Case getCase(int l, int c) { return this.plateau[l][c]; }
/**
* Accède à une case spécifique du plateau.
* @param indexLigne la ligne de la case cible.
* @param indexColonne la colonne de la case cible.
* @return l'objet Case correspondant.
*/
public Case getCase(int indexLigne, int indexColonne) { return this.plateau[indexLigne][indexColonne]; }
/**
* Vérifie si la partie est verrouillée en état de fin.
* @return true si terminée, false si en cours.
*/
public boolean isPartieTerminee() { return this.partieTerminee; }
/**
* Modifie l'état de fin de partie (verrouillage de la grille).
* @param terminee true pour bloquer le jeu, false pour le débloquer.
*/
public void setPartieTerminee(boolean terminee) { this.partieTerminee = terminee; }
// --- NOUVELLE MÉTHODE : Calcul des mines restantes ---
/**
* Calcule le nombre de mines restantes à trouver selon les drapeaux posés.
* @return la soustraction des mines totales par le nombre d'étoiles posées.
*/
public int getMinesRestantes() {
int drapeaux = 0;
for (int i = 0; i < this.lignes; i++) {
for (int j = 0; j < this.colonnes; j++) {
if (this.plateau[i][j].getMarqueur() == 1) { // 1 = étoile
for (int ligne = 0; ligne < this.lignes; ligne++) {
for (int colonne = 0; colonne < this.colonnes; colonne++) {
if (this.plateau[ligne][colonne].getMarqueur() == Case.MARQUEUR_ETOILE) {
drapeaux++;
}
}
@@ -45,54 +94,68 @@ public class Grille implements Serializable {
return this.mines - drapeaux;
}
/**
* Place aléatoirement le nombre défini de mines sur le plateau vide.
*/
private void placerMines() {
Random rand = new Random();
int minesPlacees = 0;
while (minesPlacees < this.mines) {
int l = rand.nextInt(this.lignes);
int c = rand.nextInt(this.colonnes);
if (!this.plateau[l][c].isMinee()) {
this.plateau[l][c].setMinee(true);
int ligneAleatoire = (int) (Math.random() * this.lignes);
int colonneAleatoire = (int) (Math.random() * this.colonnes);
if (!this.plateau[ligneAleatoire][colonneAleatoire].isMinee()) {
this.plateau[ligneAleatoire][colonneAleatoire].setMinee(true);
minesPlacees++;
}
}
}
/**
* Parcourt la grille pour calculer le nombre de mines autour de chaque case non-minée.
*/
private void calculerVoisins() {
for (int i = 0; i < this.lignes; i++) {
for (int j = 0; j < this.colonnes; j++) {
if (!this.plateau[i][j].isMinee()) {
for (int ligne = 0; ligne < this.lignes; ligne++) {
for (int colonne = 0; colonne < this.colonnes; colonne++) {
if (!this.plateau[ligne][colonne].isMinee()) {
int compteMines = 0;
for (int di = -1; di <= 1; di++) {
for (int dj = -1; dj <= 1; dj++) {
int voisinI = i + di;
int voisinJ = j + dj;
if (voisinI >= 0 && voisinI < this.lignes && voisinJ >= 0 && voisinJ < this.colonnes) {
if (this.plateau[voisinI][voisinJ].isMinee()) {
for (int decalageLigne = -1; decalageLigne <= 1; decalageLigne++) {
for (int decalageColonne = -1; decalageColonne <= 1; decalageColonne++) {
int voisinLigne = ligne + decalageLigne;
int voisinColonne = colonne + decalageColonne;
if (voisinLigne >= 0 && voisinLigne < this.lignes && voisinColonne >= 0 && voisinColonne < this.colonnes) {
if (this.plateau[voisinLigne][voisinColonne].isMinee()) {
compteMines++;
}
}
}
}
this.plateau[i][j].setNbMinesVoisines(compteMines);
this.plateau[ligne][colonne].setNbMinesVoisines(compteMines);
}
}
}
}
public boolean revelerCase(int l, int c) {
Case caseCliquee = this.plateau[l][c];
if (caseCliquee.isRevelee() || caseCliquee.getMarqueur() == 1) return false;
/**
* Révèle une case et déclenche une réaction en chaîne récursive si elle vaut 0.
* @param cibleLigne la ligne de la case à révéler.
* @param cibleColonne la colonne de la case à révéler.
* @return true si une mine a explosé, false sinon.
*/
public boolean revelerCase(int cibleLigne, int cibleColonne) {
Case caseCliquee = this.plateau[cibleLigne][cibleColonne];
if (caseCliquee.isRevelee() || caseCliquee.getMarqueur() == Case.MARQUEUR_ETOILE) return false;
caseCliquee.setRevelee(true);
if (caseCliquee.isMinee()) return true;
if (caseCliquee.getNbMinesVoisines() == 0) {
for (int di = -1; di <= 1; di++) {
for (int dj = -1; dj <= 1; dj++) {
int voisinL = l + di;
int voisinC = c + dj;
if (voisinL >= 0 && voisinL < this.lignes && voisinC >= 0 && voisinC < this.colonnes) {
revelerCase(voisinL, voisinC);
for (int decalageLigne = -1; decalageLigne <= 1; decalageLigne++) {
for (int decalageColonne = -1; decalageColonne <= 1; decalageColonne++) {
int voisinLigne = cibleLigne + decalageLigne;
int voisinColonne = cibleColonne + decalageColonne;
if (voisinLigne >= 0 && voisinLigne < this.lignes && voisinColonne >= 0 && voisinColonne < this.colonnes) {
revelerCase(voisinLigne, voisinColonne);
}
}
}
@@ -100,11 +163,15 @@ public class Grille implements Serializable {
return false;
}
/**
* Vérifie si le joueur a révélé toutes les cases non-minées du plateau.
* @return true si la partie est gagnée, false si elle est toujours en cours.
*/
public boolean estGagnee() {
int casesRevelees = 0;
for (int i = 0; i < this.lignes; i++) {
for (int j = 0; j < this.colonnes; j++) {
if (this.plateau[i][j].isRevelee()) casesRevelees++;
for (int ligne = 0; ligne < this.lignes; ligne++) {
for (int colonne = 0; colonne < this.colonnes; colonne++) {
if (this.plateau[ligne][colonne].isRevelee()) casesRevelees++;
}
}
return casesRevelees == ((this.lignes * this.colonnes) - this.mines);