game.java

来自「J2ME MIDP_Example_Applications」· Java 代码 · 共 280 行

JAVA
280
字号
// Copyright 2002 Nokia Corporation. 
// 
// THIS SOURCE CODE IS PROVIDED 'AS IS', WITH NO WARRANTIES WHATSOEVER, 
// EXPRESS OR IMPLIED, INCLUDING ANY WARRANTY OF MERCHANTABILITY, FITNESS 
// FOR ANY PARTICULAR PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE 
// OR TRADE PRACTICE, RELATING TO THE SOURCE CODE OR ANY WARRANTY OTHERWISE 
// ARISING OUT OF ANY PROPOSAL, SPECIFICATION, OR SAMPLE AND WITH NO 
// OBLIGATION OF NOKIA TO PROVIDE THE LICENSEE WITH ANY MAINTENANCE OR 
// SUPPORT. FURTHERMORE, NOKIA MAKES NO WARRANTY THAT EXERCISE OF THE 
// RIGHTS GRANTED HEREUNDER DOES NOT INFRINGE OR MAY NOT CAUSE INFRINGEMENT 
// OF ANY PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OWNED OR CONTROLLED 
// BY THIRD PARTIES 
// 
// Furthermore, information provided in this source code is preliminary, 
// and may be changed substantially prior to final release. Nokia Corporation 
// retains the right to make changes to this source code at 
// any time, without notice. This source code is provided for informational 
// purposes only. 
// 
// Nokia and Nokia Connecting People are registered trademarks of Nokia
// Corporation.
// Java and all Java-based marks are trademarks or registered trademarks of
// Sun Microsystems, Inc.
// Other product and company names mentioned herein may be trademarks or
// trade names of their respective owners.
// 
// A non-exclusive, non-transferable, worldwide, limited license is hereby 
// granted to the Licensee to download, print, reproduce and modify the 
// source code. The licensee has the right to market, sell, distribute and 
// make available the source code in original or modified form only when 
// incorporated into the programs developed by the Licensee. No other 
// license, express or implied, by estoppel or otherwise, to any other 
// intellectual property rights is granted herein.


//
// NOTE:
// -----
// The WINS array in the game logic was partially derived from a similar
// table in an openly available applet version of TicTacToe from Sun
// Microsystems:
//     http://java.sun.com/applets/jdk/1.0/demo/TicTacToe/TicTacToe.java
// That applet source code contained the following disclaimer, which
// is included here for completeness:
//
// * @(#)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.
//


package example.tictactoe;

import java.util.Random;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;


// The game logic for TicTacToe
class Game
{
    private static final int[] WINS =
    {
        // horizontals
        bit(0) | bit(1) | bit(2),
        bit(3) | bit(4) | bit(5),
        bit(6) | bit(7) | bit(8),
        // verticals
        bit(0) | bit(3) | bit(6),
        bit(1) | bit(4) | bit(7),
        bit(2) | bit(5) | bit(8),
        // diagonals
        bit(0) | bit(4) | bit(8),
        bit(2) | bit(4) | bit(6)
    };
    private static final int DRAWN_GAME =
        bit(0) | bit(1) | bit(2) |
        bit(3) | bit(4) | bit(5) |
        bit(6) | bit(7) | bit(8);

    private int playerState;
    private int computerState;
    private Random random;


    Game(Random random)
    {
        this.random = random;
        initialize();
    }


    void initialize()
    {
        playerState = 0;
        computerState = 0;
    }


    boolean isFree(int position)
    {
        int bit = bit(position);
        return (((playerState & bit) == 0) && ((computerState & bit) == 0));
    }


    // The 'Contract' is that caller will always make valid moves.
    // We don't check that it's the player's turn.
    void makePlayerMove(int position)
    {
        playerState |= bit(position);
    }


    // The 'Contract' is that we will be called only when there is still
    // at least one free square.
    int makeComputerMove()
    {
        int move = getWinningComputerMove();
        if (move == -1)
        {
            // can't win
            move = getRequiredBlockingComputerMove();
            if (move == -1)
            {
                // don't need to block
                move = getRandomComputerMove();
            }
        }

        computerState |= bit(move);

        return move;
    }


    boolean isGameOver()
    {
        return isPlayerWinner() | isComputerWinner() | isGameDrawn();
    }


    boolean isPlayerWinner()
    {
        return isWin(playerState);
    }


    boolean isComputerWinner()
    {
        return isWin(computerState);
    }


    boolean isGameDrawn()
    {
        return (playerState | computerState) == DRAWN_GAME;
    }


    // Return a winning move if there is at least one, otherwise return -1
    private int getWinningComputerMove()
    {
        int move = -1;
        for (int i = 0; i < 9; ++i)
        {
            if (isFree(i) && isWin(computerState | bit(i)))
            {
                move = i;
                break;
            }
        }
        return move;
    }


    // Return a required blocking move if there is at least one (more
    // than one and we've inevitably lost), otherwise return -1
    private int getRequiredBlockingComputerMove()
    {
        int move = -1;
        for (int i = 0; i < 9; ++i)
        {
            if (isFree(i) && isWin(playerState | bit(i)))
            {
                move = i;
                break;
            }
        }
        return move;
    }


    // Return a random move in a free square,
    // or return -1 if none are available
    private int getRandomComputerMove()
    {
        int move = -1;
        
        // determine how many possible moves there are
        int numFreeSquares = 0;
        for (int i = 0; i < 9; ++i)
        {
            if (isFree(i))
            {
                numFreeSquares++;
            }
        }

        // if there is at least one possible move, pick randomly
        if (numFreeSquares > 0)
        {
            // shift twice to get rid of sign bit, then modulo numFreeSquares
            int pick = ((random.nextInt()<<1)>>>1) % numFreeSquares;

            // now find the chosen free square by counting pick down to zero
            for (int i = 0; i < 9; ++i)
            {
                if (isFree(i))
                {
                    if (pick == 0)
                    {
                        move = i;
                        break;
                    }
                    pick--;
                }
            }
        }
        
        return move;
    }


    private static boolean isWin(int state)
    {
        boolean isWinner = false;
        for (int i = 0; i < WINS.length; ++i)
        {
            if ((state & WINS[i]) == WINS[i])
            {
                isWinner = true;
                break;
            }
        }
        return isWinner;
    }


    private static int bit(int i)
    {
        return 1 << i;
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?