Files
DEV/SAE21_2024/code_source/Grille.java
2025-12-05 10:28:17 +01:00

207 lines
6.4 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import java.util.Random;
/**
* La classe <code>Grille</code> représente la logique du jeu SameGame.
* Elle gère la création aléatoire des blocs, la détection et suppression de groupes,
* lapplication de la gravité et le décalage des colonnes.
*
* @author Emmanuel Srivastava-Tiamzon & Wael ATIK
* @version 1.8
*/
public class Grille {
private static final int LIGNES = 10;
private static final int COLONNES = 15;
private final char[][] grille;
private Score score;
/**
* Constructeur : initialise la grille avec des blocs aléatoires.
*/
public Grille() {
this.grille = new char[LIGNES][COLONNES];
this.score = new Score();
this.score.setScore(0);
char[] couleurs = {'R', 'V', 'B'};
Random rand = new Random();
for (int i = 0; i < LIGNES; i++) {
for (int j = 0; j < COLONNES; j++) {
grille[i][j] = couleurs[rand.nextInt(couleurs.length)];
}
}
}
/**
* Par polymorphisme on adapte le constructeur pour que l'on puisse jouer avec une grille préféfini.
*/
public Grille(char[][] grille) {
this.grille = grille;
this.score = new Score();
this.score.setScore(0);
}
/**
* Vérifie si un groupe de blocs de même couleur existe à une position donnée.
*
* @param ligne ligne de la case
* @param colonne colonne de la case
* @return true si un groupe valide (taille > 1) existe
*/
public boolean estGroupe(int ligne, int colonne) {
char couleur = grille[ligne][colonne];
if (couleur == ' ') return false;
boolean[][] visite = new boolean[LIGNES][COLONNES];
return tailleGroupe(ligne, colonne, couleur, visite) > 1;
}
/**
* Supprime un groupe de blocs si sa taille est supérieure à 1 et applique la gravité et le décalage.
*
* @param ligne ligne de départ
* @param colonne colonne de départ
*/
public void supprimerGroupe(int ligne, int colonne) {
char couleur = grille[ligne][colonne];
if (couleur == ' ') return;
boolean[][] visite = new boolean[LIGNES][COLONNES];
int taille = tailleGroupe(ligne, colonne, couleur, visite);
if (taille > 1) {
this.score.addToScore((taille - 2) * (taille - 2));
supprimerRec(ligne, colonne, couleur, new boolean[LIGNES][COLONNES]);
appliquerGravite();
appliquerDecalageGauche();
}
}
/**
* Calcule la taille dun groupe avec un parcours en largeur.
*/
private int tailleGroupe(int i, int j, char couleur, boolean[][] visite) {
if (i < 0 || i >= this.LIGNES || j < 0 || j >= this.COLONNES) return 0;
if (visite[i][j] || this.grille[i][j] != couleur) return 0;
visite[i][j] = true;
return 1
+ tailleGroupe(i + 1, j, couleur, visite)
+ tailleGroupe(i - 1, j, couleur, visite)
+ tailleGroupe(i, j + 1, couleur, visite)
+ tailleGroupe(i, j - 1, couleur, visite);
}
/**
* Supprime récursivement un groupe avec un parcours en largeur.
*/
private void supprimerRec(int i, int j, char couleur, boolean[][] visite) {
if (i < 0 || i >= this.LIGNES || j < 0 || j >= this.COLONNES) return;
if (visite[i][j] || this.grille[i][j] != couleur) return;
visite[i][j] = true;
this.grille[i][j] = ' ';
supprimerRec(i + 1, j, couleur, visite);
supprimerRec(i - 1, j, couleur, visite);
supprimerRec(i, j + 1, couleur, visite);
supprimerRec(i, j - 1, couleur, visite);
}
/**
* Applique la gravité : fait tomber les blocs vers le bas.
*/
private void appliquerGravite() {
for (int col = 0; col < this.COLONNES; col++) {
int ligneVide = this.LIGNES - 1;
for (int i = this.LIGNES - 1; i >= 0; i--) {
if (this.grille[i][col] != ' ') {
this.grille[ligneVide][col] = this.grille[i][col];
if (ligneVide != i) this.grille[i][col] = ' ';
ligneVide--;
}
}
}
}
/**
* Décale les colonnes vers la gauche si elles sont vides.
*/
private void appliquerDecalageGauche() {
int colDestination = 0;
for (int colSource = 0; colSource < this.COLONNES; colSource++) {
boolean colonneVide = true;
for (int i = 0; i < this.LIGNES; i++) {
if (this.grille[i][colSource] != ' ') {
colonneVide = false;
break;
}
}
if (!colonneVide) {
if (colDestination != colSource) {
for (int i = 0; i < this.LIGNES; i++) {
this.grille[i][colDestination] = this.grille[i][colSource];
this.grille[i][colSource] = ' ';
}
}
colDestination++;
}
}
}
/**
* Marque toutes les cases dun groupe à partir dune position donnée.
*
* @param couleur couleur du bloc de départ
* @param i ligne de départ
* @param j colonne de départ
* @param surbrillance tableau où marquer les blocs du groupe
*/
public void marquerGroupe(char couleur, int i, int j, boolean[][] surbrillance) {
if (i < 0 || i >= this.LIGNES || j < 0 || j >= this.COLONNES) return;
if (surbrillance[i][j] || this.grille[i][j] != couleur) return;
surbrillance[i][j] = true;
marquerGroupe(couleur, i + 1, j, surbrillance);
marquerGroupe(couleur, i - 1, j, surbrillance);
marquerGroupe(couleur, i, j + 1, surbrillance);
marquerGroupe(couleur, i, j - 1, surbrillance);
}
/**
Vérifie sil reste des groupes de blocs valides
@return true si le jeu est terminé, false sinon*/
public boolean jeuFini() {
for (int i = 0; i < this.LIGNES; i++) {
for (int j = 0; j < this.COLONNES; j++) {
char bloc = this.grille[i][j];
if (bloc != ' ' && estGroupe(i, j)) {
return false;
}
}
}
return true;
}
public char getCase(int i, int j) {
return this.grille[i][j];
}
public char[][] getGrille() {
return this.grille;
}
public int getLignes() {
return this.LIGNES;
}
public int getColonnes() {
return this.COLONNES;
}
}