/** * La classe Grid est utilisée pour générer la grille de blocs * * @version 0.1 * @author Adil HAMMERSCHMIDT & Lucas GRANDJEAN */ import java.io.*; import java.awt.*; import javax.swing.*; import java.util.Random; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; public class Grid extends JPanel { private Random random = new Random(); private int col = 15; private int row = 10; private char charTab[][] = new char[10][15]; private Block blockTab[][] = new Block[10][15]; private String[] connectedCellList = null; private final ArrayList cellNeigbors = new ArrayList<>(); private HUD gameHUD; private int score = 0; /** *Constructeur de la Grid : Génère une grille aléatoire. *@param HUD Nom de l'HUD */ public Grid(HUD gameHUD) { this.gameHUD = gameHUD; this.setLayout(new GridLayout(row,col,0,0)); this.setBackground(Color.WHITE); this.initGrid(); } /** *TODO : Surchage du constructeur avec le fichier * *@param s Nom du fichier *@param HUD Nom de l'HUD */ public Grid(String s, HUD gameHUD) { this.gameHUD = gameHUD; this.setLayout(new GridLayout(row,col,0,0)); try { File grid_file = new File(s); FileInputStream flux = new FileInputStream(grid_file); this.initGrid(flux); try { flux.close(); } catch (IOException e) { System.err.println("Impossible de fermer le fichier " + s + " !"); } } catch (FileNotFoundException e) { System.err.println("Impossible d'ouvrir le fichier " + s + " !"); } } /** * Met en place la grille * */ public void initGrid() { GridMouseHandler gridMouseHandler = new GridMouseHandler(); int i,j; for (i=0; i= 0 && (matrix_X + dx) < (matrix.length) && (matrix_Y + dy) >= 0 && (matrix_Y + dy) < (matrix[0].length) && matrix[matrix_X + dx][matrix_Y + dy] == matrix[matrix_X][matrix_Y] && matrix[matrix_X][matrix_Y] != '1') { // Pour les celulles avec des voisins à la même valeur String neighbor = String.valueOf((matrix_X + dx)) + ";" + String.valueOf((matrix_Y + dy)); if (!this.cellNeigbors.contains(neighbor)) { this.cellNeigbors.add(neighbor); // Récursivité pour les voisins String[] tmp = getMatrixNeighCells(matrix, matrix_X + dx, matrix_Y + dy); if (tmp != null) { for (String str : tmp) { if (!this.cellNeigbors.contains(str)) { this.cellNeigbors.add(str); } } } } } } // On return la liste s'il y'a au moins une cellule voisine aux valeurs adjacente à celle de base if (this.cellNeigbors.size() >= 2) { return this.cellNeigbors.toArray(new String[this.cellNeigbors.size()]); } return null; } /** * Permet de vérifier s'il y'a des lignes vides en dessous de chaques boules. * S'il y'en a, on abaisse d'un niveau la boule et on fait une récursion. *@param j Numéro de colonne */ public void reorganizeCol(int j) { for(int i = 0; i < row-1; i++) { if(blockTab[i][j].getStatus() == 1 && blockTab[i+1][j].getStatus() == 0) { blockTab[i+1][j].setColor(blockTab[i][j].getColor()); blockTab[i+1][j].setStatus(1); blockTab[i][j].setStatus(0); blockTab[i+1][j].setBackground(Color.WHITE); blockTab[i][j].setBackground(Color.WHITE); charTab[i][j]='1'; charTab[i+1][j]=blockTab[i+1][j].getColor(); reorganizeCol(j); } } this.validate(); this.repaint(); } /** * Permet de vérifier si une des colonnes est vide. Si oui, on décale et on relance. *@param i Numéro de col */ public void reorganizeRow(int i) { int nbCount = 0; for(int j = 0; j < row; j++) { if(blockTab[j][i].getStatus() == 0) { nbCount++; } if(nbCount == row) { for(int k = 0; k < row; k++) { blockTab[k][i].setColor(blockTab[k][i+1].getColor()); if(blockTab[k][i+1].getStatus() == 1) { blockTab[k][i].setStatus(1); blockTab[k][i+1].setStatus(0); charTab[k][i]=blockTab[k][i+1].getColor(); } blockTab[k][i].setBackground(Color.WHITE); blockTab[k][i+1].setBackground(Color.WHITE); charTab[k][i+1]='1'; } if(i != col-2) { reorganizeRow(i+1); } } } this.validate(); this.repaint(); } /** * Getter du tableau de la grille * *@return tableau de la grille */ public char[][] getGrid() { return this.charTab; } /** * Un setter avec incrémentation du score * On change le label du score. */ public void addScore(int score) { this.score += score; gameHUD.setScoreLabel(this.score); } /** * Getter du score * @return le score */ public int getScore() { return this.score; } /** * On itère chaque blocs pour savoir s'il leur reste des voisins * Si non, on fait gagner le joueur * @return un bool, true marquant la victoire du joueur. */ public void checkWin() { int moveLeft = 0; for (int i=0; i< blockTab.length; i++) { for (int j=0; j< blockTab[i].length; j++) { cellNeigbors.clear(); connectedCellList = getMatrixNeighCells(getGrid(), i,j); if (connectedCellList != null && connectedCellList.length > 1) moveLeft++; } } if(moveLeft <= 0) endGame(); } /** * Créé l'écran de fin de partie */ public void endGame() { FinalScreen fs = new FinalScreen(score); JFrame topFrame = (JFrame) SwingUtilities.getWindowAncestor(this); topFrame.dispose(); } /** * Mouse Event */ public class GridMouseHandler extends MouseAdapter { /** * Si le joueur passe la souris sur un des Blocks, * on vérifie les cellules voisines du block ponté * puis on change le backGround des cellules voisines */ @Override public void mouseEntered(MouseEvent evt) { Block source = (Block) evt.getSource(); for (int i = 0; i < blockTab.length; i++) { for (int j = 0; j < blockTab[i].length; j++) { if (blockTab[i][j] == source) { cellNeigbors.clear(); connectedCellList = getMatrixNeighCells(getGrid(), i, j); if (connectedCellList != null && connectedCellList.length > 1) { for (String cells : connectedCellList) { int x = Integer.valueOf(cells.split(";")[0]); int y = Integer.valueOf(cells.split(";")[1]); blockTab[x][y].setBackground(Color.YELLOW); } } } } } } /** * Si le joueur quitte le block avec le pointeur de souris, * on remet le background à sa couleur de base */ @Override public void mouseExited(MouseEvent evt) { if (connectedCellList != null) { for (String cells : connectedCellList) { int x = Integer.valueOf(cells.split(";")[0]); int y = Integer.valueOf(cells.split(";")[1]); blockTab[x][y].setBackground(Color.WHITE); } } } /** * Si le joueur clique et relâche la souris, * on désactive le block (en changeant le status), * on remet le fond, on lui assigne une couleur hors du champs * (afin de désactiver le surlignage), et on réorganise les * lignes et colonnes du grid. * On cherche aussi si le joueur a gagné en appelant CheckWin() */ @Override public void mouseReleased(MouseEvent evt) { if (connectedCellList != null) { int ccListSize = connectedCellList.length; for (String cells : connectedCellList) { int x = Integer.valueOf(cells.split(";")[0]); int y = Integer.valueOf(cells.split(";")[1]); charTab[x][y]='1'; blockTab[x][y].setStatus(0); blockTab[x][y].setBackground(Color.WHITE); } addScore((ccListSize-2) * (ccListSize-2)); for(int j = 0; j < col; j++) { reorganizeCol(j); } for(int i = (col-2) ; i >= 0; i--) { reorganizeRow(i); } } checkWin(); mouseEntered(evt); } } }