Remet moi le bout de code fini que tu as fait (celui avec les setCoupPossible) que je regarde qui ne va pas ?
Version imprimable
mets moi aussi le code de la méthode getCase() de la classe Echiquier
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 for (int ligne = 0; ligne < 8; ligne++) { for (int colonne = 0; colonne < 8; colonne++) { Position pos = new Position(colonne,ligne); Deplacement deplacement=new Deplacement(temp,pos); if (pieceTampon.estValide(deplacement)) { if(e.captureParUnPionPossible(deplacement)){ tab[colonne][ligne].setCoupPossible(CoupPossible.prisepion);} else if (tab[colonne][ligne].estOccupe()){ tab[colonne][ligne].setCoupPossible(null);} else { tab[colonne][ligne].setCoupPossible(CoupPossible.mouvement); } } else { tab[colonne][ligne].setCoupPossible(null); } } }
Merci..Code:
1
2
3 public Case getCase(int colonne, int ligne) { return plateau[colonne][ligne]; }
je m'en doutais : je t'ai fait créer une classe Case extends JLabel, mais j'ai dans l'idée que tu as confondu les deux classes, parce que j'ai vu dans tes posts précédent que tu avais ajouté dans cette classe des méthodes genre estOccupe etc...Code:
1
2
3 public Case getCase(int colonne, int ligne) { return plateau[colonne][ligne]; }
si tu avais déjà une classe Case, il ne fallait pas la remplacer par celle là : mais changer le nom, genre CaseLabel extends JLabel
donc quand tu appelles tab[i][j].estOccupe() tu obtiens toujours false, parce que Echiquier gère ses propres instances de Case, qui ne sont pas celles qu'on créé quand on construit l'échiquier graphique
tu vois ce que je veux dire :
- remet le code d'origine de la classe Case (si tu avais modifié des trucs dedans, remet les)
- recréé une classe CaseLabel extends JLabel sur le modèle de ce que je t'avais dit (mais que j'avais appelé Case)
ensuite il faut modifier le test de condition :
remplace la condition en rouge par la dernière condition qu'on a vu :Code:
1
2
3
4
5
6
7
8
9
10
11 if (pieceTampon.estValide(deplacement)) { if(e.captureParUnPionPossible(deplacement)){ tab[colonne][ligne].setCoupPossible(CoupPossible.prisepion);} else if (tab[colonne][ligne].estOccupe()){ tab[colonne][ligne].setCoupPossible(null);} else { tab[colonne][ligne].setCoupPossible(CoupPossible.mouvement); } } else { tab[colonne][ligne].setCoupPossible(null); }
et en orange parCode:if (e.getCase(colonne,ligne).estOccupe(pieceTampon.getCouleur().equals("blanc") ? "noir" : "blanc")
Code:e.getCase(colonne,ligne).estOccupe()
J'ai remis a l'état initial et changer le texte orange et rouge par ce que vous avez gentillement proposé.
Mon fichier case.java contient donc :
Code:
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87 package projet; import java.awt.Color; import javax.swing.JLabel; import projet.Piece; public class Case { private Piece piece; public Case() { //constructeur par defaut } public Case(Piece piece) { this.piece = piece; } public Piece getPiece() { //sert a retourner la piece sur la case ou return null si case vide return piece; } public void setPiece(Piece piece) { //permet d'inserer la piece dans une case this.piece = piece; } public boolean estOccupe() { //sert a savoir si la case est occuper ou non return (piece != null); } public boolean estOccupe(String couleur) { //Si il n'y a pas de piece sur la case c'est que la case n'est pas occuper au contraire la fonctioin retournera la piece de la couleur en question. if (piece == null) return false; else return (piece.getCouleur().equals(couleur)); } } class CaseLabel extends JLabel { private static final long serialVersionUID = 1L; private boolean blanc; // false si case noire, true si case blanche private CoupPossible couppossible; public enum CoupPossible { mouvement, prisepion, roque } private void setCouleur() { if ( couppossible!=null ) switch(couppossible) { case mouvement: setBackground(new Color(0, 240, 0)); //couleur d'un coup possible : vert break; case prisepion: setBackground(new Color(255, 0, 0)); //couleur d'un coup possible avec prise de pion : rouge break; case roque: setBackground(new Color(247, 255, 60)); //couleur d'un roque possible : jaune break; } else if (blanc) setBackground(new Color(255, 255, 255)); //couleur des cases : blanc else setBackground(new Color(153, 153, 153)); //couleur des cases : noir } public void setCoupPossible(CoupPossible couppossible) { this.couppossible=couppossible; setCouleur(); } public void setCouleur(boolean blanc) { this.blanc=blanc; setCouleur(); } }
Je ne suis pas sur pour CaseLabel...
oui c'est ça
il faut pas que tu oublies de modifier la création des cases !
le code ressemblait à ça :
evidemment le truc en rouge devient :Code:
1
2
3
4
5
6
7 //J'attribue la couleur aux JLabels int a = 1; for (int ligne = 0; ligne < 8; ligne++) { a = a == 1 ? 0 : 1; for (int colonne = 0; colonne < 8; colonne++) { tab[colonne][ligne] = new Case(); panelGrille.add(tab[colonne][ligne]); // ajouter au Panel
et bien sur la déclaration du tableau tab !Code:new CaseLabel()
J'ai remplacer ici :
J'ai tester et cela m'affiche bien les choix disponibles en vert et miracle !! Les cases occupé sont marqué de rien !Code:
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90 import java.awt.Color; //cette classe permet de faire l'inteface graphique avec les boutons reset et commencer ainsi que le champs texte informant que c'est sont tour et des Jpanel pour recuperer les pions manger public class FenetreJeu extends JFrame { private static final long serialVersionUID = 42L; //serialVersionUID permet d'affecter un numéro de version à la classe //construction tableau echequier private Echiquier e; // echiquier private CaseLabel[][] tab; // tableau de cases private JPanel panelControle = new JPanel(); // panel du haut private JPanel panelGrille = new JPanel(); // panel du bas ( grille ) GridLayout gridLayout1 = new GridLayout(); private JButton boutonDebuter = new JButton(); private JTextField champTexte = new JTextField(); private JButton boutonfin = new JButton(); //Constructeur public FenetreJeu() { try { initialisationPanel(); //appelle methode initialisationPanel } catch (Exception e) { e.printStackTrace(); //affiche l'exception au moment de son appel } } // initialise la surface de jeu. Cre tout les elements et initialise leur position, leur couleur.. etc private void initialisationPanel() throws Exception { tab = new CaseLabel[8][8]; // création du tableau de JLabel e = new Echiquier(); // création de l'échiquier this.getContentPane().setLayout(null); // permet de centrer le cadre du haut this.setSize(new Dimension(900, 700)); //dimension fenetre this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //fermer la fenetre this.setTitle("ECHEC"); //titre de la fenetre panelControle.setBounds(new Rectangle(160, 10, 550, 45)); //dimension du bloc du haut panelControle.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED)); //bordure cadre du haut panelControle.setLayout(null); //permet de voir le champ en haut panelGrille.setBounds(new Rectangle(160, 65, 550, 465)); //dimension de l'échiquier panelGrille.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED)); panelGrille.setLayout(gridLayout1); // insert les colonnes et les lignes pour les cases gridLayout1.setColumns(8); gridLayout1.setRows(8); panelControle.add(boutonfin, null); panelControle.add(champTexte, null); panelControle.add(boutonDebuter, null); this.getContentPane().add(panelControle, null); //visualiser le champ text en haut boutonDebuter.setBounds(new Rectangle(15, 10, 130, 25)); boutonDebuter.setText("Commencer"); champTexte.setBounds(new Rectangle(160, 10, 215, 25)); // les écouteurs boutonfin.setText("Terminé"); boutonfin.setBounds(new Rectangle(390, 10, 130, 25)); GestionnaireEvenement gest = new GestionnaireEvenement(); boutonDebuter.addMouseListener(gest); boutonfin.addMouseListener(gest); //crŽation des labels panelblanc.setBounds(new Rectangle(30, 65, 90, 465)); // dimension recuperateur de piece blanche panelblanc.setBackground(new Color(255, 0, 0)); panelblanc.setLayout(new FlowLayout()); panelblanc.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED)); panelnoir.setBounds(new Rectangle(750, 65, 90, 465)); // dimension recuperateur de piece noire panelnoir.setBackground(new Color(0, 0, 0)); panelnoir.setLayout(new FlowLayout()); //J'attribue la couleur aux cases int a = 1; for (int ligne = 0; ligne < 8; ligne++) { a = a == 1 ? 0 : 1; for (int colonne = 0; colonne < 8; colonne++) { tab[colonne][ligne] = new CaseLabel(); panelGrille.add(tab[colonne][ligne]); // ajouter au Panel tab[colonne][ligne].setOpaque(true); tab[colonne][ligne].setHorizontalAlignment(SwingConstants.CENTER); //centre les pieces dans les cases tab[colonne][ligne].addMouseListener(gest); if ((colonne + 1) % 2 == a) tab[colonne][ligne].setCouleur(true); //couleur des cases : blanc else tab[colonne][ligne].setCouleur(false); //couleur des cases : noir } } }
Merci
Le rouge fonctionne aussi :O
Mais Pour le pion il marche que de face alors que normalement on prend un pion adverse en diagonale ...
De plus, la dame ou le fou par exemple ont des cases vertes quand on clique (ce qui est normal) et les cases occupées sont pas vertes (toujours normal) sauf que si par exemple il y a un pion devant la tour, juste devant le pion il y a que des cases vertes alors que la tour ne peut pas passer au dessus en théorie ...
possible que le code que tu as pris en exemple ne soit pas tout à fait au pointCitation:
Mais Pour le pion il marche que de face alors que normalement on prend un pion adverse en diagonale ...
De plus, la dame ou le fou par exemple ont des cases vertes quand on clique (ce qui est normal) et les cases occupées sont pas vertes (toujours normal) sauf que si par exemple il y a un pion devant la tour, juste devant le pion il y a que des cases vertes alors que la tour ne peut pas passer au dessus en théorie ...
Merci, pour le roque,
Il faut un boolean qui verifie que le roi n'est pas en echec puis qu'il y a rien entre le roi et la tour pour que sa permute ???
les règles pour le roque :
- ni le roi ni la tour ne doivent avoir déjà bouger
- aucune des cases entre la tour et le roi ne doivent être occupée
- aucune des cases entre la tour et le roi, ou la tour ou le roi, ne doivent être menacée (c'est à dire qu'une pièce adverse pourrait s'y déplacer), donc par déduction le roi ne peut être en echec pour roquer
Le seul hic c'est que je n'ai pas la methode roi en echec,
Pour gagner il suffit de manger le roi...
fait 2 méthodes :
- une qui teste le petit roque
- une qui teste le grand roque
pour chacune d'entre elles,
détermine la tour concernée
puis traite chaque règle
1 ni le roi ni la tour ne doivent avoir déjà bouger
2 aucune des cases entre la tour et le roi ne doivent être occupée
3 aucune des cases entre la tour et le roi, ou la tour ou le roi, ne doivent être menacée (c'est à dire qu'une pièce adverse pourrait s'y déplacer), donc par déduction le roi ne peut être en echec pour roquer
pour la 1, tu peux faire un boolean pour le roi, 1 pour le tour droite, et 1 pour la tour gauche : dès que tu bouges la pièce tu passes le booleen correspondant à true
ce qui te permet de tester si la pièce à bouger
tu peux aussi mettre le boolean directement dans la classe pièce : on pourra savoir pour n'importe quelle pièce si elle a déjà bougé une fois
pour la 2, tu connais les x,y de chacune de ces cases, donc tu peux tester si elles sont occupées ou non
pour la 3, il te suffit de parcourir toutes les pièces adverses, pour chacune des ces pièces, parcourir toutes les cases concernées (donc celle ou est le roi, celle ou est la tour, celles entre les deux, donc en gros celles qui ont été testées pour la règle 2) : pour tous ces couples de case, tu simules le mouvement (comme on a fait pour déterminer les cases vertes) : dès qu'un deplacement simulé est valide, tu peux arreter ton test : tu as trouvé un cas qui interdit le roque !
déjà un cas mal géré par ton programme d'echec: aux echecs le roi ne peut être "mangé" : dès que le roi est menacé et ne peut plus se déplacer sans se mettre dans une position menacée, et qu'aucune de ses pièces ne peut être déplacé pour protéger le roi, le jeu s'arrête : on appelle ça "echec et mat" !Citation:
Pour gagner il suffit de manger le roi...
Pour la couleur rouge du pion qui déconnait , j'ai essayer cela en vain :
car dans la classe deplacement j'avais :Code:
1
2
3
4
5
6
7
8
9
10
11
12 if (pieceTampon.estValide(deplacement)) { if (e.getCase(colonne,ligne).estOccupe(pieceTampon.getCouleur().equals("blanc") ? "noir" : "blanc ") || (e.getCase(colonne,ligne).captureParUnPionPossible())){ tab[colonne][ligne].setCoupPossible(CoupPossible.prisepion);} else if (e.getCase(colonne,ligne).estOccupe()){ tab[colonne][ligne].setCoupPossible(null); } else { tab[colonne][ligne].setCoupPossible(CoupPossible.mouvement); } } else { tab[colonne][ligne].setCoupPossible(null); }
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 public boolean captureParUnPionPossible(Deplacement deplacement) { //Je verifie si la piece est un pion if(plateau[deplacement.getDepart().getColonne()][deplacement.getDepart().getLigne()].getPiece() instanceof Pion) { //initialisation des variables, et savoir la couleur de la piece de depart et la case d'arrive. Case Arrive = plateau[(int)deplacement.getArrivee().getColonne()][(int)deplacement.getArrivee().getLigne()]; String couleurDepart = plateau[(int)deplacement.getDepart().getColonne()][(int)deplacement.getDepart().getLigne()].getPiece().getCouleur(); //je verifie d'abord si la piece d'arrive existe et si elle est de la couleur contraire de celle de depart. if(Arrive.estOccupe(couleurDepart.equals("blanc") ? "noir" : "blanc")) //on verifie si le deplacement est valide par le produit du deplacement des ordonner et absices et si cela fait 1 pour les noir ou -1 pour les blanc cela sera accepter return (deplacement.getDeplacementY() * Math.abs(deplacement.getDeplacementX()) == (couleurDepart.equals("noir et jaune") ? 1 : -1)); //en diagonale } return false; }
Ensuite dans ma classe Piece j'ai ajouté :
Mais plateau n'est pas reconnu.Code:
1
2
3
4
5
6 public boolean ReineGaucheDejabouge(){ if(plateau[0][0].getPiece() instanceof Tour(couleur)); return true; else return fase; }
Comment faire une méthode pour chaque pion s'il a déjà bougé une fois ou non ?
Pour tester les cases entre la tour et le roi , je fais une méthode booléenne dans quelle classe ? Merci
Pour ce qui est en est de l'echec , je pensais a si une case est rouge cela signifie qu'il est en echec mais il faut cliquer sur la piece en question pour apercevoir les couleurs...
Merci
euh, c'est quoi ça ?
c'est dans le code d'origine ce genre de test ? ou c'est toi qui a ajouté ça ?
c'est quoi le code de la classe PieceCode:pieceTampon.getCouleur().equals("rouge et jaune")
MerciCode:
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 public abstract class Piece { // nom de la piece private String nom; // couleur de la pièce private String couleur; // constructeur permettant d'initialiser le nom et la couleur d'une pièce public Piece(String nom, String couleur) { setNom(nom); setCouleur(couleur); } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } public String getCouleur() { return couleur; } public void setCouleur(String couleur) { if ((couleur == "noir et jaune") || (couleur == "rouge et jaune")) this.couleur = couleur; } // méthode permettant de vérifier si le déplacement de la pièce est valide public abstract boolean estValide(Deplacement deplacement); public boolean ReineGaucheDejabouge(){ if(plateau[0][0].getPiece() instanceof Tour(couleur)); return true; else return fase; } }
et ça c'est quoi au juste ? dans la classe Piece ?Code:
1
2
3
4
5
6 public boolean ReineGaucheDejabouge(){ if(plateau[0][0].getPiece() instanceof Tour(couleur)); return true; else return fase; }
déjà je suppose que ça devrait s'appeler TourGaucheDejabouge
ça n'a rien a faire dans Piece
et si la tour se déplace et revient à sa place d'origine, ta méthode va dire que la tour n'a pas bougé alors que si
pour traiter le mouvement tu dois simplement ajouter à ta classe Piece
- une variable booléenne pour stocker l'état déplacé, par exemple :
- un mutateur (une méthode pour modifier cette valeur) :Code:private boolean deplaceunefois;
- un accesseur pour connaitre l'état de cette variableCode:
1
2
3 public void enregistreDeplacement(boolean deplace) { deplaceunefois=deplace; }
maintenant il faut appeler enregistreDeplacement() au bon endroit dans le code : c'est à dire au moment ou un joueur déplace une pièce.Code:
1
2
3 public boolean aDejaEteDeplaceUneFois(){ return deplaceunefois; }
à priori c'est dans un des bloc du code principal de l'écouteur de clic, là ou y'a le commentaire //on met le tampon sur la case vide et on vide le tampon apresCode:pieceTampon.enregistreDeplacement(true)
dans la méthode RAZ() : parcourt toutes les pièces et remet à false la variableautre chose :Code:enregistreDeplacement(false)
dans
a noter l'appel e.cheminPossible(deplacement) : voilà peut être une méthode qui sert dans les test pour déterminer les coupPossible en plus de estValide : à vérifier ce qu'elle fait exactementCode:if ((pieceTampon.estValide(deplacement) && e.cheminPossible(deplacement)) | e.captureParUnPionPossible(deplacement))
ouais je vois le code d'origine traitait les 2 couleurs de jouer par une chaine,qui contenant "noir" ou "blanc" et toi tu as remplacé ça
c'est pas comme ça qu'on fait (le code d'origine) : et toi tu modifié directement un code pourri en le pourrissant encore plus
on doit distinguer les états et valeurs de leur représentation, ce qui évite d'avoir à écrire ce genre d'horreur et à tout modifier quand on change la représentation
le codeur initial aurait du utiliser un type à 2 états, moi j'aurais utiliser une énumération à 2 valeurs : aux echecs il y a un joueur blanc et un joueur noir, que les pièces soit rouge, jaune, rouge à pois vert, ou bleue rayée d'orange, ou texture bois
et on teste toujours la couleur de la pièce par le même test
et on utilise ensuite une méthode qui détermine le texte à afficher (ou autre chose à afficher) en fonction de la valeur.
le jour ou tu voudras ajouter la possibilité au joueur de choisir parmi plusieurs type de pièce différent, tu vas écrire des tests dans le genre
if ( piece.getCouleur().equals("rouge et jaune") || piece.getCouleur().equals("rouge et vert") || piece.getCouleur().equals("bleue et rouge") || piece.getCouleur().equals("orange et violet") || ... piece.getCouleur().equals("bleue et jaune")
tu imagines ?
et un jour tu as un pote anglais qui aimerait bien jouer avec ton jeu d'echec : il va traduire les textes et quand il va voir qu'il doit changer des tests dans tout le code, à priori, il va un peu criser
tu vois que ce que j'ai mis en rouge ne peut plus marcher puisque tu as changé les textes des couleurs des pièces : encore une bonne raison de ne pas faire ça comme ça, mais comme je l'ai dit, ou au moins avec des constantes (dont tu peux changer la valeur sans modifier tous les tests relatifs)Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 public boolean captureParUnPionPossible(Deplacement deplacement) { //Je verifie si la piece est un pion if(plateau[deplacement.getDepart().getColonne()][deplacement.getDepart().getLigne()].getPiece() instanceof Pion) { //initialisation des variables, et savoir la couleur de la piece de depart et la case d'arrive. Case Arrive = plateau[(int)deplacement.getArrivee().getColonne()][(int)deplacement.getArrivee().getLigne()]; String couleurDepart = plateau[(int)deplacement.getDepart().getColonne()][(int)deplacement.getDepart().getLigne()].getPiece().getCouleur(); //je verifie d'abord si la piece d'arrive existe et si elle est de la couleur contraire de celle de depart. if(Arrive.estOccupe(couleurDepart.equals("blanc") ? "noir" : "blanc")) //on verifie si le deplacement est valide par le produit du deplacement des ordonner et absices et si cela fait 1 pour les noir ou -1 pour les blanc cela sera accepter return (deplacement.getDeplacementY() * Math.abs(deplacement.getDeplacementX()) == (couleurDepart.equals("noir et jaune") ? 1 : -1)); //en diagonale } return false; }
J'ai changer les couleurs par les variables,
mais j'ai eu un soucis au niveau de :
enregistredeplacement(false) car il ne connait pas enregistredeplacement dans la methode RAZ..
Pourtant le enregistreDeplacement(true); ne produit aucune erreur :Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 public void RAZ() { for (int ligne = 0; ligne < 8; ligne++) for (int colonne = 0; colonne < 8; colonne++) { tab[colonne][ligne].setIcon(null); e.getCase(colonne, ligne).setPiece(null); tab[colonne][ligne].enregistreDeplacement(false); } champTexte.setText(""); boutonDebuter.setEnabled(true); e.debuter(); panelblanc.removeAll(); panelblanc.repaint(); panelnoir.removeAll(); panelnoir.repaint(); }
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 else//si on depose la piece sur une case vide { //on met le tampon sur la case vide et on vide le tampon apres e.getCase(temp.getColonne(), temp.getLigne()).setPiece(null); tab[temp.getColonne()][temp.getLigne()].setBorder(BorderFactory.createLineBorder(new Color(0, 0, 0),0)); // j'enleve le cadre rouge de la piece selectionne tab[colonneClic][ligneClic].setIcon(iconeTampon); e.getCase(colonneClic, ligneClic).setPiece(pieceTampon); // pour pouvoir le rebouger plusieurs fois dans une partie tab[temp.getColonne()][temp.getLigne()].setIcon(null); // permet de faire bouger la piece selectionne en supprimant la piece bouger de sa position initiale pieceTampon.enregistreDeplacement(true); pieceTampon = null; iconeTampon = null; temp = null; couleurControle = couleurControle.equals(COULEUR_JOUEUR_BLANC) ? COULEUR_JOUEUR_NOIR : COULEUR_JOUEUR_BLANC; champTexte.setText(couleurControle + " , a vous de jouer"); }
J'ai donc mon fichier piece qui ressemble a ceci :
Code:
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
45
46 public abstract class Piece { private boolean deplaceunefois; // nom de la piece private String nom; // couleur de la pièce private String couleur; public final static String COULEUR_JOUEUR_BLANC="rouge et jaune"; public final static String COULEUR_JOUEUR_NOIR="noir et jaune"; // constructeur permettant d'initialiser le nom et la couleur d'une pièce public Piece(String nom, String couleur) { setNom(nom); setCouleur(couleur); } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } public String getCouleur() { return couleur; } public void setCouleur(String couleur) { if ((couleur == COULEUR_JOUEUR_NOIR) || (couleur == COULEUR_JOUEUR_BLANC)) this.couleur = couleur; } // méthode permettant de vérifier si le déplacement de la pièce est valide public abstract boolean estValide(Deplacement deplacement); public void enregistreDeplacement(boolean deplace) { deplaceunefois=deplace; } public boolean aDejaEteDeplaceUneFois(){ return deplaceunefois; } }
Merci
enregistreDeplacement est une méthode de Piece et la tu l'appelle sur CaseLabel...
il faut que tu parcourt toutes les pièces et que tu appelles cette méthode sur ces instances de piece. peut être voir si tu ne peux pas le faire dans la méthode débuter de Echiquier ou une autre méthode ! cherche celle qui est la plus adaptée, et qui ne risque pas d'être appelée en plein milieu de partie
si tu n'arrives pas à trouver un moyen de parcourir toutes les pièces, tu peux aussi modifier le code qui place les pièces sur l'échiquier : la a priori on parcourir toutes les pieces pour les placer, et on est en démarrage de partie
Code:
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 public Case getCase(int colonne, int ligne) { return plateau[colonne][ligne]; } //place les pieces au debut public void debuter() { int ligne = 7; for (String couleur = COULEUR_JOUEUR_NOIR ; !couleur.equals(COULEUR_JOUEUR_BLANC); couleur = COULEUR_JOUEUR_BLANC, ligne = 0){ //J'initialise tout mes pieces de la premieres rangee (tour, cavalier etc...) plateau[0][ligne].setPiece(new Tour(couleur)); plateau[1][ligne].setPiece(new Cavalier(couleur)); plateau[2][ligne].setPiece(new Fou(couleur)); plateau[3][ligne].setPiece(new Reine(couleur)); plateau[4][ligne].setPiece(new Roi(couleur)); plateau[5][ligne].setPiece(new Fou(couleur)); plateau[6][ligne].setPiece(new Cavalier(couleur)); plateau[7][ligne].setPiece(new Tour(couleur)); //Je change de ligne ligne += couleur.equals(COULEUR_JOUEUR_NOIR) ? -1 : 1; //J'initialise tout mes pions. for (int ctr = 0; ctr <= 7; ctr++) plateau[ctr][ligne].setPiece(new Pion(couleur)); } }
Dans ce code, je ne vois pas ou le mettre car on s'interrese qu'au ligne ici
Je n'ai pas trop compris ce qu'il devait y avoir avant
enregistreDeplacement(false);
J'ai compris qu'il fallais parcourir chaque case pour mettre deplacement a faux comme on débute la partie mais je ne vois pas ou le mettre.
attention, au test d'égalité :Code:
1
2
3
4 public void setCouleur(String couleur) { if ((couleur == COULEUR_JOUEUR_NOIR) || (couleur == COULEUR_JOUEUR_BLANC)) this.couleur = couleur; }
- il faut que tu comprennes la différence entre
etCode:couleur.equals(COULEUR_JOUEUR_NOIR)
sinon tu risques d'avoir des dysfonctionnement sans comprendre pourquoiCode:couleur==COULEUR_JOUEUR_NOIR
les variables sont typées en java. il y a 2 types de type : les types primitifs et les classes.
quand une variable est de type primitid, elle "contient" directement sa valeur
int est un type primitif, a contient 123.Code:
1
2 int a; a=123;
mais quand une variable est de type classe, la variable contient une référence à l'instance de classe
String est une classeCode:
1
2String s; s="TOTO";
s ne contient pas "TOTO", mais une référence à une instance de la classe String qui contient une tableau de char qui contient les lettres T, O, T et O.
si tu écris
tu auras a l'écran :Code:
1
2
3
4
5
6
7
8
9
10
11
12 public static void main(String[] args) { String s="TOTO"; String s1=s.substring(0,2); String s2=s.substring(0,2); System.out.println("s1 : " + s1); System.out.println("s2 : " + s2); System.out.println("s1==s2 : " + (s1==s2)); System.out.println("s1.equals(s2) : " + s1.equals(s2)); }
bien sur ton == marchera tant que tu utiliseras uniquement les constantes pour affecter la valeur de couleur (puisqu'en fait tu utiliseras la même référence à chaque fois pour chacune des deux constantes), mais tu risques à un moment que ton test ne marche pas parce que tu compares à une chaine qui n'est pas la constante de départCode:
1
2
3
4 s1 : TO s2 : TO s1==s2 : false s1.equals(s2) : true
avec des String, à moins d'être sur de ton coup, utilise equals
Merci pour ces explications,
Donc je remplace :
.equals par == si j'ai bien compris
Est-ce que je change aussi ici :
Code:
1
2
3
4
5
6
7 public boolean estOccupe(String couleur) { //Si il n'y a pas de piece sur la case c'est que la case n'est pas occuper au contraire la fonctioin retournera la piece de la couleur en question. if (piece == null) return false; else return (piece.getCouleur().equals(couleur));}
Merci
ouais effectivement comme il n'y a pas une belle boucle qui boucle sur toutes les pièces, tu ne peux pas intervenir facilement pour boucler sur la liste des pièces : mais tu as de la chance : on voit ici que pour recréer le damier, le code recréer les Piece à zéro par un new
(new Pion(..), new Fou(..), new Tour(...) etc...)
du coup pas la peine de remettre la valeur à zéro, puis qu'elle sera à sa bonne valeur initiale des le départ, comme à la première exécution : comme la variable est un booleen, par défaut elle contient false à l'instanciation donc elle a la bonne valeur
Donc je peux enfin le recompiler,
Mais j'ai toujours le même soucis des cases vertes :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 for (int ligne = 0; ligne < 8; ligne++) { for (int colonne = 0; colonne < 8; colonne++) { Position pos = new Position(colonne,ligne); Deplacement deplacement=new Deplacement(temp,pos); if (pieceTampon.estValide(deplacement)) { if (e.getCase(colonne,ligne).estOccupe(pieceTampon.getCouleur()==(COULEUR_JOUEUR_BLANC) ? COULEUR_JOUEUR_NOIR : COULEUR_JOUEUR_BLANC)){ tab[colonne][ligne].setCoupPossible(CoupPossible.prisepion);} else if (e.getCase(colonne,ligne).estOccupe() && !e.cheminPossible(deplacement)){ tab[colonne][ligne].setCoupPossible(null); } else { tab[colonne][ligne].setCoupPossible(CoupPossible.mouvement); } } else { tab[colonne][ligne].setCoupPossible(null); } }
envoie le code complet (zip en pièce jointe), j'essayerai de voir pourquoi
oui et non
moi j'aurai pas recréer toutes les pièces : j'évite toujours de créer plusieurs fois une même instance qui représente la même chose : je prefère avoir un état (c'est comme si au vrai jeu d'echec tu jetais tes pièces à la poubelle à chaque fin de partie et que tu allais abbatre un arbre pour fabriquer des nouvelles pièces : bien sur ça facilite les choses de faire comme ça, mais c'est pas clean.
y'a pas beaucoup de pièces donc peu d'impact, mais si on faisait ça pour un plus grand nombre d'instances de classes, on aurait des problèmes de performances, à l'instanciation et au garbage recollecting.
imagine que tu veuilles maintenant faire qu'à chaque fois que tu recommences une partie, on ait une animation qui déplace les pièces pour les remettre à la bonne place...
Je comprend qu'il faudrait optimiser mon code mais l'idéal serait qu'il fonctionne car sans vous je serais dans les choux...
Merci
(avec ECLIPSE)
bon c'est ce que je t'avais plus ou fait remarquer : le test du déplacement se fait pas seulement avec estValide mais aussi avec cheminPossible
Piece.estValide(Deplacement) retourne true si le déplacement est possible quelque soit la position des autres pièces
Echiquier.cheminPosible(Deplacement); retour true si la pièce peut se déplacer librement de la position de départ à la position d'arrivée
donc pour commencer :
permet d'avoir les cases vers lesquelles on peut se déplacer en vertCode:
1
2
3
4
5
6
7
8
9
10
11
12 if (pieceTampon.estValide(deplacement) && e.cheminPossible(deplacement) ) { if (e.getCase(colonne,ligne).estOccupe(pieceTampon.getCouleur()==(COULEUR_JOUEUR_BLANC) ? COULEUR_JOUEUR_NOIR : COULEUR_JOUEUR_BLANC)){ tab[colonne][ligne].setCoupPossible(CoupPossible.prisepion);} else if (e.getCase(colonne,ligne).estOccupe()/*&& !e.cheminPossible(deplacement)*/){ tab[colonne][ligne].setCoupPossible(null); } else { tab[colonne][ligne].setCoupPossible(CoupPossible.mouvement); } } else { tab[colonne][ligne].setCoupPossible(null); }
http://www.developpez.net/forums/att...1&d=1370974462
http://www.developpez.net/forums/att...1&d=1370974462
http://www.developpez.net/forums/att...1&d=1370974462
certaines configurations de prise de pièces fonctionnent :
http://www.developpez.net/forums/att...1&d=1370974462
http://www.developpez.net/forums/att...1&d=1370974462
mais effectivement la prise de pion ne s'affiche pas en rouge
en regardant de plus près la méthode estValide() on se rend compte que le mouvement en diagonal du pion n'est pas considéré comme valide, ce qui n'est pas faux
donc (j'ai un peu refactorisé pour plus de clarté):
Code:
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 for (int ligne = 0; ligne < 8; ligne++) { for (int colonne = 0; colonne < 8; colonne++) { if ( colonne==temp.getColonne() && ligne==temp.getLigne() ) continue; // une pièce ne peut pas se déplacer sur elle même Position pos = new Position(colonne,ligne); Deplacement deplacement=new Deplacement(temp,pos); if (pieceTampon.estValide(deplacement) ) { // si la pièce peut effectuer ce déplacement (en la considérant seule sur l'échiquier) if ( e.cheminPossible(deplacement) ) { // si la pièce peut se déplacer vers la case d'arrivée, c'est à dire si le chemin est libre Deplacement deplacementinverse=new Deplacement(pos,temp); if ( e.getCase(colonne,ligne).estOccupe() ) { // si la case d'arrivée est occupée, alors c'est que c'est une pièce adverse prenable // pas beson de tester la couleur, puisque si la couleur est la couleur du joueur le déplacement n'est pas possible tab[colonne][ligne].setCoupPossible(CoupPossible.prisepion); } else { // alors le déplacement est possible tab[colonne][ligne].setCoupPossible(CoupPossible.mouvement); } } } else if ( e.captureParUnPionPossible(deplacement) ) { tab[colonne][ligne].setCoupPossible(CoupPossible.prisepion); } else { tab[colonne][ligne].setCoupPossible(null); } } }
Le déplacement du pion est vraiment bizarre...
En position initiale il peux "sauter" au dessus du cavalier...
Grace au boolean qui verifie qu'une piece a deja bougé on pourrait rajouter la condition que s'il a pas encore bougé et qu'il y a une piece devant lui il ne puisse pas sauté au dessus ? (et ainsi enlever la case verte )
Merci
maintenant le roque !
et dans echiquier j'ai ajouté la méthode :Code:
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 for (int ligne = 0; ligne < 8; ligne++) { for (int colonne = 0; colonne < 8; colonne++) { if ( colonne==temp.getColonne() && ligne==temp.getLigne() ) continue; // une pièce ne peut pas se déplacer sur elle même Position pos = new Position(colonne,ligne); Deplacement deplacement=new Deplacement(temp,pos); if (pieceTampon.estValide(deplacement) ) { // si la pièce peut effectuer ce déplacement (en la considérant seule sur l'échiquier) if ( e.cheminPossible(deplacement) ) { // si la pièce peut se déplacer vers la case d'arrivée, c'est à dire si le chemin est libre Deplacement deplacementinverse=new Deplacement(pos,temp); if ( e.getCase(colonne,ligne).estOccupe() ) { // si la case d'arrivée est occupée, alors c'est que c'est une pièce adverse prenable // pas beson de tester la couleur, puisque si la couleur est la couleur du joueur le déplacement n'est pas possible tab[colonne][ligne].setCoupPossible(CoupPossible.prisepion); } else { // alors le déplacement est possible tab[colonne][ligne].setCoupPossible(CoupPossible.mouvement); } } } else if ( e.captureParUnPionPossible(deplacement) ) { tab[colonne][ligne].setCoupPossible(CoupPossible.prisepion); }else if ( e.isRoquePossible(deplacement) ) { tab[colonne][ligne].setCoupPossible(CoupPossible.roque); } else { tab[colonne][ligne].setCoupPossible(null); } } }
quand les 2 roques sont possibles :Code:
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 public boolean isRoquePossible(Deplacement deplacement) { return isPetitRoquePossible(deplacement) || isGrandRoquePossible(deplacement); } public boolean isGrandRoquePossible(Deplacement deplacement) { return isRoquePossible(deplacement,true); } public boolean isPetitRoquePossible(Deplacement deplacement) { return isRoquePossible(deplacement,false); } private boolean isRoquePossible(Deplacement deplacement, boolean grand) { Piece pieceDeDepart = getCase(deplacement.getDepart().getColonne(),deplacement.getDepart().getLigne()).getPiece(); Piece pieceDArrivee = getCase(deplacement.getArrivee().getColonne(),deplacement.getArrivee().getLigne()).getPiece(); if ( pieceDeDepart instanceof Roi && pieceDArrivee instanceof Tour ) { // les deux pièces doivent être de la même couleur if ( pieceDeDepart.getCouleur().equals(pieceDArrivee.getCouleur() ) ) { // aucune des deux pièces ne doit pas avoir bouger if ( !pieceDeDepart.aDejaEteDeplaceUneFois() && !pieceDArrivee.aDejaEteDeplaceUneFois() ) { // distance horizontale int distance = Math.abs(deplacement.getDepart().getColonne()-deplacement.getArrivee().getColonne()); if ( (distance==4 && grand) || (distance==3 && !grand) ) { // toutes les cases doivent être innocupées int ligneroque = deplacement.getDepart().getLigne(); // on pourrait utiliser la couleur de la pièce aussi // le grand roque va de 0 à 4 (donc les cases entre les deux sont 1,2,3 // le petit roque va de 4 à 7 (donc les cases entre les deux sont 5,6 int cased = grand?1:5; int casef = grand?3:6; for(int col=cased; col<=casef; col++) { if ( getCase(col, ligneroque).estOccupe() ) { return false; // case occupee roque impossible } } // on doit vérifier si les cases sont menacées // donc occupée par la couleur adverse... String couleurAdverse = pieceDeDepart.getCouleur().equals(COULEUR_JOUEUR_BLANC)?COULEUR_JOUEUR_NOIR:COULEUR_JOUEUR_BLANC; // ...est qui controle une des cases cased--; casef++; // on inclut les cases avec le roi et la tour int prisepion=couleurAdverse.equals(COULEUR_JOUEUR_NOIR) ? 1 : -1; // on précalcul cette valeur, parce qu'on va en avoir besoin plusieurs fois for(int col=cased; col<=casef; col++) { // on va simuler un déplacement avec toutes les cases adverses Position positionATester = new Position(col,ligneroque); for (int ligne = 0; ligne < 8; ligne++) { for (int colonne = 0; colonne < 8; colonne++) { if ( getCase(colonne, ligne).estOccupe(couleurAdverse) ) { Deplacement simuleDeplacement = new Deplacement(new Position(colonne, ligne), positionATester); if ( getCase(colonne, ligne).getPiece().estValide(simuleDeplacement) && cheminPossible(simuleDeplacement) ) { // la pièce peut se déplacer, la case est menacé return false; // le roque n'est pas possible } else if ( (simuleDeplacement.getDeplacementY() * Math.abs(simuleDeplacement.getDeplacementX()) == prisepion) ) { // le cas de la prise par le pion est traitée à part // et on ne peut pas utiliser la méthode captureParUnPionPossible(simuleDeplacement) car elle ne retourne true que si la case est occupée // on a simplement reprise la formule utilisée dans cette méthode (on pourrait faire une méthode spéciale pour ce calcul) return false; // le roque n'est pas possible } } } } } return true; } } } } /* ici on pourrait indiquer si le roque est possible par la tour else if (pieceDeDepart instance Tour && pieceDArrivee instanceof Roi) { ... } */ return false; }
http://www.developpez.net/forums/att...1&d=1370978158
le petit n'est plus possible :
http://www.developpez.net/forums/att...1&d=1370978158
c'est de la bidouille çaCitation:
Grace au boolean qui verifie qu'une piece a deja bougé on pourrait rajouter la condition que s'il a pas encore bougé et qu'il y a une piece devant lui il ne puisse pas sauté au dessus ? (et ainsi enlever la case verte )
Merci
en fait c'est un bug de la validation de déplacement
c'est un oubli que exceptionnellement le pion peut se déplacer de 2 casesCode:
1
2 //Si c'est un pion, je verifie si la case est libre de toute piece. return !plateau[(int)deplacement.getArrivee().getColonne()][(int)deplacement.getArrivee().getLigne()].estOccupe();
il faut ajouter un test (si la case est occupée) sur la case juste avant le pion (éventuellement on testera 2 fois la même case : tu peux optimiser ton test si tu veux en ne le faisant que si la abs(deplacement.getDeplacementY())>1.
je te laisse y réfléchir...
Merci vraiment pour tout ...
Vous êtes une personne très aimable !