📄 game.java
字号:
/*
* 创建日期 2005-6-28
*
* TODO 要更改此生成的文件的模板,请转至
* 窗口 - 首选项 - Java - 代码样式 - 代码模板
*/
package game;
import java.util.Random;
/**
* @author Administrator
*
* TODO 要更改此生成的类型注释的模板,请转至
* 窗口 - 首选项 - Java - 代码样式 - 代码模板
*/
public class Game{
private static final int[] WINS = {
// 水平方向
bit(0) | bit(1) | bit(2), // 位置0,1,2时胜 |0|1|2| 9个位置(0,1,2,3,4,5,6,7,8)
bit(3) | bit(4) | bit(5), // 位置3,4,5时胜 |3|4|5|
bit(6) | bit(7) | bit(8), // 位置6,7,8时胜 |6|7|8|
// 垂直方向
bit(0) | bit(3) | bit(6), // 位置0,3,6时胜
bit(1) | bit(4) | bit(7), // 位置1,4,7时胜
bit(2) | bit(5) | bit(8), // 位置2,5,8时胜
// 对角线方向
bit(0) | bit(4) | bit(8), // 位置0,4,8时胜
bit(2) | bit(4) | bit(6) }; // 位置2,4,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));
}
boolean isPlayer(int position){
// 当前位置是否被选手占用
int bit = bit(position);
return (playerState & bit) == 1;
}
boolean isComputer(int position){
// 当前位置是否被计算机占用
int bit = bit(position);
return (computerState & bit) == 1;
}
void makePlayerMove(int position) {
// 当前选手占用的所有位置
playerState |= bit(position);
}
int makeComputerMove() {
// 如果下一步计算机能获胜则在获胜位置下子
int move = getWinningComputerMove();
if (move == -1) {
// 如果计算机下一步不能获胜而选手下一步将要获胜,则在选手将获胜的位置下子
move = getRequiredBlockingComputerMove();
if (move == -1)
{
// 无关紧要时随机下子
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;
}
private int getWinningComputerMove() {
// 通过对所有可能下子位置的枚举,智能判断计算机下一步走到哪里才能获胜
int move = -1;
for (int i = 0; i < 9;++i) {
if (isFree(i) && isWin(computerState | bit(i))) {
// 找到获胜位置时中断
move = i;
break;
}
}
// 返回下一步获胜的下子位置,如为-1则表示下一步无法获胜
return move;
}
private int getRequiredBlockingComputerMove() {
// 通过对所有可能下子位置的枚举,智能判断选手下一步走到哪里才能获胜
int move = -1;
for (int i = 0; i < 9;++i) {
if (isFree(i) && isWin(playerState | bit(i))) {
// 找到选手获胜时的位置
move = i;
break;
}
}
// 返回选手获胜时的位置,为-1时表示选手下一步不能获胜
return move;
}
private int getRandomComputerMove() {
// 计算当前空余位置
int move = -1;
int numFreeSquares = 0;
for (int i = 0; i < 9;++i) {
if (isFree(i))
numFreeSquares++;
}
// 判断是否可以继续行子
if (numFreeSquares > 0) {
// 检取随机行子位置
int pick = ((random.nextInt()<<1)>>>1) % numFreeSquares;
for (int i = 0; i < 9;++i) {
if (isFree(i)) {
if (pick == 0) {
move = i;
break;
}
pick--;
}
}
}
// 返回随机下子的位置,如为-1表示当前已无可行子的位置
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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -