Alpha-beta 算法是棋类游戏中最常用的,也是最基础的剪枝方法,
要说Alpha-beta 算法 就得先说下max_min博弈树 算法,就是模拟电脑下子,要下在对电脑最优的地方,模拟人下子就要下在对人最优的地方,对电脑来说最差的地方
此图中甲是电脑,乙是玩家,那么在甲层的时候,总是选其中值最大的节点,乙层的时候,总是选其中最小的节点。
而每一个节点的分数,都是由子节点决定的,因此我们对博弈树只能进行深度优先搜索而无法进行广度优先搜索。深度优先搜索用递归非常容易实现,然后主要工作其实是完成一个评估函数,这个函数需要对当前局势给出一个比较准确的评分。
解释一下,也就是在MAX层的时候会把当前层已经搜索到的最大值X存起来,如果下一个节点的下一层会产生一个比X还小的值Y,那么之前说过玩家总是会选择最小值的。也就是说这个节点玩家的分数不会超过Y,那么这个节点显然没有必要进行计算了。
通俗点来讲就是,AI发现这一步是对玩家更有利的,那么当然不会走这一步。
int alphaBeta2(int chess, int depth, int alpha, int beta,int i,int j) //alphaBeta剪枝;极大极小博弈树,人工智能第一步 模拟五步下子
{
int best;
if( getQuan(i,j,chess%2+1)>=Q5)
{
return getComputerQuan()-getPeopleQuan();
}
else if(depth==0)
{
//System.out.println(getComputerQuan()-getPeopleQuan());
return getComputerQuan()-getPeopleQuan();
}
else {
if(chess==2)
{
int now;
for( i = 0;i<= 14;i++)
for(j = 0;j<=14;j++)
{
if(num[i][j]==0)
{
if(alpha>=beta)return alpha;
else if(generator( i,j)==true){
num[i][j]=2;
now=alphaBeta2(1,depth-1,alpha,beta,i,j);
num[i][j]=0;
if(now>alpha)alpha=now;
}
}
}
best=alpha;
}
else {
int now;
for( i = 0;i<= 14;i++)
for(j = 0;j<=14;j++)
{
if(num[i][j]==0)
{
if(alpha>=beta)return beta;
else if(generator(i,j)==true){
num[i][j]=1;
now=alphaBeta2(2,depth-1,alpha,beta,i,j);
num[i][j]=0;
if(now
可以看出搜索的复杂度是m^n 所以要想多搜几步减少m的值是必要的,m的值怎么减少呢?启发式搜索就是找最优的点有了打分之后,我们就可以按照分数高低进行排序了。具体实现的时候,是根据按照成五,活四,双三,活三,其他 的顺序来排序的。这个难度也比较高,我就按着这个顺序排序,取最优的五个进行下一步循环,大大减少了基数m可以搜索到第六步,多搜索了2步而且时间是几乎相同的,关键代码如下:
if(chess==2)//电脑下子
{
int now;//一个记录当前值的数,
for( i = 0;i<= 14;i++)
for(j = 0;j<=14;j++)
{
if(num[i][j]==0)
{
if(alpha>=beta)return alpha;//alpha剪枝
else if(generator(i,j)==true){//相邻剪枝
num[i][j]=2;
// now=getQuan(i,j,chess);
now=getQuan(i,j,1)+getQuan(i,j,2);
num[i][j]=0;
bestson[cnt]=new struct();//入队
bestson[cnt].i=i;
bestson[cnt].j=j;
bestson[cnt++].value=now;
}
}
}
struct t=new struct();
for(i=0;i<cnt;i++)//冒泡排序
for(j=i+1;j<cnt;j++)
if(bestson[i].value<bestson[j].value)
{
t=bestson[i];
bestson[i]=bestson[j];
bestson[j]=t;
}
cnt=cnt<5?cnt:5;
for(i=0;i<cnt;i++)//启发式搜索,取前五
{
num[bestson[i].i][bestson[i].j]=2;
now=alphaBeta(1,depth-1,alpha,beta,bestson[i].i,bestson[i].j);
if(now>alpha)alpha=now;
num[bestson[i].i][bestson[i].j]=0;
}
best=alpha;
}
现在的棋力已经很厉害了。
开始我也一点没接触过五子棋的算法,经过一周课余的努力也能做的不错了,好开心。。