// these are needed for applets to work
import java.applet.Applet;
import java.awt.*;
// this is required for JOptionPane
import javax.swing.JOptionPane;

public class TicTacToe extends Applet
{
    // defines a simple 2d array to store which player has gone where
    private int[][] board;
    // defines the size of each square for the applet
    private int sizesquare = 50;

    // you can put code you want to run when the applet first starts in this method
    public void start()
    {
        // allow drawing...
        setVisible(true);
        // initialize the board...
        board = new int[3][3];
        // play the game
        playgame();
    }

    // return true if the position on the board has been claimed by a player
    // (it would have a non-zero value stored there if it is)
    // Make sure to NOT allow invalid coordinates (return true if x and y
    // are invalid values)
    private boolean istaken(int x, int y) {
        if (x < 0 || x > 2 || y < 0 || y > 2) return true;
        return board[x][y] != 0;
    }
    
    // return true if all of the given coordinates are owned by the player
    // (ie: if the values at those array positions are the player's number)
    // note:  haswon(1,0,0,1,1,2,2) is asking if player 1 has the positions (0,0) (1,1) and (2,2)
    // in the format where the first integer in each pair represents the X value, and the 2nd
    // represents the Y value
    private boolean haswon(int player, int x1, int y1, int x2, int y2, int x3, int y3) {
        return board[x1][y1]==player && board[x2][y2]==player && board[x3][y3]==player;
    }
    
    // return true if anyone has won the game yet, false otherwise.  
    // You need to check each possible way to win at tic tac toe to see if either player has
    // won.  (ie: check if they have a full row or column, or the diagonals).
    // Hint: there are a total of 8 ways a player can win...  Also, you are expected to
    // use the above method (the other haswon) to help you here.
    private boolean haswon(int player) {
        // take care of diagonal wins
        if (haswon(player,0,0,1,1,2,2)) return true;
        if (haswon(player,2,0,1,1,0,2)) return true;
        for (int a = 0; a < 3; a++) {
            // take care of horizontal and vertical wins
            if (haswon(player,a,0,a,1,a,2)) return true;
            if (haswon(player,0,a,1,a,2,a)) return true;
        }
        return false;
    }
    
    private boolean boardfull() {
        for (int a = 0; a < 2; a++) {
            for (int b = 0; b < 2; b++) {
                if (board[a][b] == 0) return false;
            }
        }
        return true;
    }
    
    // This is where the action is...  
    private void playgame() {
        int xpos;
        int ypos;
        while (!haswon(1) && !haswon(2) && !boardfull()) {
            xpos = -1;
            ypos = -1;
            // get player 1's move
            while (istaken(xpos, ypos)) {
                xpos = Integer.parseInt(JOptionPane.showInputDialog("Player 1, please enter the x position:"));
                ypos = Integer.parseInt(JOptionPane.showInputDialog("Player 1, please enter the y position:"));
                }
            board[xpos][ypos] = 1;
            repaint();
            xpos = -1;
            ypos = -1;
            if (!haswon(1) && !boardfull()) {
                while (istaken(xpos, ypos)) {
                    xpos = Integer.parseInt(JOptionPane.showInputDialog("Player 2, please enter the x position:"));
                    ypos = Integer.parseInt(JOptionPane.showInputDialog("Player 2, please enter the y position:"));
                    }             
                    board[xpos][ypos] = 2;
                    repaint();
            }            
        }
        if (haswon(1))
            JOptionPane.showMessageDialog(null, "Ok, so player 1 won this time!");
        else if (haswon(2)) JOptionPane.showMessageDialog(null, "Ok, so player 2 won this time!");
        else JOptionPane.showMessageDialog(null, "Only now do we understand the folly of such conflict!");
    }
 
    // draw a single box (including if it's taken or not)
    public void drawbox(int x, int y, Graphics2D g) {
        g.setColor(Color.black);
        g.drawRect(x*sizesquare,y*sizesquare,sizesquare,sizesquare);
        // does player 1 own this place, if so fill it black
        if (board[x][y]==1) {
            g.setColor(Color.black);
            g.fillRect(x*sizesquare,y*sizesquare,sizesquare,sizesquare);
        }
        // if player 2 owns this place put in a black X
        else if (board[x][y]==2) {
            g.setColor(Color.black);
            g.drawLine(x*sizesquare,y*sizesquare,(x+1)*sizesquare,(y+1)*sizesquare);
            g.drawLine(x*sizesquare,(y+1)*sizesquare,(x+1)*sizesquare,y*sizesquare);
        }
        
    }
    
    // this is called by Java every time the window needs to be drawn or redrawn
    public void paint(Graphics g)
    {
        Graphics2D page = (Graphics2D) g;
        // draw the board
        page.setColor(Color.white);
        page.fillRect(0, 0, sizesquare*3, sizesquare*3);
        for (int a = 0; a < 3; a++) {
            for (int b = 0; b < 3; b++) {
                drawbox(a,b,page);
            }
        }
        page.drawString("Tic Tac Toe Simulator 1.0 - Mr. Casaburi's CSAP class, this is free software (in case anyone cares)",0,sizesquare*3+20);
    }
}