Accéder au contenu principal

Programmer un jeu , c'est trop facile !








Recherche personnalisée







Introduction :




Le but de ce tutoriel est de vous permettre de réaliser un jeu en java avec une interface graphique pour rendre l’affichage plus agréable. Je vais donc vous présenter mes sources afin de vous aider à construire vos classes correctement. Bien évidemment, ces dernières peuvent être améliorées !
En ce qui concerne l’interface graphique, j'ai utilisé les bibliothèques suivantes : awt et/ou swing. L’awt m’a permis de gérer les événements engendrés par l’utilisateur à l’aide de la souris et la création des fenêtres du menu, la fenêtre du jeu et la barre d’état ont toutes été créées avec swing.
En revanche, la barre de menu a été créée à l’aide de l’awt.

Le programme devra posséder certaines fonctionnalités comme :
1) Pouvoir démarrer une nouvelle partie.
2) Sauvegarder une partie dans un fichier.
3) Charger une partie à partir d'un fichier.
4) Quitter la partie.

Ces fonctionnalités seront accessibles via des boutons situés dans le menu et seront
implémentées dans la classe « Fenetre ».
Tout d’abord, je vais présenter le jeu et ses règles puis je finirai par expliquer toutes les structures des classes du projet avec une description détaillée des méthodes difficiles.

En résumé, le tutoriel sera présenté suivant le plan ci-dessous :


1. Présentation du jeu et de ses règles.





1.1. Présentation du jeu de dames.


1.2. Règle du jeu de dames.



2. Description technique des structures des classes et des méthodes complexes.


2.1. Diagramme des classes et description de toutes les classes du jeu.


2.2. Description détaillée des méthodes complexes du jeu.


Avant de nous attaquer à la description de mon programme, intéressons nous tout
d’abord à ce qu’est les Dames.




1. Présentation du jeu et de ses règles.




1.1. Présentation du jeu de dames :





Les Dames ou jeu de dames est un jeu de société opposant deux joueurs dans lequel les joueurs jouent à tour de rôle. Le jeu de dames est également un jeu de stratégie combinatoire abstrait puisque c’est un jeu à information complète (tous les éléments sont connus) et où le hasard n’intervient pas pendant le déroulement du jeu. Une forme primitive de jeu de dames, avec la règle de capture par saut du pion existait déjà il y a 40 siècles, ce jeu de société est donc loin d’être récent.
Le but du jeu est simple : il faut capturer ou immobiliser toutes les pièces de son
adversaire. Pour cela, on dispose traditionnellement d’un damier à 100 cases et un tablier de 10 cases sur 10 de deux couleurs alternées : noir et blanc et il faut au minimum être deux pour pouvoir y jouer. Certaines variantes de ce jeu utilisent des damiers à 64 cases, 8 sur 8, et à 144 cases, 12 sur 12. Dans notre cas, le damier contient 121 cases soit un tablier de 11 cases sur 11 et de deux couleurs alternées qui sont le noir et le blanc et il est possible de jouer face à un ordinateur.
Le damier est disposé de sorte que la case en bas à gauche soit de la couleur foncée.
Chaque joueur place ses pions (Dans notre cas, 22 pions par joueur) sur les cases de
couleur foncée ou claire ceci dépend de la version du jeu de dames. Pour mon
programme, j’ai choisi les cases de couleur claire. Le choix du joueur qui joue en premier est déterminé par la couleur des jetons joués : le joueur qui joue les jetons blancs commence.



1.2. Règles du jeu :



Les pions se déplacent sur les diagonales, du joueur vers l’adversaire. Ils ne se déplacent que d’une case à la fois sauf lorsqu’il il y a une prise, c'est-à-dire, lorsque le pion peut capturer (on dit aussi « manger », « prendre » ou encore « sauter ») un pion adverse.
Lorsqu’une case voisine sur la diagonale est occupée par un pion de l’adversaire et que la case qui se trouve derrière ce dernier est vide, on dit que ce pion doit être mangé ce qui entraîne sa disparition du jeu. Il est important d’insister sur l’obligation de manger un pion de l’adversaire quand c’est possible car dans certaine version des Dames, ce n’est pas obligatoire. On parle alors de la fameuse règle « souffler n’est pas jouer » qui, depuis son abolition, oblige un joueur à manger un pion adverse quelles que soient les conséquences. De plus, si il existe plusieurs façons d’effectuer une ou plusieurs prises, c’est au joueur de choisir celle qui lui convient le mieux. Une prise peut s’effectuer vers l’avant ou vers l’arrière.
Pour finir, il est possible d’échanger un pion contre une dame, on parle alors d’une
promotion. Elle a lieu lorsqu’un pion atteint la dernière rangée. Si un pion vient à passer au dessus de la dernière rangée au cours d’une prise multiple, il devient une dame même s’il ne finit pas la rafle sur une case de promotion. Dans ce programme, la dame peut se déplacer dans tous les sens à partir du moment où elle suit les diagonales et elle ne peut franchir qu’une seule case à la fois (comme les pions). La partie s’achève lorsque l’un des deux joueurs n’a plus de pions ou lorsque tous ses pions sont immobilisés.
Après la présentation des Dames, je vais vous lister les différentes fonctionnalités du programme.



2. Description technique des structures des classes et des méthodes complexes




2.1. Diagramme des classes et description de toutes les classes du jeu :










-Une partie Interface graphique qui, comme son nom l’indique, montre toutes les
classes qui sont nécessaires à la gestion de l’interface graphique du jeu.
-Une partie Moteur du jeu qui montre toutes les classes responsables de la gestion
d’une partie de jeu entre deux joueurs.
Ces deux parties ne sont pas isolées, elles communiquent via la composition entre la
classe « Plateform » et « FenetreduJeu », la composition entre « Joueur » et
« FenetreduJeu » et enfin, la composition entre « FenetreduJeu » et « Jeu». Le choix
d’une telle structure sera expliqué par la suite tout au long de la description de chaque classe du jeu.


La classe « FenetreduJeu » va gérer à elle seule toute l’interface graphique du jeu.
Cette classe va donc créer le menu, la fenêtre principale, la barre de menu, les
composants du menu et enfin la barre d’état. L’évènement engendré par l’appuie de
n’importe quel bouton sera géré grâce à la méthode actionPerformed(). Les images des
fenêtres seront affichées à l’aide de la méthode paint(). De plus, les fonctionnalités du programme telles que sauvegarder ou charger une partie seront implémentées dans cette même classe. La classe « Jeu » initialisera la fenêtre de jeu, c’est pourquoi, la classe « FenetreduJeu » compose « Jeu ».
La classe interne « Fin » permet de créer la fenêtre de fin de partie. Cette classe sera instanciée dans la méthode WinorLose().


Source :



package packJeu;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.MenuShortcut;
import java.io.*;
import java.awt.FileDialog;



class FenetreduJeu extends JFrame implements ActionListener{

private static final long serialVersionUID = 1L;
//pxl : pixel
private final int pxl_c=45;
private Image image;
protected boolean succes;
private boolean depart;
private Plateform plateau=new Plateform();
private MenuItem menu1=new MenuItem("Recommencer partie");
private MenuItem menu2=new MenuItem("Sauvegarder");
private MenuItem menu3=new MenuItem("Charger");
private MenuItem menu4=new MenuItem("Quitter");
private MenuItem menu5=new MenuItem("Aide");
protected JTextField tf=null;
JFrame frame=new JFrame();


JButton bouton1=new JButton();
JButton bouton2=new JButton();

//On créé un thread pour jouer la musique de fond.
MThread t=new MThread("fond.wav",true);

protected Joueur pa=new Joueur(plateau,1);
protected Joueur pb=new Joueur(plateau,2);

protected int cas=0;
private int id=0;



public FenetreduJeu() {
Menu("MENU","Nouvelle Partie","Charger Partie");
bouton1.addActionListener(this);
bouton2.addActionListener(this);
}


public void Menu(String str,String str1,String str2)
{
//MENU
frame.setTitle(str);
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
panel.setBackground(Color.black);

JButton a=new JButton(str1);
JButton b=new JButton(str2);
bouton1=a;
bouton2=b;

panel.add(bouton1);
panel.add(bouton2);

frame.setSize(320,240);
frame.setLocationRelativeTo(null);
frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(panel);
frame.setVisible(true);
}


public void Fenetrejeu()
{
//On initialise la fenêtre de jeu.
frame.dispose();
setTitle("Jeu de Dame ");
setSize(495, 567); //(11*45)x(11*45) pxl par ligne et par colonne + 45 pour le menu + barre d'état


// On créé une barre de menu
MenuBar mb = new MenuBar();
setMenuBar(mb);



// On centre la fenêtre
setLocationRelativeTo(null);
// On empêche le redimensionnement de la fenêtre
setResizable(false);



// Bouton de la barre de menu
Menu m = new Menu("Fichier");


// On ajoute les boutons à la barre de menu
mb.add(m);



// Barre d'état
tf = new JTextField();
tf.setFont(new Font("Verdana",Font.BOLD,15));
tf.setEnabled(false);
tf.setText("Ca commence !!");
tf.setDisabledTextColor(Color.black);
add(tf,"South");


// On ajoute un premier bouton au menu Fichier
m.add(menu1);
// Raccourci pour recommencer partie
int key1='N';
MenuShortcut shrt1=new MenuShortcut(key1);
menu1.setShortcut(shrt1);
m.addSeparator();


// On ajoute un 2ième bouton au menu Fichier
m.add(menu2);
// Raccourci pour sauvegarder
int key2='S';
MenuShortcut shrt2=new MenuShortcut(key2);
menu2.setShortcut(shrt2);
m.addSeparator();


// On ajoute un 3ième bouton à Fichier
m.add(menu3);
// Raccourci pour Charger
int key3='C';
MenuShortcut shrt3=new MenuShortcut(key3);
menu3.setShortcut(shrt3);
m.addSeparator();


// On ajoute un 4ième bouton à Fichier
m.add(menu4);
// Raccourci pour quitter
int key4='Q';
MenuShortcut shrt4=new MenuShortcut(key4);
menu4.setShortcut(shrt4);
m.addSeparator();


// On ajoute un 5ième bouton à Fichier
m.add(menu5);
// Raccourci pour quitter
int key5='A';
MenuShortcut shrt5=new MenuShortcut(key5);
menu5.setShortcut(shrt5);

// affiche la fenêtre
setVisible(true);


// On lance la musique =)
t.start();

m.addActionListener(this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

//Afficher Aide
public void Aide() {

JFrame aide=new JFrame("Aide");
JTextArea ar=new JTextArea("CTRL+n : Nouvelle Partie \nCTRL+s : Sauvegarder \nCTRL+c : Charger \nCTRL+q : Quitter \n\n" +
"Règle du jeu : Le but de ce jeu est de capturer ou immobiliser les pièces de son\nadversaire. Les pions se déplacent sur les diagonales, du joueur vers le joueur\nadverse." +
"Ils ne se déplacent que d'une case à la fois sauf lorsqu'il y a une prise.\nLorsqu'une case voisine sur la diagonale est occupée par un pion du joueur\nadverse, et qu'il y a une case libre derrière, ce pion peut être sauté."+
"Il est\nainsi pris et supprimé du jeu.Le pion déplacé peut capturer plusieurs pions\nà partir du moment où il peut être posé sur le damier entre deux prises.Quand\nvous pouvez prendre,"+
" vous devez prendre, et ce, QUELLES QUE SOIENT\nLES CONSEQUENCES !");
ar.setFont(new Font("Verdana",Font.ITALIC,12));
ar.setEnabled(false);
ar.setDisabledTextColor(Color.black);
aide.setSize(500,300);
aide.add(ar);
aide.setVisible(true);
aide.setResizable(false);

}

//Gestionnaire de fichier pour charger
public void FenetreChargement()
{
// On ouvre la boîte de dialogue pour choisir le fichier que l'on veut charger.
FileDialog c=new FileDialog(this,"Charger");
c.setVisible(true);

//On charge la partie si et seulement si l'utilisateur n'a pas annulé l'action
if(c.getFile() != null)
Charger(c.getFile());



}



//Gestionnaire de fichier pour sauvegarder
public void FenetreSauvegarde()
{
//On ouvre la boîte de dialogue pour choisir l'endroit où on va sauvegarder la partie
FileDialog s=new FileDialog(this,"Saisie",1);
s.setVisible(true);

//On sauvegarde la partie
if(s.getFile() != null)
Sauvegarder(s.getFile());
}


//Méthode qui implémente Recommencer partie.
public void nvlpartie()
{

plateau.nouveau();
tf.setText("Ca commence !!");
succes=depart;
update();

}


//Methode qui implémente Sauvegarder
public void Sauvegarder(String nomFichier) {

String quicommence=new String("0");
if(succes)
quicommence=new String("1");

String jejouevski=new String("1");
if(cas==2)
jejouevski=new String("2");


String ident=new String("1");
if(id==2)
ident=new String("2");


try {
FileWriter fichier = new FileWriter(nomFichier);
for(int i=0;i<11;i++)
for(int j=0;j<11;j++)
fichier.write(""+plateau.getlocal(i,j));
//On sauvegarde succes afin de savoir qui doit jouer une fois le fichier chargé
fichier.write(quicommence);
//On sauvegarde l'identité du joueur.
fichier.write(ident);
//On sauvegarde le type de partie. (J vs J ou AI vs J)
fichier.write(jejouevski);
fichier.close();
}

catch (Exception ex){System.out.println("pb de fichier: " + ex);};

tf.setText("Sauvegarde terminé!");

}

//Méthode qui implémente Charger
public void Charger(String fileName)
{
int tableau[]=new int[126];
int i=0;
try
{
File file = new File(fileName);
FileReader in = new FileReader(fileName);
int size = (int)file.length();
char car=0;
int djavu=0;
String lol=new String();

while (djavu <>
car=(char)in.read();
lol=""+car;
tableau[i]=Integer.parseInt(lol);
djavu++;
i++;
}

in.close();
}
catch (Exception e)
{
//Le fichier n'éxiste pas ou il n'est pas au bon format on annule donc le chargement.
System.out.println("Erreur d'ouverture du fichier "+fileName);
System.out.println("Chargement annulé ");
return;
}
// Une partie vient d'être chargée, on relance la musique de fond.
//on stop l'ancien thread.
t.stoper();

//On en créé un nouveau.
MThread th=new MThread("fond.wav",true);
t=th;
t.start();
tf.setText("Chargement terminé!");


int k=0;

for(i=0;i<11;i++)
for(int j=0;j<11;j++)
{
plateau.setlocal(i, j, tableau[k]);
k++;
}

//On reprend au tour du bon joueur
if(tableau[k]==0)
succes=false;
else
succes=true;

int Identite=0;
int eIdentite=0;

//On charge l'identité du joueur 1 (1 : jeton blanc, 2 : jeton noir)
if(tableau[k+1]==1)
Identite=1;
else
Identite=2;

//On charge l'identité du joueur 2
if(Identite==1)
eIdentite=2;
if(Identite==2)
eIdentite=1;

//On charge le type de partie (cas 1 : joueur vs Joueur sinon AI vs Joueur)
if(tableau[k+2]==1)
{
cas=1;
pa=new Joueur(plateau,Identite);
pb=new Joueur(plateau,eIdentite);


}

else
{
cas=2;
pa=new Joueur(plateau,Identite);
pb=new IA(plateau,eIdentite);
}
//Dans le cas où on recommencera une partie de jeu
if(Identite==1)
depart=false;
else
depart=true;

update();

}



public void actionPerformed(ActionEvent e) {

String choix = e.getActionCommand();
//****************Items du menu*************
if(choix=="Aide")
Aide();

if(choix=="Sauvegarder")
FenetreSauvegarde();

if(choix=="Recommencer partie")
nvlpartie();

if(choix=="Charger")
FenetreChargement();

if(choix=="Quitter")
System.exit(0);

//*******ActionListener des boutons du menu************
if(choix=="Nouvelle Partie")
{
Menu("MODE","Joueur VS Joueur","Joueur VS IA");
bouton1.addActionListener(this);
bouton2.addActionListener(this);
}

if(choix=="Charger Partie")
{
Fenetrejeu();
FenetreChargement();
}

//**************MODE Joueur vs Joueur***********
if(choix=="Joueur VS Joueur")
{
Menu("Choisir jeton","BLANC","NOIR");
bouton1.addActionListener(this);
bouton2.addActionListener(this);
}

if(choix=="BLANC" || choix=="NOIR")
{
if(choix=="BLANC")
{
id=1;
pa=new Joueur(plateau,id);
pb=new Joueur(plateau,2);
succes=false;
depart=succes;
cas=1;
}
else
{
id=2;
pa=new Joueur(plateau,id);
pb=new Joueur(plateau,1);
succes=true;
depart=succes;
cas=1;
}
Fenetrejeu();
}

//****************MODE IA vs Joueur***********
if(choix=="Joueur VS IA")
{
Menu("Choisir jeton","Blanc","Noir");
bouton1.addActionListener(this);
bouton2.addActionListener(this);
}

if(choix=="Blanc" || choix=="Noir")
{
if(choix=="Blanc")
{
id=1;
pa=new Joueur(plateau,id);
pb=new IA(plateau,2);
succes=false;
depart=succes;
cas=2;
}
else
{
id=2;
pa=new Joueur(plateau,id);
pb=new IA(plateau,1);
succes=true;
depart=succes;
cas=2;
}
Fenetrejeu();
}





}


public class Fin extends JFrame{


private static final long serialVersionUID = 1L;
String mess;
public Fin(String mess)
{
this.mess=mess;
setSize(564,315);
setResizable(false);
setLocationRelativeTo(null);
setVisible(true);
}


public void paint(Graphics g) {

image=Toolkit.getDefaultToolkit().getImage(mess) ;
g.drawImage(image,0 ,25,564,315,this);

}
}


public void WinorLose(String mess,String son)
{
Fin f=new Fin(mess);
t.stoper();
this.dispose();
MThread th=new MThread(son,true);
t=th;
t.start();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

//On affiche le jeu.
public void paint(Graphics g) {


//On charge la table de jeu
image=Toolkit.getDefaultToolkit().getImage("damier.jpg") ;
g.drawImage(image,0 ,45,495,495,this);

//On charge les pions blancs et les pions noirs.

for(int i=0;i<=10;i++)
{
for(int j=0;j<=10;j++)
{
if(plateau.getlocal(i,j)==1)
{
image=Toolkit.getDefaultToolkit().getImage("blanc.png") ;
g.drawImage(image, j*pxl_c,(i+1)*pxl_c,pxl_c,pxl_c,this);
}

if(plateau.getlocal(i,j)==2)
{
image=Toolkit.getDefaultToolkit().getImage("noir.png") ;
g.drawImage(image, j*pxl_c,i*pxl_c+pxl_c,pxl_c,pxl_c,this);
}

if(plateau.getlocal(i,j)==3)
{
image=Toolkit.getDefaultToolkit().getImage("d_blanc.png") ;
g.drawImage(image, j*pxl_c,(i+1)*pxl_c,pxl_c,pxl_c,this);
}

if(plateau.getlocal(i,j)==4)
{
image=Toolkit.getDefaultToolkit().getImage("d_noir.png") ;
g.drawImage(image, j*pxl_c,i*pxl_c+pxl_c,pxl_c,pxl_c,this);
}
if(plateau.getlocal(i,j)==5)
{
image=Toolkit.getDefaultToolkit().getImage("or.png") ;
g.drawImage(image, j*pxl_c,(i+1)*pxl_c,pxl_c,pxl_c,this);
}

if(plateau.getlocal(i,j)==6)
{
image=Toolkit.getDefaultToolkit().getImage("d_or.png") ;
g.drawImage(image, j*pxl_c,(i+1)*pxl_c,pxl_c,pxl_c,this);
}
}
}


}

//On rafraîchie l'ecran.

public void update()
{
paint(getGraphics()); //Les scintillements sont moins importants que avec repaint().
}


}//Fin de la classe




Explications :

Attributs :

private final int pxl_c=45 : Nombre de pixel d’un côté d’un carreau du damier.
private Image image : Variable qui va stocker une image.
protected boolean succes : Cet attribut est utilisé dans la classe « Jeu ». Tant que
succes=false P1 joue sinon c’est au tour de P2. Si P1 joue les pions blancs alors succes est initialisé à false sinon à true.
private boolean depart : Cette variable permet de connaître quel joueur a commencé à jouer. Si depart=true alors c’est P2 qui a commencé sinon c’est P1.
private Plateform plateau=new Plateform() : Plateau du jeu.
Les boutons qui se situent dans le menu Fichier.
private MenuItem menu1=new MenuItem("Recommencer partie") :
private MenuItem menu2=new MenuItem("Sauvegarder");
private MenuItem menu3=new MenuItem("Charger");
private MenuItem menu4=new MenuItem("Quitter");
private MenuItem menu5=new MenuItem("Aide");
protected JTextField tf=null : Variable qui permet d’afficher des lignes de texte à
l’écran. Elle sera utilisée comme barre d’état.
JFrame frame=new JFrame() : Cette variable permet d’afficher une fenêtre à l’écran.
Elle sera utilisée pour la création du menu.
Ces boutons seront utilisés pour le menu.
JButton bouton1=new JButton();
JButton bouton2=new JButton();
MThread t=new MThread("fond.wav",true) : On créé un thread pour jouer la musique
de fond.
protected Joueur pa=new Joueur(plateau,1) : Initialisation du premier joueur.
protected Joueur pb=new Joueur(plateau,2) : Initialisation du second joueur.
protected int cas=0 : Cet attribut permet de distinguer si il s’agit d’une partie entre un joueur humain et un ordinateur ou entre deux joueurs humains. Cet attribut prend toute son importance dans la méthode jouer() de la classe « Jeu ». En effet, si cas=1 on fera appel à la méthode JvsJ() sinon à la méthode IAvsJoueur().
private int id=0 : Variable qui prend comme valeur 1 si le joueur choisit de jouer
avec les pions blancs sinon 2.


Méthodes :

public FenetreduJeu() : Constructeur de la classe « FenetreduJeu ». Il initialise la première fenêtre du menu et les deux boutons de la fenêtre.
public void Menu(String str,String str1,String str2) : Cette méthode permet d’afficher une fenêtre à l’écran avec comme titre le contenu de str. La fenêtre contient deux boutons avec comme nom str1 et str2. Toutes les fenêtres du menu seront créées à partir de cette méthode, il suffira juste de modifier le contenu des variables passées en paramètre.
public void Fenetrejeu() : Cette méthode permet d’afficher à l’écran la fenêtre
principale, c'est-à-dire, la fenêtre de jeu. La barre de menu, les menus et la barre d’état sont également initialisés dans cette méthode.
public void FenetreChargement() : Cette méthode permet d’ouvrir le gestionnaire de
fichier afin de choisir le fichier que l’on veut charger. Une fois que le joueur a choisi le fichier, elle fait appel à la méthode Charger() qui va gérer le chargement de ce fichier en mémoire. Si le joueur annule, le gestionnaire de fichier se ferme et la méthode Charger n’est pas appelée.
public void Charger(String fileName) : Méthode qui gère le chargement en
mémoire d’une partie de jeu à partir d’un fichier texte.
public void nvlpartie() : Cette méthode permet de recommencer un partie de jeu
lorsque le joueur possède déjà une partie en cours.
public void FenetreSauvegarde() : Cette méthode gère la sauvegarde. De la même
manière que pour FenetreChargement(), le gestionnaire de fichier se ferme et la
méthode Sauvegarder n’est pas appelée lorsque le joueur annule l’opération.
public void Sauvegarder(String nomFichier) : Méthode qui sauvegarde une partie
de jeu sur le disque dur.
public void WinorLose(String mess,String son) : Méthode qui affiche la fenêtre
de fin de partie. Si l’un des deux joueurs gagne, on affiche la fenêtre de victoire puis on lit le fichier audio « victoire.wav » sinon on affiche la fenêtre de défaite et on lit le fichier audio «defaite.wav ».
public void paint(Graphics g) : Méthode qui dessine à l’écran l’image stockée dans
la variable image.
public void update() : Méthode qui « refresh » l’écran, autrement dit, met à jour
l’affichage à l’écran.
public void actionPerformed(ActionEvent e) : Méthode qui va gérer les actions sur
les boutons pour toutes fenêtres confondues.

Cette classe n'est qu'une démonstration ! Il est donc évident qu'il existe bien d'autres manières de créer une table de jeu de dame. Néanmoins, cette classe constitue un bon exemple à suivre car cette interface graphique reste assez complet dans l'ensemble. La sauvegarde et le chargement d'une partie n'est pas indispensable ! vous n'êtes donc pas obligé de le programmer. Néanmoins, plus le jeu sera complet et plus le joueur prendra plaisir à jouer ! =)

La classe « Joueur » va gérer une partie de joueur humain. Elle sera à l’origine du changement de phase entre sélection et déplacement, elle vérifiera si l’endroit cliqué se situe sur un de nos jetons et c’est également cette classe qui obligera à capturer un pion si bien entendu le joueur a la possibilité de le faire.
Elle compose la classe « FenetreduJeu » car c’est dans cette dernière que les Joueurs
vont être initialisés en fonction des choix du joueur à partir du menu. Elle compose
également la classe « Jeu » puisque la gestion d’une partie entre deux joueurs a lieu
dans « Jeu ». La classe « Joueur » hérite de la classe « GamePlay » puisque la gestion de la partie d’un joueur humain se réalise via la méthode « jouer() » qui fait appel à des méthodes contenues dans « GamePlay ».


Source :


package packJeu;

public class Joueur extends GamePlay{

private int atour=0;
private int stock[][]=new int[2][2]; //Tableau qui va stocker les actions du joueur.(SELECTION+DEPLACEMENT)
private int cpt[][]=new int[5][2];
private int checkout=0;
private int rem1=0;
private int rem2=0;
protected String mess=new String();



public Joueur(Plateform plateau,int i)
{
super(plateau,i);

}


public boolean Jouer(int x,int y,boolean succes,boolean fin[]){

x=x/45; //Aire case du damier : 45x45
y=y-50; //Marge de 50 pixel à cause du menu
y=y/45;

if(aperdu())
fin[0]=true;

//On test pour savoir si l'endroit cliqué correspond bien à l'un des jetons du joueur.
else if(atour==0 && plateau.getlocal(y,x) == 0)
mess+=" "+"Ceci n'est pas un jeton";

else if(atour==0 && (plateau.getlocal(y,x) == jeton || plateau.getlocal(y,x) == Djeton))
mess+=" "+"Ce jeton ne vous appartient pas";



//Cas un peu plus délicat...on est obligé de jouer un jeton parmi ceux qui peut manger un jeton adverse.
//Ainsi, la méthode GooDPiece permet de tester si oui ou non le joueur a sélectionné un bon jeton.

else if(atour==0 && pemanger(cpt)!=0 && !(GooDPiece(cpt,nbPionquiPeManger,x,y,checkout,rem1,rem2)))
mess+=" "+"Choisissez le bon jeton!!";


//Sinon g.pemanger(cpt)=0, le joueur sélectionne le jeton qu'il désire ou g.pemanger(cpt) != 0 et
//le joueur a sélectionné le bon jeton.
else
{
//atour=0, on se trouve alors dans une phase de sélection sinon atour=1 ce qui signifie qu'on se trouve dans une phase de déplacement.
stock[atour][0]=x;
stock[atour][1]=y;
mess+=" "+"Pions restants :"+Compter();


if(!Exist())
{
if(plateau.getlocal(y,x) !=Identite+2)
plateau.setlocal(y, x, 5);

else
plateau.setlocal(y,x,6);
}


//Si le tour est de type action et que le joueur a la possibilité de manger un jeton adverse,
//on effectue l'action.

//MANGER
if(atour !=0 && jepemanger!=0)
{
int valeur=manger(stock);
//5--->Le joueur a choisi un bon jeton mais pas le bon déplacement.
if(valeur==5)
{
mess=""+"Déplacement impossible";

//Couleur or->Initiale.
if(plateau.getlocal(stock[0][1],stock[0][0])==5)
plateau.setlocal(stock[0][1],stock[0][0],Identite);
else
plateau.setlocal(stock[0][1],stock[0][0],Identite+2);
}

else
{

//Le joueur vient de manger un jeton ennemie.
//On modifie le plateau du jeu en conséquence.
if(valeur==1)
plateau.setlocal(stock[0][1]+1,stock[0][0]+1,0);


if(valeur==2)
plateau.setlocal(stock[0][1]-1,stock[0][0]+1,0);

if(valeur==3)
plateau.setlocal(stock[0][1]+1,stock[0][0]-1,0);


if(valeur==4)
plateau.setlocal(stock[0][1]-1,stock[0][0]-1,0);

RetablirCouleur();
plateau.setlocal(stock[0][1],stock[0][0],0);

//On test si le joueur pourra encore manger un jeton ennemie le prochain tour.
//Si c'est le cas, on ne passe pas la main à l'adversaire.
mess=""+"Bon appétit !";

if(!pourramanger(stock[1][0],stock[1][1]))
{
checkout=0; //Le joueur aura le choix du jeton parmi ceux proposés par cpt[][].
//On ne peut pas manger de nouveau donc on passe la main à l'autre joueur
succes=!succes;

}
else
{
//Sinon c'est toujours au même joueur de jouer
checkout=1;//Le joueur sera dans l'obligation de jouer le même jeton.
rem1=stock[1][0]; //x-On sauvegarde les coordonnées du jeton à jouer
rem2=stock[1][1]; //y
}
//A chaque fois qu'un pion va manger un jeton adverse, on joue le son.
MThread thread=new MThread("mange.wav",false);
thread.start();

}

}

else if(atour !=0 && !(TestDep(stock)))
{
mess=""+"Déplacement impossible";

//Le jeton reprend sa couleur initiale. (or -> blanc ou noir)
if(plateau.getlocal(stock[0][1],stock[0][0])==5)
plateau.setlocal(stock[0][1],stock[0][0],Identite);
else
plateau.setlocal(stock[0][1],stock[0][0],Identite+2);
//Le jeton n'a pas été déplacé.
}


//Sinon si le déplacement est possible...
else if(atour !=0)
{
mess=""+"Déplacement réussi";
RetablirCouleur();
plateau.setlocal(stock[0][1],stock[0][0],0);

//C'est au tour de l'autre joueur de jouer
succes=!succes;

}
atour++;
if(atour==2)
atour=0;
}
return succes;
}


public void RetablirCouleur()
{
// On se trouve dans le cas ou l'on joue les jetons blancs.
if(Identite==1)
{
// S'il est question d'un jeton simple sélectionné et qu'il ne se situe pas sur une case de promotion alors ...
if(plateau.getlocal(stock[atour-1][1],stock[atour-1][0])==5 && stock[atour][1]!=0)
plateau.setlocal(stock[atour][1],stock[atour][0],1);
else
// Sinon c'est soit une dame ou soit qu'on a atteint la dernière ligne
plateau.setlocal(stock[atour][1],stock[atour][0],3);
}
else
// Sinon on se trouve dans le cas ou l'on joue les jeton noirs
//On procède de la même manière qu'avec les jetons blancs.
{
if(plateau.getlocal(stock[atour-1][1],stock[atour-1][0])==5 && stock[atour][1]!=10)
plateau.setlocal(stock[atour][1],stock[atour][0],2);
else
plateau.setlocal(stock[atour][1],stock[atour][0],4);
}
}




//Il ne peut avoir qu'un seul jeton/dame sélectionné en même temps.
public boolean Exist()
{
for(int i=0;i<11;i++)
for(int j=0;j<11;j++)
if(plateau.getlocal(i,j)==5 || plateau.getlocal(i,j)==6)
return true;

return false;
}

//On compte le nombre de jeton qui nous appartient.
public int Compter()
{
int cpt=0;
for(int i=0;i<11;i++)
for(int j=0;j<11;j++)
if(plateau.getlocal(i,j)==Identite || plateau.getlocal(i,j)==Identite+2)
cpt++;
return cpt;
}


}//Fin de la classe.



Explication :



Attributs :

private int atour=0 : Cette variable va permettre de connaître le type d’action que le joueur doit effectuer. Si atour=0 alors le joueur se trouvera dans une phase de sélection et il devra donc choisir un pion sinon si atour=1, le joueur sera dans une phase de déplacement et il devra choisir un endroit où déplacer son pion.
private int stock[][]=new int[2][2] : Cette variable est un tableau à deux
dimensions qui va stocker les coordonnées des pions sélectionnés avant et après son
déplacement.
stock[0][0] : abscisse de la position du pion avant le déplacement.
stock[0][1] : ordonnée de la position du pion avant le déplacement.
stock[1][0] : abscisse de la position du pion après le déplacement.
stock[1][1] : ordonnée de la position du pion après le déplacement.
Tous les tests sur les pions se feront à partir de ce tableau.
private int cpt[][]=new int[5][2] : Ce tableau à deux dimensions va stocker les
coordonnées des pions qui peuvent capturer des pions adverses. L’intérêt de ce tableau c’est qu’il permet au joueur de choisir un pion pour la capture d’un pion adverse parmi ceux dont les coordonnées sont stockées dans ce tableau.
private int checkout=0 : Cette variable permet de faire la distinction entre les deux
cas possibles de faire une prise : une prise multiple ou une prise simple. Dans le cas d’une prise multiple, checkout=1, le joueur doit continuer à capturer les pions adverses avec le même pion. Dans l’autre cas, checkout=0, le joueur choisit un pion parmi ceux capables de capturer un pion adverse.
private int rem1=0 : Dans le cas d’une prise multiple, le joueur doit sélectionner un
pion particulier. On stock l’abscisse de la position de ce pion dans cette variable.
private int rem2=0 : Et dans celle-ci, on stock l’ordonnée de la position de ce pion.
protected String mess=new String() : Cette variable permet de stocker les
messages qui seront affichés dans la barre d’état.


Méthodes :

public Joueur(Plateform plateau,int i) : Cette méthode est le constructeur de la
classe « Joueur », elle permet d’initialiser certaines variables contenues dans la classe mère « GamePlay ».
public void RetablirCouleur() : Un pion sélectionné change sa couleur initiale en
couleur or. Cette méthode permet de rétablir la couleur initiale d’un pion.
public boolean Exist() : Cette méthode indique si un pion est déjà sélectionné. Si
c’est le cas elle retourne true sinon false.
public int Compter() : Cette méthode permet tout simplement de retourner le
nombre de pion restant du joueur.
public boolean Jouer(int x,int y,boolean succes,boolean fin[]) : Méthode qui
permet de faire jouer un joueur humain.
La méthode Jouer() sera détaillée dans la seconde sous partie.


La classe « GamePlay » va contrôler tous les faits et gestes du joueur humain. Ainsi, c’est elle qui va permettre de tester le déplacement d’un pion ou d’une dame, contrôler les débordements de plateau, informer si un des pions du joueur peut capturer et si oui, gérer la capture, tester également si ce même pion pourra capturer de nouveau, contrôler si le joueur a perdu ou encore vérifier si le joueur a sélectionné le bon pion.


Source :

package packJeu;
public class GamePlay{

protected Plateform plateau;
protected int jeton;//Valeur pion ennemie
protected int Djeton;//Valeur dame ennemie
protected int Identite;//Joueur blanc --> 1
//Joueur noir --> 2

//Variable qui donne le signal si oui ou non le joueur peut manger un jeton.
protected int jepemanger=0;
//Variable qui indique le nombre de jetons qui peuvent manger un jeton ennemi.
protected int nbPionquiPeManger=0;

public GamePlay(Plateform plateau,int Identite)
{
this.plateau=plateau;
this.Identite=Identite;

if(Identite==1) //Joueur de pion blanc.
{
jeton=2; //Les pions ennemies auront comme valeur : 2
Djeton=4;//Les dames " " 4
}
else if(Identite==2)//Joueur de pion noir.
{
jeton=1; //Les pions ennemies auront comme valeur : 1
Djeton=3;//Les dames " " 3
}
}


//Cette méthode est appelée lorsque le joueur possède des jetons qui peuvent manger un jeton de l'adversaire.
//Elle permet de tester si oui ou non le joueur a bien choisi un bon jeton parmi ceux proposés par le tableau cpt[][]
//dans le cas où la variable checkout=0 sinon on oblige le joueur de jouer le dernier jeton déplacé.
public boolean GooDPiece(int cpt[][],int alors,int x,int y,int checkout,int rem1, int rem2)
{

//On oblige le joueur à jouer avec le même jeton tant qu'il peut manger du jeton adverse.
if(checkout==1)
{
if(rem1==x && rem2==y)
return true;
else
return false;

}
else
{
//On laisse choisir le jeton qui poura manger un jeton ennemie parmi tous ceux qui peuvent en manger un.
for(int i=0;i
if(cpt[i][0]==x && cpt[i][1]==y)//Le jeton selectionné correspond bien à un jeton dont les coordonnées ont été sauvegardées dans le table cpt[][].
return true;

//Sinon on return false ce qui obligera par la suite de sélectionner un nouveau jeton et ce, jusqu'à ce que le joueur choisisse un bon jeton.
return false;
}

}

//Si le joueur n'est pas dans l'obligation de manger alors il peut effectuer un déplacement.
//Cette méthode gère le deplacement des jetons de base mais également celui des dames.
public boolean TestDep(int stock[][])
{
if(jeton==2)
{

//On test pour savoir si la case où l'on veut se déplacer est vide
//Si la case est occupée par un jeton adverse, la méthode manger() entre en jeu.
if(plateau.getlocal(stock[1][1],stock[1][0])==Identite || plateau.getlocal(stock[1][1],stock[1][0])==Identite+2
|| plateau.getlocal(stock[1][1],stock[1][0])==jeton || plateau.getlocal(stock[1][1],stock[1][0])==Djeton)
return false;

//Les jetons de base ne peuvent pas reculer.
if(plateau.getlocal(stock[0][1],stock[0][0])==5)
{
if(stock[1][0]==stock[0][0]+1 && stock[1][1]==stock[0][1]-1 ||
stock[1][0]==stock[0][0]-1 && stock[1][1]==stock[0][1]-1 )
return true;
}
else
{
//Les dames peuvent avancer et reculer.
if(stock[1][0]==stock[0][0]+1 && stock[1][1]==stock[0][1]-1 ||
stock[1][0]==stock[0][0]-1 && stock[1][1]==stock[0][1]+1 ||
stock[1][0]==stock[0][0]-1 && stock[1][1]==stock[0][1]-1 ||
stock[1][0]==stock[0][0]+1 && stock[1][1]==stock[0][1]+1)
return true;
}
}

else
{
//On test pour savoir si la case où l'on veut se déplacer est vide
if(plateau.getlocal(stock[1][1],stock[1][0])==Identite || plateau.getlocal(stock[1][1],stock[1][0])==Identite+2
|| plateau.getlocal(stock[1][1],stock[1][0])==jeton || plateau.getlocal(stock[1][1],stock[1][0])==Djeton)
return false;


if(plateau.getlocal(stock[0][1],stock[0][0])==5)
{
//Les jetons de base ne peuvent pas reculer.
if(stock[1][0]==stock[0][0]+1 && stock[1][1]==stock[0][1]+1 ||
stock[1][0]==stock[0][0]-1 && stock[1][1]==stock[0][1]+1 )
return true;
}

else
{
//Les dames peuvent avancer et reculer.
if(stock[1][0]==stock[0][0]+1 && stock[1][1]==stock[0][1]+1 ||
stock[1][0]==stock[0][0]-1 && stock[1][1]==stock[0][1]+1 ||
stock[1][0]==stock[0][0]-1 && stock[1][1]==stock[0][1]-1 ||
stock[1][0]==stock[0][0]+1 && stock[1][1]==stock[0][1]-1)
return true;
}
}
//Sinon le mouvement n'est pas accepté.
return false;
}

//Cette méthode permet de verifier si les indices passés en paramètre sort de la matrice, autrement dit,
//on test si les indices ne correspondent pas à une zone externe du plateau de jeu.
public boolean jedepasseoupas(int x,int y)
{
if(x<0>10)
return true;

if(y<0>10)
return true;

else
return false;

}


public int pemanger(int cpt[][])
{
//Variable qui compte le nombre de jetons qui peuvent manger des jetons de l'adversaire.
int capturer=0;


for(int i=0;i<11;i++)
for(int j=0;j<11;j++)
{
//On test si l'endroit où on se trouve correspond bien à un de nos jetons.
if(plateau.getlocal(j,i)==Identite || plateau.getlocal(j,i)==Identite+2)
{
//On test tout d'abord si on ne sort pas du plateau de jeu.
if(!jedepasseoupas(i+2,j+2))
{
//Puis on test si un jeton ennemie est à proximité et si ce dernier est capturable.
if((plateau.getlocal(j+1,i+1)==jeton || plateau.getlocal(j+1,i+1)==Djeton) && plateau.getlocal(j+2,i+2)==0)
{
cpt[capturer][0]=i;
cpt[capturer][1]=j;
capturer++;
}
}

if(!jedepasseoupas(i+2,j-2))
{

if((plateau.getlocal(j-1,i+1)==jeton || plateau.getlocal(j-1,i+1)==Djeton) && plateau.getlocal(j-2,i+2)==0)
{
cpt[capturer][0]=i;
cpt[capturer][1]=j;
capturer++;
}
}

if(!jedepasseoupas(i-2,j+2))
{
if((plateau.getlocal(j+1,i-1)==jeton || plateau.getlocal(j+1,i-1)==Djeton) && plateau.getlocal(j+2,i-2)==0 )
{
cpt[capturer][0]=i;
cpt[capturer][1]=j;
capturer++;
}
}
if(!jedepasseoupas(i-2,j-2))
{
if((plateau.getlocal(j-1,i-1)==jeton || plateau.getlocal(j-1,i-1)==Djeton) && plateau.getlocal(j-2,i-2)==0)
{

cpt[capturer][0]=i;
cpt[capturer][1]=j;
capturer++;

}
}
}
}
//Si le compteur n'est pas égal à 0 alors il y a des jetons à manger donc...
if(capturer!=0)
jepemanger=1;
else//Sinon...
jepemanger=0;
nbPionquiPeManger=capturer;
return capturer;

}


public int manger(int stock[][])
{
//Pour chaque cas, on test donc si derrière le jeton ennemie se trouve une case vide.

//On test s'il est possible de manger un jeton adverse.
//Si oui, on reagit en fonction de l'action du joueur :
//1) Le joueur a placé son jeton juste derrière de celui de l'adversaire----->On return un int qui indique la manière dont a été mangé le jeton
//ce qui par la suite, facilitera la gestion du plateau.Par exemple, si la valeur retournée est 1 alors je sais que le jeton mangé se situe
//en bas à droite avant mon déplacement. 2---->en haut à droite, 3---->en bas à gauche et 4---->en haut à gauche.
//2) Le joueur a tenté d'effecuter une action autre que manger un jeton adverse, la valeur retournée sera 5 ce qui indiquera une erreur de déplacement.

if(plateau.getlocal(stock[1][1],stock[1][0])==0 && stock[1][0]==stock[0][0]+2 && stock[1][1]==stock[0][1]+2
&& (plateau.getlocal(stock[0][1]+1,stock[0][0]+1)==jeton || plateau.getlocal(stock[0][1]+1,stock[0][0]+1)==Djeton))
return 1;



if(plateau.getlocal(stock[1][1],stock[1][0])==0 && stock[1][0]==stock[0][0]+2 && stock[1][1]==stock[0][1]-2
&& (plateau.getlocal(stock[0][1]-1,stock[0][0]+1)==jeton || plateau.getlocal(stock[0][1]-1,stock[0][0]+1)==Djeton))
return 2;



if(plateau.getlocal(stock[1][1],stock[1][0])==0 && stock[1][0]==stock[0][0]-2 && stock[1][1]==stock[0][1]+2
&& (plateau.getlocal(stock[0][1]+1,stock[0][0]-1)==jeton || plateau.getlocal(stock[0][1]+1,stock[0][0]-1)==Djeton))
return 3;



if(plateau.getlocal(stock[1][1],stock[1][0])==0 && stock[1][0]==stock[0][0]-2 && stock[1][1]==stock[0][1]-2
&& (plateau.getlocal(stock[0][1]-1,stock[0][0]-1)==jeton || plateau.getlocal(stock[0][1]-1,stock[0][0]-1)==Djeton))
return 4;


else
return 5;


}


//Comme son nom l'indique, on test si un jeton aux coordonnées x et y pourra manger de nouveau un jeton.
public boolean pourramanger(int x,int y)
{

if(!jedepasseoupas(x+2,y+2))
if((plateau.getlocal(y+1,x+1)==jeton || plateau.getlocal(y+1,x+1)==Djeton)
&& plateau.getlocal(y+2,x+2)==0)
return true;



if(!jedepasseoupas(x-2,y+2))
if((plateau.getlocal(y+1,x-1)==jeton || plateau.getlocal(y+1,x-1)==Djeton)
&& plateau.getlocal(y+2,x-2)==0)
return true;



if(!jedepasseoupas(x+2,y-2))
if((plateau.getlocal(y-1,x+1)==jeton || plateau.getlocal(y-1,x+1)==Djeton)
&& plateau.getlocal(y-2,x+2)==0)
return true;


if(!jedepasseoupas(x-2,y-2))
if((plateau.getlocal(y-1,x-1)==jeton || plateau.getlocal(y-1,x-1)==Djeton)
&& plateau.getlocal(y-2,x-2)==0)
return true;

return false;

}//Fin de la fonction


public boolean aperdu()
{
boolean perdu=true;

for(int i=0;i<11;i++)
for(int j=0;j<11;j++)
{
//On test si il existe au moins un jeton qui puisse se déplacer ou manger , on n'oublie pas celui qui vient d'être
//sélectionné (plateau.getlocal(i,j)==5 ou si c'est une dame plateau.getlocal(i,j)==6)
if(plateau.getlocal(i,j)==Identite || plateau.getlocal(i,j)==Identite+2 ||
plateau.getlocal(i,j)==5 || plateau.getlocal(i,j)==6)
{

if(Identite==2 || plateau.getlocal(i,j)==3 || plateau.getlocal(i,j)==6)
{
if(!jedepasseoupas(j+1,i+1))
{
if(plateau.getlocal(i+1,j+1)==0)
perdu=false;
}

if(!jedepasseoupas(j-1,i+1))
{
if(plateau.getlocal(i+1,j-1)==0)
perdu=false;
}
}

if(Identite==1 || plateau.getlocal(i,j)==4 || plateau.getlocal(i,j)==6)
{
if(!jedepasseoupas(j-1,i-1))
{
if(plateau.getlocal(i-1,j-1)==0)
perdu=false;
}

if(!jedepasseoupas(j+1,i-1))
{
if(plateau.getlocal(i-1,j+1)==0)
perdu=false;
}
}

if(pourramanger(j,i))
perdu=false;


}
}
return perdu;
}

}//Fin de la classe



Explications :


Attributs :

protected Plateform plateau : Cette variable est de type Plateform, elle représente
le plateau du jeu. Tous les tests sur les pions se baseront sur ce plateau.
protected int jeton : Cette variable va prendre comme valeur celle des pions
(Dames exclues) de l’adversaire. Par exemple, la valeur de la variable jeton prendra la valeur 2 si le joueur joue avec les pions blancs.
protected int Djeton : Cette variable va prendre comme valeur celle des Dames de
l’adversaire.
protected int Identite : Cette variable va prendre comme valeur 1 si le joueur joue
les pions blancs sinon 2.
protected int jepemanger=0 : Cette variable s’initialise lors de l’appel de la méthode pemanger(). Si le joueur est dans une situation où il peut effectivement manger un pion de l’adversaire, la variable jepemanger prend comme valeur 1 sinon elle prend 0.
protected int nbPionquiPeManger=0 : Cette variable va stocker le nombre de pion
qui peut capturer un pion de l’adversaire.


Méthodes :

public GamePlay(Plateform plateau,int Identite): Cette méthode est le
constructeur de la classe « GamePlay ». Elle permet d’initialiser les variables plateau, Identite, jeton et Djeton.
public boolean GooDPiece(int cpt[][],int alors,int x,int y,int checkout,int
rem1, int rem2) : Cette méthode permet de vérifier si le joueur a sélectionné soit un
bon pion parmi ceux stockés dans la variable cpt[][] (checkout=0), soit le pion qui a déjà mangé au moins un pion de l’adversaire et qui peut de nouveau en manger un autre
(checkout=1).
public boolean TestDep(int stock[][]): Cette méthode permet de tester le
déplacement d’un pion. Si le déplacement est possible, la méthode retourne true sinon
elle retourne false.
public boolean jedepasseoupas(int x,int y) : Cette méthode permet tout
simplement de vérifier si, lors des tests, on ne sort pas du plateau de jeu.
public int pemanger(int cpt[][]) : Cette méthode permet de vérifier si le joueur
est dans une situation où il peut manger un pion adverse. Pour cela, elle vérifie dans les 4 diagonales si chaque pion du joueur peut capturer un pion adverse. De plus, elle retourne le nombre de pion qui peut capturer un pion de l’adversaire. C’est dans cette méthode que les variables cpt[][], jepemanger et nbPionPeManger s’initialisent.
public int manger(int stock[][]) : Cette méthode va gérer la capture d’un pion
adverse. En fonction des coordonnées du pion sélectionné et des coordonnées de la case où l’on veut déplacer le pion, cette méthode retourne une valeur correspondant au sens de la prise :
1 : En bas à droite.
2 : En haut à droite.
3 : En bas à gauche.
4 : En haut à gauche.
5 : Déplacement impossible.
En fonction de la valeur retournée, en modifiera le plateau dans la méthode « Jouer() ».
public boolean pourramanger(int x,int y) : Cette méthode indique si un pion,
dont les coordonnées sont passées en paramètre, est capable de manger de nouveau un
pion de l’adversaire. Cette méthode permet donc de savoir s’il est question d’une prise multiple ou simple.
public boolean aperdu() : Cette méthode permet de vérifier si le joueur a perdu la
partie. Pour ceci, on test si il n’existe pas au moins un jeton qui peut soit manger un pion adverse, soit se déplacer. La méthode retourne true si le joueur a perdu sinon false.


La classe « Jeu » permet de gérer une partie de jeu entre deux humains ou entre un humain et un ordinateur. Après chaque tour pour chacun des joueurs, il sera indispensable de mettre à jour la fenêtre. Ainsi, la classe « Jeu » sera responsable de la maintenance de la fenêtre de jeu.


Source :


package packJeu;
import java.awt.event.*;



public class Jeu extends FenetreduJeu{

private static final long serialVersionUID = 9058170540313820419L;



public void JvsJ(int x,int y)
{
if(!succes)
{ //Joueur P1 joue...
pa.mess=""+"Tour P1 :";
succes=pa.Jouer(x,y,succes,perdu);
tf.setText(pa.mess);
update();
if(perdu[0])
WinorLose("J2.png","victoire.wav");
}
else if(succes)
{ //Joueur P2 joue...
pb.mess=""+"Tour P2 :";
tf.setText(pb.mess);
succes=pb.Jouer(x,y,succes,perdu);
tf.setText(pb.mess);
update();
if(perdu[0])
WinorLose("J1.png","victoire.wav");
}
}


public void IAvsJoueur(int x,int y)
{
if(!succes)
{ //Joueur P1 joue...
pa.mess=""+"Tour P1 :";
tf.setText(pa.mess);
succes=pa.Jouer(x,y,succes,perdu);
tf.setText(pa.mess);
update();
if(perdu[0])
WinorLose("game-over.jpg","defaite.wav");


}
if(succes)
{ //IA joue
succes=pb.Jouer(x,y,succes,perdu);
tf.setText("AI a joué !!");
update();
if(perdu[0])
WinorLose("J1.png","victoire.wav");
}
}



//Gestion de la partie entre 2 joueurs humains ou entre un ordinateur et un joueur.
public void jouer()
{
addMouseListener(new MouseAdapter()
{
//La variable succes permet de faire jouer les joueurs chacun leur tour.
public void mousePressed(MouseEvent e)
{
int x = e.getX();
int y = e.getY();

if(cas==1)//Joueur VS Joueur
JvsJ(x,y);

else//AI vs Joueur
IAvsJoueur(x,y);
}

});
}




public static void main(String argc[])
{

Jeu j=new Jeu();
j.jouer();

}

}//Fin de la classe.


Explication :

Attributs :

protected boolean perdu[] : Tableau de booléen qui va permettre de tester si le
joueur a perdu.
private FenetreduJeu fenetre : Instance de la classe « FenetreduJeu ».
private Joueur P1 : Joueur 1.
private Joueur P2 : Joueur 2.


Méthodes :

public Jeu() : Initialisation de la fenêtre de jeu et de l’attribut perdu à false.
public void JvsJ(int x,int y) : Cette méthode permet de gérer une partie entre
deux joueurs humains. Lorsqu’un joueur joue, il modifie la variable « succes ». Le joueur
P1 passe son tour lorsque succes=true et le joueur P2 passe le sien lorsque succes=false.
Les paramètres x et y correspondent aux coordonnées de l’endroit cliqué avec la souris.
public void IAvsJoueur(int x,int y) : Cette méthode permet de gérer une partie
entre un joueur humain et un ordinateur. Elle ressemble fortement à la méthode du
dessus mise à part un détail, dans cette méthode le tour par tour est géré par deux
conditions if alors que dans l’autre méthode, le tour par tour est géré par les deux
conditions suivantes if et else if. Cette différence permet au joueur de ne pas devoir cliquer avec la souris pour passer son tour lorsqu’il joue contre un ordinateur.
public void jouer() : Cette méthode gère une partie de jeu de dames. En fonction
des choix du joueur via le menu, cette méthode fera appel soit à la méthode JvsJ() ou
soit à la méthode IAvsJoueur(). Pour pouvoir jouer, la méthode jouer() fait appel à la méthode addMouseListener() contenue dans la classe « MouseListener ». Dès que le
joueur pressera le bouton de la souris, la méthode addMouseListener() fera appel à la
méthode MousePressed() pour gérer l’action.



La classe « IA » permet de créer un joueur virtuel contre qui un joueur humain pourra
jouer. Une IA est un Joueur à part entière, le faite qu’elle hérite de la classe Joueur lui procure comme type déclaré « Joueur » et comme type réel « IA ». De plus, « Joueur »
hérite de « GamePlay » ce qui, par transitivité, conduit « IA » à être une classe dérivée de « GamePlay ». L’avantage d’une telle structure réside dans l’implémentation des classes « Joueur » et « IA ». En effet, il n’est pas nécessaire de redéfinir les méthodes aperdu() et pourramanger() dans chaque une des classes filles.



Source :


package packJeu;

public class IA extends Joueur
{
//Tableau qui va stocker tous les jetons qui appartiennent à l'ordinateur.
private int tab[][];
//Nombre de jeton qui reste.
private int n;
//La variable rem(=remember) permet à l'ordinateur de jouer avec le même jeton dans le cas
//où le jeton peut manger de nouveau.
private int rem[];


public IA(Plateform p,int i)
{
super(p,i);
tab=new int [30][4];
n=0;
rem=new int[2];
rem[0]=0; //On stockera x
rem[1]=0;// et y
}

//On remplie le tableau.
public void Fill()
{
n=0;
for(int i=0;i<11;i++)
{
for(int j=0;j<11;j++)
{
if(plateau.getlocal(i,j)==Identite)
{
tab[n][1]=i;
tab[n][0]=j;
tab[n][2]=Identite; //Présence d'un jeton noir
n++;
}
if(plateau.getlocal(i,j)==Identite+2)
{
tab[n][1]=i;
tab[n][0]=j;
tab[n][2]=Identite+2; //Présence d'une dame noir
n++;
}
}
}

}

//De la même manière que manger() de la classe Joueur(), on test tout d'abord si on ne sort pas du plateau de jeu.
//Puis, on test si un jeton ennemi à proximité est capturable.
//Si c'est le cas, on sauvegarde alors les coordonnées du jeton qui peut manger dans la variable rem.
public boolean manger()
{
int j=0;

if(rem[0] !=0 && rem[1] !=0)
while(!(tab[j][0]==rem[0] && tab[j][1]==rem[1]))
{
System.out.println("j :"+j);
j++;
}

for(int i=j;i
{
if(!jedepasseoupas(tab[i][0]+2,tab[i][1]+2))
{
if((plateau.getlocal(tab[i][1]+1,tab[i][0]+1)==jeton || plateau.getlocal(tab[i][1]+1,tab[i][0]+1)==Djeton) && plateau.getlocal(tab[i][1]+2,tab[i][0]+2)==0)
{
plateau.setlocal(tab[i][1],tab[i][0],0);
plateau.setlocal(tab[i][1]+1,tab[i][0]+1,0);
//Même algo que pour Joueur.

if(tab[i][2]==Identite && tab[i][1]+2!=10)
plateau.setlocal(tab[i][1]+2,tab[i][0]+2,Identite);
else
plateau.setlocal(tab[i][1]+2,tab[i][0]+2,Identite+2);

rem[0]=tab[i][0]+2;
rem[1]=tab[i][1]+2;
return true;
}


}

if(!jedepasseoupas(tab[i][0]-2,tab[i][1]+2))
{
if((plateau.getlocal(tab[i][1]+1,tab[i][0]-1)==jeton || plateau.getlocal(tab[i][1]+1,tab[i][0]-1)==Djeton) && plateau.getlocal(tab[i][1]+2,tab[i][0]-2)==0)
{
plateau.setlocal(tab[i][1],tab[i][0],0);
plateau.setlocal(tab[i][1]+1,tab[i][0]-1,0);

if(tab[i][2]==Identite && tab[i][1]+2!=10)
plateau.setlocal(tab[i][1]+2,tab[i][0]-2,Identite);
else
plateau.setlocal(tab[i][1]+2,tab[i][0]-2,Identite+2);

rem[0]=tab[i][0]-2;
rem[1]=tab[i][1]+2;
return true;

}

}


if(!jedepasseoupas(tab[i][0]+2,tab[i][1]-2))
{
if((plateau.getlocal(tab[i][1]-1,tab[i][0]+1)==jeton || plateau.getlocal(tab[i][1]-1,tab[i][0]+1)==Djeton) && plateau.getlocal(tab[i][1]-2,tab[i][0]+2)==0)
{
plateau.setlocal(tab[i][1],tab[i][0],0);
plateau.setlocal(tab[i][1]-1,tab[i][0]+1,0);

if(tab[i][2]==Identite && tab[i][1]-2!=0)
plateau.setlocal(tab[i][1]-2,tab[i][0]+2,Identite);
else
plateau.setlocal(tab[i][1]-2,tab[i][0]+2,Identite+2);

rem[0]=tab[i][0]+2;
rem[1]=tab[i][1]-2;
return true;

}


}

if(!jedepasseoupas(tab[i][0]-2,tab[i][1]-2))
{
if((plateau.getlocal(tab[i][1]-1,tab[i][0]-1)==jeton || plateau.getlocal(tab[i][1]-1,tab[i][0]-1)==Djeton) && plateau.getlocal(tab[i][1]-2,tab[i][0]-2)==0)
{
plateau.setlocal(tab[i][1],tab[i][0],0);
plateau.setlocal(tab[i][1]-1,tab[i][0]-1,0);

if(tab[i][2]==Identite && tab[i][1]-2 != 0)
plateau.setlocal(tab[i][1]-2,tab[i][0]-2,Identite);
else
plateau.setlocal(tab[i][1]-2,tab[i][0]-2,Identite+2);

rem[0]=tab[i][0]-2;
rem[1]=tab[i][1]-2;
return true;
}

}
}
//Aucun jeton peut manger donc on reinitialise rem.
rem[0]=0;
rem[1]=0;
return false;

}


//Cette méthode permet de faire jouer un ordinateur.
public boolean Jouer(int x,int y,boolean succes,boolean fin[]){

Fill();
//Pause
long time2=0;
long time=System.currentTimeMillis();
while(time2<(time+500))
time2=System.currentTimeMillis();

if(aperdu())
fin[0]=true;

//On test si on peut manger et si oui, on mange!
if(manger())
{
//On test si le jeton qui vient de manger peut manger de nouveau.
if(pourramanger(rem[0],rem[1]))
Jouer(x,y,succes,fin); //Si oui, on fait un appel reccursif de la fonction Jouer()

else//Sinon on passe la main à l'adversaire.
{
rem[0]=0;
rem[1]=0;
return !succes;
}
}
else //Si on ne peut pas manger, alors on se déplace.
Deplacement();

//Puis on passe la main à l'adversaire.
return !succes;
}


//On verifie si l'endroit où l'ordinateur veut deplacer son jeton est libre.
public boolean TestDep(int x,int y)
{

if(plateau.getlocal(x,y) == 0)
return true;

else
return false;
}

//Dans le cas où l'ordinateur ne peut pas manger, il effectue un déplacement mais pas n'importe comment.
//En effet, il test tout d'abord si l'endroit où il veut déplacer son jeton est libre, puis si à cet endroit il ne sera pas mangé.
//Si tout est bon, alors il effectue l'action sinon il change de jeton et il refait les mêmes tests.
//Si aucun jeton ne peut être deplacé sans être mangé alors il joue tout de même un jeton.

public boolean DeplacementHG(int i,int j)
{
if(!jedepasseoupas(tab[i][0]-1,tab[i][1]-1))
{
//CAS EN HAUT A GAUCHE
if(j==0)
{
if(TestDep(tab[i][1]-1,tab[i][0]-1) && !vaetremange(tab[i][0]-1,tab[i][1]-1,3))
{
plateau.setlocal(tab[i][1],tab[i][0],0);
if(tab[i][2]==Identite && tab[i][1]-1!=0)
plateau.setlocal(tab[i][1]-1,tab[i][0]-1,Identite);
else
plateau.setlocal(tab[i][1]-1,tab[i][0]-1,Identite+2);

return true;



}
}

if(j==1)
{
if(TestDep(tab[i][1]-1,tab[i][0]-1))
{
plateau.setlocal(tab[i][1],tab[i][0],0);
if(tab[i][2]==Identite && tab[i][1]-1!=0)
plateau.setlocal(tab[i][1]-1,tab[i][0]-1,Identite);
else
plateau.setlocal(tab[i][1]-1,tab[i][0]-1,Identite+2);

return true;

}


}
}
return false;

}

public boolean DeplacementHD(int i,int j)
{
if(!jedepasseoupas(tab[i][0]+1,tab[i][1]-1))
{
//CAS EN HAUT A DROITE
if(j==0)
{
if(TestDep(tab[i][1]-1,tab[i][0]+1) && !vaetremange(tab[i][0]+1,tab[i][1]-1,2))
{

plateau.setlocal(tab[i][1],tab[i][0],0);

if(tab[i][2]==Identite && tab[i][1]-1!=0)
plateau.setlocal(tab[i][1]-1,tab[i][0]+1,Identite);
else
plateau.setlocal(tab[i][1]-1,tab[i][0]+1,Identite+2);

return true;
}

}


if(j==1)
{
if(TestDep(tab[i][1]-1,tab[i][0]+1))
{
plateau.setlocal(tab[i][1],tab[i][0],0);
if(tab[i][2]==Identite && tab[i][1]-1!=0)
plateau.setlocal(tab[i][1]-1,tab[i][0]+1,Identite);
else
plateau.setlocal(tab[i][1]-1,tab[i][0]+1,Identite+2);

return true;
}

}
}
return false;

}

public boolean DeplacementBG(int i,int j)
{
//On effectue les mêmes tests pour les 3 autres directions.
if(!jedepasseoupas(tab[i][0]-1,tab[i][1]+1))
{
//CAS EN BAS A GAUCHE
if(j==0)
{
if(TestDep(tab[i][1]+1,tab[i][0]-1) && !vaetremange(tab[i][0]-1,tab[i][1]+1,1))
{
plateau.setlocal(tab[i][1],tab[i][0],0);
if(tab[i][2]==Identite && tab[i][1]+1!=10)
plateau.setlocal(tab[i][1]+1,tab[i][0]-1,Identite);
else
plateau.setlocal(tab[i][1]+1,tab[i][0]-1,Identite+2);

return true;



}
}

if(j==1)
{
if(TestDep(tab[i][1]+1,tab[i][0]-1))
{
plateau.setlocal(tab[i][1],tab[i][0],0);
if(tab[i][2]==Identite && tab[i][1]+1!=10)
plateau.setlocal(tab[i][1]+1,tab[i][0]-1,Identite);
else
plateau.setlocal(tab[i][1]+1,tab[i][0]-1,Identite+2);

return true;

}


}
}
return false;
}

public boolean DeplacementBD(int i,int j)
{

if(!jedepasseoupas(tab[i][0]+1,tab[i][1]+1))
{
if(j==0) //Premier tour
{
if(TestDep(tab[i][1]+1,tab[i][0]+1) && !vaetremange(tab[i][0]+1,tab[i][1]+1,0)) //On test si la case est vide et si le jeton ne va pas être mangé.
{
//Si c'est le cas, on modifie le plateau de jeu en conséquence
plateau.setlocal(tab[i][1],tab[i][0],0);

if(tab[i][2]==Identite && tab[i][1]+1!=10)
plateau.setlocal(tab[i][1]+1,tab[i][0]+1,Identite);
else
plateau.setlocal(tab[i][1]+1,tab[i][0]+1,Identite+2);

return true;
}

}


if(j==1)//Second tour
{
if(TestDep(tab[i][1]+1,tab[i][0]+1)) //On test uniquement si la case est vide.
{
plateau.setlocal(tab[i][1],tab[i][0],0);
if(tab[i][2]==Identite && tab[i][1]+1!=10)
plateau.setlocal(tab[i][1]+1,tab[i][0]+1,Identite);
else
plateau.setlocal(tab[i][1]+1,tab[i][0]+1,Identite+2);

return true;
}
}
}
return false;

}


public boolean Deplacement()
{
//Le principe est simple :

int j=0;
while(j<2) j="=">
{ //Si cela n'est pas possible, on refait un tour (j==1) mais cette fois on ne verifie plus si le jeton déplacé va être mangé.
for(int i=n-1;i>=0;i--)
{

//Jeton noir
if(Identite==2)
{
if(tab[i][2]==Identite+2)
{
if(DeplacementHG(i,j))
return true;

if(DeplacementHD(i,j))
return true;
}

if(tab[i][2]==Identite+2 && compteur()==0 || tab[i][2]==Identite)
{
if(DeplacementBD(i,j))
return true;

if(DeplacementBG(i,j))
return true;
}


}

//Jeton blanc
if(Identite==1)
{
if(tab[i][2]==Identite+2)
{
if(DeplacementBD(i,j))
return true;

if(DeplacementBG(i,j))
return true;
}

if(tab[i][2]==Identite+2 && compteur()==0 || tab[i][2]==Identite)
{
if(DeplacementHG(i,j))
return true;

if(DeplacementHD(i,j))
return true;
}
}

} //Fin for()

j++;
}//Fin while()

return false;

}


//On compte le nombre de jeton (dame exclue) qui reste.
public int compteur()
{
int compt=0;
for(int i=0;i<11;i++)
for(int j=0;j<11;j++)
if(plateau.getlocal(i,j)==Identite)
compt++;

return compt;

}

//Fonction qui test si un des jetons de l'ordinateur peut être mangé.
public boolean vaetremange(int x,int y,int cas)
{
//On se trouve sur une arrête du plateau, aucun jeton ne peut être mangé.
if(y==0 || y==10 || x==0 || x==10)
return false;


else
{

if(cas==0)
if((plateau.getlocal(y+1,x+1)==jeton || plateau.getlocal(y+1,x+1)==Djeton))
return true;
if(cas!=0)
if((plateau.getlocal(y+1,x+1)==jeton || plateau.getlocal(y+1,x+1)==Djeton)&& plateau.getlocal(y-1,x-1)==0)
return true;


if(cas==2)
if((plateau.getlocal(y-1,x+1)==jeton || plateau.getlocal(y-1,x+1)==Djeton))
return true;
if(cas!=2)
if((plateau.getlocal(y-1,x+1)==jeton || plateau.getlocal(y-1,x+1)==Djeton) && plateau.getlocal(y+1,x-1)==0)
return true;


if(cas==1)
if((plateau.getlocal(y+1,x-1)==jeton || plateau.getlocal(y+1,x-1)==Djeton))
return true;
if(cas!=1)
if((plateau.getlocal(y+1,x-1)==jeton || plateau.getlocal(y+1,x-1)==Djeton) && plateau.getlocal(y-1,x+1)==0)
return true;


if(cas==3)
if((plateau.getlocal(y-1,x-1)==jeton || plateau.getlocal(y-1,x-1)==Djeton))
return true;
if(cas!=3)
if((plateau.getlocal(y-1,x-1)==jeton || plateau.getlocal(y-1,x-1)==Djeton) && plateau.getlocal(y+1,x+1)==0)
return true;
return false;
}
}

}//Fin de la classe


Explication :


Attributs :

private int tab[][] : Cette variable est un tableau à deux dimensions. Ce tableau va
permettre de stocker les coordonnées et la valeur de chacun des pions de l’ordinateur.
tab[i][0] : abscisse de la position du pion
tab[i][1] : ordonnée de la position du pion
tab[i][2] : valeur du pion
et i correspond au ième pion.
private int n : Cette variable représente le nombre de pion restant.
private int rem[] : La variable rem(=remember) est un tableau qui va stocker les
coordonnées d’un des pions de l’ordinateur ce qui, par la suite, lui permettra de jouer avec le même jeton dans le cas où ce jeton pourra manger de nouveau.


Méthodes :

public IA(Plateform p,int i) : Cette méthode est le constructeur de la classe
« IA ». Cette méthode initialise les attributs de la classe « GamePlay » puis également ses attributs.
public void Fill() : Cette méthode permet de remplir le tableau tab[][].
public boolean manger() : De la même manière que pemanger() de la classe
« GamePlay », on test tout d'abord si on ne sort pas du plateau de jeu puis on test si un jeton ennemi à proximité est capturable.
Si c'est le cas, on sauvegarde alors dans la variable rem les coordonnées du pion qui
peut capturer.
public boolean TestDep(int x,int y) : Cette méthode test si la case où l’ordinateur
veut déplacer un des ses pions est libre (La valeur de la case est égale à 0).
public boolean DeplacementHG(int i,int j): Cette méthode contrôle le
déplacement en diagonale orientée vers le haut à gauche d’un pion. Pour ceci, on vérifie que le pion ne sort pas du plateau de jeu et qu’une fois arrivé sur la nouvelle case, il ne se fera pas manger par un pion adverse. Si cela n’est pas réalisable, alors l’ordinateur change de pion et effectue de nouveau les mêmes tests. Si aucun pion n’a pu être déplacé, on refait un tour mais cette fois ci en supprime le test qui vérifie si le pion se fera mangé sur la nouvelle case. En procédant de cette manière, on est sûr que l’ordinateur déplacera un de ses pions. Si l’ordinateur n’a effectué aucun déplacement, c’est que tous ses pions sont bloqués ce qui signifie que l’ordinateur a perdu la partie.
Cette méthode sera détaillée dans la dernière sous partie.
public boolean DeplacementHD(int i,int j): Identique à la méthode
DeplacementHG() mais pour la diagonale orientée vers le haut à droite.
public boolean DeplacementBG(int i,int j): Identique à la méthode
DeplacementHG() mais pour la diagonale orientée vers le bas à gauche.
public boolean DeplacementBD(int i,int j): Identique à la méthode
DeplacementHG() mais pour la diagonale orientée vers le bas à droite.
public boolean Deplacement() : Cette méthode gère le déplacement complet d’un
pion (Dames incluses). Cette méthode sera détaillée dans la toute dernière sous partie.
public int compteur() : Cette méthode retourne le nombre de pion (Dames exclues)
restant.
public boolean vaetremange(int x,int y,int cas) : Cette méthode vérifie si la
case où le pion va se déplacer, ce dernier va se faire capturer. Tout comme la méthode Deplacement(), cette méthode sera détaillée par la suite.
public boolean Jouer(int x,int y,boolean succes,boolean fin[]) : Méthode qui
permet de faire jouer un ordinateur. L’ordinateur possèdera comme algorithme :
1-Si je peux capturer.
1.1-Je capture tant qu’il existe un pion de l’adversaire à prendre.
2-Sinon je déplace un pion sur une case où il ne sera pas capturé
2.2-Si cela n’est pas possible je change de pion.
2.3-Si aucun pion n’a été déplacé à la fin du tour.
2.4-Je refais un tour mais je ne vérifie plus si mon pion peut être
capturé.


La classe « Plateform » (Traduit en français par plateau) constitue le plateau du jeu et donc la pièce maîtresse du moteur de jeu. De plus, outre le fait qu’elle représente une pièce importante pour le moteur du jeu, tout l’affichage graphique d’une partie de jeu est basé dessus. Le plateau de jeu est symbolisé par une matrice constituée de 11 lignes et de 11 colonnes. Les coefficients de la matrice représente l’objet qui doit être dessiné sur le damier lors de l’affichage graphique. Les différentes valeurs possibles sont au nombre de 7 :
0 : case vide.
1 : case avec un pion blanc.
2 : case avec un pion noir.
3 : case avec une dame blanche.
4 : case avec une dame noire.
5 : case avec un pion sélectionné. (Blanc -> or, noir -> or)
6 : case avec une dame sélectionnée. (Dame blanche -> Dame or, Dame noir -> Dame
or).
Une matrice est particulièrement pratique pour gérer le damier du jeu. Par exemple, si un pion atteint une case de promotion, il suffira de remplacer à la bonne position la valeur du pion par la valeur de la dame correspondant à sa couleur.



Source :

package packJeu;


public class Plateform
{
//Plateau de jeu.
private int tab[][];

public Plateform()
{
tab=new int [11][11];
Fill();
}

//On remplie le tableau :
//On place les jetons avec une case vide d'intervalle
//On commence par placer les jetons noirs puis ensuite les jetons blancs.
public void Fill()
{
for(int i=0;i<11;i++)
for(int j=0;j<11;j++)
{
if(i==0 || i==2 )
{
if(j%2==0)
tab[i][j]=0;
else
tab[i][j]=2;
}
else if(i==1 || i==3)
{
if(j%2!=0)
tab[i][j]=0;
else
tab[i][j]=2;
}

if(i==7 || i==9)
{
if(j%2!=0)
tab[i][j]=0;
else
tab[i][j]=1;
}
else if(i==8 || i==10)
{
if(j%2==0)
tab[i][j]=0;
else
tab[i][j]=1;
}

}
}


//On reinitialise le plateau a 0.
public void nouveau()
{
//Clean all
for(int i=0;i<11;i++)
for(int j=0;j<11;j++)
tab[i][j]=0;

//On réinitialise le plateau.
Fill();
}


//Accesseurs
public int getlocal(int x, int y)
{
return tab[x][y];
}

public void setlocal(int x,int y,int n)
{
tab[x][y]=n;
}


}//Fin de la classe


Explication :


Attributs :

private int tab[][] : Matrice qui représente le plateau du jeu.


Méthodes :

public Plateform() : Constructeur de la classe « Plateform » . Cette méthode
initialise le plateau du jeu.
public void Fill() : Cette méthode remplie la matrice de manière à placer les pions
noirs en haut et les pions blancs en bas avec entre chaque pion une case vide.
public void nouveau() : Cette méthode est appelée lorsque l’on décide au cours
d’une partie de recommencer une partie de jeu. Elle réinitialise la matrice avec des 0 puis elle la remplie de nouveau à l’aide de la fonction Fill().
public int getlocal(int x, int y) : Cette méthode est un accesseur. Elle permet
de lire le coefficient de la matrice à la xième ligne et yième colonne.
public void setlocal(int x,int y,int n) : Cette méthode est également un
accesseur. Elle permet d’écrire une valeur dans la matrice à la xième ligne et yième
colonne.


La « classe MThread » gère les sons. Elle dérive de la classe « Thread ». Pour pouvoir jouer la musique de fond tout en jouant une partie de jeu, ceci ne peut pas se faire de manière séquentiel car sinon il serait impossible de jouer tant que la musique ne soit pas finie. La classe « Thread » va donc créer un thread, c'est-à-dire, un processus léger qui va s’exécuter en parallèle. Ainsi, le code qui permet de lire un son va s’exécuter en parallèle au code qui permet de gérer une partie de jeu ce qui au final permettra de jouer tout en écoutant de la musique. La classe « MThread » va pouvoir lire un fichier audio (format : *.wav ou *.au) de deux manières, soit en boucle (la musique de fond par exemple), soit en une seule fois (le son joué lorsque l’on capture un pion adverse).



Source :


package packJeu;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.DataLine.Info;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.AudioSystem;
import java.io.File;


public class MThread extends Thread {

private String fileName; //Nom du fichier
private boolean distinct;//On joue le son en boucle ou pas.
private boolean stop=true;//Variable qui permet de stoper le thread.

public MThread(String fileName,boolean distinct) {
this.fileName=fileName;
this.distinct=distinct;
}

//Le thread va jouer le son en parallèle à la gestion du jeu.
public void run() {
ReadAudioFile();
}

//Une fois la fonction appelée, stop devient false et le thread est stopé.
public void stoper()
{
stop=false;
}

public void Read()
{
try
{
AudioInputStream ais = AudioSystem.getAudioInputStream(new File(fileName));
AudioFormat format = ais.getFormat();
Info info = new Info(SourceDataLine.class, format);
SourceDataLine source = (SourceDataLine)AudioSystem.getLine(info);
source.open(format);
source.start();
int read = 0;
byte[] audioData = new byte[16384];
while(read > -1 && stop)
{
read = ais.read(audioData, 0 , audioData.length);
if(read >= 0)
source.write(audioData, 0, read);
}
source.drain();
source.close();

} catch(Exception e) { e.printStackTrace(); }
}

public void ReadAudioFile()
{
if(distinct) //Si distinct=true alors on boucle...
{
while(stop) //...tant que stop=true
Read();

}
else //Sinon on passe le son une seule fois.
Read();

}
//Une fois la tâche accomplie, le thread est supprimé de la mémoire.

}//Fin de la classe.


Explication :


Attributs :

private String fileName : Chaîne de caractères qui va stocker le nom du fichier
audio que l’on veut lire.
private boolean distinct : Lors de la lecture du fichier audio, si distinct=true on
boucle sinon on le lit qu’une seule fois.
private boolean stop=true : Cette variable permet de stopper le thread.


Méthodes :

public MThread(String fileName,boolean distinct) : On initialise les attributs.
public void run() : Le thread exécute les instructions contenues dans cette méthode,
ici la méthode readAudioFile() sera donc exécutée.
public void Read() : Cette méthode permet de lire un fichier audio au bon format.
public void ReadAudioFile() : Cette méthode permet de jouer un son en boucle ou
en une seule fois.
Certaines méthodes sont plus difficiles que d’autres à assimiler, c’est pourquoi, je vais détailler leurs algorithmes.






2.2. Description détaillée des méthodes complexes du jeu :




Intéressons nous à la méthode Jouer() de la classe « Joueur » :

Etape 1 :
if(aperdu())
fin[0]=true;

Etape 2 :
else if(atour==0 && plateau.getlocal(y,x) == 0)
mess+=" "+"Ceci n'est pas un jeton";

Etape 3 :
else if(atour==0 && (plateau.getlocal(y,x) == jeton ||
plateau.getlocal(y,x) == Djeton))
mess+=" "+"Ce jeton ne vous appartient pas";

Etape 4 :
else if(atour==0 && pemanger(cpt)!=0 &&
!(GooDPiece(cpt,nbPionquiPeManger,x,y,checkout,rem1,rem2)))
mess+=" "+"Choisissez le bon jeton!!";

Etape 5 :
else
{
stock[atour][0]=x;
stock[atour][1]=y;
mess+=" "+"Pions restant :"+Compter();

Etape 6 :
if(!Exist())
{
if(plateau.getlocal(y,x) !=Identite+2)
plateau.setlocal(y, x, 5);
else
plateau.setlocal(y,x,6);
}

Etape 7 :
if(atour !=0 && jepemanger!=0)
{
int valeur=manger(stock);

Etape 8 :
if(valeur==5)
{
mess=""+"Déplacement impossible";
if(plateau.getlocal(stock[0][1],stock[0][0])==5)
plateau.setlocal(stock[0][1],stock[0][0],Identite);
else
plateau.setlocal(stock[0][1],stock[0][0],Identite+2);
}

Etape 9 :
else
{
if(valeur==1)
plateau.setlocal(stock[0][1]+1,stock[0][0]+1,0);
if(valeur==2)
plateau.setlocal(stock[0][1]-1,stock[0][0]+1,0);
if(valeur==3)
plateau.setlocal(stock[0][1]+1,stock[0][0]-1,0);
if(valeur==4)
plateau.setlocal(stock[0][1]-1,stock[0][0]-1,0);
RetablirCouleur();
plateau.setlocal(stock[0][1],stock[0][0],0);
mess=""+"Bon appétit !";

Etape 10 :
if(!pourramanger(stock[1][0],stock[1][1]))
{
checkout=0;
succes=!succes;
}
else
{
checkout=1;
rem1=stock[1][0];
rem2=stock[1][1];
}

Etape 11 :
MThread thread=new MThread("mange.wav",false);
thread.start();
}
}

Etape 12 :
else if(atour !=0 && !(TestDep(stock)))
{
mess=""+"Déplacement impossible";
if(plateau.getlocal(stock[0][1],stock[0][0])==5)
plateau.setlocal(stock[0][1],stock[0][0],Identite);
else
plateau.setlocal(stock[0][1],stock[0][0],Identite+2);
}

Etape 13 :
else if(atour !=0)
{
mess=""+"Déplacement réussi";
RetablirCouleur();
plateau.setlocal(stock[0][1],stock[0][0],0);
succes=!succes;
}
atour++;
if(atour==2)
atour=0;
}

Etape 1 :
if(aperdu())
fin[0]=true;
La variable fin[] est un tableau qui va retourner par adresse un boolean. Si le joueur a
perdu la partie, fin[0] est initialisé à true.

Etape 2 :
else if(atour==0 && plateau.getlocal(y,x) == 0)
mess+=" "+"Ceci n'est pas un jeton";
Sinon si le joueur se trouve dans une phase de sélection (atour=0) et si l’endroit où a
cliqué le joueur correspond à une case vide alors on affiche un message pour l’avertir. La
variable atour sera toujours égale à 0, le joueur devra donc sélectionner de nouveau.

Etape 3 :
else if(atour==0 && (plateau.getlocal(y,x) == jeton ||
plateau.getlocal(y,x) == Djeton))
mess+=" "+"Ce jeton ne vous appartient pas";
Sinon si le joueur se trouve dans une phase de sélection (atour=0) et que l’endroit où a
cliqué le joueur correspond à une case occupée par un pion de l’adversaire, le joueur
restera dans la phase de sélection.

Etape 4 :
else if(atour==0 && pemanger(cpt)!=0 &&
!(GooDPiece(cpt,nbPionquiPeManger,x,y,checkout,rem1,rem2)))
mess+=" "+"Choisissez le bon jeton!!";
Sinon si le joueur se trouve dans une phase de sélection (atour=0) et que le joueur a la
possibilité de capturer un pion de l’adversaire, la méthode GoodPiece() vérifie si oui ou
non le joueur a sélectionné le bon pion. Si ce n’est pas le cas, le joueur restera dans la
phase de sélection.

Etape 5 :
else
{
stock[atour][0]=x;
stock[atour][1]=y;
mess+=" "+"Pions restant :"+Compter();
Sinon si atour=0, le joueur a sélectionné un de ses pions correctement.
Si atour=1, la phase de sélection est terminée et le joueur doit choisir une case vide pour
le déplacement.

Etape 6 :
if(!Exist())
{
if(plateau.getlocal(y,x) !=Identite+2)
plateau.setlocal(y, x, 5);
else
plateau.setlocal(y,x,6);
}
On vérifie qu’il n’existe pas de pion de couleur or puis si c’est le cas alors le pion
sélectionné devient de couleur or.

Etape 7 :
if(atour !=0 && jepemanger!=0)
Si atour != 0 alors le joueur est entré dans la phase de déplacement. La variable
jepemanger s’initialise lors de l’appel de la méthode pemanger(), si jepemanger != 0, le
joueur entre dans l’étape 8.

Etape 8 :
int valeur=manger(stock);
if(valeur==5)
{
mess=""+"Déplacement impossible";
if(plateau.getlocal(stock[0][1],stock[0][0])==5)
plateau.setlocal(stock[0][1],stock[0][0],Identite);
else
plateau.setlocal(stock[0][1],stock[0][0],Identite+2);
}
Le joueur va devoir manger un pion adverse. On fait donc appel à la méthode manger()
et on stock la valeur retournée dans la variable valeur. Puis, suivant la valeur retournée,
on gère le damier en conséquence. Par exemple, si valeur=5 alors cela signifie que le
joueur a tenté de faire un déplacement impossible. Toutes tentatives de déplacement
autre que la capture d’un pion adverse entraînent ce résultat.

Etape 9 :
else
{
if(valeur==1)
plateau.setlocal(stock[0][1]+1,stock[0][0]+1,0);
if(valeur==2)
plateau.setlocal(stock[0][1]-1,stock[0][0]+1,0);
if(valeur==3)
plateau.setlocal(stock[0][1]+1,stock[0][0]-1,0);
if(valeur==4)
plateau.setlocal(stock[0][1]-1,stock[0][0]-1,0);
RetablirCouleur();
plateau.setlocal(stock[0][1],stock[0][0],0);
mess=""+"Bon appétit !";
La variable valeur peut prendre jusqu’à 5 valeurs différentes. Si variable !=5 alors le
joueur a effectué le bon déplacement. Si valeur=1, la capture se fait dans le sens de la
diagonale orientée en bas à droite, on supprime donc du damier la pion adverse qui se
situe à (i+1,j+1) où i et j représentent la position du pion du joueur.

Etape 10 :
if(!pourramanger(stock[1][0],stock[1][1]))
{
checkout=0;
succes=!succes;
}
else
{
checkout=1;
rem1=stock[1][0];
rem2=stock[1][1];
}
Si le pion du joueur qui vient de capturer un pion adverse ne peut pas en capturer un
autre, on initialise checkout à 0 et succes = !succes. La variable checkout=0 signifie que
lors d’une prochaine prise, le joueur ne sera pas dans l’obligation de capturer avec ce
pion. L’instruction succes = !succes signifie que le joueur passe la main à l’adversaire.
Dans le cas contraire, la variable checkout=1 signale que le joueur effectuera la
prochaine prise avec le même pion et ses coordonnées seront stockées dans les variables
rem1 et rem2.

Etape 11 :
MThread thread=new MThread("mange.wav",false);
thread.start();
A chaque fois qu’un joueur va capturer un pion de l’adversaire, on créé un thread qui
jouera le son mange.wav.

Etape 12 :
else if(atour !=0 && !(TestDep(stock)))
{
mess=""+"Déplacement impossible";
if(plateau.getlocal(stock[0][1],stock[0][0])==5)
plateau.setlocal(stock[0][1],stock[0][0],Identite);
else
plateau.setlocal(stock[0][1],stock[0][0],Identite+2);
}
Sinon si le joueur est dans la phase de déplacement et qu’il n’est pas obligé de prendre
un pion adverse, il peut donc se déplacer sur un case vide. Si le joueur tente d’effectuer
un déplacement impossible, le pion reste à sa position d’origine et retrouve sa couleur
d’origine.

Etape 13 :
else if(atour !=0)
{
mess=""+"Déplacement réussi";
RetablirCouleur();
plateau.setlocal(stock[0][1],stock[0][0],0);
succes=!succes;
}
atour++;
if(atour==2)
atour=0;
Sinon si le joueur a exécuté un bon déplacement, le pion a été déplacé et a retrouvé sa
couleur initiale.
Si atour=2, on remet le compteur à 0.

Regardons maintenant la méthode DeplacementHG() de la classe « IA » :
Etape 1 :
if(!jedepasseoupas(tab[i][0]-1,tab[i][1]-1))
{
//CAS EN HAUT A GAUCHE
if(j==0)
{

Etape 2 :
if(TestDep(tab[i][1]-1,tab[i][0]-1) &&
!vaetremange(tab[i][0]-1,tab[i][1]-1,3))
{
plateau.setlocal(tab[i][1],tab[i][0],0);
if(tab[i][2]==Identite && tab[i][1]-1!=0)
plateau.setlocal(tab[i][1]-1,tab[i][0]-1,Identite);
else
plateau.setlocal(tab[i][1]-1,tab[i][0]-1,Identite+2)
return true;
}
}

Etape 3 :
if(j==1)
{
if(TestDep(tab[i][1]-1,tab[i][0]-1))
{
plateau.setlocal(tab[i][1],tab[i][0],0);
if(tab[i][2]==Identite && tab[i][1]-1!=0)
plateau.setlocal(tab[i][1]-1,tab[i][0]-1,Identite)
else
plateau.setlocal(tab[i][1]-1,tab[i][0]-1,Identite+2)
return true;
}
}
}

Etape 4 :
return false;
}

Etape 1 :
if(!jedepasseoupas(tab[i][0]-1,tab[i][1]-1))
On vérifie si on ne déborde pas du plateau de jeu.

Etape 2 :
if(j==0)
{
if(TestDep(tab[i][1]-1,tab[i][0]-1) && !vaetremange(tab[i][0]-
1,tab[i][1]-1,3))
{
plateau.setlocal(tab[i][1],tab[i][0],0);
if(tab[i][2]==Identite && tab[i][1]-1!=0)
plateau.setlocal(tab[i][1]-1,tab[i][0]-1,Identite);
else
plateau.setlocal(tab[i][1]-1,tab[i][0]-1,Identite+2)
return true;
}
}
Pour commencer, on vérifie si c’est le premier tour, ici j=0 c’est donc la première fois
qu’on parcourt tout le tableau. Ensuite, on vérifie si la case en haut à gauche de notre
pion est vide et si il ne va pas être capturé une fois déplacé sur la nouvelle case. Si tout
est validé, on modifie soigneusement le plateau du jeu puis on retourne true pour
confirmer que le déplacement a bien eu lieu.

Etape 3 :
if(j==1)
{
if(TestDep(tab[i][1]-1,tab[i][0]-1))
{
plateau.setlocal(tab[i][1],tab[i][0],0);
if(tab[i][2]==Identite && tab[i][1]-1!=0)
plateau.setlocal(tab[i][1]-1,tab[i][0]-1,Identite)
else
plateau.setlocal(tab[i][1]-1,tab[i][0]-1,Identite+2)
return true;
}
}
Dans cette étape, j=1 ce qui veut dire qu’aucun pion n’a été déplacé jusqu’à présent. A
ce tour, on ne vérifie plus que si le déplacement est possible. Si c’est le cas, on retourne
true pour confirmer que le déplacement s’est bien déroulé.

Etape 4 :
return false;
Si on ne rentre dans aucune des conditions alors il est impossible de déplacer le pion et
on retourne false.
L’algorithme des méthodes DeplacementHD(),DeplacementBG() et DeplacementBD() est
identique à celui-ci, seul le sens de la diagonale change.



Etape 3 :
if(Identite==2)
{

Etape 4 :
if(tab[i][2]==Identite+2)
{

Etape 5 :
if(DeplacementHG(i,j))
return true;
if(DeplacementHD(i,j))
return true;
}

Etape 6 :
if(tab[i][2]==Identite+2 && compteur()==0 ||
tab[i][2]==Identite)
{

Etape 7 :
if(DeplacementBD(i,j))
return true;
if(DeplacementBG(i,j))
return true;
}
}

Etape 8 :
if(Identite==1)
{
if(tab[i][2]==Identite+2)
{
if(DeplacementBD(i,j))
return true;

Etape 1 :
while(j<2) i="n-1;i">=0;i--)
Si l’ordinateur joue les pions noirs, il jouera toujours les premières lignes en premier. En revanche, si l’ordinateur joue les pions blancs, c’est les dernières lignes qui seront jouées en premier. J’ai trouvé le concept assez intéressant. En effet, le joueur pourra affronter un ordinateur qui possède deux styles opposés : un style plutôt défensif (pions blancs) et l’autre offensif (pions noirs).


La méthode Deplacement() de la classe « IA » :

Etape 1 :
while(j<2) i="n-1;i">=0;i--)
{

Etape 3 :
if(Identite==2)
{

Etape 4 :
if(tab[i][2]==Identite+2)
{

Etape 5 :
if(DeplacementHG(i,j))
return true;
if(DeplacementHD(i,j))
return true;
}

Etape 6 :
if(tab[i][2]==Identite+2 && compteur()==0 ||
tab[i][2]==Identite)
{

Etape 7 :
if(DeplacementBD(i,j))
return true;
if(DeplacementBG(i,j))
return true;
}
}

Etape 8 :
if(Identite==1)
{
if(tab[i][2]==Identite+2)
{
if(DeplacementBD(i,j))
return true;

Etape 1 :
while(j<2) i="n-1;i">=0;i--)
Si l’ordinateur joue les pions noirs, il jouera toujours les premières lignes en premier. En
revanche, si l’ordinateur joue les pions blancs, c’est les dernières lignes qui seront jouées
en premier. J’ai trouvé le concept assez intéressant. En effet, le joueur pourra affronter
un ordinateur qui possède deux styles opposés : un style plutôt défensif (pions blancs) et
l’autre offensif (pions noirs).

Etape 3 :
if(Identite==2)
Si l’ordinateur joue les pions noirs.

Etape 4 :
if(tab[i][2]==Identite+2)
Et si le pion sélectionné par l’ordinateur est une dame.

Etape 5 :
if(DeplacementHG(i,j))
return true;
if(DeplacementHD(i,j))
return true;
Alors l’ordinateur déplace sa dame en priorité vers le haut à gauche sinon vers le haut à droite. Si l’ordinateur déplaçait une dame noire en priorité vers le bas, des bugs surviendrait. En effet, lorsqu’un pion est promu en dame, ce pion se trouve donc sur la toute dernière ligne du damier. Le déplacement vers le bas étant impossible, l’ordinateur déplacerait donc sa dame vers le haut. Au prochain tour, l’ordinateur jouera le pion le plus avancé sur le damier, c'est-à-dire la dame et puisque le déplacement vers le bas serait une priorité, l’ordinateur replacerait la dame sur sa case initiale. Ces déplacements se répéteraient et ceux, jusqu’à la fin de la partie si la situation n’évolue pas.

Etape 6 :
if(tab[i][2]==Identite+2 && (compteur()==0 || j==1) ||
tab[i][2]==Identite)
Si le pion sélectionné est une dame et que le nombre de pion (dames exclues) est égal à 0 ou que le pion sélectionné est un pion de base, on rentre dans l’étape 7.

Etape 7 :
if(DeplacementBD(i,j))
return true;
if(DeplacementBG(i,j))
return true;
L’ordinateur est autorisé à déplacer son pion vers le bas. En résumé, l’ordinateur déplace les dames noires en priorité vers le haut. Si le déplacement est impossible, il déplacera les dames noires vers le bas à une seule condition, qu’il n’y est plus de pion (Dames exclues). Cette condition permet à l’ordinateur de ne pas « bugger » en jouant une dame. En effet, supposons que l’ordinateur obtient une dame et que tous ses autres pions sont à 5 lignes des cases de promotion, d’après les tests logiques précèdent, l’ordinateur va jouer sa dame. Or l’ordinateur a comme ordre de déplacer les dames vers le haut en priorité. Ainsi, l’ordinateur va faire monter sa dame tant que le déplacement sera possible et qu’elle ne se fera pas capturée. Dans le cas contraire, l’ordinateur va déplacer sa dame en bas à droite. Le tour d’après, sa dame étant le pion le plus avancé sur le plateau, l’ordinateur va donc déplacer sa dame de nouveau vers le haut à gauche.
Au prochain tour, la dame est toujours le pion le plus avancé et elle va donc être rejouée or supposons que la situation n’est toujours pas changée et donc que le déplacement vers le haut soit toujours impossible, l’ordinateur va donc déplacer sa dame vers le bas une nouvelle fois. L’ordinateur recommencera les mêmes déplacements jusqu’à la fin de la partie si la situation n’évolue pas ! C’est pour palier à ce problème que l’instruction suivante : compteur()==0 || j==1
a été introduite dans la condition. Reprenons l’exemple précédent, si la dame ne peut
plus monter et que de plus il reste au moins un pion de base dans la partie, l’ordinateur ne va donc pas déplacer la dame vers le bas mais il va changer de pion. En revanche, si il n’y a plus de jeton de base (compteur()==0), ou si tous les pions sont immobilisés ou qu’ils ne peuvent pas se déplacer sans être capturé (On effectuera un second tour et donc j==1) alors l’ordinateur déplacera ses dames.

Etape 8 :
if(Identite==1)
{
if(tab[i][2]==Identite+2)
{
if(DeplacementBD(i,j))
return true;
if(DeplacementBG(i,j))
return true;
}
if(tab[i][2]==Identite+2 && (compteur()==0 || j==1) ||
tab[i][2]==Identite)
{
if(DeplacementHG(i,j))
return true;
if(DeplacementHD(i,j))
return true;
}
}
j++;
}
return false;
L’étape 8 fonctionne de la même manière que les étapes 4, 5, 6 et 7. L’ordre de priorité sur les déplacements des dames est inversé. En effet, dans l’étape 8 l’ordinateur joue les pions blancs, le sens de déplacement des pions et la position des cases de promotion sont donc inversés.
La variable j est incrémentée ce qui permet de rentrer dans les conditions où j=1.
La méthode vaetremange() de la classe « IA » :

Etape 1 :
if(y==0 || y==10 || x==0 || x==10)
return false;

Etape 2 :
else
{
if(cas==0)
if((plateau.getlocal(y+1,x+1)==jeton ||
plateau.getlocal(y+1,x+1)==Djeton))
return true;
if(cas!=0)
if((plateau.getlocal(y+1,x+1)==jeton ||
plateau.getlocal(y+1,x+1)==Djeton)&& plateau.getlocal(y-1,x-1)==0)
return true;
if(cas==2)
if((plateau.getlocal(y-1,x+1)==jeton ||
plateau.getlocal(y-1,x+1)==Djeton))
return true;
if(cas!=2)
if((plateau.getlocal(y-1,x+1)==jeton ||
plateau.getlocal(y-1,x+1)==Djeton) &&
plateau.getlocal(y+1,x-1)==0)
return true;
if(cas==1)
if((plateau.getlocal(y+1,x-1)==jeton ||
plateau.getlocal(y+1,x-1)==Djeton))
return true;
if(cas!=1)
if((plateau.getlocal(y+1,x-1)==jeton ||
plateau.getlocal(y+1,x-1)==Djeton) && plateau.getlocal(y-
1,x+1)==0)
return true;
if(cas==3)
if((plateau.getlocal(y-1,x-1)==jeton ||
plateau.getlocal(y-1,x-1)==Djeton))
return true;
if(cas!=3)
if((plateau.getlocal(y-1,x-1)==jeton ||
plateau.getlocal(y-1,x-1)==Djeton) &&
plateau.getlocal(y+1,x+1)==0)
return true;
return false;
}

Etape 1 :
if(y==0 || y==10 || x==0 || x==10)
return false;
On vérifie si le pion se situe sur une arrête du plateau. Si c’est le cas, le pion ne peut être
capturé on retourne donc false.

Etape 2 :
if(cas==0)
if((plateau.getlocal(y+1,x+1)==jeton ||
plateau.getlocal(y+1,x+1)==Djeton))
return true;
if(cas!=0)
if((plateau.getlocal(y+1,x+1)==jeton ||
plateau.getlocal(y+1,x+1)==Djeton)&& plateau.getlocal(y-1,x-1)==0)
return true;
On va simuler un déplacement. Pour faire simple considérons l'exemple où la variable
cas=0. L'ordinateur bouge un de ses jetons en bas à droite donc x=x+1, y=y+1. Pour
vérifier s'il va être mangé par un jeton adverse, il est nécessaire de vérifier dans les 4 directions sauf UNE ! Celle qui correspond au sens inverse du déplacement donc ici x-1, y-1. En effet, nous sommes dans une simulation et donc la mise à jour du plateau de jeu n'a pas été encore effectuée ce qui signifie que notre pion n’a toujours pas bougé et donc plateau.getlocal(y-1, x-1) est égale à notre jeton. Ceci fausse donc les tests car plateau.getlocal(y-1, x-1) ne pourra jamais être égale à 0 et l'ordinateur déplacera ainsi son pion sur la nouvelle case alors que celui-ci en réalité n'est pas protégé derrière lui.
Pour y remédier, on ne vérifie pas dans le sens opposé du déplacement puisque un pion
déplacé laisse une case vide derrière lui. Il suffit donc de vérifier si un jeton ennemi se trouve à proximité dans le sens du déplacement, si c'est le cas, le pion de l'ordinateur sera mangé, la méthode retournera true et l'ordinateur choisira donc une autre direction.

Commentaires

JDLE a dit…
Bonjour

Sympa le jeu de dames.
Seulement le damier est inversé.
La diagonale est toujours à gauche des joueurs.
Merci de le modifier afin d'évaluer ses capacités.

Cordialement
dud a dit…
Bonjour
Étudiant en école d'ingénieur, je me suis intéressé à ce programme de jeu de dame et je n'arrive pas à savoir à quoi correspond le package packjeu. Merci de m'éclairer sur le sujet.
Sinon merci beaucoup pour ce tutoriel, il m'a aider à comprendre un tas de truc en java.
yass a dit…
Ce commentaire a été supprimé par l'auteur.
baldwinlagattuta a dit…
Casino Games - Dr.MD.com
If you want to win, try a 시흥 출장샵 few 여주 출장안마 of the 전라남도 출장샵 best casino games available. You will find your favorite game, slots 제천 출장안마 or video poker. Slots, video poker. 대구광역 출장샵