Android五子棋算法简单实现

有一天在网上看到一个Android的五子棋,该程序的作者的GoogleTalk: [email protected]。遂下载下来看看,可以下棋,但是没有实现电脑下棋算法,所以我一时兴起花了几个小时加了个电脑下棋算法在里面,很简单。原作者的游戏绘制就不多说了,主要讲电脑下棋算法。

1、准备一个数组表示当前棋盘,另外准备两个数组分别保存电脑和玩家每个可下点的坐标及其分数(棋型数组),每个可下点包括4个方向的分数,分别是横、竖、左斜、右斜。

private int[][]mChessTable= new int[CHESS_GRID][CHESS_GRID]; // 网格

private int[][][]computerTable= new int[CHESS_GRID][CHESS_GRID][CHECK_DIR]; // 电脑棋形表
private int[][][]playerTable= new int[CHESS_GRID][CHESS_GRID][CHECK_DIR]; // 电脑棋形表

2、每个可下点的4个方向分数判断,每个方向取当前点左右每边5个棋点的状态,然后分析它们是否构成五连、活四、活三等,每种棋型给予不同的分数。1//-------------------------------------------------------------

2 /**
3 *分析存在五连
4 *
5 * @param tmpChess
6 */
7 public booleananalyzeWulian( int[]tmpChess, intisWho){
8 intcount=0;
9 for( inti=0;i<HALF_LEN;i++){
10 if(tmpChess[HALF_LEN-(i+1)]==isWho){
11count++;
12} else{
13 break;
14}
15}
16 for( inti=0;i<HALF_LEN;i++){
17 if(tmpChess[HALF_LEN+i]==isWho){
18count++;
19} else{
20 break;
21}
22}
23 if(count==4){
24 return true;
25}
26 return false;
27}
28
29 /**
30 *
31 *分析活四return是否存在活四
32 *
33 * @param tmpChess
34 */
35 public booleananalyzeHuosi( int[]tmpChess, intisWho){
36 intcount=0;
37 inti=0;
38 booleanisSpace= false;
39 for(i=0;i<HALF_LEN;i++){
40 if(tmpChess[HALF_LEN-(i+1)]==isWho){
41count++;
42} else{
43 break;
44}
45}
46 if(tmpChess[HALF_LEN-(i+1)]==0){
47isSpace= true;
48}
49 for(i=0;i<HALF_LEN;i++){
50 if(tmpChess[HALF_LEN+i]==isWho){
51count++;
52} else{
53 break;
54}
55}
56 if(tmpChess[HALF_LEN+i]==0){
57isSpace= true;
58} else{
59isSpace= false;
60}
61
62 if(count==3&&isSpace){
63 return true;
64}
65 return false;
66}
67
68 /**
69 *
70 *分析活三return是否存在活三
71 *
72 * @param tmpChess
73 */
74 public booleananalyzeHuosan( int[]tmpChess, intisWho){
75 intcount=0;
76 inti=0;
77 booleanisSpace= false;
78 for(i=0;i<HALF_LEN;i++){
79 if(tmpChess[HALF_LEN-(i+1)]==isWho){
80count++;
81} else{
82 break;
83}
84}
85 if(tmpChess[HALF_LEN-(i+1)]==0){
86isSpace= true;
87}
88 for(i=0;i<HALF_LEN;i++){
89 if(tmpChess[HALF_LEN+i]==isWho){
90count++;
91} else{
92 break;
93}
94}
95 if(tmpChess[HALF_LEN+i]==0){
96isSpace= true;
97} else{
98isSpace= false;
99}
100
101 if(count==2&&isSpace){
102 return true;
103}
104 return false;
105} 3、将玩家棋型数组和电脑棋型数组每个元素的分数比较,选出最大的五个放入一个降序排列的数组中。
/**
*找到最佳点
*
*
@return 最佳点
*/
privateChessPointfindBestPoint(){
inti,j;
ChessPointpoint;
intmaxScore=0;
inttmpScore=0;
for(i=0;i<CHESS_GRID;i++){
for(j=0;j<CHESS_GRID;j++){
// 电脑比较
tmpScore=computerTable[i][j][0];
tmpScore+=computerTable[i][j][1];
tmpScore+=computerTable[i][j][2];
tmpScore+=computerTable[i][j][3];
if(maxScore<=tmpScore){
maxScore=tmpScore;
point= newChessPoint();
point.x=j;
point.y=i;
point.score=maxScore;
insertBetterChessPoint(point);
}
// 玩家比较
tmpScore=playerTable[i][j][0];
tmpScore+=playerTable[i][j][1];
tmpScore+=playerTable[i][j][2];
tmpScore+=playerTable[i][j][3];
if(maxScore<=tmpScore){
maxScore=tmpScore;
point= newChessPoint();
point.x=j;
point.y=i;
point.score=maxScore;
insertBetterChessPoint(point);
}

}
}

// Log.v("cmaxpoint=",""+cMaxScore);
// Log.v("pmaxpoint=",""+pMaxScore);


returnanalyzeBetterChess();
} 4、处理降序排列的数组,如果第一个元素的分数>=(必胜的条件的分数),直接返回就可以了,如果小于就继续处理我们降序排列的数组每个元素,假设每个元素已下,然后判断其产生的后果,取出具有最佳后果的元素,并返回其值,作为电脑下棋点。判断每个元素的产生后果时,其实只需要处理其产生作用的棋盘范围就行了(以该元素位置为中心的正方形的棋盘范围,正方形边长为4 + 1 + 4,我用的10),不必要处理搜索处理整个棋盘的棋子。 private ChessPointanalyzeBetterChess(){
if(fiveBetterPoints[0].score>30){
returnfiveBetterPoints[0];
}
else
{
ChessPointbetterPoint= null;
ChessPointtmpPoint= null;

intgoodIdx=0;
inti=0;
intstartx,starty,endx,endy;
ChessPoint[]fbpTmp= newChessPoint[5];
for(i=0;i<5;i++){
fbpTmp[i]=fiveBetterPoints[i];
}

for(i=0;i<5;i++){
if(fbpTmp[i]== null) break;
mChessTable[fbpTmp[i].y][fbpTmp[i].x]=BLACK;
clearChessArray();

startx=fbpTmp[i].x-5;
starty=fbpTmp[i].y-5;

if(startx<0){
startx=0;
}

if(starty<0){
starty=0;
}

endx=startx+10;
endy=starty+10;

if(endx>CHESS_GRID){
endx=CHESS_GRID;
}

if(endy>CHESS_GRID){
endy=CHESS_GRID;
}
analyzeChessMater(computerTable,BLACK,startx,starty,endx,endy);
// 分析玩家的棋型 //////////////////////////////////////////////////// /
analyzeChessMater(playerTable,WHITE,startx,starty,endx,endy);
tmpPoint=findBetterPoint(startx,starty,endx,endy);
if(betterPoint!= null){
if(betterPoint.score<=tmpPoint.score){
betterPoint=tmpPoint;
goodIdx=i;
}
}
else{
betterPoint=tmpPoint;
goodIdx=i;
}

mChessTable[fbpTmp[i].y][fbpTmp[i].x]=0;
}
tmpPoint= null;
betterPoint= null;
returnfbpTmp[goodIdx];
}

} OK,差不多就这样,看 源码吧,应该还有问题,其实速度还算可以。我要睡觉了,明天还要上班。

更多相关文章

  1. AssetManager读取assets下多张图片资源输出到ImageView动画
  2. android 模拟器和电脑服务器端用socket通讯
  3. android中SparseArray和ArrayMap代替HashMap
  4. Android应用程序介绍页面实现 (二)
  5. Eclipse Android(安卓)SDK content Loader一直显示为0%的问题
  6. 如何将uboot里面的参数传给recovery或kernel
  7. Android(安卓)性能优化——使用优化集合类SparseArray&ArrayMap
  8. Android操作JNI函数以及复杂对象传递
  9. Android(安卓)ListView适配器BaseAdapter中getItemViewType需要

随机推荐

  1. SQL Server 2016 CTP2.2安装配置方法图文
  2. SQL Server中参数化SQL写法遇到parameter
  3. MySQL 及 SQL 注入与防范方法
  4. sql server 2012 备份集中的数据库备份与
  5. SQL Server2016正式版安装配置方法图文教
  6. SQL中遇到多条相同内容只取一条的最简单
  7. SqlServer存储过程实现及拼接sql的注意点
  8. SQL中位数函数实例
  9. SQL Server使用row_number分页的实现方法
  10. SQL Server简单实现数据的日报和月报功能