S O U R C E C O D E
/ 1999 / 07
/ java
/ 2.lst
/// This is the tic-tac-toe applet
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
// Just a simple button with an integer tag
// could have used the ActionCommand, but that's a string
class TagBtn extends Button {
public int tag;
TagBtn(String label, int tag) {
super(label);
this.tag=tag;
}
}
// The applet
public class TicTacToe extends Applet implements ActionListener {
// arrays for buttons
public TagBtn [][] btns = new TagBtn[3][3];
// status message
public Label lbl;
// X or O
public String player;
// no moves allowed unless this is true
public volatile boolean mymove=false;
// my move
volatile int move;
int xosize=20; // size of X and O
String server; // remote game host
public void init() {
int x;
int y;
String tmp;
// Set X or O size
tmp=getParameter("XOSize");
try {
xosize=Integer.parseInt(tmp);
if (xosize==0) xosize=20;
} catch (Exception e) { xosize=20; }
// Get host name
server=getParameter("Server");
// set up GUI
// The GUI has a border layout that contains a grid layout
// The status window is south and the grid is north
BorderLayout main = new BorderLayout();
setLayout(main);
Panel tictac = new Panel();
tictac.setBackground(new Color(0,0,0));
lbl = new Label("Tic Tac Toe by Al Williams");
add(tictac,BorderLayout.CENTER);
// gap of 5 makes the grid show up nicely
GridLayout ly = new GridLayout(3,3,5,5);
tictac.setLayout(ly);
// Init buttons
for (x=0;x<3;x++) {
for (y=0;y<3;y++) {
btns[x][y]=new TagBtn(" ",y*3+x+'0');
btns[x][y].addActionListener(this);
btns[x][y].setFont(new Font("Helvtica",Font.BOLD,xosize));
tictac.add(btns[x][y]);
}
}
add(lbl,BorderLayout.SOUTH);
// start a thread to do all the network stuff
new PlayThread(this).start();
}
// button press?
public synchronized void actionPerformed(ActionEvent e) {
TagBtn b = (TagBtn)e.getSource();
// no move if not your turn or button has X or O in it already
if (!mymove || !b.getLabel().equals(" ")) return;
move=b.tag; // tell the thread
notify();
b.setLabel(player);
}
// This routine gets the next move... it won't return
// until the actionPerformed function calls notify
public synchronized int getMove() throws InterruptedException {
wait();
return move;
}
}
// This is the network thread
class PlayThread extends Thread {
private TicTacToe host;
PlayThread(TicTacToe host) { this.host = host; }
public void run() {
int c;
// connect to host
Socket sock;
InputStream in;
OutputStream out;
try {
sock=new Socket(host.server,9001); // port # could be a param
in = sock.getInputStream();
out=sock.getOutputStream();
// this loop waits for our partner to connect
while (true) {
c=in.read();
if (c=='Q') {
host.lbl.setText(
"Other player quit. Press Refresh for a new game.");
return;
}
if (c=='X' || c=='O') {
host.player=c=='X'?"X":"O";
// small flaw... player X hardly gets a
// chance to see this message
host.lbl.setText("You are " + host.player);
break;
}
if (c=='W') host.lbl.setText("Waiting....");
}
// both players ready to go!
while (true) {
c=in.read();
if (c==-1) continue; // no input
if (c=='G') {
host.lbl.setText("Game over! Press Refresh.");
return;
}
if (c=='W') {
host.lbl.setText("You win! Press Refresh.");
return;
}
if (c=='L') {
host.lbl.setText("You lose! Press Refresh.");
return;
}
if (c=='Q') {
host.lbl.setText("Other player quit. Press Refresh.");
return;
}
// My turn?
if (c=='M') {
host.mymove=true; // enable UI
host.lbl.setText("Your turn");
int m=host.getMove(); // wait for user to respond
host.lbl.setText(""); // disable UI
host.mymove=false;
// send it
out.write(m);
continue;
}
// hmmm must be a move for opposite player
c=c-'0';
host.btns[c%3][c/3].setLabel(
host.player.equals("X")?"O":"X");
} // end while(true);
} catch (Exception e) { e.printStackTrace(); }
}
}
|
home
|
current issue
|
archives
|
source code
|
demo express
|
events
|
search
|
editorial calendar
|
advertising
|
customer service
|
author guidelines
|
jobs
|
about
Entire contents copyright 1996-2000 CMP Media Inc.
Read our privacy policy.