home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / JBuilder8.iso / Solaris / resource / jre / demo / applets / TicTacToe / TicTacToe.java < prev   
Encoding:
Java Source  |  2002-09-06  |  8.1 KB  |  337 lines

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