Programmation Java pour les enfants, les parents et les grands-parents


précédentsommairesuivant

IX. Chapitre 7. L'applet Morpion

Quand tu es en ligne sur ton site web favori, il y a des chances pour que certains des jeux et autres programmes qui te sont proposés soient écrits en Java à l'aide de ce qu'on appelle des applets ou, parfois, des appliquettes. Ces applications spéciales existent et s'exécutent dans la fenêtre du navigateur web. Les navigateurs web comprennent un langage simple appelé HTML, qui te permet d'insérer des marques spéciales, ou balises (tags), dans les fichiers texte, afin de leur donner une apparence agréable lorsqu'ils sont affichés par les navigateurs. En plus du texte, tu peux inclure dans un fichier HTML la balise <applet>, qui indique au navigateur où trouver une applet Java et comment l'afficher.

Les applets Java sont téléchargées sur ton ordinateur depuis Internet en tant que parties d'une page web. Le navigateur est suffisamment malin pour lancer son propre Java afin de les exécuter.

Image non disponible

Dans ce chapitre, tu vas apprendre comment créer des applets sur ton ordinateur. L'annexe C explique comment publier tes pages web sur Internet pour que d'autres personnes puissent les utiliser.

Les gens naviguent sur Internet sans savoir si les pages web contiennent des applets Java ou pas, mais veulent être certains que leurs ordinateurs sont à l'abri des dégâts que pourraient causer des personnes malintentionnées en incorporant à une page une applet nuisible. C'est pourquoi les applets ont été conçues avec les limitations suivantes :

  • Les applets ne peuvent pas accéder aux fichiers de ton disque dur, à moins que tu n'aies sur ton disque un fichier spécial, appelé certificat, qui leur en donne l'autorisation.
  • Les applets ne peuvent se connecter qu'à l'ordinateur duquel elles ont été téléchargées.
  • Les applets ne peuvent démarrer aucun des programmes situés sur ton disque dur.

Pour exécuter une applet, il te faut une classe Java écrite d'une certaine manière, un fichier texte HTML contenant la balise <applet> pointant sur cette classe et un navigateur web qui supporte Java. Tu peux aussi tester les applets dans Eclipse ou à l'aide d'un programme spécial appelé visualisateur d'applet (appletviewer). Mais avant d'apprendre à créer des applets, prenons 15 minutes pour nous familiariser avec quelques balises HTML.

IX-A. Apprendre HTML en 15 minutes

Imagine un instant que tu aies écrit et compilé une applet de jeu appelée Morpion. Tu dois maintenant créer le fichier HTML contenant les informations la concernant. Crée tout d'abord le fichier texte Morpion.html (à propos, Eclipse peut aussi créer des fichiers texte). Les fichiers HTML ont des noms terminés soit par .html soit par .htm. Ils contiennent en général les sections header (en-tête) et body (corps). La plupart des balises HTML ont une balise fermante correspondante, commençant par une barre oblique. Par exemple : <Head> et </Head>. Voici à quoi pourrait ressembler le fichier Morpion.html :

 
Sélectionnez
<HTML>
<Head>
<Title>Ma première page web</Title>
</Head>
<BODY>
  Mon jeu de morpion va bientôt arriver&#8230;
</BODY>
</HTML>

Les balises peuvent être placées soit sur la même ligne, comme nous l'avons fait avec les balises <Title> et </Title>, soit sur des lignes distinctes. Ouvre ce fichier avec ton navigateur web à l'aide des menus Fichier et Ouvrir. La barre de titre bleue de la fenêtre affiche "Ma première page web" et à l'intérieur de la page sont affichés les mots "Mon jeu de morpion va bientôt arriver…" :

Image non disponible

Modifie maintenant ce fichier en ajoutant la balise pour l'applet Morpion :

 
Sélectionnez
<HTML>
<Head>
<Title>Ma première page web</Title>
</Head>
<BODY>
  Voici mon jeu de morpion :
  <p><APPLET code = "Morpion.class" width=300     
                                    height=250>
  </APPLET>
</BODY>
</HTML>

L'écran n'a plus la même apparence :

Image non disponible

Evidemment, puisque le navigateur web ne peut pas trouver Morpion.class, il affiche simplement un rectangle vide. Nous créerons cette classe un peu plus loin dans ce chapitre.

Les balises HTML sont entourées par des signes inférieur (<) et supérieur (>). Certaines balises peuvent avoir des attributs supplémentaires. La balise <APPLET> de notre exemple utilise les attributs suivants :

  • code : nom de la classe Java de l'applet.
  • width : largeur en pixels de la surface rectangulaire de l'écran qui sera occupée par l'applet.
  • height : hauteur de la surface occupée par l'applet.

Si une applet Java est constituée de plusieurs classes, rassemble-les dans un fichier archive à l'aide du programme jar fourni avec J2SDK. Dans ce cas, l'attribut archive doit préciser le nom de cette archive. L'annexe A propose des lectures relatives aux jars.

IX-B. Choix de la librairie AWT pour écrire des applets

Pourquoi utiliser AWT pour écrire des applets si la librairie Swing est meilleure ? Est-il possible d'écrire des applets à l'aide de classes Swing ? Oui, c'est possible ; mais il faut savoir ceci.

Les navigateurs web sont fournis avec leur propre Java, qui supporte AWT, mais pas nécessairement les classes Swing incluses dans ton applet. Bien sûr, les utilisateurs peuvent télécharger et installer le dernier Java et il existe des convertisseurs HTML spéciaux permettant de modifier le fichier HTML pour faire pointer les navigateurs vers ce nouveau Java ; mais souhaites-tu vraiment demander aux utilisateurs de faire tout ça ? Une fois ta page web publiée sur Internet, tu ne sais pas qui peut l'utiliser. Imagine un vieux type, quelque part dans un désert avec un ordinateur vieux de 10 ans ; il laissera simplement tomber ta page, plutôt que de se lancer dans tous ces soucis d'installation. Imagine que notre applet aide à vendre des jeux en ligne et que nous ne voulions pas abandonner cette personne : elle pourrait être un client potentiel (les gens vivant dans le désert ont aussi des cartes de crédit). :

Utilise AWT si tu n'es pas sûr du type de navigateur web de tes utilisateurs.

En réalité, l'autre option consiste à demander aux utilisateurs de télécharger un plugin (module d'extension) Java spécial et de configurer leur navigateur pour utiliser ce plugin à la place du Java fourni avec leur navigateur. Tu trouveras plus d'explications à ce sujet sur ce site :

http://java.sun.com/j2se/1.5.0/docs/guide/plugin/.

IX-C. Comment écrire des applets AWT

Les applets Java AWT doivent hériter de la classe java.applet.Applet. Par exemple :

 
Sélectionnez
class Morpion extends java.applet.Applet {

}

Contrairement aux applications Java, les applets n'ont pas besoin de méthode main() car le navigateur web les télécharge et les exécute dès qu'il rencontre la balise <applet> dans une page web. Le navigateur envoie aussi des signaux aux applets quand des événements importants se produisent, par exemple quand l'applet est lancée, est repeinte, etc. Pour être sûr que l'applet réagisse à ces événements, tu dois programmer des méthodes de rappel (callback methods) spéciales : init() (initialiser), start() (démarrer), paint() (peindre), stop() (arrêter) et destroy() (détruire). Le Java du navigateur appelle ces méthodes dans les cas suivants :

  • init() est appelée quand l'applet est chargée par le navigateur. Elle n'est appelée qu'une fois : elle joue donc un rôle similaire à celui des constructeurs des classes Java normales.
  • start() est appelée juste après init(). Elle est aussi appelée si l'utilisateur revient à une page web après avoir visité une autre page.
  • paint() est appelée quand la fenêtre de l'applet a besoin d'être affichée ou rafraîchie après une activité quelconque sur l'écran. Par exemple, l'applet a été recouverte par une autre fenêtre et le navigateur a besoin de la repeindre.
  • stop() est appelée quand l'utilisateur quitte la page web contenant l'applet.
  • destroy() est appelée quand le navigateur détruit l'applet. Tu n'as besoin d'écrire du code pour cette méthode que si l'applet utilise d'autres ressources, par exemple quand elle maintient une connexion avec l'ordinateur duquel elle a été téléchargée.

Même s'il n'est pas nécessaire de programmer toutes ces méthodes, chaque applet doit définir au moins init() et paint(). Voici le code d'une applet qui affiche les mots "Bonjour Monde !". Cette applet ne contient que la méthode paint(), qui reçoit une instance de l'objet Graphics du Java du navigateur. Cet objet dispose d'un tas de méthodes graphiques. L'exemple suivant utilise la méthode drawString() (dessiner une chaîne de caractères) pour dessiner le texte "Bonjour Monde !".

 
Sélectionnez
public class AppletBonjour extends java.applet.Applet {
  public void paint(java.awt.Graphics contexteGraphique) {
    contexteGraphique.drawString("Bonjour Monde !", 70, 40);
  }
}

Crée cette classe dans Eclipse. Ensuite, dans la fenêtre Exécuter, sélectionne Applet Java dans le coin supérieur gauche, appuie sur le bouton Créer et entre AppletBonjour dans le champ Applet.

Pour tester cette applet dans le navigateur web, crée le fichier Bonjour.html dans le dossier où est enregistrée ton applet.

 
Sélectionnez
<HTML>
 <BODY>
  Voici ma première applet :<P>
 <APPLET code = AppletBonjour.class width = 200 height = 100>
 </APPLET>
 </BODY>
</HTML>

Ouvre maintenant le fichier Bonjour.html à l'aide des menus Fichier et Ouvrir de ton navigateur.

L'écran devrait ressembler à ceci :

Image non disponible

Crois-tu qu'après ce simple exemple nous soyons prêts pour écrire un programme de jeu ? Tu m'étonnes ! Boucle juste ta ceinture…

IX-D. Ecriture d'un jeu de morpion

Image non disponible

IX-D-1. Stratégie

Tous les jeux utilisent un algorithme - un ensemble de règles ou une stratégie à appliquer en fonction des actions du joueur. Pour un même jeu, il peut y avoir des algorithmes simples ou très compliqués. Quand on dit que le champion du monde d'échecs Gary Kasparov joue contre un ordinateur, il joue en fait contre un programme. Des équipes d'experts essaient d'inventer des algorithmes sophistiqués pour le battre. Le jeu de morpion peut aussi être programmé selon différentes stratégies ; nous allons en utiliser la plus simple :

  1. Nous utilisons un plateau 3 x 3.
  2. L'utilisateur joue avec le symbole X et l'ordinateur avec le O.
  3. Pour gagner, il faut avoir complété une ligne, une colonne ou une diagonale avec le même symbole.
  4. Après chaque coup, le programme vérifie s'il y a un gagnant.
  5. S'il y a un gagnant, la combinaison gagnante est mise en surbrillance et la partie se termine.
  6. La partie se termine aussi s'il n'y a plus de cases libres.
  7. Pour faire une nouvelle partie, le joueur appuie sur le bouton Nouvelle partie.
  8. Quand l'ordinateur décide où placer le prochain O, il essaie de trouver une ligne, une colonne ou une diagonale où se trouvent déjà deux O pour la compléter.
  9. S'il n'y pas deux O alignés, l'ordinateur essaie de trouver deux X alignés afin de parer un coup gagnant du joueur en plaçant un O.
  10. Si aucun coup gagnant ou bloquant n'a été trouvé, l'ordinateur essaie d'occuper la case centrale, ou choisit la prochaine case vide au hasard.

IX-D-2. Code

Je vais juste te donner ici une brève description du programme car le code de l'applet contient de nombreux commentaires qui t'aideront à comprendre comment il fonctionne.

L'applet utilise un gestionnaire de disposition BorderLayout. La zone nord de la fenêtre contient le bouton Nouvelle partie. La zone centrale affiche neuf boutons représentant les cases et la zone sud affiche les messages :

Image non disponible

Tous les composants de la fenêtre sont créés par la méthode init() de l'applet. Tous les événements sont traités par le récepteur ActionListener dans la méthode actionPerformed(). La méthode chercherUnGagnant() est appelée après chaque coup pour vérifier si la partie est terminée.

Les règles 8, 9 et 10 de notre stratégie sont codées dans la méthode coupOrdinateur(), qui peut avoir besoin de générer un nombre aléatoire (random number). On utilise pour cela la classe Java Math et sa méthode random().

Tu rencontreras aussi une syntaxe assez inhabituelle où plusieurs appels de méthodes sont effectués en une seule expression, comme dans cet exemple :

 
Sélectionnez
if(cases[0].getLabel().equals(cases[1].getLabel())){&#8230;}

Cette ligne raccourcit le code car elle effectue en fait les mêmes actions que l'ensemble des lignes suivantes :

 
Sélectionnez
String label0 = cases[0].getLabel();
String label1 = cases[1].getLabel();
if(label0.equals(label1)){&#8230;}

Dans les expressions complexes, Java évalue le code entre parenthèses avant d'effectuer d'autres calculs. La version courte de ce code cherche d'abord le résultat de l'expression entre parenthèses, puis l'utilise comme argument de la méthode equals(), qui est appliquée au résultat du premier appel à getLabel().

Même si le code du jeu occupe plusieurs pages, il n'est pas très difficile à comprendre. Lis simplement tous les commentaires qui s'y trouvent.

 
Sélectionnez
/**
 * Un jeu de morpion sur un plateau 3x3
 */

import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;

public class Morpion extends Applet implements 
                                        ActionListener {

  Button cases[];     
  Button boutonNouvellePartie;
  Label score;
  int casesLibresRestantes = 9;

  /** 
   * La méthode init est comme un constructeur pour l'applet
   */ 
  public void init() {
   
    // Affecte le gestionnaire de disposition et la couleur 
    // de l'applet
    this.setLayout(new BorderLayout());
    this.setBackground(Color.CYAN);
	
    // Passe la police de l'applet en style gras et taille 20
    Font policeApplet = new Font("Monospaced", Font.BOLD, 20);
    this.setFont(policeApplet);

    // Crée le bouton Nouvelle partie et enregistre 
    // le récepteur d'actions auprès de lui 
    boutonNouvellePartie = new Button("Nouvelle partie");
    boutonNouvellePartie.addActionListener(this);

    // Crée deux panneaux et un label et les agence en 
    // utilisant le border layout
    Panel panneauSupérieur = new Panel();
    panneauSupérieur.add(boutonNouvellePartie);

	this.add(panneauSupérieur, "North");
	
    Panel panneauCentral = new Panel();
    panneauCentral.setLayout(new GridLayout(3, 3));
    this.add(panneauCentral, "Center");
	
    score = new Label("A vous de jouer !");
    this.add(score, "South");
	
    // Crée un tableau pour stocker les références des 
    // 9 boutons
    cases = new Button[9];
	  
    // Instancie les boutons, stocke leurs références dans le 
    // tableau, enregistre le récepteur auprès d'eux, peint
    // les boutons en orange et les ajoute au panneau central 
    for(int i = 0; i < 9; i++) {
      cases[i]= new Button();
      cases[i].addActionListener(this);
      cases[i].setBackground(Color.ORANGE);
      panneauCentral.add(cases[i]);
    }
  }
  /**
  * Cette méthode traite tous les événements d'action
  * @param événement l'événement à traiter
  */
  public void actionPerformed(ActionEvent événement) {
    Button leBouton = (Button) événement.getSource();
    // S'agit-il du bouton Nouvelle partie ?
    if (leBouton == boutonNouvellePartie) {
      for(int i = 0; i < 9; i++) {
        cases[i].setEnabled(true);
        cases[i].setLabel("");
        cases[i].setBackground(Color.ORANGE);
      }
      casesLibresRestantes = 9;
      score.setText("A vous de jouer !");
      boutonNouvellePartie.setEnabled(false);
      return;  // Sort de la méthode
    }

    String gagnant = "";
	
	// S'agit-il de l'une des cases ? 
    for (int i = 0; i < 9; i++) {
      if (leBouton == cases[i]) {
        cases[i].setLabel("X");
        gagnant = chercherUnGagnant();

        if(!"".equals(gagnant)) {
          terminerLaPartie();
        } else {
          coupOrdinateur();
          gagnant = chercherUnGagnant();
          if (!"".equals(gagnant)) {
            terminerLaPartie();
          }
        }
        break;  
      }
    } // Fin de la boucle for
    
    if (gagnant.equals("X")) {
	score.setText("Vous avez gagné !");
    } else if (gagnant.equals("O")) {
      score.setText("Vous avez perdu !");
    } else if (gagnant.equals("T")) {
      score.setText("Partie nulle !");
    }
  } // Fin de actionPerformed 

 /**
  *  Cette méthode est appelée après chaque coup joué pour 
  *  voir s'il y a un gagnant. Elle vérifie pour chaque ligne,   
  *  colonne et diagonale, s'il y a trois symboles identiques 
  *  @return "X", "O", "T" (terminé, partie nulle) ou "" (pas
  *  fini)     
  */
  String chercherUnGagnant() {

    String leGagnant = "";
    casesLibresRestantes--;
	
	// Vérifie la ligne 1 - éléments 0, 1 et 2 du tableau 
    if (!cases[0].getLabel().equals("") &&
        cases[0].getLabel().equals(cases[1].getLabel()) &&
        cases[0].getLabel().equals(cases[2].getLabel())) {
      leGagnant = cases[0].getLabel();
      montrerGagnant(0, 1, 2);
 
    // Vérifie la ligne 2 - éléments 3, 4 et 5 du tableau
    } else if (!cases[3].getLabel().equals("") && 
        cases[3].getLabel().equals(cases[4].getLabel()) &&
        cases[3].getLabel().equals(cases[5].getLabel())) {
      leGagnant = cases[3].getLabel();
      montrerGagnant(3, 4, 5);
    
    // Vérifie la ligne 3 - éléments 6, 7 et 8 du tableau 
    } else if (!cases[6].getLabel().equals("") && 
        cases[6].getLabel().equals(cases[7].getLabel()) &&
        cases[6].getLabel().equals(cases[8].getLabel())) {
      leGagnant = cases[6].getLabel();
      montrerGagnant(6, 7, 8);

    // Vérifie la colonne 1 - éléments 0, 3 et 6 du tableau
    } else if (!cases[0].getLabel().equals("") && 
        cases[0].getLabel().equals(cases[3].getLabel()) &&
        cases[0].getLabel().equals(cases[6].getLabel())) {
      leGagnant = cases[0].getLabel();
      montrerGagnant(0, 3, 6);

    // Vérifie la colonne 2 - éléments 1, 4 et 7 du tableau
    } else if (!cases[1].getLabel().equals("") && 
        cases[1].getLabel().equals(cases[4].getLabel()) &&
        cases[1].getLabel().equals(cases[7].getLabel())) {
      leGagnant = cases[1].getLabel();
      montrerGagnant(1, 4, 7);

    // Vérifie la colonne 3 - éléments 2, 5 et 8 du tableau
    } else if (!cases[2].getLabel().equals("") && 
        cases[2].getLabel().equals(cases[5].getLabel()) &&
        cases[2].getLabel().equals(cases[8].getLabel())) {
      leGagnant = cases[2].getLabel();
      montrerGagnant(2, 5, 8);
	  
	  // Vérifie la première diagonale - éléments 0, 4 et 8 
    } else if (!cases[0].getLabel().equals("") && 
        cases[0].getLabel().equals(cases[4].getLabel()) &&
        cases[0].getLabel().equals(cases[8].getLabel())) {
      leGagnant = cases[0].getLabel();
      montrerGagnant(0, 4, 8);

    // Vérifie la seconde diagonale - éléments 2, 4 et 6 
    } else if (!cases[2].getLabel().equals("") && 
        cases[2].getLabel().equals(cases[4].getLabel()) &&
        cases[2].getLabel().equals(cases[6].getLabel())) {
      leGagnant = cases[2].getLabel();
      montrerGagnant(2, 4, 6);
    } else if (casesLibresRestantes == 0) {
      return "T";  // Partie nulle
    }

    return leGagnant;
  }
  /**
   * Cette méthode applique un ensemble de règles afin de 
   * trouver le meilleur coup pour l'ordinateur. Si un bon 
   * coup ne peut être trouvé, elle choisit une case au 
   * hasard. 
   */
  void coupOrdinateur() {
    int caseSélectionnée;
    // L'ordinateur essaie d'abord de trouver une case 
    // vide près de deux case marquées "O" pour gagner
    caseSélectionnée = trouverCaseVide("O");
    // S'il n'y a pas deux "O" alignés, essaie au moins 
    // d'empêcher l'adversaire d'aligner trois "X" en 
    // plaçant un "O" près de deux "X"
    if (caseSélectionnée == -1) {
      caseSélectionnée = trouverCaseVide("X");
    }    
    // Si caseSélectionnée vaut toujours -1, essaie d'occuper  
    // la case centrale
    if ((caseSélectionnée == -1) 
           && (cases[4].getLabel().equals(""))) {
      caseSélectionnée = 4;
    }
    // Pas de chance avec la case centrale non plus...
    // Choisit une case au hasard
    if (caseSélectionnée == -1) {
      caseSélectionnée = choisirCaseAuHasard();
    }
    cases[caseSélectionnée].setLabel("O");
  }

  /**
   * Cette méthode examine chaque ligne, colonne et diagonale 
   * pour voir si elle contient deux cases avec le même label  
   * et une case vide. 
   * @param joueur "X" pour l'utilisateur ou "O" pour
   *               l'ordinateur 
   * @return numéro de la case vide à utiliser ou le nombre
   *         négatif -1 si la recherche est infructueuse    
   */
  int trouverCaseVide(String joueur) {
  	
    int poids[] = new int[9];

    for (int i = 0; i < 9; i++ ) {
      if (cases[i].getLabel().equals("O"))
        poids[i] = -1;
      else if (cases[i].getLabel().equals("X"))
        poids[i] = 1;
      else
        poids[i] = 0;
    }

   int deuxPoids = joueur.equals("O") ? -2 : 2;

   // Regarde si la ligne 1 a 2 cases identiques et une vide
   if (poids[0] + poids[1] + poids[2] == deuxPoids) {
     if (poids[0] == 0)
       return 0;
     else if (poids[1] == 0)
       return 1;
     else
       return 2;
   }
   // Regarde si la ligne 2 a 2 cases identiques et une vide
   if (poids[3] + poids[4] + poids[5] == deuxPoids) {
     if (poids[3] == 0)
       return 3;
     else if (poids[4] == 0)
       return 4;
     else
       return 5;
   }
   // Regarde si la ligne 3 a 2 cases identiques et une vide
    if (poids[6] + poids[7] + poids[8] == deuxPoids) {
      if (poids[6] == 0)
        return 6;
      else if (poids[7] == 0)
        return 7;
      else
        return 8;
    }
    // Regarde si la colonne 1 a 2 cases identiques et une vide
    if (poids[0] + poids[3] + poids[6] == deuxPoids) {
      if (poids[0] == 0)
        return 0;
      else if (poids[3] == 0)
        return 3;
      else
        return 6;
    }
    // Regarde si la colonne 2 a 2 cases identiques et une vide
    if (poids[1] + poids[4] + poids[7] == deuxPoids) {
      if (poids[1] == 0)
        return 1;
      else if (poids[4] == 0)
        return 4;
      else
        return 7;
    }
    // Regarde si la colonne 3 a 2 cases identiques et une vide
    if (poids[2] + poids[5] + poids[8] == deuxPoids) {
      if (poids[2] == 0)
        return 2;
      else if (poids[5] == 0)
        return 5;
      else
        return 8;
    }

    // Regarde si la diagonale 1 a 2 cases identiques et une 
    // vide
    if (poids[0] + poids[4] + poids[8] == deuxPoids) {
      if (poids[0] == 0)
        return 0;
      else if (poids[4] == 0)
        return 4;
      else
        return 8;
    }

	// Regarde si la diagonale 2 a 2 cases identiques et une 
    // vide
    if (poids[2] + poids[4] + poids[6] == deuxPoids) {
      if (poids[2] == 0)
        return 2;
      else if (poids[4] == 0)
        return 4;
      else
        return 6;
    }
    // Il n'y a pas de cases alignées identiques
    return -1;
  } // Fin de trouverCaseVide()
  /**
   * Cette méthode sélectionne une case vide quelconque.
   * @return un numéro de case choisi au hasard
   */
  int choisirCaseAuHasard() {
    boolean caseVideTrouvée = false;
    int caseSélectionnée = -1;

    do {
      caseSélectionnée = (int) (Math.random() * 9);  
      if (cases[caseSélectionnée].getLabel().equals("")) {
        caseVideTrouvée = true; // Pour terminer la boucle 
      }
    } while (!caseVideTrouvée);

    return caseSélectionnée;
  } // Fin de choisirCaseAuHasard()
  /** 
   * Cette méthode affiche la ligne gagnante en surbrillance.  
   * @param gagnante1 première case à montrer.
   * @param gagnante2 deuxième case à montrer.
   * @param gagnante3 troisième case à montrer.
   */
  void montrerGagnant(int gagnante1, int gagnante2, int 
gagnante3) {
    cases[gagnante1].setBackground(Color.CYAN);
    cases[gagnante2].setBackground(Color.CYAN);
    cases[gagnante3].setBackground(Color.CYAN);
  }
  // Désactive les cases et active le bouton Nouvelle partie
  void terminerLaPartie() {
    boutonNouvellePartie.setEnabled(true);
    for (int i = 0; i < 9; i++) {
	cases[i].setEnabled(false);
    } 
  }
} // Fin de la classe

Félicitations ! Tu as terminé ton premier jeu en Java.

Tu peux exécuter cette applet directement depuis Eclipse ou en ouvrant le fichier Morpion.html que nous avons créé au début de ce chapitre (copie simplement les fichiers Morpion.html et Morpion.class dans le même répertoire). Notre classe Morpion a un petit bogue (bug) - tu pourrais même ne pas t'en apercevoir, mais je suis sûr qu'il sera corrigé lorsque tu auras terminé le deuxième exercice ci-dessous.

Notre classe Morpion utilise une stratégie simple parce que notre objectif est juste d'apprendre à programmer. Mais si tu souhaites améliorer ce jeu, applique l'algorithme appelé minimax qui te permet de choisir le meilleur coup pour l'ordinateur. La description de cette stratégie n'est pas du ressort de ce livre, mais tu peux facilement la trouver sur le web.

IX-E. Autres lectures

IX-F. Exercices

Image non disponible

1. Ajoute au panneau supérieur de la classe Morpion deux champs affichant les nombres de victoires et de défaites. Pour ce faire, déclare deux variables de classe que tu incrémenteras à chaque victoire ou défaite. Le score doit être rafraîchi juste après que le programme ait affiché le message "Vous avez gagné" ou "Vous avez perdu".

2. Notre programme permet de cliquer sur une case qui est déjà marquée d'un X ou d'un O. C'est un bogue ! Le programme continue comme si on avait joué un coup valide. Modifie le code pour ignorer les clics sur des cases déjà marquées.

3. Ajoute la méthode main() à la classe Morpion pour qu'on puisse lancer le jeu non seulement comme une applet, mais aussi comme une application Java.

IX-G. Exercices pour les petits malins

Image non disponible

1. Réécris le Morpion en remplaçant le tableau à une dimension qui stocke les neuf boutons :

JButton cases[]

par un tableau à deux dimensions 3 x 3 :

JButton cases[][]

Va sur le web pour t'informer à propos des tableaux multidimensionnels.


précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Copyright © 2015 Yakov Fain. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.