import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
public class BoardGame extends MouseAdapter implements ActionListener {
BoardPanel board;
int turn = 0;
public void mousePressed(MouseEvent e) {
Point p = e.getPoint();
if(board.contains(p)) {
Point cell = board.getCell(p);
if(board.isCellEmpty(cell)) {
board.setToken(cell, turn++ % 2);
// check for winner
}
}
}
public void actionPerformed(ActionEvent e) {
String ac = e.getActionCommand();
if(ac.equals("RESET")) {
board.clearBoard();
turn = 0;
}
}
private JPanel getBoard() {
board = new BoardPanel();
board.addMouseListener(this);
return board;
}
private JPanel getControls() {
JButton reset = new JButton("reset");
reset.setActionCommand("RESET");
reset.addActionListener(this);
JPanel panel = new JPanel();
panel.add(reset);
return panel;
}
public static void main(String[] args) {
BoardGame game = new BoardGame();
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(game.getBoard());
f.getContentPane().add(game.getControls(), "Last");
f.setSize(400,400);
f.setLocation(200,200);
f.setVisible(true);
}
}
class BoardPanel extends JPanel {
final int NAUGHT = 0;
final int CROSS = 1;
final int COLS = 3;
final int ROWS = 3;
final int PAD = 20;
int[][] tokens = new int[ROWS][COLS];
double xInc; // cell width
double yInc; // cell height
BoardPanel() {
clearBoard();
}
public void clearBoard() {
for(int j = 0; j < ROWS; j++)
for(int k = 0; k < COLS; k++)
tokens[j][k] = -1;
repaint();
}
public boolean contains(Point p) {
Rectangle r = getBounds();
r.grow(-PAD, -PAD);
return r.contains(p);
}
public Point getCell(Point p) {
Point cell = new Point();
for(int j = 0; j < ROWS; j++) {
double y = PAD + j*yInc;
if(p.y < y + yInc) {
cell.y = j;
break;
}
}
for(int j = 0; j < COLS; j++) {
double x = PAD + j*xInc;
if(p.x < x + xInc ) {
cell.x = j;
break;
}
}
return cell;
}
public boolean isCellEmpty(Point p) {
return tokens[p.x][p.y] == -1;
}
public void setToken(Point p, int token) {
tokens[p.x][p.y] = token;
repaint();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(new BasicStroke(4f));
g2.setPaint(Color.blue);
int w = getWidth();
int h = getHeight();
xInc = (double)(w - 2*PAD)/COLS;
yInc = (double)(h - 2*PAD)/ROWS;
// Horizontal grid lines.
for(int j = 0; j <= ROWS; j++) {
double y = PAD + j*yInc;
g2.draw(new Line2D.Double(PAD, y, w-PAD, y));
}
// Vertical grid lines.
for(int j = 0; j <= COLS; j++) {
double x = PAD + j*xInc;
g2.draw(new Line2D.Double(x, PAD, x, h-PAD));
}
// Draw tokens.
g2.setPaint(Color.red);
double tokenWidth = xInc*4/5;
double tokenHeight = yInc*4/5;
for(int j = 0; j < ROWS; j++) {
for(int k = 0; k < COLS; k++) {
int token = tokens[j][k];
double d = Math.min(tokenWidth, tokenHeight);
double x = PAD + j*xInc + (xInc - d)/2;
double y = PAD + k*yInc + (yInc - d)/2;
switch(token) {
case NAUGHT:
g2.draw(new Ellipse2D.Double(x, y, d, d));
break;
case CROSS:
g2.draw(new Line2D.Double(x, y, x+d, y+d));
g2.draw(new Line2D.Double(x+d, y, x, y+d));
}
}
}
}
}