import java.io.PrintStream;
import java.util.*;
import javax.microedition.lcdui.Canvas;
public class FIRLogic
{
private FIRCanvas myCanvas;//游戏画布
private int boardSize;//棋盘大小
private boolean isComputerFirst;//是否计算机先行
private int degree;//难度等级
public static int PLAYER_NONE = 0;//该位置设置为空
public static int PLAYER_COMPUTER = 1;//该位置为计算机落子
public static int PLAYER_MAN = 2;//该位置为玩家落子
private int table[][];//棋盘盘面
private Dot lastDot;//棋子对象,存储最后一步落子状态
private int playerCounter[];
private Stack steps;//堆栈,内容为棋子对象
private Dot triedDot;
private static int GAIN_BY_COMPUTER = 5;
private static int GAIN_BY_NONE = 1;
private boolean isGameOver;
private boolean isComputerWon;
private boolean isThinking;
private Random rndNum;
public FIRLogic(FIRCanvas canvas, int boardSize, boolean isComputerFirst, int degree)
{
this.boardSize = 15;//默认大小
isComputerFirst = true;//默认计算机先手
degree = 1;//默认等级
myCanvas = canvas;//外部传递游戏画布界面
this.boardSize = boardSize;//外部传递游戏棋盘大小
this.isComputerFirst = isComputerFirst;//外部传递计算机先手
this.degree = degree;//外部传递难度等级
table = new int[boardSize][boardSize];//创建棋盘数组
for(int r = 0; r < boardSize; r++)
{
for(int c = 0; c < boardSize; c++)//初始化盘面为空
table[r][c] = 0;
}
playerCounter = new int[3];//落子状态计数器
playerCounter[0] = boardSize * boardSize;//整个盘面都是空的状态
playerCounter[1] = 0;//计算机落子个数为0
playerCounter[2] = 0;//玩家落子个数为0
lastDot = new Dot(boardSize);//创建棋子对象勇于存储最后一步棋,初始化位置为棋盘中央
steps = new Stack();//堆栈对象,用于存储最近的几步棋
triedDot = new Dot(-1, -1);
isGameOver = false;
isThinking = false;
rndNum = new Random();
}
public int[][] getTable()
{
return table;
}
public Dot lastDot()
{
return lastDot;
}
public Dot triedDot()
{
return triedDot;
}
public boolean checkGameOver()
{
return isGameOver;
}
public boolean isComputerWon()
{
return isComputerWon;
}
public boolean isThinking()
{
return isThinking;
}
private boolean isGameOver()
{/*
*根据“连五”的检测结果,可以判断游戏是否结束,并根据获胜方的落子代码判断是谁赢得了游戏
*/
isGameOver = false;//是否游戏结束
for(int r = 0; r < boardSize; r++)//遍历棋盘的行
{
for(int c = 0; c < boardSize; c++)//遍历棋盘的列
{
if(table[r][c] == 0 || checkFiveInRow(r, c, 5, -1) == -1)
continue;//如果检测的位置为空,或者不存在五子连珠的情况,则进行下一轮循环
isGameOver = true;//否则判断游戏结束
isComputerWon = table[r][c] == 1;//根据当前棋子判断是否是计算机赢
break;//存在五连子,终止列循环
}
if(isGameOver)//如果游戏结束,终止行循环
break;
}
if(isGameOver)//如果游戏结束,则在画布上相应的处理
myCanvas.notifyGameEnd();
return isGameOver;//返回判断结果
}
/*
* 双方落子的驱动有所不同,游戏的键盘输入驱动游戏逻辑在指定位置落子,落子时先判断落子方位的合法性
* ,如果成功落子,则判断是否存在“连五”情况,判断游戏是否结束,并根据获胜方设置游戏画布的屏幕提示
*/
public void manGo(int row, int col)
{
if(row >= 0 && row < boardSize && col >= 0 && col < boardSize && table[row][col] == 0)
{//判断落子位置的合法性,该位置在棋盘上,并且还没有被占用
goAt(row, col, 2);//人的代码是2
if(isGameOver())//判断游戏是否结束
{
if(isComputerWon)//如果计算机赢
myCanvas.setStatus("真遗憾!", 0xff0000, 2);
else//如果玩家赢
myCanvas.setStatus("恭喜你!", 65280, 1);
} else
{
computerGo();//计算机继续落子
}
}
}
private void goAt(int row, int col, int player)//计算机或人在row,col位置上走
{
int lastRow = lastDot.row;//记录上一步得行坐标
int lastCol = lastDot.col;//记录上一步得列坐标
table[row][col] = player;//当前位置填充玩家代码
lastDot.setRowCol(row, col);//将这一步设置为“最后一步”
myCanvas.repaintAt(lastRow, lastCol);//重新绘制上一步(将引导框去掉)
myCanvas.repaintAt(row, col);//绘制当前这步
switch(player)//统计双方落子数
{
case 1: //计算机的不数
playerCounter[1]++;
break;
case 2: //玩家的步数
playerCounter[2]++;
break;
}
playerCounter[0]--;//空白的个数
if(steps.size() > 10)//对战数量超过上限(10)
steps.removeElementAt(0);//清除栈底
steps.push(new Dot(row, col));//将这步棋压入堆栈
}
public boolean undo()//悔棋
{
if(steps.size() >= 3)
{
Dot d = new Dot();//创建棋子对象
d.copyFrom((Dot)steps.pop());//从堆栈弹出的棋子中复制行列位置坐标
table[d.row][d.col] = 0;//将该位置设置为空
myCanvas.repaintAt(d.row, d.col);//在棋盘上重新绘制该位置
d.copyFrom((Dot)steps.pop());//从堆栈弹出的棋子中复制行列位置坐标
table[d.row][d.col] = 0;//将该位置设置为空
myCanvas.repaintAt(d.row, d.col);//在棋盘上重新绘制该位置
d.copyFrom((Dot)steps.peek());//获取栈顶对象,作为最后一步棋存储
lastDot.copyFrom(d);
myCanvas.repaintAt(d.row, d.col);//重新绘制最后一步(添加引导框)
return true;
} else
{
return false;//悔棋失败
}
}
public void computerGo()//计算机落子
{
myCanvas.setStatus("思考中...", 0, 0);//在游戏画布上加以提示
myCanvas.serviceRepaints();//重新绘制屏幕
think();//进行逻辑运算
}
public void think()
{
isThinking = true;
Dot dc = null;
if((dc = to5L(1)) == null && (dc = to5L(2)) == null && (dc = to4B(1)) == null && (dc = to4B(2)) == null && (dc = toDouble4S_3B_2N1B(1, true)) == null && (dc = toDouble4S_3B_2N1B(2, true)) == null && (dc = toDouble4S_3B_2N1B(1, false)) == null && (dc = toDouble4S_3B_2N1B(2, false)) == null && (dc = toSingle4S_3B_2N1B(1)) == null)
dc = toSingle4S_3B_2N1B(2);
if(dc == null)
dc = maxGainedDot();
if(dc == null || playerCounter[0] == 0)
{
myCanvas.setStatus("平局!", 255, 3);
} else
{
System.out.println("Gone!");
goAt(dc.row, dc.col, 1);
if(isGameOver())
{
if(isComputerWon)
myCanvas.setStatus("真遗憾!", 0xff0000, 2);
else
myCanvas.setStatus("真厉害!", 65280, 1);
} else
{
myCanvas.setStatus("请落子...");
}
}
isThinking = false;
}
private Dot to4B(int player)
{//活四 棋型的实现
if(playerCounter[player] < 3)//如果该方下的棋子小于3,则不进行检测
return null;
Dot dot = null;
int maxGain = 0;//对某位置进行评分
for(int r = 1; r < boardSize - 1; r++)
{
for(int c = 1; c < boardSize - 1; c++)
if(table[r][c] == 0)//如果该位置为空白,则检测是否实现“活四”
{
int cd[] = connectedIn8D(player, r, c);//检测同类棋子在8个方向上的连续数目
int ed[] = expandedIn8D(playe