/**
* Title: Playing Tic Tac Toe no Graphics
* Author: Kay A. Robbins
*/
public class TicTacToe {
protected static final int DEFAULT_BOARD_SIZE = 3;
private static final char BOARD_EMPTY_MARKER = '-';
private char [][] myBoard;
private int myBoardSize;
private boolean myXTurn; // true if it is X's turn to play
private char myWinner; // Holds winner ('X', 'O', 'N')
private int myNumberMoves; // Contains number of moves
// Constructors
public TicTacToe() {
this(DEFAULT_BOARD_SIZE);
}
public TicTacToe(int size) {
myBoardSize = size;
myXTurn = true;
myWinner = 'N';
myNumberMoves = 0;
initializeBoard();
}
// Accessors
public int getBoardSize() {
return myBoardSize;
}
public int getNumberMoves() {
return myNumberMoves;
}
public char getWinner() {
return myWinner;
}
public boolean isXTurn() {
return myXTurn;
}
public char getElement(int row, int col ) {
return myBoard[row][col];
}
public void printBoard() {
System.out.println("After " + myNumberMoves + " moves the board is:");
for (int row = 0; row < myBoardSize; row++) {
for (int col = 0; col < myBoardSize; col++)
System.out.print(myBoard[row][col] + " ");
System.out.println();
}
}
// Modifiers
/**
* If move is valid (in range and not already set)
* make the move, check for winner and return true.
* Otherwise return false.
*/
public boolean play (int row, int column) {
if (myWinner != 'N')
return false;
if (row < 0 || row >= myBoardSize || column < 0 || column >= myBoardSize)
return false;
if (myBoard[row][column] != BOARD_EMPTY_MARKER)
return false;
if (myXTurn)
myBoard[row][column] = 'X';
else
myBoard[row][column] = 'O';
myNumberMoves++;
myXTurn = !myXTurn;
if (checkForWinner('X'))
myWinner = 'X';
else if (checkForWinner('O'))
myWinner = 'O';
return true;
}
// Private helpers --- these will be very important for clean code
private void initializeBoard() {
myBoard = new char [myBoardSize] [myBoardSize];
for (int row = 0; row < myBoardSize; row++)
for (int col = 0; col < myBoardSize; col++)
myBoard[row][col] = BOARD_EMPTY_MARKER;
}
// returns true if all entries in row r match c
private boolean checkRow(int row, char c) {
for (int col = 0; col < myBoardSize; col++)
if (myBoard[row][col] != c)
return false;
return true;
}
private boolean checkColumn(int col, char c) {
for (int row = 0; row < myBoardSize; row++)
if (myBoard[row][col] != c)
return false;
return true;
}
private boolean checkDiagonal(char c) {
for (int row = 0; row < myBoardSize; row++)
if (myBoard[row][row] != c)
return false;
return true;
}
private boolean checkBackDiagonal(char c) {
for (int row = 0; row < myBoardSize; row++)
if (myBoard[row][myBoardSize-1 - row] != c)
return false;
return true;
}
private boolean checkForWinner(char c) {
for (int i = 0; i < myBoardSize; i++) {
if (checkRow(i,c))
return true;
else if (checkColumn(i, c))
return true;
}
return checkDiagonal(c) || checkBackDiagonal(c);
}
}
/*
* TicTacToeGraphics: TicTacToe class extended for graphics
*/
import java.applet.Applet;
import java.awt.*;
public class TicTacToeGraphics extends TicTacToe {
private static final Color X_COLOR = Color.green;
private static final Color O_COLOR = Color.blue;
private static final Color B_COLOR = new Color(255, 255, 200);
private static final Color BLACK = Color.black;
public int boxWidth = 70;
public int boxHeight = 70;
// Constructors
public TicTacToeGraphics() {
this(DEFAULT_BOARD_SIZE);
}
public TicTacToeGraphics(int size) {
super(size);
}
// drawX: draw two lines in the square making an "X"
private void drawX(int i, int j, Graphics g) {
g.setColor(BLACK);
int xCen = i*boxWidth + boxWidth/2;
int yCen = j*boxHeight + boxHeight/2;
int r = boxWidth/3;
g.drawLine(xCen - r, yCen - r, xCen + r, yCen + r);
g.drawLine(xCen - r, yCen + r, xCen + r, yCen - r);
}
// drawO: draw a circle in the square making an "O"
private void drawO(int i, int j, Graphics g) {
g.setColor(BLACK);
int xCen = i*boxWidth + boxWidth/2;
int yCen = j*boxHeight + boxHeight/2;
int r = boxWidth/3;
g.drawOval(xCen - r, yCen - r, 2*r, 2*r);
}
// displayBoard: display graphical version of board in applet
public void displayBoard(Graphics g) { // need graphics class
for (int i = 0; i < getBoardSize(); i++) {
int xpos = i * boxWidth;
for (int j = 0; j < getBoardSize(); j++) {
int ypos = j*boxHeight;
char c = getElement(i, j);
if (c == 'X') {
g.setColor(X_COLOR);
g.fillRect(xpos, ypos, boxWidth, boxHeight);
drawX(i, j, g);
}
else if (c == 'O') {
g.setColor(O_COLOR);
g.fillRect(xpos, ypos, boxWidth, boxHeight);
drawO(i, j, g);
}
else {
g.setColor(B_COLOR);
g.fillRect(xpos, ypos, boxWidth, boxHeight);
}
}
}
// draw vertical and horizontal lines
g.setColor(BLACK);
for (int i = 1; i <= 2; i++) {
g.drawLine(i*boxWidth,0, i*boxWidth, 3*boxWidth);
g.drawLine(0, i*boxHeight, 3*boxWidth, i*boxHeight);
}
}
}
/*
* TicTacToeApplet.java: applet for TicTacToe game
*/
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.net.URL;
public class TicTacToeApplet extends Applet implements MouseListener {
TicTacToeGraphics tttg = new TicTacToeGraphics(3);
private int mRelX, mRelY; // coords of mouse, returned by mouseReleased
private int posX, posY; // row and col numbers of mouse position
public void init() {
setBackground(Color.white);
addMouseListener(this); // so it notices the mouse
}
// for painting and repainting
public void paint(Graphics g) {
tttg.displayBoard(g);
// must do items below in the proper order
if (tttg.getWinner() == 'X')
g.drawString("X wins!", 10, 3*tttg.boxHeight + 30);
else if (tttg.getWinner() == 'O')
g.drawString("O wins!", 10, 3*tttg.boxHeight + 30);
else if (tttg.getNumberMoves() == 9)
g.drawString("Board Full, No Winner", 10, 3*tttg.boxHeight + 30);
else if (tttg.isXTurn())
g.drawString("X's turn to play", 10, 3*tttg.boxHeight + 30);
else if (!tttg.isXTurn())
g.drawString("0's turn to play", 10, 3*tttg.boxHeight + 30);
}
// do actions as mouse button is released
public void mouseReleased(MouseEvent e) {
mRelX = e.getX(); mRelY = e.getY();
int posX = mRelX/tttg.boxWidth;
int posY = mRelY/tttg.boxHeight;
tttg.play(posX, posY);
repaint();
}
// not needed or used except for interface implementation
public void mousePressed(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
}
<html>
<applet code="TicTacToeApplet.class" width=210 height=250>
</applet>
</html>