安卓五子棋-人机对战
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语言实现五子棋三子棋人机对战,包含电脑人工智能对战(可攻可守)(非标题党)