<html>
<head>
<title>TicTacToe.java</title>
</head>
<body bgcolor=#ffffff>
<pre>
/*
** This is were the game plays.  It's the applet itself.
*/
import java.awt.*;
import java.applet.*;
import TttString;
import ComputerMove;

public class TicTacToe extends Applet {

    final int LABELHEIGHT = 50;
        //  Make a new board
    TttString board = new TttString();
        // instanciate a computerMove.
    ComputerMove computer = new ComputerMove();
    Dimension d = new Dimension(200, 200);
    Label lblInformation = new Label("Your Move", Label.LEFT);
        // True means your move. False is my move.
    boolean whoseMove = true;
        // GameStatus contains a static variable
        // which means that any change in value
        // of it will lead to a global change
        // no matter where and howmany instantces
        // we choose to declare of it.
    GameStatus currentGame = new GameStatus();
    int GameNumber = 0;

    public void init() {

        super.init();
        setBackground(Color.white);
        //{{INIT_CONTROLS
        setLayout(null);
        resize(500,200);
        add(lblInformation);
        lblInformation.reshape(210, 0 , 400, 30);
        //}}
    }

    public boolean handleEvent(Event event) {
        return super.handleEvent(event);
    }

    //===============================================================
    //  Draw the entire board everytime that is required.
    //===============================================================
    public void paint(Graphics g)
    {
        int i, j;
        int ttt;

    	int xoff = d.width / 3;
    	int yoff = d.height / 3;

    	for (i = 0; i < 3; i++)
    	{
    	    for (j = 0; j < 3; j++)
    	    {
                g.setColor(Color.black);
    	        g.drawRect(j * xoff + 2, i * yoff + 2, xoff - 4, yoff - 4);
    	        ttt = board.GetXO(i * 3 + j + 1);
    	        if (ttt == board.X)
    	        {
    	            g.setColor(Color.blue);
    	            DrawX(g, d, i, j);
    	        }
    	        else if (ttt == board.O)
    	        {
    	            g.setColor(Color.red);
    	            DrawO(g, d, i, j);
    	        }
    	    }
    	}

    }

    //===============================================================
    //  When the user selects a move then label it. Then check to
    //  see if there were any wining moves.
    //===============================================================
    public boolean mouseUp(Event evt, int x, int y)
    {
            // Don't allow clicks out of the range of the board.
        if (x > d.width || y > d.height)
        {
            return(true);
        }
        if (currentGame.status == currentGame.NOTHING)
        {
        	int col = (x * 3) / d.width;
        	int row = (y * 3) / d.height;
                //  Save the user's choice into the board.
            if (!board.SetTttString(row * 3 + col + 1, board.X))
            {
                return(true);
            }
            repaint();
                // Do we have winner?
            CheckBoardStatus();
            if (currentGame.status == currentGame.NOTHING)
            {
                    // let the computer make it's move
                computer.MakeMove(board);
                repaint();
                CheckBoardStatus();
            }
        }
        else
        {
            board.ClearTttString();
            currentGame.status = currentGame.NOTHING;
                // I do this just to supply the appropriate
                // message in the label
            whoseMove = false;
            CheckBoardStatus();

            repaint();
        }

        return(true);

    }

    //===============================================================
    // What's happening with the game?  Do we have a winner?
    //===============================================================
    private void CheckBoardStatus()
    {
        String message;
        CheckStatus();
        switch (currentGame.status)
        {
            case currentGame.XWON:
                lblInformation.setText("You Win!  Click for a another game.");
                computer.Lost();
                break;
            case currentGame.OWON:
                lblInformation.setText("I Win!  Click for a another game.");
                break;
            case currentGame.TIE:
                lblInformation.setText("Tie!  Click for a another game.");
                break;
            case currentGame.NOTHING:
                whoseMove = !whoseMove;
                message = (whoseMove ? "Your Move" : "My Move");
                lblInformation.setText(message);
        }
    }
    //{{DECLARE_CONTROLS
    Label label1;
    //}}

    //===============================================================
    //  Draw an X on the board
    //===============================================================
    public void DrawX(Graphics g, Dimension d, int row, int col)
    {
        int xStart, yStart, xOff, yOff;
        int i;

        xOff = d.width / 3;
        yOff = d.height / 3;
        xStart = xOff  * col;
        yStart = yOff * row;
        for (i = 0; i < 4; i++)
        {
            g.drawLine(xStart + i + 6, yStart + 6,
                      xStart + xOff + i - 10, yStart + yOff - 10);
            g.drawLine(xStart + xOff + i - 10, yStart + 6,
                       xStart + i + 6, yStart + yOff - 10);
        }
    }

    //===============================================================
    //  Draw an O on the board
    //===============================================================
    public void DrawO(Graphics g, Dimension d, int row, int col)
    {
        int xStart, yStart, xOff, yOff;
        int i;

        xOff = d.width / 3;
        yOff = d.height / 3;
        xStart = xOff  * col;
        yStart = yOff * row;
        for (i = 0; i < 4; i++)
        {
            g.drawOval(xStart + i + 6, yStart + i + 6,
                       xOff - i * 2 - 10, yOff - i * 2 - 10);
        }
    }

    //===============================================================
    //  Check to see if anyone has won or it was a tie or nothing
    //  has happened yet.
    //===============================================================
    public int CheckStatus()
    {
        int i, j, hor, ver;
        int xWins, oWins, xdWins, odWins, tie;
        int location;

            // Check vertical and horizontal statuses
        for (hor = 1, ver = 0; ver < 2; hor--, ver++)
        {
            xdWins = odWins = tie = 0;
            for (i = 0; i < 3; i++)
            {
                xWins = oWins = 0;
                for (j = 0; j < 3; j++)
                {
                        // once it's a horizontal check
                        // the other it's a vertical check
                    location = (i * 3 + j) * hor + (j * 3 + i) * ver + 1;
                    switch(board.GetXO(location))
                    {
                        case board.X:
                            xWins++;
                            tie++;
                            break;
                        case board.O:
                            oWins++;
                            tie++;
                    }
                }
                    // Check the diagonal locations
                location = (i * 3 + i) * hor + (i * 3 + (2 - i)) * ver + 1;
                switch(board.GetXO(location))
                {
                    case board.X:
                        xdWins++;
                        break;
                    case board.O:
                        odWins++;
                }
                    // confusing so far, isn't it??
                if (xWins == 3 || oWins == 3 || xdWins == 3 || odWins == 3)
                {
                    xWins = (xWins == 3 ? xWins : xdWins);
                    oWins = (oWins == 3 ? oWins : odWins);
                    currentGame.status = (xWins == 3 ? currentGame.XWON : currentGame.OWON);
                    return(0);
                }
                else if (tie == 9)
                {
                    currentGame.status = currentGame.TIE;
                }
            }
        }
     return(1);
    }

}
</pre>
</body>
</html>
