Mega Code Archive

 
Categories / Java Tutorial / Development
 

Tic Tac Toe game

File: test.htm <title>TicTacToe</title> <hr> <applet code=TicTacToe.class width=120 height=120> </applet> File: TicTacToe.java /*  * @(#)TicTacToe.java 1.2 95/10/13   *  * Copyright (c) 1994-1996 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!   *  * 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   1.2, 13 Oct 1995  * @author Arthur van Hoff  * @modified 96/04/23 Jim Hagen : winning sounds  */ 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(getClass().getResource("images/not.gif"));   crossImage = getImage(getClass().getResource("images/cross.gif"));     }     /**      * Paint it.      */     public void paint(Graphics g) {   Dimension d = getSize();   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(getClass().getResource("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 = getSize();   int c = (x * 3) / d.width;   int r = (y * 3) / d.height;   if (yourMove(c + r * 3)) {       repaint();       switch (status()) {         case WIN:     play(getClass().getResource("audio/yahoo1.au"));     break;         case LOSE:     play(getClass().getResource("audio/yahoo2.au"));     break;         case STALEMATE:     break;         default:     if (myMove()) {         repaint();         switch (status()) {           case WIN:       play(getClass().getResource("audio/yahoo1.au"));       break;           case LOSE:       play(getClass().getResource("audio/yahoo2.au"));       break;           case STALEMATE:       break;           default:       play(getClass().getResource("audio/ding.au"));         }     } else {         play(getClass().getResource("audio/beep.au"));     }       }   } else {       play(getClass().getResource("audio/beep.au"));   }   return true;     }     public String getAppletInfo() {   return "TicTacToe by Arthur van Hoff";     } }