安卓五子棋-人机对战

Posted forSmile

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了安卓五子棋-人机对战相关的知识,希望对你有一定的参考价值。

人机对战,无非是通过算法来实现AI,遍历五子棋棋盘,返回一个X,Y的值,再去绘制棋盘就行了。

不多说,下面直接附上代码,人机的算法,有这个算法后,在自定义的View里去用就行了

 

 

package com.dcx.bean;

import android.util.Log;

public class SmartAIPlayer  {

private final static int FIVE = 10000;
private final static int LIVE_FOUR = 4500;
private final static int FOUR = 2000;
private final static int LIVE_THREE = 900;
private final static int THREE = 400;
private final static int LIVE_TWO = 150;
private final static int TWO = 70;
private final static int LIVE_ONE = 30;
private final static int ONE = 15;
private final static int DEAD = 1;

private ChessBean chessBean;

public Point findBestPoint() {
// 智能AI寻找合适点
//Log.d("Smart AI", "this is a smart AI");
//最佳点位
Point point = new Point();
//记录目前点位最高得分
int scores = 0;
//对每个空白点综合评分
chessBean = ChessBean.getInstance();
int[][] data = chessBean.dataArray;
for(int i=0;i<data.length;i++){
for(int j=0;j<data[i].length;j++){
if(data[i][j] == StaticUtils.NO_CHESS){
//模拟AI在此位置下棋,并计算棋势得分
int aiScore = getScoreHorizontal(i, j, StaticUtils.CHESS_BLACK)
+getScoreVertical(i, j, StaticUtils.CHESS_BLACK)
+getScoreLeftTop(i, j, StaticUtils.CHESS_BLACK)
+getScoreRightTop(i, j, StaticUtils.CHESS_BLACK);
//模拟对方在此位置下棋,并计算棋势得分
int playerScore = getScoreHorizontal(i, j, StaticUtils.CHESS_WHITE)
+getScoreVertical(i, j, StaticUtils.CHESS_WHITE)
+getScoreLeftTop(i, j, StaticUtils.CHESS_WHITE)
+getScoreRightTop(i, j, StaticUtils.CHESS_WHITE);
//计算总分
if(aiScore+playerScore > scores){
scores = aiScore+playerScore;
point.setX(i);
point.setY(j);
Log.d("scores",i+","+j+" "+scores);
}
}
}
}
return point;
}

/**
* 横向得分
*/
private int getScoreHorizontal(int x,int y,int chessType){
int[][] data = chessBean.dataArray;
//记录开始一端是否被堵
boolean isStartDead = false;
//记录结束一端是否被堵
boolean isEndDead = false;
//记录所下棋子连续出现的次数
int total = 1;
if(x==0
|| data[x-1][y]!=chessType && data[x-1][y]!=StaticUtils.NO_CHESS){
isStartDead = true;
}
if(x==StaticUtils.ARRAY_X_LENGTH-1
|| data[x+1][y]!=chessType && data[x+1][y]!=StaticUtils.NO_CHESS){
isEndDead = true;
}
//前搜索
for(int i=x-1;i>=0;i--){
if(data[i][y] != chessType){//如果与给棋子类型不同结束
break;
}
total++;
}
//后搜索
for(int i=x+1;i<StaticUtils.ARRAY_X_LENGTH;i++){
if(data[i][y] != chessType){//如果与给棋子类型不同结束
break;
}
total++;
}
return getScore(total,isStartDead,isEndDead);
}

private int getScore(int total, boolean isStartDead, boolean isEndDead) {
// TODO Auto-generated method stub
if(total >= 5){
return FIVE;
}
if(isStartDead && isEndDead){
return DEAD;
}
if(isStartDead || isEndDead){
switch(total){
case 4:
return FOUR;
case 3:
return THREE;
case 2:
return TWO;
case 1:
return ONE;
}
}
//任意一端都没有堵死
switch(total){
case 4:
return LIVE_FOUR;
case 3:
return LIVE_THREE;
case 2:
return LIVE_TWO;
case 1:
return LIVE_ONE;
default:
return 0;
}

}
/**
* 纵向得分
*/
private int getScoreVertical(int x,int y,int chessType){
int[][] data = chessBean.dataArray;
//记录开始一端是否被堵
boolean isStartDead = false;
//记录结束一端是否被堵
boolean isEndDead = false;
//记录所下棋子连续出现的次数
int total = 1;
if(y==0
|| data[x][y-1]!=chessType && data[x][y-1]!=StaticUtils.NO_CHESS){
isStartDead = true;
}
if(y==StaticUtils.ARRAY_Y_LENGTH-1
|| data[x][y+1]!=chessType && data[x][y+1]!=StaticUtils.NO_CHESS){
isEndDead = true;
}
//上搜索
for(int i=y-1;i>=0;i--){
if(data[x][i] != chessType){//如果与给棋子类型不同结束
break;
}
total++;
}
//下搜索
for(int i=y+1;i<StaticUtils.ARRAY_Y_LENGTH;i++){
if(data[x][i] != chessType){//如果与给棋子类型不同结束
break;
}
total++;
}
return getScore(total,isStartDead,isEndDead);
}


/**
* 左上到右下得分
*/
private int getScoreLeftTop(int x,int y,int chessType){
int[][] data = chessBean.dataArray;
//记录开始一端是否被堵
boolean isStartDead = false;
//记录结束一端是否被堵
boolean isEndDead = false;
//记录所下棋子连续出现的次数
int total = 1;
if((x==0||y==0)
|| data[x-1][y-1]!=chessType && data[x-1][y-1]!=StaticUtils.NO_CHESS){
isStartDead = true;
}
if((x==StaticUtils.ARRAY_X_LENGTH-1||y==StaticUtils.ARRAY_Y_LENGTH-1)
|| data[x][y+1]!=chessType && data[x][y+1]!=StaticUtils.NO_CHESS){
isEndDead = true;
}
//左上搜索
for(int i=x-1,j=y-1;i>=0&&j>=0;i--,j--){
if(data[i][j] != chessType){//如果与给棋子类型不同结束
break;
}
total++;
}
//右下搜索
for(int i=x+1,j=y+1;i<StaticUtils.ARRAY_X_LENGTH&&j<StaticUtils.ARRAY_Y_LENGTH;i++,j++){
if(data[i][j] != chessType){//如果与给棋子类型不同结束
break;
}
total++;
}
return getScore(total,isStartDead,isEndDead);
}

/**
* 右上到左下得分
*/
private int getScoreRightTop(int x,int y,int chessType){
int[][] data = chessBean.dataArray;
//记录开始一端是否被堵
boolean isStartDead = false;
//记录结束一端是否被堵
boolean isEndDead = false;
//记录所下棋子连续出现的次数
int total = 1;
if((x==StaticUtils.ARRAY_X_LENGTH-1||y==0)
|| data[x+1][y-1]!=chessType && data[x+1][y-1]!=StaticUtils.NO_CHESS){
isStartDead = true;
}
if((x==0||y==StaticUtils.ARRAY_Y_LENGTH-1)
|| data[x-1][y+1]!=chessType && data[x-1][y+1]!=StaticUtils.NO_CHESS){
isEndDead = true;
}
//右上搜索
for(int i=x+1,j=y-1;i<StaticUtils.ARRAY_X_LENGTH-1&&j>=0;i++,j--){
if(data[i][j] != chessType){//如果与给棋子类型不同结束
break;
}
total++;
}
//左下搜索
for(int i=x-1,j=y+1;i>=0&&j<StaticUtils.ARRAY_Y_LENGTH;i--,j++){
if(data[i][j] != chessType){//如果与给棋子类型不同结束
break;
}
total++;
}
return getScore(total,isStartDead,isEndDead);
}
}

 

 

下面是一个常量类,在算法中用到的数据,比如棋盘的长度

package com.dcx.bean;

public class StaticUtils {

public final static int ARRAY_X_LENGTH =12;
public final static int ARRAY_Y_LENGTH = 12;
public final static int CHESS_BLACK = 1;
public final static int CHESS_WHITE = 2;
public final static int NO_CHESS = 0;

//赢得玩家
public final static int AI_WIN = 0x10;
public final static int PLAY_WIN = 0x11;
public final static int CHESS_FULL = 0x12;

}

以上是关于安卓五子棋-人机对战的主要内容,如果未能解决你的问题,请参考以下文章

C语言实现五子棋三子棋人机对战,包含电脑人工智能对战(可攻可守)(非标题党)

python实现五子棋-人机对战/人人对战(动图演示+源码分享)

Java Swing局域网对战五子棋(人人和人机对战)

C#五子棋小游戏源码(人机对战)

Android 蓝牙对战五子棋项目实现(含人机对战功能)

批处理实现的五子棋人机对战游戏