# Java Tic-Tac-Toe



## Geek4Life (Jan 30, 2008)

I'm just a Junior in High School, and have hardly a Quarter's worth of experience in JAVA. That said, i enjoy proggrmming (very few people can boost this claim ), so in my spare time im working on developing a Tic-Tac-Toe program that involves clicking the mouse in the quadrent you want to place your "X" or "O"; I haven't got verry far, so I realize this code is missing much but I'm stumped on an error I'm recieving. Here's my code:


```
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class TicTacToe extends Applet {
    private int x,y;
    public  TicTacToe() {
      addMouseListener(new Listen());  
    }
    public void paint(Graphics page) {}
    private class Listen implements MouseListener {
        public void mouseClicked (MouseEvent event) { 
            y = event.getXOnScreen();
            x = event.getXOnScreen();
}
public void mousePressed (MouseEvent event) {}
    }
}
```
now here's my problem (I run Netbeans for an IDE): next to "private class Listen implements MouseListener" it gives me a little red exclamation point telling me that "TicTacToe.Listen is not abstract and does not override abstract Method mouseExited(java.awt.event.MouseEvent) in java.awt.event.MouseListener". Can anybody shed some light on this error, and give me any ideas of how I'm supposed to resolve it?


----------



## Chicon (Jul 29, 2004)

Hi Geek4Life,

I've had a look to your coding : both following statements are wrong(*) :
*y = event.getXOnScreen();
x = event.getXOnScreen();*

Also, the *MouseListener* interface has 5 methods that must be implemented.
Therefore :

```
[SIZE=2]
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class TicTacToe extends Applet {
    private int x,y;
    
    public  TicTacToe() {
        addMouseListener(new Listen());
    }
    
    public void paint(Graphics page) {}
    
    private class Listen implements MouseListener {
        public void mouseClicked(MouseEvent event) {
            y = event.[COLOR=BLUE]getY()[/COLOR];
            x = event.[COLOR=BLUE]getX()[/COLOR];
        }
        public void mousePressed(MouseEvent e) {}

        public void mouseReleased(MouseEvent e) {}

        public void mouseEntered(MouseEvent e) {}

        public void mouseExited(MouseEvent e) {}
    }
}[/SIZE]
```
I'm using NetBeans too ! 

(*)
Edit : the methods are only available since Java 6. They are used in multi-screen envrionment context. In the case of applets, the classical methods are preferred.


----------



## Geek4Life (Jan 30, 2008)

"Classical Methods"? I'm affraid i dont know what your talking about.

So wait....the only reason it was giving me an error was because i hadn't mentioned the other 3 methods yet?


----------



## Chicon (Jul 29, 2004)

> "Classical Methods"? I'm affraid i dont know what your talking about.


I meant the good old _getX_ and _getY_ methods of the _MouseEvent_ class.


----------



## Geek4Life (Jan 30, 2008)

Thiings are running better, but now I have a new problem: keeping the "X"'s and "O"'s to stay on the board. I don't want to "repaint();" but if I don't I can't read the x and y co-ordinates of the mouse: I tried to create a sort-of work around, by before every round checking the squares, and if their filled put either the appropriate "x" or "O" in it's proper place, but this isn't working further when run, im getting some errors int the output box. Here's my code as it stands now:


```
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class TicTacToe extends Applet {
    int x,y;
    int turn = 1;
    boolean t3 = false;
    int [][] Board = new int[3][3];
    public  TicTacToe() {
       addMouseListener(new Listen());
    }
    private class Listen implements MouseListener {
        public void mouseClicked (MouseEvent event) { 
            y = event.getY();
            x = event.getX();
            repaint();
        }
public void mousePressed(MouseEvent event) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
    }
    public void paint(Graphics page) {
        page.drawLine(50, 100, 200, 100);
        page.drawLine(50,150,200, 150);
        page.drawLine(100, 50, 100, 200);
        page.drawLine(150,50,150,200);
        for (int round = 1; round < 10; round++) {    
            if (round != 1) {
                for (int row = 1; row <= 3; row ++) {
                    x = row * 50;
                    for (int col = 1; col <= 3; col++) {
                        y = col * 50;
                        if (Board[row][col] == 1) {
                            page.drawLine(x+5, y+5, x+45, y+45);
                            page.drawLine(x+45, y+5, x+5, y+45);
                        } else if (Board[row][col] == 2) page.drawOval(x+5, y+5, 40, 40);
                    }
                }
            }
            if (x > 50 && x < 100) {
                if (y > 50 && y < 100) {
                    if (Board[1][1] == 0) {
                        if (turn == 1) {
                            page.drawLine(55, 55, 95, 95);
                            page.drawLine(95, 55, 55, 95);
                        } else page.drawOval(55, 55, 40, 40);
                        Board[1][1] = turn;
                    }
                }                
                if (y > 100 && y < 150) {
                    if (Board[1][2] == 0) {
                        if (turn == 1) {
                            page.drawLine(55, 105, 95, 145);
                            page.drawLine(95, 105, 55, 145);
                        } else page.drawOval(55, 105, 40, 40);
                        Board[1][2] = turn;
                    }
                }
                if (y > 150 && y < 200) {
                    if (Board[1][3] == 0) {
                        if (turn == 1) {
                            page.drawLine(55, 155, 95, 195);
                            page.drawLine(95, 155, 55, 195);
                        } else page.drawOval(55, 155, 40, 40);
                        Board[1][3] = turn;
                    }
                }
            }
            if (x > 100 && x < 150) {
                if (y > 50 && y < 100) {
                    if (Board[2][1] == 0) {
                        if (turn == 1) {
                            page.drawLine(105, 55, 145, 95);
                            page.drawLine(145, 55, 105, 95);
                        } else page.drawOval(105, 55, 40, 40);
                        Board[2][1] = turn;
                    }
                }
                if (y > 100 && y < 150) {
                    if (Board[2][2] == 0) {
                        if (turn == 1) {
                            page.drawLine(105, 105, 145, 145);
                            page.drawLine(145, 105, 105, 145);
                        } else page.drawOval(105, 105, 40, 40);
                    Board[2][2] = turn;
                    }
                }
                if (y > 150 && y < 200) {
                    if (Board[2][3] == 0) {
                        if (turn == 1) {
                            page.drawLine(105, 155, 145, 195);
                            page.drawLine(145, 155, 105, 195);
                        } else page.drawOval(105, 155, 40, 40);      
                        Board[2][3] = turn;
                    }
                }
            }
            if (x > 150 && x < 200) {
                if (y > 50 && y < 100) {
                    if (Board[3][1] == 0) {
                        if (turn == 1) {
                            page.drawLine(155, 55, 195, 95);
                            page.drawLine(195, 55, 155, 95);
                        } else page.drawOval(155, 55, 40, 40);
                        Board[3][1] = turn;
                    }
                }
                if (y > 100 && y < 150) {
                    if (Board[3][3] == 0) {
                        if (turn == 1) {
                            page.drawLine(155, 105, 195, 145);
                            page.drawLine(195, 105, 155, 145);
                        } else page.drawOval(155, 105, 40, 40);
                        Board[3][2] = turn;
                    }
                }
                if (y > 150 && y < 200) {
                    if (Board[3][3] == 0) {
                        if (turn == 1) {
                            page.drawLine(155, 155, 195, 195);
                            page.drawLine(195, 155, 155, 195);
                        } else page.drawOval(155, 155, 40, 40);
                        Board[3][3] = turn;
                    }
                }
            }
            if (turn == 1) turn = 2; else turn = 1;
        }
    }
}
```
and here's the errors im geting in the Output box:

Exception in thread "AWT-EventQueue-1" java.lang.ArrayIndexOutOfBoundsException: 3
at TicTacToe.paint(TicTacToe.java:35)
at sun.awt.RepaintArea.paintComponent(RepaintArea.java:248)
at sun.awt.RepaintArea.paint(RepaintArea.java:224)
at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:301)
at java.awt.Component.dispatchEventImpl(Component.java:4489)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4243)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
Exception in thread "AWT-EventQueue-1" java.lang.ArrayIndexOutOfBoundsException: 3
at TicTacToe.paint(TicTacToe.java:35)
at java.awt.Container.update(Container.java:1818)
at sun.awt.RepaintArea.updateComponent(RepaintArea.java:239)
at sun.awt.RepaintArea.paint(RepaintArea.java:216)
at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:301)
at java.awt.Component.dispatchEventImpl(Component.java:4489)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4243)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
Exception in thread "AWT-EventQueue-1" java.lang.ArrayIndexOutOfBoundsException: 3
at TicTacToe.paint(TicTacToe.java:35)
at java.awt.Container.update(Container.java:1818)
at sun.awt.RepaintArea.updateComponent(RepaintArea.java:239)
at sun.awt.RepaintArea.paint(RepaintArea.java:216)
at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:301)
at java.awt.Component.dispatchEventImpl(Component.java:4489)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4243)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
Exception in thread "AWT-EventQueue-1" java.lang.ArrayIndexOutOfBoundsException: 3
at TicTacToe.paint(TicTacToe.java:102)
at java.awt.Container.update(Container.java:1818)
at sun.awt.RepaintArea.updateComponent(RepaintArea.java:239)
at sun.awt.RepaintArea.paint(RepaintArea.java:216)
at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:301)
at java.awt.Component.dispatchEventImpl(Component.java:4489)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4243)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
Exception in thread "AWT-EventQueue-1" java.lang.ArrayIndexOutOfBoundsException: 3
at TicTacToe.paint(TicTacToe.java:35)
at java.awt.Container.update(Container.java:1818)
at sun.awt.RepaintArea.updateComponent(RepaintArea.java:239)
at sun.awt.RepaintArea.paint(RepaintArea.java:216)
at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:301)
at java.awt.Component.dispatchEventImpl(Component.java:4489)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4243)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
Exception in thread "AWT-EventQueue-1" java.lang.ArrayIndexOutOfBoundsException: 3
at TicTacToe.paint(TicTacToe.java:102)
at java.awt.Container.update(Container.java:1818)
at sun.awt.RepaintArea.updateComponent(RepaintArea.java:239)
at sun.awt.RepaintArea.paint(RepaintArea.java:216)
at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:301)
at java.awt.Component.dispatchEventImpl(Component.java:4489)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4243)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
Exception in thread "AWT-EventQueue-1" java.lang.ArrayIndexOutOfBoundsException: 3
at TicTacToe.paint(TicTacToe.java:35)
at java.awt.Container.update(Container.java:1818)
at sun.awt.RepaintArea.updateComponent(RepaintArea.java:239)
at sun.awt.RepaintArea.paint(RepaintArea.java:216)
at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:301)
at java.awt.Component.dispatchEventImpl(Component.java:4489)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4243)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
Exception in thread "AWT-EventQueue-1" java.lang.ArrayIndexOutOfBoundsException: 3
at TicTacToe.paint(TicTacToe.java:35)
at java.awt.Container.update(Container.java:1818)
at sun.awt.RepaintArea.updateComponent(RepaintArea.java:239)
at sun.awt.RepaintArea.paint(RepaintArea.java:216)
at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:301)
 at java.awt.Component.dispatchEventImpl(Component.java:4489)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4243)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
Exception in thread "AWT-EventQueue-1" java.lang.ArrayIndexOutOfBoundsException: 3
at TicTacToe.paint(TicTacToe.java:35)
at java.awt.Container.update(Container.java:1818)
at sun.awt.RepaintArea.updateComponent(RepaintArea.java:239)
at sun.awt.RepaintArea.paint(RepaintArea.java:216)
at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:301)
at java.awt.Component.dispatchEventImpl(Component.java:4489)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4243)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

So what's going on here?


----------



## Chicon (Jul 29, 2004)

I've had a look in your coding : the error is due to the way you're managing arrays.
You've declared a 2 dimensions array :
*int [][] Board = new int[3][3];*
and further in you program, you have the following loop statements :
*for (int row = 1; row <= 3; row ++) {* and
*for (int col = 1; col <= 3; col++) {*
with *row* and *col* representing the indexes of *Board*.

In Java, like in C and C++, the index of the first item of an array is always 0.
Therefore, the loop statements must be replaced by :
*for (int row = 0; row < 3; row ++) {* and
*for (int col = 0; col < 3; col++) {*

and all the statements related to *Board* :
*Board[1][1], Board[1][2], Board[1][3], Board[2][1], ...*
must be replaced by :
*Board[O][O], Board[O][1], Board[O][2], Board[1][0], ...*


----------



## Geek4Life (Jan 30, 2008)

What about my earlier question, sure you fixed my errors, but is there a way for me to get the values of x and y recognized in the paint method without using the repaint statement?


----------



## Chicon (Jul 29, 2004)

Sorry, I only focused on the exception causes.

To answer your question, it is possible to prevent redrawing a used cell.
For example, just below the declaration of *Board*, you may declare a parallel array of boolean to keep the status of a cell :
*boolean[][] isUsed = { { false, false, false }, { false, false, false }, { false, false, false } };*

In the *mouseClicked* method, you may replaced the *repaint()* statement by :

```
[SIZE=2]
if (!isUsed[x][y]) {
    isUsed[x][y] = true;
    repaint();
}[/SIZE]
```


----------



## Geek4Life (Jan 30, 2008)

> In the mouseClicked method, you may replaced the repaint() statement by :
> 
> ```
> if (!isUsed[x][y]) {
> ...


By this I assume you actually want me to define two more variables (since the x,y variables are being used for the mouse co-ordinates) for the co-ordinates of the board, like with my other declerations adding "*int bx,by;*" and then in the mouse clicked method replace the *repaint();* statement with:

```
if (!isUsed[bx][by]) {
     isUsed[bx][by] = true;
     repaint();
}
```
I don't understand how thats going to only repaint part of the board, and not all of it.

Another observation: since repaint(); has been repainting everything, its been causing the for loop to run multiple times (which brings up another issue, how can i get it so that the loop only continues to the next turn if a player has added a placement, I tried putting it in a while loop, but then nothing was happening when I was clicking the mouse). Thanks for your patience and help, I think I almost have it working now, its just smoothing out, and streamlining some of the code. JAVA is SUCH a powerful language (especially when you consider it relative to QBASIC).


----------



## Geek4Life (Jan 30, 2008)

More information to throw out there: I have an odd bug that at times does not allow me to place an "X" or "O" in cell 2,3. I don't know what causes it. If you need the updated code here it is excluding the imports and the unchanged areas of code (I guess its too long to fit inside the code breakets, see attached .txt file for complete source (change extension to .java of course)). Take note of the pieces of code that have been commented out...it should give you further insight into how ive been attempting to work with some of these bugs.


----------



## Chicon (Jul 29, 2004)

Sure, Java is a great language but building a GUI in Java is probably the more difficult job as it requires a good knowledge of the way UI components work and the way threads concurency is managed.
Therefore, while building a desktop application or an applet, it is recommanded to build and intialize the UI components in a first time and when every component is working, then concentrate to the logic for each action the user is allowed to take.
To summarize, never mix together the graphic and the logic parts of the coding.

To give you a better representation of how it works, I've written the UI part of a Tic Tac Toe applet : you'll notice that at the end of the _init_ method, my UI is fully functional.
The _labelClicked_ method is the place where the logic of the game will start : checking if the player's move is possible, checking if the player wins, switching to player 2 (or make computer playing itself), and so on...


```
[SIZE=2]
import java.awt.Color;
import java.awt.Component;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JApplet;
import javax.swing.JLabel;

/**
 *
 * @author Joe
 */
public class Tictactoe extends JApplet {
    // status of the cells
    // = 0 : the cell is free
    // = 1 : the cell contains a circle
    // = 2 : the cell contains a cross
    private int[][] status = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
    // each cell will be a label
    private JLabel[][] label;
    // each label will contain an icon
    private Icon[] icon;
    // size of the screen passed through the .html file 
    private int sizeX;
    private int sizeY;

    @Override
    public void init() {
        // getting the parameters passed by the .html caller
        sizeX = getWidth();
        sizeY = getHeight();
        // Customized icons drawing
        // index = 0 - empty cell
        //       = 1 - cell with a circle
        //       = 2 - cell with a cross
        icon = new Icon[3];
        for (int i = 0; i < 3; i++) {
            icon[i] = new MIcon(i);
        }
        // building the GUI
        getContentPane().setLayout(new GridLayout(3, 3));
        label = new JLabel[3][3];
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                label[i][j] = new JLabel();
                label[i][j].setBorder(BorderFactory.createLineBorder(Color.BLUE, 1));
                label[i][j].setIcon(icon[0]);
                label[i][j].addMouseListener(new MAdapter(i, j));
                getContentPane().add(label[i][j]);
            }
        }
    }

    private void labelClicked(int x, int y) {
    // [COLOR=RED]TODO[/COLOR]
    // [COLOR=RED]It is the place where the game logic starts. It has still to be developed ![/COLOR]
    // [COLOR=RED]the [B]status[/B] array will be checked to see if the player move is possible[/COLOR]
    // [COLOR=RED]example : [I]if (status[x][y] == 0) {[/I][/COLOR]
    // [COLOR=RED]                 [I]label[x][y].setIcon(icon[1]);[/I][/COLOR]
    // [COLOR=Red]                 [I]status[x][y] = 1;[/I][/COLOR]
    // [COLOR=Red]                 [I]return;[/I][/COLOR]
    // [COLOR=Red]                 [I]}[/I][/COLOR]    
    // [COLOR=RED]then switch to player 2[/COLOR]
    // Temporarily : display a random icon
       Random seed = new Random();
       int n = seed.nextInt(3);
       label[x][y].setIcon(icon[n]);
    }

    // my customized MouseAdapter
    private class MAdapter extends MouseAdapter {
        private int x;
        private int y;

        public MAdapter(int x, int y) {
            this.x = x;
            this.y = y;
        }

        @Override
        public void mouseClicked(MouseEvent evt) {
            // start the check procedure
            labelClicked(x, y);
        }
    }

    // My customized icon
    private class MIcon implements Icon {
        private int type;
        private int width = sizeX / 3;
        private int height = sizeY / 3;

        public MIcon(int type) {
            this.type = type;
        }

        public void paintIcon(Component c, Graphics g, int x, int y) {
            Graphics2D g2d = (Graphics2D) g;
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            switch (type) {
                case 0:
                    // draw an empty cell
                    g2d.setPaint(new GradientPaint(0, 0, Color.LIGHT_GRAY, width, height, Color.WHITE, true));
                    g2d.fillRect(0, 0, width, height);
                    break;
                case 1:
                    // draw a cell with a circle
                    g2d.setPaint(new GradientPaint(0, 0, Color.DARK_GRAY, width, height, Color.LIGHT_GRAY, true));
                    g2d.fillRect(0, 0, width, height);
                    g2d.setPaint(new GradientPaint(width/8, height/8, Color.ORANGE, width, height, Color.YELLOW, true));
                    g2d.fillOval(width/8, height/8, (width*3)/4, (height*3)/4);
                    g2d.setPaint(new GradientPaint((width/8)+6, (height/8)+6, Color.DARK_GRAY, width, height, Color.LIGHT_GRAY, true));
                    g2d.fillOval((width/8)+6, (height/8)+6, ((width*3)/4)-12, ((height*3)/4)-12);
                    break;
                default:
                    // draw a cell with a cross
                    g2d.setPaint(new GradientPaint(0, 0, Color.DARK_GRAY, width, height, Color.LIGHT_GRAY, true));
                    g2d.fillRect(0, 0, width, height);
                    g2d.setPaint(new GradientPaint(0, 0, Color.PINK, width, height, Color.RED, true));
                    Polygon polygon = new Polygon();
                    polygon.addPoint(width/5, height/10);
                    polygon.addPoint(width/2, (height*2)/5);
                    polygon.addPoint((width*4)/5, height/10);
                    polygon.addPoint((width*9)/10, height/5);
                    polygon.addPoint((width*3)/5, height/2);
                    polygon.addPoint((width*9)/10, (height*4)/5);
                    polygon.addPoint((width*4)/5, (height*9)/10);
                    polygon.addPoint(width/2, (height*3)/5);
                    polygon.addPoint(width/5, (height*9)/10);
                    polygon.addPoint(width/10, (height*4)/5);
                    polygon.addPoint((width*2)/5, height/2);
                    polygon.addPoint(width/10, height/5);
                    g2d.fillPolygon(polygon);
            }
        }

        public int getIconWidth() {
            return width;
        }

        public int getIconHeight() {
            return height;
        }
    }
}
[/SIZE]
```
You may have a try with it. Beware, the compilation will produce 3 .class files : Tictactoe.Class, MAdapter.class and MIcon.class.
Make sure all the files are stored in the same directory.
Here's how the applet is showing :


----------



## Geek4Life (Jan 30, 2008)

looks nice, but id be getting ahead of myself to try to do something like that, which is why im taking this one step at a time...Nice program, but let's just focus on a more simplistic version (like the one im writing, maybe by the end of this class ill be able to do something like that).


----------



## Chicon (Jul 29, 2004)

Geek4Life said:


> More information to throw out there: I have an odd bug that at times does not allow me to place an "X" or "O" in cell 2,3. I don't know what causes it. If you need the updated code here it is excluding the imports and the unchanged areas of code (I guess its too long to fit inside the code breakets, see attached .txt file for complete source (change extension to .java of course)). Take note of the pieces of code that have been commented out...it should give you further insight into how ive been attempting to work with some of these bugs.


I have adapted your coding and it works.

```
[SIZE=2]
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class TicTacToe extends Applet {
    int x,y;
    int turn = 2;
    int round = 0;
    int [][] Board = new int[4][4]; // Hum ! Hum !
    
    public  TicTacToe() {
        addMouseListener(new Listen());
    }
    
    private class Listen implements MouseListener {
        public void mouseClicked(MouseEvent event) {
            y = event.getY();
            x = event.getX();
            repaint();
        }
        public void mousePressed(MouseEvent event) {}
        public void mouseReleased(MouseEvent e) {}
        public void mouseEntered(MouseEvent e) {}
        public void mouseExited(MouseEvent e) {}
    }
    public void paint(Graphics page) {
        if (round > 9) round = 0;
        page.drawLine(50, 100, 200, 100);
        page.drawLine(50,150,200, 150);
        page.drawLine(100, 50, 100, 200);
        page.drawLine(150,50,150,200);
        System.out.println(round);
        if (round == 0) {
            // Reinitialize Board
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 4; j++) {
                    Board[i][j] = 0;
                }
            }
            round++; // prepare for the 1st round
            return;
        }
        
        // The placements start from round 1
        if (round >= 1) {
            for (int row = 1; row <= 3; row ++) {
                // I replaced [I]x[/I] by [I]bx[/I] and [I]y[/I] by [I]by[/I]
                // as the values of both [I]x[/I] and [I]y[/I] are tested further  
                int bx = row * 50;  
                for (int col = 1; col <= 3; col++) {
                    int by = col * 50;
                    if (Board[row][col] == 1) {
                        page.drawLine(bx+5, by+5, bx+45, by+45);
                        page.drawLine(bx+45, by+5, bx+5, by+45);
                    } else if (Board[row][col] == 2) page.drawOval(bx+5, by+5, 40, 40);
                }
            }
            if (x > 50 && x < 100) {
                if (y > 50 && y < 100) {
                    if (Board[1][1] == 0) {
                        if (turn == 1) {
                            page.drawLine(55, 55, 95, 95);
                            page.drawLine(95, 55, 55, 95);
                        } else page.drawOval(55, 55, 40, 40);
                        Board[1][1] = turn;
                        switchTurn();
                    }
                }
                if (y > 100 && y < 150) {
                    if (Board[1][2] == 0) {
                        if (turn == 1) {
                            page.drawLine(55, 105, 95, 145);
                            page.drawLine(95, 105, 55, 145);
                        } else page.drawOval(55, 105, 40, 40);
                        Board[1][2] = turn;
                        switchTurn();
                    }
                }
                if (y > 150 && y < 200) {
                    if (Board[1][3] == 0) {
                        if (turn == 1) {
                            page.drawLine(55, 155, 95, 195);
                            page.drawLine(95, 155, 55, 195);
                        } else page.drawOval(55, 155, 40, 40);
                        Board[1][3] = turn;
                        switchTurn();
                    }
                }
            }
            if (x > 100 && x < 150) {
                if (y > 50 && y < 100) {
                    if (Board[2][1] == 0) {
                        if (turn == 1) {
                            page.drawLine(105, 55, 145, 95);
                            page.drawLine(145, 55, 105, 95);
                        } else page.drawOval(105, 55, 40, 40);
                        Board[2][1] = turn;
                        switchTurn();
                    }
                }
                if (y > 100 && y < 150) {
                    if (Board[2][2] == 0) {
                        if (turn == 1) {
                            page.drawLine(105, 105, 145, 145);
                            page.drawLine(145, 105, 105, 145);
                        } else page.drawOval(105, 105, 40, 40);
                        Board[2][2] = turn;
                        switchTurn();
                    }
                }
                if (y > 150 && y < 200) {
                    if (Board[2][3] == 0) {
                        if (turn == 1) {
                            page.drawLine(105, 155, 145, 195);
                            page.drawLine(145, 155, 105, 195);
                        } else page.drawOval(105, 155, 40, 40);
                        Board[2][3] = turn;
                        switchTurn();
                    }
                }
            }
            if (x > 150 && x < 200) {
                if (y > 50 && y < 100) {
                    if (Board[3][1] == 0) {
                        if (turn == 1) {
                            page.drawLine(155, 55, 195, 95);
                            page.drawLine(195, 55, 155, 95);
                        } else page.drawOval(155, 55, 40, 40);
                        Board[3][1] = turn;
                        switchTurn();
                    }
                }
                if (y > 100 && y < 150) {
                    if (Board[3][2] == 0) {
                        if (turn == 1) {
                            page.drawLine(155, 105, 195, 145);
                            page.drawLine(195, 105, 155, 145);
                        } else page.drawOval(155, 105, 40, 40);
                        Board[3][2] = turn;
                        switchTurn();
                    }
                }
                if (y > 150 && y < 200) {
                    if (Board[3][3] == 0) {
                        if (turn == 1) {
                            page.drawLine(155, 155, 195, 195);
                            page.drawLine(195, 155, 155, 195);
                        } else page.drawOval(155, 155, 40, 40);
                        Board[3][3] = turn;
                        switchTurn();
                    }
                }
            }
            // The test of a possible victory must be made after the last player's move has been recorded
            if (round >= 5) { // there's no possible victory below 5 rounds
                if (Board[1][1] == Board[2][2] && Board[3][3]==Board[2][2] && Board[1][1] != 0) {
                    page.setColor(Color.RED);
                    page.drawLine(50, 50, 200, 200);
                    round = 0;
                    return;
                }
                if (Board[1][3] == Board[2][2] && Board[3][1]==Board[2][2] && Board[1][3] != 0) {
                    page.setColor(Color.RED);
                    page.drawLine(200,50,50,200);
                    round = 0;
                    return;
                }
                if (Board[1][1] == Board[1][2] && Board[1][3]==Board[1][2] && Board[1][1] != 0) {
                    page.setColor(Color.RED);
                    page.drawLine(75, 50, 75, 200);
                    round = 0;
                    return;
                }
                if (Board[1][1] == Board[2][1] && Board[3][1]==Board[2][1] && Board[1][1] != 0) {
                    page.setColor(Color.RED);
                    page.drawLine(50,75,200,75);
                    round = 0;
                    return;
                }
                if (Board[1][2] == Board[2][2] && Board[3][2]==Board[2][2] && Board[1][2] != 0) {
                    page.setColor(Color.RED);
                    page.drawLine(50,125,200,125);
                    round = 0;
                    return;
                }
                if (Board[2][1] == Board[2][2] && Board[2][3]==Board[2][2] && Board[2][1] != 0) {
                    page.setColor(Color.RED);
                    page.drawLine(125,50,125,200);
                    round = 0;
                    return;
                }
                if (Board[1][3] == Board[2][3] && Board[3][3]==Board[2][3] && Board[1][3] != 0) {
                    page.setColor(Color.RED);
                    page.drawLine(50, 175, 200, 175);
                    round = 0;
                    return;
                }
                if (Board[3][1] == Board[3][2] && Board[3][3]==Board[3][2] && Board[3][1] != 0) {
                    page.setColor(Color.RED);
                    page.drawLine(175, 50, 175, 200);
                    round = 0;
                    return;
                }
            }
        }
    }
    
    private void switchTurn() {
        round++;
        if (turn == 1) turn = 2; else turn = 1;
    }
}
[/SIZE]
```


----------



## tomherry2 (Mar 31, 2008)

i will try to solve it


----------

