/* Auteur: Nicolas JANEY          */
/* nicolas.janey@univ-fcomte.fr   */
/* Fevrier 2005                   */

import java.awt.*;
import java.awt.event.*;

public class NeomixEnConsole extends Frame
                            implements WindowListener,
			                                 ActionListener,
			                                 MouseListener,
			                                 KeyListener {
  private MenuBar mb = new MenuBar();
  private Menu m1 = new Menu("Fichier");
  private MenuItem mnj = new MenuItem("Nouveau jeu");
  private MenuItem mq = new MenuItem("Quitter");
  private int [][] damier;
  private String message ="";
  private int mousex = -1;
  private int mousey = -1;
  private static int [][] directionsVoisins = { {  1, 0 },
                                                {  1, 1 },
                                                {  0, 1 },
                                                { -1, 1 },
                                                { -1, 0 },
                                                { -1,-1 },
                                                {  0,-1 },
                                                {  1,-1 } };

  public NeomixEnConsole(int [][] damier) {
    super("Neomix");
    this.damier = damier;
    addWindowListener(this);
    addMouseListener(this);
    addKeyListener(this);
    setMenuBar(mb);
    mb.add(m1);
    m1.add(mnj);
    m1.addSeparator();
    m1.add(mq);
    mq.addActionListener(this);
    setBackground(Color.white);
    setSize(24*damier.length+8,24*damier.length+72);
    setVisible(true);
  }

  public boolean dansTableau(int [][] t,int xi,int yi) {
    if ( ( xi < 0 ) || ( yi < 0 ) || ( xi >= t.length ) || ( yi >= t.length ) )
      return(false);
    return(true);
  }

  public void affichage(int [][] damier) {
    repaint();
  }

  public int distance2(int x1,int y1,int x2,int y2) {
    int dx = x2-x1;
    int dy = y2-y1;
    return(dx*dx+dy*dy);
  }

  public int [] positionEssai() {
    int [] pos = new int[2];
    boolean good = false;
    do {
      while ( ( mousex == -1 ) && ( mousey == -1 ) )
        try {
          Thread.sleep(200); }
        catch ( Exception e ) { };
      for ( int y = 0 ; y < damier.length ; y++ )
        for ( int x = 0 ; x < damier[y].length ; x++ ) {
          int px = 12+24*x;
          int py = 60+24*y;
          if ( distance2(px,py,mousex,mousey) < 100 ) {
            pos[0] = x;
            pos[1] = y;
            mousex = -1;
            mousey = -1;
            return(pos); } }
      mousex = -1;
      mousey = -1; }
    while ( !good );
    return(pos);
  }

  public int autreJoueur(int joueur) {
    if ( joueur == 1 )
      return(2);
      else
      return(1);
  }

  public boolean existeCarre(int [][] damier,int px,int py,int joueur) {
    for ( int y = py ; y <= py+1 ; y++ )
      for ( int x = px ; x <= px+1 ; x++ )
        if ( ( !dansTableau(damier,x,y) ) || ( damier[y][x] != joueur ) )
          return(false);
    return(true);
  }

  public boolean carreConstitue(int [][] damier,int x,int y,int joueur) {
    int [][] positions = { {  0, 0 },
                           { -1, 0 },
                           {  0,-1 },
                           { -1,-1 } };
    int i = 0;
    while ( i < 4 ) {
      if ( existeCarre(damier,x+positions[i][0],y+positions[i][1],joueur) )
        return(true);
      i++; }
    return(false);
  }

  public boolean existeEncadrement(int [][] damier,int px,int dx,int py,int dy,int joueur) {
    if ( !dansTableau(damier,px,py) )
      return(false);
    if ( damier[py][px] != joueur )
      return(false);
    int x;
    int y;
    x = px+4*dx;
    y = py+4*dy;
    if ( !dansTableau(damier,x,y) )
      return(false);
    if ( damier[y][x] != joueur )
      return(false);
    int autre = autreJoueur(joueur);
    for ( int i = 1 ; i <= 3 ; i++ ) {
      x = px+i*dx;
      y = py+i*dy;
      if ( damier[y][x] != autre )
        return(false); }
    return(true);
  }

  public boolean encadrementConstitue(int [][] damier,int x,int y,int joueur) {
    int i = 0;
    while ( i < 8 ) {
      if ( existeEncadrement(damier,
                             x,directionsVoisins[i][0],
                             y,directionsVoisins[i][1],
                             joueur) )
        return(true);
      i++; }
    return(false);
  }

  public boolean suicideJoueur(int [][] damier,int x,int y,int joueur) {
    int autre = autreJoueur(joueur);
    int i = 0;
/*    while ( i < 4 ) {
      if ( existeEncadrement(damier,
                             x-2*directionsVoisins[i][0],directionsVoisins[i][0],
                             y-2*directionsVoisins[i][1],directionsVoisins[i][1],
                             autre) ) {
        return(true); }
      i++; }
    i = 0;*/
    while ( i < 8 ) {
      if ( existeEncadrement(damier,
                             x-directionsVoisins[i][0],directionsVoisins[i][0],
                             y-directionsVoisins[i][1],directionsVoisins[i][1],
                             autre) ) {
        Console.out.println(i);
        return(true); }
      i++; }
    return(false);
  }

  public int jeuFini(int [][] damier,int x,int y) {
    int joueur = damier[y][x];
    //if ( carreConstitue(damier,x,y,joueur) )
    //  return(joueur);
    if ( encadrementConstitue(damier,x,y,joueur) )
      return(joueur);
    if ( suicideJoueur(damier,x,y,joueur) )
      return(autreJoueur(joueur));
    return(0);
  }

  public boolean existeVoisin(int [][] damier,int x,int y) {
    for ( int i = 0 ; i < 8 ; i++ ) {
      int px = x+directionsVoisins[i][0];
      int py = y+directionsVoisins[i][1];
      if ( dansTableau(damier,px,py) )
        if ( damier[py][px] != 0 )
          return(true); }
    return(false);
  }

  public boolean positionJouable(int [][] damier,int x,int y) {
    if ( !dansTableau(damier,x,y) )
      return(false);
    if ( damier[y][x] != 0 )
      return(false);
    if ( !existeVoisin(damier,x,y) )
      return(false);
    return(true);
  }

  public void joue() {
    int nbp = 0;
    int joueur = 2;
    int gagnant;
    int [] pos;
    do {
      joueur = autreJoueur(joueur);
      if ( joueur == 2 ) {
        message = "Le joueur 2 (X) doit jouer"; }
        else {
        message = "Le joueur 1 (O) doit jouer"; }
      nbp++;
      affichage(damier);
      do {
        pos = positionEssai(); }
      while ( !positionJouable(damier,pos[0],pos[1]) );
      damier[pos[1]][pos[0]] = joueur; }
    while ( ((gagnant = jeuFini(damier,pos[0],pos[1])) == 0) && ( nbp < 60 ) );
    if ( gagnant != 0 )
      message = "C'est le joueur "+gagnant+" qui gagne";
      else
      message = "Match nul";
    affichage(damier);
  }

  public void paint(Graphics g) {
    for ( int y = 0 ; y < damier.length ; y++ ) {
      for ( int x = 0 ; x < damier.length ; x++ )
        switch ( damier[y][x] ) {
          case 0 : g.drawLine(12+24*x,60+24*y,12+24*x,60+24*y);
                    break;
          case 1  : g.drawOval(8+24*x,56+24*y,8,8);
                    break;
          case 2  : g.drawLine(9+24*x,57+24*y,15+24*x,63+24*y);
                    g.drawLine(9+24*x,63+24*y,15+24*x,57+24*y);
                    break; } }
    g.drawString(message,10,58+damier.length*24);
  }

  public void nouveauJeu() {
  }

  public void windowActivated(WindowEvent e) {
  }

  public void windowClosed(WindowEvent e) {
  }

  public void windowClosing(WindowEvent e) {
    System.exit(0);
  }

  public void windowDeactivated(WindowEvent e) {
  }

  public void windowDeiconified(WindowEvent e) {
  }

  public void windowIconified(WindowEvent e) {
  }

  public void windowOpened(WindowEvent e) {
  }

  public void actionPerformed(ActionEvent e) {
    if ( e.getSource() == mq ) {
      System.exit(0); }
    if ( e.getSource() == mnj ) {
      nouveauJeu(); }
  }

  public void keyPressed(KeyEvent e) {
  }

  public void keyReleased(KeyEvent e) {
  }

  public void keyTyped(KeyEvent e) {
  }

  public void mouseClicked(MouseEvent e) {
    mousex = e.getX();
    mousey = e.getY();
  }

  public void mouseEntered(MouseEvent e) {
  }

  public void mouseExited(MouseEvent e) {
  }

  public void mousePressed(MouseEvent e) {
  }

  public void mouseReleased(MouseEvent e) {
  }

  /* Fonction d'initialisation du tableau de jeu          */

  public static int [][] initialise() {
    int [][] t = new int[8][8];
    for ( int i = 0 ; i < 8 ; i++ )
      for ( int j = 0 ; j < 8 ; j++ )
        t[i][j] = 0;
    t[3][3] = 1;
    t[4][4] = 1;
    t[3][4] = 2;
    t[4][3] = 2;
    return(t);
  }

  /* Fonction principale                                  */

  public static void main(String [] args) {
    Console.setTitle("Neomix");
  /* Generation et initialisation du damier               */
    int [][] damier = initialise();
  /* Lancement du jeu                                     */
    NeomixEnConsole nf = new NeomixEnConsole(damier);
    nf.joue();
  }
}