home *** CD-ROM | disk | FTP | other *** search
/ PC World 1998 October / PCWorld_1998-10_cd.bin / software / prehled / inprise / JSAMPLES.Z / TicTacToe.java < prev    next >
Text File  |  1998-05-08  |  8KB  |  306 lines

  1. /*
  2.  * @(#)TicTacToe.java    1.4 96/12/06
  3.  *
  4.  * Copyright (c) 1994-1996 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
  7.  * modify and redistribute this software in source and binary code form,
  8.  * provided that i) this copyright notice and license appear on all copies of
  9.  * the software; and ii) Licensee does not utilize the software in a manner
  10.  * which is disparaging to Sun.
  11.  *
  12.  * This software is provided "AS IS," without a warranty of any kind. ALL
  13.  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
  14.  * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
  15.  * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
  16.  * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
  17.  * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
  18.  * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
  19.  * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
  20.  * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
  21.  * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
  22.  * POSSIBILITY OF SUCH DAMAGES.
  23.  *
  24.  * This software is not designed or intended for use in on-line control of
  25.  * aircraft, air traffic, aircraft navigation or aircraft communications; or in
  26.  * the design, construction, operation or maintenance of any nuclear
  27.  * facility. Licensee represents and warrants that it will not use or
  28.  * redistribute the Software for such purposes.
  29.  */
  30.  
  31. import java.awt.*;
  32. import java.awt.image.*;
  33. import java.net.*;
  34. import java.applet.*;
  35.  
  36. /**
  37.  * A TicTacToe applet. A very simple, and mostly brain-dead
  38.  * implementation of your favorite game! <p>
  39.  *
  40.  * In this game a position is represented by a white and black
  41.  * bitmask. A bit is set if a position is ocupied. There are
  42.  * 9 squares so there are 1<<9 possible positions for each
  43.  * side. An array of 1<<9 booleans is created, it marks
  44.  * all the winning positions.
  45.  *
  46.  * @version     1.2, 13 Oct 1995
  47.  * @author Arthur van Hoff
  48.  * @modified 96/04/23 Jim Hagen : winning sounds
  49.  */
  50. public
  51. class TicTacToe extends Applet {
  52.     /**
  53.      * White's current position. The computer is white.
  54.      */
  55.     int white;
  56.  
  57.     /**
  58.      * Black's current position. The user is black.
  59.      */
  60.     int black;
  61.  
  62.     /**
  63.      * The squares in order of importance...
  64.      */
  65.     final static int moves[] = {4, 0, 2, 6, 8, 1, 3, 5, 7};
  66.  
  67.     /**
  68.      * The winning positions.
  69.      */
  70.     static boolean won[] = new boolean[1 << 9];
  71.     static final int DONE = (1 << 9) - 1;
  72.     static final int OK = 0;
  73.     static final int WIN = 1;
  74.     static final int LOSE = 2;
  75.     static final int STALEMATE = 3;
  76.  
  77.     /**
  78.      * Mark all positions with these bits set as winning.
  79.      */
  80.     static void isWon(int pos) {
  81.     for (int i = 0 ; i < DONE ; i++) {
  82.         if ((i & pos) == pos) {
  83.         won[i] = true;
  84.         }
  85.     }
  86.     }
  87.  
  88.     /**
  89.      * Initialize all winning positions.
  90.      */
  91.     static {
  92.     isWon((1 << 0) | (1 << 1) | (1 << 2));
  93.     isWon((1 << 3) | (1 << 4) | (1 << 5));
  94.     isWon((1 << 6) | (1 << 7) | (1 << 8));
  95.     isWon((1 << 0) | (1 << 3) | (1 << 6));
  96.     isWon((1 << 1) | (1 << 4) | (1 << 7));
  97.     isWon((1 << 2) | (1 << 5) | (1 << 8));
  98.     isWon((1 << 0) | (1 << 4) | (1 << 8));
  99.     isWon((1 << 2) | (1 << 4) | (1 << 6));
  100.     }
  101.  
  102.     /**
  103.      * Compute the best move for white.
  104.      * @return the square to take
  105.      */
  106.     int bestMove(int white, int black) {
  107.     int bestmove = -1;
  108.     
  109.       loop:
  110.     for (int i = 0 ; i < 9 ; i++) {
  111.         int mw = moves[i];
  112.         if (((white & (1 << mw)) == 0) && ((black & (1 << mw)) == 0)) {
  113.         int pw = white | (1 << mw);
  114.         if (won[pw]) {
  115.             // white wins, take it!
  116.             return mw;
  117.         }
  118.         for (int mb = 0 ; mb < 9 ; mb++) {
  119.             if (((pw & (1 << mb)) == 0) && ((black & (1 << mb)) == 0)) {
  120.             int pb = black | (1 << mb);
  121.             if (won[pb]) {
  122.                 // black wins, take another
  123.                 continue loop;
  124.             }
  125.             }
  126.         }
  127.         // Neither white nor black can win in one move, this will do.
  128.         if (bestmove == -1) {
  129.             bestmove = mw;
  130.         }
  131.         }
  132.     }
  133.     if (bestmove != -1) {
  134.         return bestmove;
  135.     }
  136.  
  137.     // No move is totally satisfactory, try the first one that is open
  138.     for (int i = 0 ; i < 9 ; i++) {
  139.         int mw = moves[i];
  140.         if (((white & (1 << mw)) == 0) && ((black & (1 << mw)) == 0)) {
  141.         return mw;
  142.         }
  143.     }
  144.  
  145.     // No more moves
  146.     return -1;
  147.     }
  148.  
  149.     /**
  150.      * User move.
  151.      * @return true if legal
  152.      */
  153.     boolean yourMove(int m) {
  154.     if ((m < 0) || (m > 8)) {
  155.         return false;
  156.     }
  157.     if (((black | white) & (1 << m)) != 0) {
  158.         return false;
  159.     }
  160.     black |= 1 << m;
  161.     return true;
  162.     }
  163.  
  164.     /**
  165.      * Computer move.
  166.      * @return true if legal
  167.      */
  168.     boolean myMove() {
  169.     if ((black | white) == DONE) {
  170.         return false;
  171.     }
  172.     int best = bestMove(white, black);
  173.     white |= 1 << best;
  174.     return true;
  175.     }
  176.  
  177.     /**
  178.      * Figure what the status of the game is.
  179.      */
  180.     int status() {
  181.     if (won[white]) {
  182.         return WIN;
  183.     }
  184.     if (won[black]) {
  185.         return LOSE;
  186.     }
  187.     if ((black | white) == DONE) {
  188.         return STALEMATE;
  189.     }
  190.     return OK;
  191.     }
  192.  
  193.     /**
  194.      * Who goes first in the next game?
  195.      */
  196.     boolean first = true;
  197.  
  198.     /**
  199.      * The image for white.
  200.      */
  201.     Image notImage;
  202.  
  203.     /**
  204.      * The image for black.
  205.      */
  206.     Image crossImage;
  207.  
  208.     /**
  209.      * Initialize the applet. Resize and load images.
  210.      */
  211.     public void init() {
  212.     notImage = getImage(getCodeBase(), "images/not.gif");
  213.     crossImage = getImage(getCodeBase(), "images/cross.gif");
  214.     }
  215.  
  216.     /**
  217.      * Paint it.
  218.      */
  219.     public void paint(Graphics g) {
  220.     Dimension d = size();
  221.     g.setColor(Color.black);
  222.     int xoff = d.width / 3;
  223.     int yoff = d.height / 3;
  224.     g.drawLine(xoff, 0, xoff, d.height);
  225.     g.drawLine(2*xoff, 0, 2*xoff, d.height);
  226.     g.drawLine(0, yoff, d.width, yoff);
  227.     g.drawLine(0, 2*yoff, d.width, 2*yoff);
  228.  
  229.     int i = 0;
  230.     for (int r = 0 ; r < 3 ; r++) {
  231.         for (int c = 0 ; c < 3 ; c++, i++) {
  232.         if ((white & (1 << i)) != 0) {
  233.             g.drawImage(notImage, c*xoff + 1, r*yoff + 1, this);
  234.         } else if ((black & (1 << i)) != 0) {
  235.             g.drawImage(crossImage, c*xoff + 1, r*yoff + 1, this);
  236.         }
  237.         }
  238.     }
  239.     }
  240.  
  241.     /**
  242.      * The user has clicked in the applet. Figure out where
  243.      * and see if a legal move is possible. If it is a legal
  244.      * move, respond with a legal move (if possible).
  245.      */
  246.     public boolean mouseUp(Event evt, int x, int y) {
  247.     switch (status()) {
  248.       case WIN:
  249.       case LOSE:
  250.       case STALEMATE:
  251.         play(getCodeBase(), "audio/return.au");
  252.         white = black = 0;
  253.         if (first) {
  254.         white |= 1 << (int)(Math.random() * 9);
  255.         }
  256.         first = !first;
  257.         repaint();
  258.         return true;
  259.     }
  260.  
  261.     // Figure out the row/colum
  262.     Dimension d = size();
  263.     int c = (x * 3) / d.width;
  264.     int r = (y * 3) / d.height;
  265.     if (yourMove(c + r * 3)) {
  266.         repaint();
  267.  
  268.         switch (status()) {
  269.           case WIN:
  270.         play(getCodeBase(), "audio/yahoo1.au");
  271.         break;
  272.           case LOSE:
  273.         play(getCodeBase(), "audio/yahoo2.au");
  274.         break;
  275.           case STALEMATE:
  276.         break;
  277.           default:
  278.         if (myMove()) {
  279.             repaint();
  280.             switch (status()) {
  281.               case WIN:
  282.             play(getCodeBase(), "audio/yahoo1.au");
  283.             break;
  284.               case LOSE:
  285.             play(getCodeBase(), "audio/yahoo2.au");
  286.             break;
  287.               case STALEMATE:
  288.             break;
  289.               default:
  290.             play(getCodeBase(), "audio/ding.au");
  291.             }
  292.         } else {
  293.             play(getCodeBase(), "audio/beep.au");
  294.         }
  295.         }
  296.     } else {
  297.         play(getCodeBase(), "audio/beep.au");
  298.     }
  299.     return true;
  300.     }
  301.  
  302.     public String getAppletInfo() {
  303.     return "TicTacToe by Arthur van Hoff";
  304.     }
  305. }
  306.