TicTacToe.java
/*
* @(#)TicTacToe.java 1.5 97/02/05
*
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
*
* Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
* modify and redistribute this software in source and binary code form,
* provided that i) this copyright notice and license appear on all copies of
* the software; and ii) Licensee does not utilize the software in a manner
* which is disparaging to Sun.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
* LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import com.sap.ip.me.api.runtime.awt.AWTConfigurationUI;
import com.sap.ip.me.api.runtime.awt.AwtApplication;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.net.*;
/**
* A TicTacToe applet. A very simple, and mostly brain-dead implementation of
* your favorite game! <p>
*
* In this game a position is represented by a white and black bitmask. A bit
* is set if a position is ocupied. There are 9 squares so there are 1<<9
* possible positions for each side. An array of 1<<9 booleans is created, it
* marks all the winning positions.
*
*@author Arthur van Hoff
*@created 14. Oktober 2002
*@version 1.2, 13 Oct 1995
*@modified 04/23/96 Jim Hagen : winning sounds
*@modified 02/10/98 Mike McCloskey : added destroy()
*/
public class TicTacToe extends Applet implements MouseListener, AwtApplication {
/**
* Description of the Field
*/
public final static String homeMenuEntry = "home";
/**
* The squares in order of importance...
*/
final static int moves[] = {4, 0, 2, 6, 8, 1, 3, 5, 7};
final static int DONE = (1 << 9) - 1;
final static int OK = 0;
final static int WIN = 1;
final static int LOSE = 2;
final static int STALEMATE = 3;
/**
* The winning positions.
*/
static boolean won[] = new boolean[1 << 9];
/**
* White's current position. The computer is white.
*/
int white;
/**
* Black's current position. The user is black.
*/
int black;
/**
* Who goes first in the next game?
*/
boolean first = true;
/**
* The image for white.
*/
Image notImage;
/**
* The image for black.
*/
Image crossImage;
/**
* Initialize the applet. Resize and load images.
*/
public void initApplication() {
addMouseListener(this);
/*
* Menu navMenu = new Menu("Nav");
* / menuBar.add(actionMenu);
* MenuItem menuItem;
* menuItem = new MenuItem("home");
* navMenu.add(menuItem);
* AWTConfigurationUI.setMenu(navMenu);
*/
}
/**
* Description of the Method
*/
public void destroy() {
removeMouseListener(this);
}
/**
* Paint it.
*
*@param g Description of the Parameter
*/
public void paint(Graphics g) {
Dimension d = getSize();
g.setColor(Color.black);
int xoff = d.width / 3;
int yoff = d.height / 3;
int xab = d.width / 12;
int yab = d.height / 12;
g.drawLine(xoff, 0, xoff, d.height);
g.drawLine(2 * xoff, 0, 2 * xoff, d.height);
g.drawLine(0, yoff, d.width, yoff);
g.drawLine(0, 2 * yoff, d.width, 2 * yoff);
int i = 0;
for (int r = 0; r < 3; r++) {
for (int c = 0; c < 3; c++, i++) {
if ((white & (1 << i)) != 0) {
g.drawOval(c * xoff + xab, r * yoff + yab, xoff - 2 * xab, yoff - 2 * yab);
}
else if ((black & (1 << i)) != 0) {
g.drawLine(c * xoff + xab, r * yoff + yab, (c + 1) * xoff - xab, (r + 1) * yoff - yab);
g.drawLine((c + 1) * xoff - xab, r * yoff + yab, c * xoff + xab, (r + 1) * yoff - yab);
}
}
}
}
/**
* The user has clicked in the applet. Figure out where and see if a legal
* move is possible. If it is a legal move, respond with a legal move (if
* possible).
*
*@param e Description of the Parameter
*/
public void mouseReleased(MouseEvent e) {
int x = e.getX();
int y = e.getY();
switch (status()) {
case WIN:
case LOSE:
case STALEMATE:
white = black = 0;
if (first) {
white |= 1 << (int) (Math.random() * 9);
}
first = !first;
repaint();
return;
}
// Figure out the row/column
Dimension d = getSize();
int c = (x * 3) / d.width;
int r = (y * 3) / d.height;
if (yourMove(c + r * 3)) {
repaint();
switch (status()) {
case WIN:
break;
case LOSE:
break;
case STALEMATE:
break;
default:
if (myMove()) {
repaint();
switch (status()) {
case WIN:
break;
case LOSE:
break;
case STALEMATE:
break;
default:
}
}
else {
}
}
}
else {
}
}
/**
* Description of the Method
*
*@param e Description of the Parameter
*/
public void mousePressed(MouseEvent e) {
}
/**
* Description of the Method
*
*@param e Description of the Parameter
*/
public void mouseClicked(MouseEvent e) {
}
/**
* Description of the Method
*
*@param e Description of the Parameter
*/
public void mouseEntered(MouseEvent e) {
}
/**
* Description of the Method
*
*@param e Description of the Parameter
*/
public void mouseExited(MouseEvent e) {
}
/**
* Gets the appletInfo attribute of the TicTacToe object
*
*@return The appletInfo value
*/
public String getAppletInfo() {
return "TicTacToe by Arthur van Hoff";
}
/**
* Gets the rootPanel attribute of the TicTacToe object
*
*@return The rootPanel value
*/
public Panel getRootPanel() {
return this;
}
/**
* Description of the Method
*/
public void activateApplication() {
}
/**
* Description of the Method
*/
public void deactivateApplication() {
}
/**
* Description of the Method
*/
public void destroyApplication() {
}
/**
* Description of the Method
*
*@param menuItem Description of the Parameter
*/
public void actionMenuItem(MenuItem menuItem) {
if (homeMenuEntry.equals(menuItem.getLabel())) {
AWTConfigurationUI.goHome();
}
}
/**
* Gets the applicationName attribute of the TicTacToe object
*
*@return The applicationName value
*/
public String getApplicationName() {
// return "TICTACTOE";
return "DEMOAWTTTT";
}
/**
* Mark all positions with these bits set as winning.
*
*@param pos Description of the Parameter
*/
static void isWon(int pos) {
for (int i = 0; i < DONE; i++) {
if ((i & pos) == pos) {
won[i] = true;
}
}
}
/**
* Compute the best move for white.
*
*@param white Description of the Parameter
*@param black Description of the Parameter
*@return t3he square to take
*/
int bestMove(int white, int black) {
int bestmove = -1;
loop :
for (int i = 0; i < 9; i++) {
int mw = moves[i];
if (((white & (1 << mw)) == 0) && ((black & (1 << mw)) == 0)) {
int pw = white | (1 << mw);
if (won[pw]) {
// white wins, take it!
return mw;
}
for (int mb = 0; mb < 9; mb++) {
if (((pw & (1 << mb)) == 0) && ((black & (1 << mb)) == 0)) {
int pb = black | (1 << mb);
if (won[pb]) {
// black wins, take another
continue loop;
}
}
}
// Neither white nor black can win in one move, this will do.
if (bestmove == -1) {
bestmove = mw;
}
}
}
if (bestmove != -1) {
return bestmove;
}
// No move is totally satisfactory, try the first one that is open
for (int i = 0; i < 9; i++) {
int mw = moves[i];
if (((white & (1 << mw)) == 0) && ((black & (1 << mw)) == 0)) {
return mw;
}
}
// No more moves
return -1;
}
/**
* User move.
*
*@param m Description of the Parameter
*@return true if legal
*/
boolean yourMove(int m) {
if ((m < 0) || (m > 8)) {
return false;
}
if (((black | white) & (1 << m)) != 0) {
return false;
}
black |= 1 << m;
return true;
}
/**
* Computer move.
*
*@return true if legal
*/
boolean myMove() {
if ((black | white) == DONE) {
return false;
}
int best = bestMove(white, black);
white |= 1 << best;
return true;
}
/**
* Figure what the status of the game is.
*
*@return Description of the Return Value
*/
int status() {
if (won[white]) {
return WIN;
}
if (won[black]) {
return LOSE;
}
if ((black | white) == DONE) {
return STALEMATE;
}
return OK;
}
/**
* Initialize all winning positions.
*/
static {
isWon((1 << 0) | (1 << 1) | (1 << 2));
isWon((1 << 3) | (1 << 4) | (1 << 5));
isWon((1 << 6) | (1 << 7) | (1 << 8));
isWon((1 << 0) | (1 << 3) | (1 << 6));
isWon((1 << 1) | (1 << 4) | (1 << 7));
isWon((1 << 2) | (1 << 5) | (1 << 8));
isWon((1 << 0) | (1 << 4) | (1 << 8));
isWon((1 << 2) | (1 << 4) | (1 << 6));
}
}