IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

AWT/Swing Java Discussion :

LigneLibre entre deux cases


Sujet :

AWT/Swing Java

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut LigneLibre entre deux cases
    Bonjour à tous,
    je suis entrain de développer une petite interface graphique modélisant un jeu de plateau et je souhaite savoir s'il y a une ou des pièces sur le chemin entre deux cases (les cases sont représentées par des objets de la classe Position que voici) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    public class Position { 
        // La position est définie par un numéro de ligne et un de colonne
        private int ligne;
        private int colonne;
     
        public Position(int ligne, int colonne) { // Constructeur
            this.ligne = ligne;  this.colonne = colonne; 
        } 
     
        // Retourne le numéro de ligne de la position. 
        public int ligne() { return ligne; } 
     
        // Retourne le numéro de colonne de la position. 
        public int colonne() { return colonne; } 
    }
    Grâce à cette classe, je souhaite savoir si une ligne entre deux cases (deux positions) est libre ou non et ceci, horizontalement, verticalement et en diagonale. Voici la fonction que je développe pour celà :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
        public boolean ligneLibre(final Position depart, final Position arrivee) {
     
            // Ligne non libre horizontalement
            if((depart.ligne() == arrivee.ligne())){
                for(int i = Math.abs(arrivee.colonne()-depart.colonne())-(Math.abs(arrivee.colonne()-depart.colonne())-1) ; i<Math.abs(arrivee.colonne()-depart.colonne()) ; i++){
                    if(plateau[depart.ligne()][i] != null){ // S'il y a une pièce
                        return false;
                    }
                }
            }
            // Ligne non libre verticalement
            if((depart.colonne() == arrivee.colonne())){
                for(int i = Math.abs(arrivee.ligne()-depart.ligne())-(Math.abs(arrivee.ligne()-depart.ligne())-1) ; i<Math.abs(arrivee.ligne()-depart.ligne()) ; i++){
                    if(plateau[i][depart.colonne()] != null){ // S'il y a une pièce
                        return false;
                    }
                }
            }
            // Ligne non libre en diagonale
            if(Math.abs(depart.ligne()-arrivee.ligne()) == Math.abs(depart.colonne()-arrivee.colonne())){
                for(int i = Math.abs(arrivee.ligne()-depart.ligne())-(Math.abs(arrivee.ligne()-depart.ligne())-1) ; i<Math.abs(arrivee.ligne()-depart.ligne()) ; i++){
                    for(int j = Math.abs(arrivee.ligne()-depart.ligne()); j >= Math.abs(arrivee.ligne()-depart.ligne())-(Math.abs(arrivee.ligne()-depart.ligne())-1); j--){
                        if(plateau[i][j] != null){ // S'il y a une pièce
                            return false;
                        }
                    }
                }
            }
    	// Sinon, on retourne toujours vrai car ligne libre
    	return true; 
        }
    plateau[][] est un plateau de pièces. La fonction ci-dessus renvoie true si la ligne est libre et false sinon.
    Je pense avoir trouvé pour la ligne horizontale ou verticale, mais la diagonale me pose des problèmes. Si vous avez des idées, merci beaucoup !
    Et si vous voyez des fautes, n'hésitez pas à me le préciser, merci.

  2. #2
    Membre Expert
    Avatar de CheryBen
    Inscrit en
    Mai 2005
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 599
    Par défaut
    Bonjour, en simplifiant ton code, je pense que tu te serais rendu compte de l'erreur. N'est-ce pas plus simple avec des variables intermédiaires?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // Ligne non libre en diagonale
    int deltaLigne = Math.abs(depart.ligne()-arrivee.ligne());
    int deltaColonne = Math.abs(depart.colonne()-arrivee.colonne());
     
    if(deltaLigne == deltaColonne){
        for(int i = 0 ; i < deltaLigne : i++){                
            if(plateau[depart.ligne()+i][depart.colonne()+i] != null){ // S'il y a une pièce
                return false;
            }
        }
    }
    (Reste à faire fonctionner dans tous les cas de figure, ici ça ne marche que si depart.ligne() < arrivee.ligne() et depart.colonne() < arrivee.colonne()

  3. #3
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Si tu cherches pour une diagonale générale (pas seulement celle qui peut être contenue dans un carré), inspire-toi de l'algorithme de Bresenham pour le tracé de segment.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut
    Merci beaucoup pour ces bonnes idées et merci à toi morph41. Si je suis ton principe, il faut que je répète 4 fois ton code avec quelques petites modifs pour avoir les 4cas voulus ?
    Et as-tu remarqué des erreurs pour les lignes libres horizontale et verticale ??
    Encore merci.

  5. #5
    Membre Expert
    Avatar de CheryBen
    Inscrit en
    Mai 2005
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 599
    Par défaut
    Il y a plus simple que de faire 4 cas, mais ce n'est pas facile à expliquer sans faire de code...donc voila ma proposition (à ne pas utiliser , voir la fin du post) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    // Ligne non libre en diagonale
    int deltaLigne = arrivee.ligne()-depart.ligne();
    int deltaColonne = arrivee.colonne()-depart.colonne();
     
    boolean diagonelMontante = true;
    Position newDepart; // fait en sorte qu'on parcours la diagonale de gauche à droite pour savoir si elle monte ou descend
     
    if(deltaLigne > 0) {
        newDepart = depart;
        if(deltaColonne < 0) {
            diagonaleMontante = false;
        }
    }
    else {
        newDepart = arrivee;
        if(deltaColonne > 0) {
            diagonaleMontante = false;
        }
    }
     
    int absDeltaLigne = Math.abs(deltaLigne);
    int absDeltaColonne = Math.abs(deltaColonne);
     
    if(absDeltaLigne == absDeltaColonne){
        if(diagonaleMontante) {
            for(int i = 0 ; i < absDeltaLigne ; i++){                
                if(plateau[newDepart.ligne()+i][newDepart.colonne()+i] != null){ // S'il y a une pièce
                    return false;
                }
            }
        }
        else {
            for(int i = 0 ; i < absDeltaLigne ; i++){                
                if(plateau[newDepart.ligne()-i][newDepart.colonne()-i] != null){ // S'il y a une pièce
                    return false;
                }
            }
        }
    }
    Finallement une fois écrit ce n'est pas aussi simple que ce que je pensais . C'est un bel algo bien incompréhensible pour pas grand chose... autant tester au préalable et faire les 4 cas comme tu le proposais.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut
    En effet, j'ai fais les 4 cas, au moins c'est plutôt clair bien que long. Cependant il reste des erreurs dans mon code.
    Voici ce que j'ai fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    // Chemin non libre en diagonale
            int deltaLigne = Math.abs(depart.ligne()-arrivee.ligne());
            int deltaColonne = Math.abs(depart.colonne()-arrivee.colonne());
            // diagonale vers le haut et la droite
            if((deltaLigne < 0) && (deltaColonne < 0)){
                if(deltaLigne == deltaColonne){
                    for(int i = 1 ; i < deltaLigne ; i++){                
                        if(plateau[depart.ligne()+i][depart.colonne()+i] != null){ // S'il y a une pièce
                            return false;
                        }
                    }
                }
            }
            // diagonale vers le bas et la gauche
            else if((deltaLigne > 0) && (deltaColonne > 0)){
                if(deltaLigne == deltaColonne){
                    for(int i = 1 ; i < deltaLigne ; i++){                
                        if(plateau[depart.ligne()-i][depart.colonne()-i] != null){ // S'il y a une pièce
                            return false;
                        }
                    }
                }
            }
            // diagonale vers le haut et la gauche
            else if((deltaLigne < 0) && (deltaColonne > 0)){
                if(deltaLigne == deltaColonne){
                    for(int i = 1 ; i < deltaLigne ; i++){                
                        if(plateau[depart.ligne()+i][depart.colonne()-i] != null){ // S'il y a une pièce
                            return false;
                        }
                    }
                }
            }
            // diagonale vers le bas et la droite
            else if((deltaLigne > 0) && (deltaColonne < 0)){
                if(deltaLigne == deltaColonne){
                    for(int i = 1 ; i < deltaLigne ; i++){                
                        if(plateau[depart.ligne()-i][depart.colonne()+i] != null){ // S'il y a une pièce
                            return false;
                        }
                    }
                }
            }
    Ceci est seulement pour la diagonale, je n'ai pas changé le reste. A chaque fois que je change de cas, je mets 'else if', penses tu que c'est logique ou vaut mieux que des 'if' ??
    Merci de ton aide

    P.S : Mes boucles 'for' commencent à 1 pour ne tester que les cases entre les deux initialement données.

  7. #7
    Membre Expert
    Avatar de CheryBen
    Inscrit en
    Mai 2005
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 599
    Par défaut
    Tu as tout à fait raison de mettre des else if
    imagine que tu rentres dans le 1er if, en sortant de ce if les autres seraient testés pour rien.

    Bien vu pour commencer à i=1 au lieu de 0

    Attention au if(deltaLigne == deltaColonne)
    tu peux l'écrire au tout début, pas la peine de le faire 4 fois.

    Attention à deltaLigne et deltaColonne
    tu les initialise avec la valeur absolu, donc ils ne seront jamais négatifs. Tu devrais enlever cette valeur absolue et l'utiliser uniquement dans le if(Math.abs(deltaLigne) == Math.abs(deltaColonne)) initial.

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut
    Concernant les 'else if', ta réponse est tout à fait logique, je suis bête de ne pas y a voir pensé tout seul.
    Je te retourne le compliment, bien vu pour les valeurs absolues , j'avais pas vu.

    Merci beaucoup pour ton aide, ca devrait marcher maintenant.
    Bonne soirée !!

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut
    Je viens de me rendre compte que finalement, cela ne marche pas pour les déplacements en diagonal vers le haut , que ce soit du coté gauche ou droit alors que pour les déplacements vers le bas, cela marche parfaitement. C'est incompréhensible, yaurait-il une faute que je n'aurais pas vu ??

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut
    En fin de compte, celà marche bien, il fallait interchanger deltaLigne et deltaColonne pour les déplacements vers le haut.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Selection entre deux cases vides
    Par flom93 dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 24/03/2013, 19h21
  2. Formule pour créer un lien entre deux case
    Par kasse08 dans le forum Access
    Réponses: 1
    Dernier message: 13/08/2012, 19h58
  3. Table, faire la fusion entre deux case
    Par dftrish dans le forum WinDev
    Réponses: 4
    Dernier message: 05/06/2007, 16h22
  4. Connexion entre deux ordi [Débutant]
    Par Ryadus dans le forum Développement
    Réponses: 2
    Dernier message: 12/06/2003, 21h47
  5. Réponses: 5
    Dernier message: 25/03/2003, 19h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo