import java.awt.*;
import java.awt.event.*;
  
/**********************************************/
/*USING 'X' FOR HUMAN  AND '0' FOR COMPUTER*/
/* Class example 2/10/2009                                            */
/**********************************************/
public class TicTacMine extends java.applet.Applet implements ActionListener
  {
  static Button  squares[],
                 nGameB;
  static Label   label,
                 aboutL;
  static int     squaresRemaining=9;
  static String  forAbout="",
                 difLevel="";
   
  public void init()
    {
    setSize(500,500);
    setLayout(new BorderLayout());
    setFont(new Font("TimesRoman",Font.BOLD,30));
    Panel p1=new Panel();
    p1.setLayout(new GridLayout(3,3));
    add(p1,BorderLayout.CENTER);
    label=new Label("TIC TAC TOW!",1);
    label.setBackground(Color.black);
    label.setForeground(Color.white);
    add(label,BorderLayout.SOUTH);
    Panel p2=new Panel();
    p2.setLayout(new FlowLayout());
    p2.setBackground(Color.black);
    
    //		NEW GAME BUTTON
    nGameB=new Button("New Game");
    nGameB.setBackground(Color.black);
    nGameB.setForeground(Color.blue);
    nGameB.addActionListener(new ActionListener()
      {
      public void actionPerformed(ActionEvent e)
        {
        for(int i=0;i<9;i++)
          {
          squares[i].setEnabled(true);
          squares[i].setLabel("");
          squares[i].setBackground(Color.green);
          }
        squaresRemaining=8;
        label.setText("TIC TAC");
        label.setAlignment(1);
        nGameB.setEnabled(false);
        }
      }
    );
    p2.add(nGameB);
    
    //		ABOUT
    aboutL=new Label("About");
    aboutL.setBackground(Color.black);
    aboutL.setForeground(Color.white);
    aboutL.addMouseListener(new MouseAdapter()
      {
      public void mouseEntered(MouseEvent e)
        {
        forAbout=label.getText();
        aboutL.setForeground(Color.red);
        label.setText("ITIS 3310");
        label.setAlignment(1);
        }
      }
    );
    aboutL.addMouseListener(new MouseAdapter()
      {
      public void mouseExited(MouseEvent e)
        {
        aboutL.setForeground(Color.white);
        label.setText(forAbout);
        label.setAlignment(1);
        }
      }
    );
    p2.add(aboutL);
    add(p2,BorderLayout.NORTH);
    squares=new Button[9];
    for(int i=0;i<9;i++)
      {
      squares[i]=new Button();
      squares[i].addActionListener(this);
      squares[i].setBackground(new Color(98,156,245));
      p1.add(squares[i]);
      }
    nGameB.setEnabled(false);
    }//end init
   
  public void actionPerformed(ActionEvent e)
    {
    for ( int i=0; i<9; i++ )
      {
      if ( e.getSource() == squares[i] )
        {
        if ( squares[i].getLabel().equals("X") ||
             squares[i].getLabel().equals("O") )
          {
          return;
          }
        squares[i].setLabel("X");
        squaresRemaining--;
        String winner = "";
        winner = checkForWin();
        if ( winner.equals("X") ||
             winner.equals("O") )
          {
          endGame();
          }
        else
          {
          if ( squaresRemaining <= 0 )
            {
            endGame();
            }
          else
            { //	for animation
            try
              {
              Thread.sleep(100);
              }
            catch(InterruptedException w){}
            computerMove();
            squaresRemaining--;
            winner = checkForWin();
            if (   winner.equals("X")
                || winner.equals("O")
                || squaresRemaining <= 0 
               )   // or if tie
              {
              endGame();
              }
            }
          }
        }
      }
    } // end actionPerformed
   
  String checkForWin() 
    {
    String theWinner = "";
    // check the rows
    for (int i=0; i<9; i=i+3)
      {
      if (    squares[i].getLabel().equals(squares[i+1].getLabel())
          &&  squares[i].getLabel().equals(squares[i+2].getLabel())
          && !squares[i].getLabel().equals("") ) 
        {
        theWinner = squares[i].getLabel();
        colorLine(i, i+1, i+2, theWinner);
        break;
        }
      }
    // check the columns
    for (int i=0; i<3; i++)
      {
      if (    squares[i].getLabel().equals(squares[i+3].getLabel())
          &&  squares[i].getLabel().equals(squares[i+6].getLabel())
          && !squares[i].getLabel().equals("") )
        {
        theWinner = squares[i].getLabel();
        colorLine(i, i+3, i+6, theWinner);
        break;
        }
      }
    // finally check the two diagonals
    if (    squares[0].getLabel().equals(squares[4].getLabel())
        &&  squares[0].getLabel().equals(squares[8].getLabel())
        && !squares[0].getLabel().equals("") )
      {
      theWinner = squares[0].getLabel();
      colorLine(0, 4, 8, theWinner);
      }
    else if (    squares[2].getLabel().equals(squares[4].getLabel())
             &&  squares[2].getLabel().equals(squares[6].getLabel())
             && !squares[2].getLabel().equals("") )
      {
      theWinner = squares[2].getLabel();
      colorLine(2, 4, 6, theWinner);
      }
    return theWinner;
    } // end checkForWin
  
  void computerMove()
    {
    int pickedSquare;
    pickedSquare = tryToWin();
    if ( pickedSquare == -1 )
      pickedSquare = makeBlock();
    if ( (pickedSquare == -1)&&(squares[4].getLabel().equals("")) )
      pickedSquare=4;
    if ( pickedSquare == -1 )
      pickedSquare = pickRandom();
    squares[pickedSquare].setLabel("O");
    return;
    } // end computerMove
  
  int tryToWin() 
    { // Since computer plays "O", find empty square that is in line with 
    return EmptySquare("O");
    } // end tryToWin
   
  int makeBlock()
    { // Since human plays "X", find empty square that is in line with 
    return EmptySquare("X");
    } // end makeBlock
  
  int EmptySquare(String player)
    {
    int a[] = new int[9];
    // Translate x's and o's to 1's and -1's in the a array
    for ( int i = 0; i < 9; i++ )
      {
      if ( squares[i].getLabel().equals("O") )
        a[i] = -1;
      else if ( squares[i].getLabel().equals("X") )
        a[i] = 1;
      else
        a[i] = 0;
      }
    int sum = player.equals("O") ? -2 :2;
     
    // Check Rows
    for (int i = 0; i < 9; i=i+3)  // for all rows
      {
      if (a[i] + a[i+1] + a[i+2] == sum)
        {
        if (a[i] == 0)
          return i; 
        else if (a[i+1] == 0)
          return i+1;
        else
          return i+2; 
        }
      } 
     
    // columns
    for (int i = 0; i < 3; i++)
      {
      if (a[i] + a[i+3] + a[i+6] == sum)
        {
        if (a[i] == 0)
          return i;
        else if (a[i+3] == 0)
          return i+3;
        else
          return i+6;
        }
      }
    
    // diagonal upper-left to lower-right
    if ( a[0] + a[4] + a[8] == sum )
      {
      if ( a[0] == 0 )
        return 0;
      else if ( a[4] == 0 )
        return 4;
      else
        return 8;
      }
     
    // diagonal upper-right to lower-left
    if ( a[2] + a[4] + a[5] == sum ) 
      {
      if ( a[2] == 0 )
        return 2;
      else if ( a[4] == 0 )
        return 4;
      else
        return 6;
      }
    // not able to find
    return -1;
    } // end EmptySquare
    
  int pickRandom()
    {
    boolean found = false;
    int pickedSquare = -1;
    do
      {
      pickedSquare = (int) (Math.random() * 9 );  // 0 to 8
      if ( ! squares[pickedSquare].getLabel().equals("X") &&
           ! squares[pickedSquare].getLabel().equals("O") )
        {
        found = true;
        System.out.println("Square:" + pickedSquare);
        }
      } while ( ! found );
    return pickedSquare;
    } // end pickRandom()
    
  void colorLine(int a, int b, int c,String win)
    {
    // mark line red if user (X) wins
    // mark line blue if computer (O) wins
    if ( win.equals("X") )
      {
      squares[a].setBackground(Color.black);
      squares[b].setBackground(Color.black);
      squares[c].setBackground(Color.black);
      label.setText("HUMAN WINS");
      label.setForeground(new Color(00,255,128));
      label.setAlignment(1);
      }
    else
      {
      squares[a].setBackground(Color.black);
      squares[b].setBackground(Color.darkGray);
      squares[c].setBackground(Color.gray);
 	  label.setText("          COMPUTER WINS");
      label.setForeground(Color.white);
      label.setAlignment(1);
      }
    } // end colorLine
   
  void endGame()
    {
    for(int i=0;i<9;i++)
      squares[i].setEnabled(false);
    nGameB.setEnabled(true);
    } // end endGame
  
  }//end class