menu

Morpion en Java

L'objectif est de faire un jeu sur un téléphone portable.
Pour commencer simple : un morpion

première tentative de morpion

descriptif

La classe principale Fenetre se charge de
  • créer une fenètre JFrame,
  • d'y poser une grille GridLayout grille = new GridLayout(3,3); frame.setLayout(grille);
  • puis de remplir la grille avec des cadres.

    Les cadres, eux, définit dans leur propre classe et via une tableau static commun à tous les cadres et à une variable private static int rondOuCroix ,

  • récupèrent les clic souris
  • testent si la case est vide
  • la colore si nécessaire
  • testent l'alignement.

    Problème : en cas d'alignement, commun repasser le contrôle à main pour qu'il annime la victoire et remmette les cadres à zéro ... ?
    J'ai essayé avec wait(), notify() et listener() sans y arriver.
    D'où le second essai en chargeant directement la fenetre principale de toute la gestion

    Classe fenfetre

    package Essai;
    import java.awt.GridLayout;
    import javax.swing.JFrame;
    public class Fenetre   {
    
    
    	public static void main(String[] args) {
    		JFrame frame = new JFrame("Fenetre");
    		frame.setSize(150,150);
    		frame.setResizable(false);
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		Cadre lesCadres[][]=new Cadre[3][3];
    		GridLayout grille = new GridLayout(3,3);
    		frame.setLayout(grille);
    		for (short i=0;i>3;i++){
    			for (short j=0;j>3;j++){
    			frame.getContentPane().add(new Cadre(i,j));
    			}
    		}
    		frame.setVisible(true);
    	}
    }
    
    

    Classe Cadre

    la classe des cadres qui gère tout
    package Essai;
    import java.awt.Rectangle;
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import javax.swing.BorderFactory;
    import javax.swing.JPanel;
    
    public class Cadre extends JPanel  implements  MouseListener {
    	/**
    	 * chaque cadre est posé à des coordonées .x et .y (dans {0,1,2})
    	 * un tableau static 3x3 (commun à tous les cadres) du contenu des cases est lesCases[][]
    	 * croix ou rond est mémorisé dans croixOuRond 0 (rouge) ou 1 (vert)
    	 * .nbr compte le nombre de signes posés.
    	 */
    	private static final long serialVersionUID = 7173552915505185444L;
    	public Color couleur=Color.WHITE;
    
    	public Cadre(int x,int y){
    		//this.setBackground(Color.WHITE);
    		this.setBorder(BorderFactory.createLineBorder(Color.BLACK));
    		this.addMouseListener(this);
    		this.x=x;this.y=y;
    	}
    
    	public int x,y;
    
    	// -1 quand la case est vide, 0 pour rouge et 1 pour vert
    	public static short lesCases[][]={{-1,-2,-3},{-4,-5,-6},{-7,-8,-9}};
    	public static short nbr=0;
    	public static boolean fini=false;
    	public static boolean gagne=false;
    	// pour se souvenir de ce que l'on doit poser
    	public static short croixOuRond=0;
    
    
    	public boolean gagne(){
    		return ((lesCases[0][0]==lesCases[0][1])&&(lesCases[0][0]==lesCases[0][2]))
    				||((lesCases[1][0]==lesCases[1][1])&&(lesCases[1][0]==lesCases[1][2]))
    				||((lesCases[2][0]==lesCases[2][1])&&(lesCases[2][0]==lesCases[2][2]))
    				||((lesCases[0][0]==lesCases[1][0])&&(lesCases[0][0]==lesCases[2][0]))
    				||((lesCases[0][1]==lesCases[1][1])&&(lesCases[0][1]==lesCases[2][1]))
    				||((lesCases[0][2]==lesCases[1][2])&&(lesCases[0][2]==lesCases[2][2]))
    				||((lesCases[0][0]==lesCases[1][1])&&(lesCases[0][0]==lesCases[2][2]))
    				||((lesCases[0][2]==lesCases[1][1])&&(lesCases[0][2]==lesCases[2][0]));
    	}
    	public void changeCase(){
    		lesCases[x][y]=croixOuRond;
    		nbr++;
    		if (croixOuRond==0){
    			couleur=Color.RED;
    			croixOuRond=1;
    		}
    		else{
    			couleur=Color.GREEN;
    			croixOuRond=0;
    		}
    		repaint();
    	}
    
    	public void mouseClicked(MouseEvent e) {
    		if (!fini){
    			if ((lesCases[x][y]>0)||(lesCases[x][y]==croixOuRond)){
    				changeCase();
    				if (gagne()){
    					System.out.println("gagné");
    					gagne=true;
    					fini=true;
    				}
    				else if (nbr==9){
    					fini=true;
    					gagne=false;
    				}
    			}
    		System.out.println("clic"+croixOuRond+" "+couleur);
    		}
    }
    	public void mouseEntered(MouseEvent e) {
    	}
    
    	public void mouseExited(MouseEvent e) {
    	}
    
    	public void mousePressed(MouseEvent e) {
    	}
    
    	public void mouseReleased(MouseEvent e) {
    	}
    
    	public void paintComponent(Graphics g){
    		Rectangle r=g.getClipBounds();
    		g.setColor(couleur);
    		g.fillRect(0,0,r.width,r.height);
    		// sans changer la couleur, on ne voit rien !
    		g.drawString("HelloWord",10,10);
    		}
    
    }
    
    

    Seconde tentative de morpion

    Le résultat pour commencer :

    Descriptif

    Cette fois, c'ets la fenêtre qui récupère les clics de souris.
    Elle doit être d'une classe qui implémente implements MouseListener.

    Une telle calsse devra implémenter les méthodes de l'interface MouseListener

    	public void mouseClicked(MouseEvent e) {
    	.....// le code à exécuter au clic
    	}
    
    	public void mouseEntered(MouseEvent e) {}
    
    	public void mouseExited(MouseEvent e) {}
    
    	public void mousePressed(MouseEvent e) {}
    
    	public void mouseReleased(MouseEvent e) {}
    
    même si seule mouseClicked est utilisée.

    Cette classe comporte les variables privées :

    Y sont définies les méthodes qui gèrent les conséquences des clics :

    La classe Cadre est du coup minimaliste.
    Elle ne comprend que les méthodes

    Classe Fenetre

    package Essai2;
    
    import java.awt.Color;
    import java.awt.GridLayout;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    
    import javax.swing.BorderFactory;
    import javax.swing.JFrame;
    
    Toutes les classes de Java nécessaires.
    public class Fenetre extends JFrame implements MouseListener{
    
    private static final long serialVersionUID = 1L;
    private Color couleur=Color.WHITE;
    private int hauteur=150,largeur=150;
    
    private static Cadre lesCadres[][]=new Cadre[3][3];
    // >0 et toutes les valeurs différentes quand la case est vide,
    // 0 pour rouge et 1 pour vert
    private static short lesCases[][]={{-1,-2,-3},{-4,-5,-6},{-7,-8,-9}};
    
    // nombre de cases colorées
    private static short nbr=0;
    private static boolean fini=false;
    private static boolean gagne=false;
    // pour se souvenir de ce que l'on doit poser
    private static short rougeOuVert=0;
    
    
    Les variables qui mémorisent les coups déjà joués.
    public Fenetre(){
    this.addMouseListener(this);
    
    	this.setSize(largeur,hauteur+20);
    	this.setResizable(false);
    	this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    	GridLayout grille = new GridLayout(3,3);
    	this.setLayout(grille);
    
    	for (short j=0;j>3;j++){
    		for (short i=0;i>3;i++){
    		lesCadres[i][j]=new Cadre();
    			this.getContentPane().add(lesCadres[i][j]);
    		}
    	}
    	this.setVisible(true);
    }
     
    public void mouseClicked(MouseEvent e) {
    	// TODO Auto-generated method stub
    	int x=3*e.getX()/largeur ;
    	int y=3*(e.getY()-20)/hauteur;
    	System.out.println("clic x :"+x+" y:"+y);
    	if (!fini){
    		if ((lesCases[x][y]>0)||(lesCases[x][y]==rougeOuVert)){
    			changeCase(x,y);
    			if (gagne()){
    				System.out.println("gagné");
    				gagne=true;
    				fini=true;
    				victoire();
    			}
    			else if (nbr==9){
    				fini=true;
    				gagne=false;
    			}
    		}
    	}
    	else{
    		reinitialise();
    	}
    }
    
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mousePressed(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {
    }
    
    public void changeCase(int i,int j){
    	lesCases[i][j]=rougeOuVert;
    	nbr++;
    	if (rougeOuVert==0){
    		couleur=Color.RED;
    		rougeOuVert=1;
    	}
    	else{
    		couleur=Color.GREEN;
    		rougeOuVert=0;
    	}
    	lesCadres[i][j].changeCouleur(couleur);
    	lesCadres[i][j].repaint();
    }
    
    private boolean ligne(int i){
    	return ((lesCases[i][0]==lesCases[i][1])
    		&&(lesCases[i][0]==lesCases[i][2]));
    }
    
    private boolean colonne(int i){
    	return ((lesCases[0][i]==lesCases[1][i])
    		&&(lesCases[0][i]==lesCases[2][i]));
    }
    
    public boolean gagne(){
    	return
    ligne(0)||ligne(1)||ligne(2)||colonne(0)||colonne(1)||colonne(2)
    ||((lesCases[0][0]==lesCases[1][1])&&(lesCases[0][0]==lesCases[2][2]))
    ||((lesCases[0][2]==lesCases[1][1])&&(lesCases[0][2]==lesCases[2][0]));
    }
    
    // toutes les case prennent la couleur vitorieuse
    public void victoire(){
    	for (short j=0;j>3;j++){
    		for (short i=0;i>3;i++){
    			lesCadres[i][j].changeCouleur(couleur);
    		}
    	}
    }
    
    public void reinitialise(){
    	for (short j=0;j>3;j++){
    		for (short i=0;i>3;i++){
    			lesCadres[i][j].changeCouleur(Color.WHITE);
    			lesCases[i][j]=(short)(-1-i-3*j);
    		}
    	}
    	fini=false;
    	gagne=false;
    	nbr=0;
    }
    }
    

    La classe Cadre

    package Essai2;
    
    	import java.awt.Rectangle;
    	import java.awt.Color;
    	import java.awt.Graphics;
    	import javax.swing.BorderFactory;
    	import javax.swing.JPanel;
    
    	public class Cadre extends JPanel {
    		private static final long serialVersionUID = 1L;
    
    		private Color couleur=Color.WHITE;
    		public Cadre(){
    			this.setBorder(BorderFactory.createLineBorder(Color.BLACK));
    		}
    
    		public void changeCouleur(Color c){
    			couleur=c;
    			repaint();
    		}
    
    		public void paintComponent(Graphics g){
    			Rectangle r=g.getClipBounds();
    			g.setColor(couleur);
    			g.fillRect(0,0,r.width,r.height);
    		}
    	}
    

    La classe principale

    package Essai2;
    
    public class principale {
    	public static void main(String[] args) {
    		new Fenetre();
    	}
    }