SAE21_2021/Grille.java

449 lines
11 KiB
Java
Raw Permalink Normal View History

2022-04-27 16:16:34 +02:00
import javax.swing.*;
import java.awt.*;
2022-04-28 16:50:06 +02:00
import java.util.Random;
2022-05-24 13:49:09 +02:00
import java.util.Arrays;
2022-05-25 15:36:29 +02:00
/**
* La classe <code>Grille</code> correspond à une grille de jeu
* elle genère un tableau de case et une Bannière
* @version 1.1
* @author Kayyissa Haïssous
*/
2022-05-21 18:41:24 +02:00
public class Grille extends JPanel{
2022-05-25 15:36:29 +02:00
/**
* Banniere
*/
2022-05-21 17:53:19 +02:00
private Banniere banniere;
2022-05-25 15:36:29 +02:00
/**
* Dimension de la grille
*/
2022-04-27 16:16:34 +02:00
private Dimension grilleSize=new Dimension(0,0);
2022-05-25 15:36:29 +02:00
/**
* tableau des cases de la partie
*/
private Case[] plateau;
2022-05-25 15:36:29 +02:00
/**
* nombre de colonnes
*/
2022-05-10 11:10:31 +02:00
private int colonnes;
2022-05-25 15:36:29 +02:00
/**
* nombre de lignes
*/
2022-05-24 13:49:09 +02:00
private int lignes;
2022-05-25 15:36:29 +02:00
/**
* nombre de cases
*/
2022-05-05 22:29:04 +02:00
private int taille;
2022-05-25 15:36:29 +02:00
/**
* nombre de mines
*/
2022-05-05 22:29:04 +02:00
private int mines;
2022-05-25 15:36:29 +02:00
/**
* nombre de mines restantes à trouver
*/
2022-05-05 23:13:52 +02:00
private int minesLeft;
2022-05-25 15:36:29 +02:00
/**
* statut si la partie est en cours ou non
*/
2022-05-17 23:04:53 +02:00
private boolean enJeu;
2022-05-25 15:36:29 +02:00
/**
* fenetre de Jeu
*/
2022-05-21 22:17:25 +02:00
private FrameJeu fenetre;
2022-04-27 16:16:34 +02:00
2022-05-25 15:36:29 +02:00
/**
* Définition du constructeur qui correspond à une nouvelle grille de jeu
* @param lignes nombre de lignes
* @param colonnes nombre de colonnes
* @param mines nombre de mines
* @param fenetre fenetre de Jeu
* @param menu fenetre du menu rattaché
*/
2022-05-23 19:32:09 +02:00
public Grille(int lignes, int colonnes, int mines, FrameJeu fenetre, FrameMenu menu){
2022-05-21 22:17:25 +02:00
super();
this.colonnes=colonnes;
2022-05-24 13:49:09 +02:00
this.lignes=lignes;
2022-05-21 22:17:25 +02:00
this.taille=lignes*colonnes;
this.mines=mines;
this.minesLeft=mines;
this.enJeu=true;
this.fenetre=fenetre;
2022-05-25 08:47:55 +02:00
2022-04-27 16:16:34 +02:00
// Découpage de l'espace en fonction des paramètres pour la mise en place de la grille
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
2022-04-28 16:50:06 +02:00
this.grilleSize = new Dimension(((screenSize.height*3/4)/lignes)*colonnes, screenSize.height*3/4 );
2022-04-27 17:42:05 +02:00
Dimension caseSize = new Dimension(this.grilleSize.height/lignes,this.grilleSize.height/lignes);
2022-04-27 16:16:34 +02:00
GridLayout damier = new GridLayout(lignes,colonnes);
Banniere banniere = new Banniere(mines,this.fenetre, menu, this);
2022-05-21 22:17:25 +02:00
this.banniere=banniere;
this.setLayout(damier);
this.setSize(grilleSize);
2022-05-21 22:17:25 +02:00
2022-05-04 23:03:02 +02:00
// On génère le plateau contenant les cases
2022-05-16 20:19:51 +02:00
GenererPlateau(caseSize);
2022-04-27 16:16:34 +02:00
2022-04-28 16:50:06 +02:00
// Instalation des mines
// Création d'un tableau de nombres aléatoires pour savoir où les placer
int[] caseMine = new int[mines];
2022-04-29 10:51:55 +02:00
Random rand = new Random();
// On initialise les emplacements des mines
2022-05-05 22:29:04 +02:00
caseMine[0] = rand.nextInt(taille);
for (int i=1;i<mines;i++){
2022-05-05 22:29:04 +02:00
caseMine[i] = rand.nextInt(taille);
2022-04-29 10:51:55 +02:00
// On vérifie que la case n'a pas déjà été minée, auquel cas on change de case
for (int j=0;j<=(i-1);j++){
2022-04-29 10:51:55 +02:00
if (caseMine[i]==caseMine[j]){
2022-05-05 22:29:04 +02:00
caseMine[i] = rand.nextInt(taille);
j=-1;
2022-04-27 16:16:34 +02:00
}
2022-04-28 16:50:06 +02:00
}
}
2022-05-04 23:03:02 +02:00
// On place maintenant les mines sur la plateau en fixant la variable minee des cases à true
2022-05-05 22:29:04 +02:00
for (int i=0; i<taille;i++){
2022-04-28 16:50:06 +02:00
for (int j=0;j<mines;j++){
if (caseMine[j]==i){
2022-05-04 23:03:02 +02:00
plateau[i].setMine();
2022-04-28 16:50:06 +02:00
}
}
}
2022-05-25 08:47:55 +02:00
// On défini l'entourage de chaque case
SetEntourage(caseMine);
// On place les cases à leur état actuel dans la grille
AfficherPlateau();
2022-05-25 13:37:32 +02:00
// On initialise le compteur de mines restantes
2022-05-25 08:47:55 +02:00
this.banniere.setMinesLeft(this.minesLeft);
}
2022-05-25 15:36:29 +02:00
/**
* Définition du constructeur qui correspond au chargement d'une grille sauvegardé
* @param lignes nombre de lignes
* @param colonnes nombre de colonnes
* @param donnees sauvegarde
* @param mines nombre de mines
* @param fenetre fenetre de Jeu
* @param menu fenetre du menu rattaché
*/
2022-05-25 08:47:55 +02:00
public Grille (int lignes,int colonnes,SaveManager.SaveData donnees,int mines,FrameJeu fenetre, FrameMenu menu){
super();
this.colonnes=colonnes;
this.lignes=lignes;
this.taille=lignes*colonnes;
2022-05-25 13:37:32 +02:00
this.mines=mines;
2022-05-25 08:47:55 +02:00
this.minesLeft=mines;
this.enJeu=true;
this.fenetre=fenetre;
// Découpage de l'espace en fonction des paramètres pour la mise en place de la grille
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.grilleSize = new Dimension(((screenSize.height*3/4)/lignes)*colonnes, screenSize.height*3/4 );
Dimension caseSize = new Dimension(this.grilleSize.height/lignes,this.grilleSize.height/lignes);
GridLayout damier = new GridLayout(lignes,colonnes);
Banniere banniere = new Banniere(mines,this.fenetre, menu, this);
this.banniere=banniere;
this.setLayout(damier);
this.setSize(grilleSize);
// On initialise un plateau de cases
GenererPlateau(caseSize);
2022-05-25 10:42:04 +02:00
// On créer un tableau pour y placer les cases minées
2022-05-25 08:47:55 +02:00
int[] caseMine = new int[mines];
int j=0;
2022-05-25 10:42:04 +02:00
// On lit maintenant les données pour fixer certains attributs et savoir où sont les mines
2022-05-25 08:47:55 +02:00
for (int i=0;i<=taille-1;i++){
if (Integer.parseInt(donnees.cases.substring(i,i+1))==1){
plateau[i].setMine();
caseMine[j]=i;
j++;
} else if (Integer.parseInt(donnees.cases.substring(i,i+1))==2){
2022-05-25 13:37:32 +02:00
plateau[i].setReperee(true,1);
2022-05-25 08:47:55 +02:00
} else if (Integer.parseInt(donnees.cases.substring(i,i+1))==3){
plateau[i].setMine();
2022-05-25 10:42:04 +02:00
caseMine[j]=i;
j++;
2022-05-25 13:37:32 +02:00
plateau[i].setReperee(true,1);
2022-05-25 08:47:55 +02:00
}
}
2022-05-25 10:42:04 +02:00
2022-05-25 08:47:55 +02:00
// On détermine l'entourage de chaque case
SetEntourage(caseMine);
2022-05-25 10:42:04 +02:00
// On affiche les cases qui doivent être visibles
for (int n=0;n<=taille-1;n++){
if (Integer.parseInt(donnees.cases.substring(n,n+1))==4){
plateau[n].setVisible();
}
}
2022-05-25 08:47:55 +02:00
// On affiche la grille
AfficherPlateau();
2022-05-25 13:37:32 +02:00
// On initialise le compteur de mines restantes
this.banniere.setMinesLeft(this.minesLeft);
}
2022-05-25 08:47:55 +02:00
2022-05-25 15:36:29 +02:00
/**
*Méthode pour Génerer le plateau
* @param caseSize taille d'une case
*/
2022-05-25 08:47:55 +02:00
protected void GenererPlateau(Dimension caseSize){
this.plateau= new Case[this.taille];
for (int i=0;i<this.taille;i++){
this.plateau[i]= new Case(this,caseSize);
}
}
2022-05-25 15:36:29 +02:00
/**
*Méthode pour Afficher le plateau
*/
2022-05-25 08:47:55 +02:00
protected void AfficherPlateau(){
for (int i=0;i<this.taille;i++){
this.add(this.plateau[i]);
}
}
2022-05-25 15:36:29 +02:00
/**
*Méthode pour établir le nombre de mines autour de chaque case
* @param caseMine tableau des cases minées
*/
2022-05-25 08:47:55 +02:00
protected void SetEntourage(int[] caseMine){
2022-05-04 23:03:02 +02:00
// On cherche à connaître le nombre de mines autour de chaque case
2022-05-05 22:29:04 +02:00
for (int i=0;i<taille;i++){
2022-05-04 23:03:02 +02:00
int entourage = 0;
// On vérifie pour chaque case qu'elle n'est pas déjà à l'extrémité du plateau où on cherche une case
// Mine au dessus à droite
2022-05-10 11:52:26 +02:00
if ((i>=colonnes)&&(i%colonnes!=colonnes-1)){
for (int j=0;j<mines;j++){
2022-05-04 23:03:02 +02:00
if (caseMine[j]==i-colonnes+1){
entourage+=1;
}
2022-04-28 17:57:18 +02:00
}
}
2022-05-04 23:03:02 +02:00
// Mine au dessus à gauche
2022-05-10 11:52:26 +02:00
if ((i>=colonnes)&&(i%colonnes!=0)){
for (int j=0;j<mines;j++){
if (caseMine[j]==i-colonnes-1){
2022-05-04 23:03:02 +02:00
entourage+=1;
}
2022-04-28 17:57:18 +02:00
}
}
2022-05-04 23:03:02 +02:00
// Mine en dessous à droite
2022-05-10 11:52:26 +02:00
if ((i<taille-colonnes)&&(i%colonnes!=colonnes-1)){
for (int j=0;j<mines;j++){
2022-05-04 23:03:02 +02:00
if (caseMine[j]==i+colonnes+1){
entourage+=1;
}
2022-04-28 17:57:18 +02:00
}
}
2022-05-04 23:03:02 +02:00
// Mine en bas à gauche
2022-05-10 11:52:26 +02:00
if ((i<taille-colonnes)&&(i%colonnes!=0)){
for (int j=0;j<mines;j++){
if (caseMine[j]==i+colonnes-1){
2022-05-04 23:03:02 +02:00
entourage+=1;
}
2022-04-28 17:57:18 +02:00
}
}
2022-05-04 23:03:02 +02:00
// Mine au dessus
2022-05-10 11:52:26 +02:00
if (i>=colonnes){
for (int j=0;j<mines;j++){
if (caseMine[j]==i-colonnes){
2022-05-04 23:03:02 +02:00
entourage+=1;
}
2022-04-28 17:57:18 +02:00
}
}
2022-05-04 23:03:02 +02:00
// Mine en dessous
2022-05-10 11:52:26 +02:00
if (i<taille-colonnes){
for (int j=0;j<mines;j++){
if (caseMine[j]==i+colonnes){
2022-05-04 23:03:02 +02:00
entourage+=1;
}
2022-04-28 17:57:18 +02:00
}
}
2022-05-04 23:03:02 +02:00
// Mine à droite
if (i%colonnes!=colonnes-1){
for (int j=0;j<mines;j++){
if (caseMine[j]==i+1){
2022-05-04 23:03:02 +02:00
entourage+=1;
}
}
2022-05-04 23:03:02 +02:00
}
// Mine à gauche
if (i%colonnes!=0){
for (int j=0;j<mines;j++){
if (caseMine[j]==i-1){
2022-05-04 23:03:02 +02:00
entourage+=1;
}
2022-04-28 17:57:18 +02:00
}
}
2022-05-04 23:03:02 +02:00
plateau[i].setEntourage(entourage);
2022-04-28 17:57:18 +02:00
}
2022-04-29 10:03:05 +02:00
}
2022-04-27 16:16:34 +02:00
2022-05-25 15:36:29 +02:00
/**
* Méthode pour obtenir la taille de la grille de jeu
* @return grilleSize
*/
2022-05-04 23:03:02 +02:00
public Dimension getGrilleSize(){
2022-04-27 16:16:34 +02:00
return grilleSize;
}
2022-05-05 22:29:04 +02:00
2022-05-25 15:36:29 +02:00
/**
*Méthode déterminant le nombre de mines restantes
*/
2022-05-05 22:29:04 +02:00
public void MinesLeft(){
2022-05-05 23:13:52 +02:00
this.minesLeft=this.mines;
2022-05-10 11:52:26 +02:00
for (int i=0;i<this.taille;i++){
2022-05-05 22:29:04 +02:00
if(plateau[i].getReperee()==true){
2022-05-05 23:13:52 +02:00
this.minesLeft-=1;
2022-05-05 22:29:04 +02:00
}
}
2022-05-05 23:13:52 +02:00
this.banniere.setMinesLeft(this.minesLeft);
2022-05-05 22:29:04 +02:00
}
2022-05-10 11:10:31 +02:00
2022-05-25 15:36:29 +02:00
/**
*Méthode déterminant les conditions de victoire
*/
2022-05-10 11:52:26 +02:00
public void verifVictoire(){
2022-05-21 17:30:12 +02:00
// Compte le nombre de cases visibles
2022-05-16 20:19:51 +02:00
int casesVisibles=0;
2022-05-10 11:52:26 +02:00
for (int i=0;i<this.taille;i++){
2022-05-16 20:19:51 +02:00
if(plateau[i].getVisible()==true){
casesVisibles+=1;
2022-05-10 11:52:26 +02:00
}
}
2022-05-21 17:30:12 +02:00
// Lance la victoire si toutes les cases non minées sont révélées
2022-05-16 20:19:51 +02:00
if (taille-mines==casesVisibles){
for (int i=0;i<taille;i++){
this.plateau[i].setVictoire();
}
2022-05-21 18:41:24 +02:00
this.banniere.setVictoire();
2022-05-10 11:52:26 +02:00
}
}
2022-05-25 15:36:29 +02:00
/**
*Méthode pour montrer la défaite
*/
2022-05-23 10:47:54 +02:00
public void Defaite(){
// Montre toutes les cases du plateau
for (int i=0;i<this.taille;i++){
this.plateau[i].setVisible();
}
this.banniere.setDefaite();
2022-05-23 12:56:40 +02:00
}
2022-05-23 10:47:54 +02:00
2022-05-25 15:36:29 +02:00
/**
* Methode pour récupérer le plateau de jeu
* @return copie du tableau de cases
*/
2022-05-16 20:19:51 +02:00
public Case[] getPlateau(){
2022-05-24 13:49:09 +02:00
return Arrays.copyOf(this.plateau,this.taille);
}
2022-05-25 15:36:29 +02:00
/**
*Méthode pour récupérer la taille de la grille
* @return la taille de la grille
*/
2022-05-24 13:49:09 +02:00
public Dimension getDimensionGrille(){
Dimension grilleSize= new Dimension(this.colonnes, this.lignes);
return grilleSize;
2022-05-16 20:19:51 +02:00
}
2022-05-25 15:36:29 +02:00
/**
*Méthode pour savoir combien de mines sont dans la grille
* @return this.mines le nombre de mines
*/
2022-05-25 08:47:55 +02:00
public int getMines(){
return this.mines;
}
2022-05-25 15:36:29 +02:00
/**
*Méthode pour rendre visibles les cases autour d'un 0
* @param panel case autour de laquelle il faut révéler les cases
*/
2022-05-10 11:10:31 +02:00
public void setEntourageVisible(Case panel){
for(int i=0; i<this.taille;i++){
if (plateau[i]==panel){
// Mine au dessus à droite
2022-05-10 11:52:26 +02:00
if ((i>=colonnes)&&(i%colonnes!=colonnes-1)){
2022-05-10 11:10:31 +02:00
for (int j=0;j<mines;j++){
plateau[i-colonnes+1].setVisible();
}
}
// Mine au dessus à gauche
2022-05-10 11:52:26 +02:00
if ((i>=colonnes)&&(i%colonnes!=0)){
2022-05-10 11:10:31 +02:00
for (int j=0;j<mines;j++){
plateau[i-colonnes-1].setVisible();
}
}
// Mine en dessous à droite
if ((i<taille-colonnes)&&(i%colonnes!=colonnes-1)){
for (int j=0;j<mines;j++){
plateau[i+colonnes+1].setVisible();
}
}
// Mine en bas à gauche
if ((i<taille-colonnes)&&(i%colonnes!=0)){
for (int j=0;j<mines;j++){
plateau[i+colonnes-1].setVisible();
}
}
// Mine au dessus
2022-05-10 11:52:26 +02:00
if (i>=colonnes){
2022-05-10 11:10:31 +02:00
for (int j=0;j<mines;j++){
plateau[i-colonnes].setVisible();
}
}
// Mine en dessous
if (i<taille-colonnes){
for (int j=0;j<mines;j++){
plateau[i+colonnes].setVisible();
}
}
// Mine à droite
if (i%colonnes!=colonnes-1){
for (int j=0;j<mines;j++){
plateau[i+1].setVisible();
}
}
// Mine à gauche
if (i%colonnes!=0){
for (int j=0;j<mines;j++){
plateau[i-1].setVisible();
}
}
}
}
}
2022-05-17 11:11:29 +02:00
2022-05-25 15:36:29 +02:00
/**
*Méthode qui renvoie la banniere d'état de la partie
* @return this.banniere
*/
2022-05-21 17:53:19 +02:00
public Banniere getBanniere(){
2022-05-17 11:11:29 +02:00
return this.banniere;
}
2022-05-25 15:36:29 +02:00
/**
*Méthode qui défini si la partie est en cours ou non
* @param enJeu statut de la partie
*/
2022-05-17 23:04:53 +02:00
public void setEnJeu(boolean enJeu){
this.enJeu=enJeu;
}
2022-05-25 15:36:29 +02:00
/**
*Méthode qui renvoie si la partie est en cours ou non
* @return statut enjeu
*/
2022-05-17 23:04:53 +02:00
public boolean getEnJeu(){
return this.enJeu;
}
2022-04-27 16:16:34 +02:00
}