Optimisation code

Fermé
Marin64 - Modifié le 21 avril 2020 à 20:32
 Marin64 - 22 avril 2020 à 16:23
Bonjour à tous,

je doit coder en java un puissance 4 et je galere sur le tchek pour voir siles 4 pionts sont aligner.
pour l'instant j'ai reussi a cree ca :

static boolean regarderSiCGagne(String[][] plateau) {
    boolean gagner = false;
    // check 4 en colonne :
    for (int regarderColonne = 0; regarderColonne < plateau[0].length; regarderColonne++) {// 0 car matrice rectangulaire
        for (int regarderLigne = 0; regarderLigne < plateau.length - 3; regarderLigne++) {
            if (plateau[regarderLigne][regarderColonne] != " ") {
                if (plateau[regarderLigne][regarderColonne] == plateau[regarderLigne + 1][regarderColonne]
                        && plateau[regarderLigne + 1][regarderColonne] == plateau[regarderLigne
                                + 2][regarderColonne]
                        && plateau[regarderLigne + 2][regarderColonne] == plateau[regarderLigne
                                + 3][regarderColonne]) {
                    gagner = true;
                }
            }
        }
    }
    // check 4 en ligne :
    for (int regarderLigne = 0; regarderLigne < plateau.length; regarderLigne++) {
        for (int regarderColone = 0; regarderColone < plateau[0].length - 3; regarderColone++) {// 0 car rectangulaire
            if (plateau[regarderLigne][regarderColone] != " ") {
                if (plateau[regarderLigne][regarderColone] == plateau[regarderLigne][regarderColone + 1]
                        && plateau[regarderLigne][regarderColone + 1] == plateau[regarderLigne][regarderColone + 2]
                        && plateau[regarderLigne][regarderColone + 2] == plateau[regarderLigne][regarderColone
                                + 3]) {
                    gagner = true;
                }
            }
        }
    }
    // check 4 en diagonale dans le sens "\" :
    for (int regarderLigne = 0; regarderLigne < plateau.length - 3; regarderLigne++) {
        for (int regarderColonne = 0; regarderColonne < plateau[0].length - 3; regarderColonne++) {// 0 car
                                                                                                   // rectangulaire
            if (plateau[regarderLigne][regarderColonne] != " ") {
                if (plateau[regarderLigne][regarderColonne] == plateau[regarderLigne + 1][regarderColonne + 1]
                        && plateau[regarderLigne + 1][regarderColonne
                                + 1] == plateau[regarderLigne + 2][regarderColonne + 2]
                        && plateau[regarderLigne + 2][regarderColonne
                                + 2] == plateau[regarderLigne + 3][regarderColonne + 3]) {
                    gagner = true;
                }
            }
        }
    }
    // check 4 en diagonale dans le sens "/" :
    for (int regarderLigne = 0; regarderLigne < plateau.length - 3; regarderLigne++) {
        for (int regarderColonne = 3; regarderColonne < plateau[0].length; regarderColonne++) {// 0 car rectangulaire
            if (plateau[regarderLigne][regarderColonne] != " ") {
                if (plateau[regarderLigne][regarderColonne] == plateau[regarderLigne + 1][regarderColonne - 1]
                        && plateau[regarderLigne + 1][regarderColonne
                                - 1] == plateau[regarderLigne + 2][regarderColonne - 2]
                        && plateau[regarderLigne + 2][regarderColonne
                                - 2] == plateau[regarderLigne + 3][regarderColonne - 3]) {
                    gagner = true;
                }
            }
        }
    }

    return gagner;
}

avez vous des idee pour optimiser ce code ?
merci d'avance pour votre aide
Configuration: Windows / Edge 81.0.416.60
A voir également:

3 réponses

Salut,
pour optimiser penser objet et méthodes.
Là vous êtes en procédural ce qui en Java correspondrais à avoir une voiture de course pour rester en première.

La structure objet(ou POO/OOP en anglais) permet d'organiser des éléments de la vie réelle(ou conceptuels comme ici) et concrète en objets qui regroupent ces éléments.
Leur interaction éventuelle est possible par la présence d’accesseurs et régulateurs(GET et SET).

Pour le reste au niveau récursivité de vos vérifications il y a des améliorations possibles en tenant compte de 2 points uniquement à relier par une droite(exprimé par leur ligne colonne dans un puissance 4), si ces 2 points correspondent à la ligne on peut vérifier les autres sinon il n'y a pas de ligne et pas de puissance 4 donc ça sert à rien de vérifier le reste.
Si les 2 points vérifiés sont les 2 les plus opposés(horizontalement ou verticalement) c'est encore plus évident et rapide à faire.

Décomposer en plusieurs méthodes chaque étapes est la clé qui peut rendre le code plus clair, plus simple et plus efficace:
on ne vérifies pas que tous les 4 points sont alignés mais simplement que 2 points peuvent être sur la même ligne.
Et si ces 2 point s sont sur la même ligne il faut vérifier à nouveau pour les autres points avec des critères plus strict car les points correspondant possibles sont plus limités.
En espérant avoir été clair.
1
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
Modifié le 22 avril 2020 à 09:29
Bonjour,

Tout d'abord il faut revoir ta structure de données, les String sont fait pour manipuler des chaînes de caractères, ici tu as trois valeurs possibles (Rouge, Jaune ou Vide), ici une enum serait plus pertinente.
NB. La comparaison de String ne devrait jamais se faire avec
==
(il faut utiliser la méthode equals)

Ensuite, tu as des copier-coller dans ton code, il faut donc penser à le factoriser via des appels à des sous-méthodes. Cela te permettra également de mettre en place des ruptures dans tes boucles pour optimiser l'exécution du programme. Car en l'état toutes les combinaisons sont systématiquement testées, quand bien même on aurait un gagnant dès le premier test...

Ci-dessous, un exemple de code. Au passage j'en profite pour remonter les coordonnées de la ligne gagnante (cela peut être utile pour la mettre en évidence dans une interface graphique).

import java.util.Arrays;

public class Puissance4 {

    /** Taille des lignes pour gagner */
    public static final int SIZE = 4;

    /** Largeur de la grille de jeu */
    public static final int WIDTH = 7;

    /** Hauteur de la grille de jeu */
    public static final int HEIGHT = 6;

    /** Couleur des cases de la grille */
    public static enum Color {
        RED, YELLOW
    }

    /**
     * Contrôle de la victoire d'un joueur.
     * 
     * @param game   toute la grille
     * @param player la couleur du joueur
     * @return les coordonnées d'une ligne victorieuse, ou null s'il y en a aucune
     */
    public static int[][] getVictoriousLine(Color[][] game, Color player) {
        int[][] victoriousLine = getVictoriousLine(game, player, 0, WIDTH-SIZE, 1, 0, HEIGHT-1, 0); // horizontal
        if (victoriousLine == null)
            victoriousLine = getVictoriousLine(game, player, 0, WIDTH-1, 0, 0, HEIGHT-SIZE, 1); // vertical
        if (victoriousLine == null)
            victoriousLine = getVictoriousLine(game, player, 0, WIDTH-SIZE, 1, 0, HEIGHT-SIZE, 1); // ascending
        if (victoriousLine == null)
            victoriousLine = getVictoriousLine(game, player, SIZE-1, WIDTH-1, -1, 0, HEIGHT-SIZE, 1); // descending
        return victoriousLine;
    }

    /**
     * Contrôle de la victoire d'un joueur pour une orientation de ligne donnée.
     * 
     * @param game   toute la grille
     * @param player la couleur du joueur
     * @param minX   le numéro de colonne de la première case à tester
     * @param maxX   le numéro de colonne de la dernière case à tester
     * @param dx     le déplacement de colonne (-1, 0 ou +1) pour aller d'une case à l'autre
     * @param minY   le numéro de ligne de la première case à tester
     * @param maxY   le numéro de ligne de la dernière case à tester
     * @param dy     le déplacement de colonne (0 ou +1) pour aller d'une case à l'autre
     * @return les coordonnées d'une ligne victorieuse, ou null s'il y en a aucune
     */
    private static int[][] getVictoriousLine(Color[][] game, Color player, int minX, int maxX, int dx, int minY, int maxY, int dy) {
        for (int y = minY; y <= maxY; y++) {
            for (int x = minX; x <= maxX; x++) {
                int[][] victoriousLine = getVictoriousLine(game, player, x, dx, y, dy);
                if (victoriousLine != null)
                    return victoriousLine;
            }
        }
        return null;
    }

    /**
     * Contrôle de la victoire d'une ligne pour un joueur donné.
     * 
     * @param game   toute la grille
     * @param player la couleur du joueur
     * @param minX   le numéro de colonne de la première case à tester
     * @param dx     le déplacement de colonne (-1, 0 ou +1) pour aller d'une case à l'autre
     * @param minY   le numéro de ligne de la première case à tester
     * @param dy     le déplacement de colonne (0 ou +1) pour aller d'une case à l'autre
     * @return les coordonnées de la ligne si elle est gagnante, ou null si elle est perdante
     */
    private static int[][] getVictoriousLine(Color[][] game, Color player, int minX, int dx, int minY, int dy) {
        int[][] victoriousLine = new int[SIZE][2];
        for (int i = 0, x = minX, y = minY; i < SIZE; i++, x += dx, y += dy) {
            victoriousLine[i][0] = x;
            victoriousLine[i][1] = y;
            if (game[x][y] != player)
                return null;
        }
        return victoriousLine;
    }

    public static void main(String[] args) {
        Color[][] game = new Color[WIDTH][HEIGHT];
        game[5][1] = game[4][2] = game[3][3] = game[2][4] = Color.YELLOW;
        System.out.println(Arrays.deepToString(getVictoriousLine(game, Color.RED))); // null
        System.out.println(Arrays.deepToString(getVictoriousLine(game, Color.YELLOW))); // (5,1) (4,2) (3,3) (2,4)
    }
}

1
Merci beaucoup pour vos réponses.
Je vais essayer de passer par vos méthode. Je vient de commencer le java et c'est pas evident ; )
0