home *** CD-ROM | disk | FTP | other *** search
Java Source | 1996-07-23 | 7.6 KB | 306 lines |
- /*
- * %W% %E%
- *
- * Copyright (c) 1994-1995 Sun Microsystems, Inc. All Rights Reserved.
- *
- * Permission to use, copy, modify, and distribute this software
- * and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
- * without fee is hereby granted.
- * Please refer to the file http://java.sun.com/copy_trademarks.html
- * for further important copyright and trademark information and to
- * http://java.sun.com/licensing.html for further important licensing
- * information for the Java (tm) Technology.
- *
- * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
- * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
- * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
- * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
- * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
- *
- * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
- * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
- * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
- * NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
- * SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
- * SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
- * PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). SUN
- * SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
- * HIGH RISK ACTIVITIES.
- */
-
- import java.awt.*;
- import java.awt.image.*;
- import java.net.*;
- import java.applet.*;
-
- /**
- * 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.
- *
- * @version %I%, %G%
- * @author Arthur van Hoff
- */
- public
- class tictactoe extends Applet {
- /**
- * White's current position. The computer is white.
- */
- int white;
-
- /**
- * Black's current position. The user is black.
- */
- int black;
-
- /**
- * The squares in order of importance...
- */
- final static int moves[] = {4, 0, 2, 6, 8, 1, 3, 5, 7};
-
- /**
- * The winning positions.
- */
- static boolean won[] = new boolean[1 << 9];
- static final int DONE = (1 << 9) - 1;
- static final int OK = 0;
- static final int WIN = 1;
- static final int LOSE = 2;
- static final int STALEMATE = 3;
-
- /**
- * Mark all positions with these bits set as winning.
- */
- static void isWon(int pos) {
- for (int i = 0 ; i < DONE ; i++) {
- if ((i & pos) == pos) {
- won[i] = true;
- }
- }
- }
-
- /**
- * 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));
- }
-
- /**
- * Compute the best move for white.
- * @return the 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.
- * @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.
- */
- int status() {
- if (won[white]) {
- return WIN;
- }
- if (won[black]) {
- return LOSE;
- }
- if ((black | white) == DONE) {
- return STALEMATE;
- }
- return OK;
- }
-
- /**
- * 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 init() {
- notImage = getImage(getCodeBase(), "images/not.gif");
- crossImage = getImage(getCodeBase(), "images/cross.gif");
- }
-
- /**
- * Paint it.
- */
- public void paint(Graphics g) {
- Dimension d = size();
- g.setColor(Color.black);
- int xoff = d.width / 3;
- int yoff = d.height / 3;
- 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.drawImage(notImage, c*xoff + 1, r*yoff + 1, this);
- } else if ((black & (1 << i)) != 0) {
- g.drawImage(crossImage, c*xoff + 1, r*yoff + 1, this);
- }
- }
- }
- }
-
- /**
- * 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).
- */
- public boolean mouseUp(Event evt, int x, int y) {
- switch (status()) {
- case WIN:
- case LOSE:
- case STALEMATE:
- play(getCodeBase(), "audio/return.au");
- white = black = 0;
- if (first) {
- white |= 1 << (int)(Math.random() * 9);
- }
- first = !first;
- repaint();
- return true;
- }
-
- // Figure out the row/colum
- Dimension d = size();
- int c = (x * 3) / d.width;
- int r = (y * 3) / d.height;
- if (yourMove(c + r * 3)) {
- repaint();
-
- switch (status()) {
- case WIN:
- play(getCodeBase(), "audio/joy.au");
- break;
- case LOSE:
- play(getCodeBase(), "audio/joy.au");
- break;
- case STALEMATE:
- break;
- default:
- if (myMove()) {
- repaint();
- switch (status()) {
- case WIN:
- play(getCodeBase(), "audio/joy.au");
- break;
- case LOSE:
- play(getCodeBase(), "audio/joy.au");
- break;
- case STALEMATE:
- break;
- default:
- play(getCodeBase(), "audio/ding.au");
- }
- } else {
- play(getCodeBase(), "audio/beep.au");
- }
- }
- } else {
- play(getCodeBase(), "audio/beep.au");
- }
- return true;
- }
-
- public String getAppletInfo() {
- return "TicTacToe by Arthur van Hoff";
- }
- }
-