资源简介
用α-β剪枝算法写的井子棋,为人机对弈形式,可选择人先走或计算机先走,可改搜索深度提高计算机智力
代码片段和文件信息
#include
using namespace std;
int num=0;
int pq;
int tmpQP[3][3]; //表示棋盘数据的临时数组,其中的元素0表示该格为空,
int cur[3][3];
const int depth=3; //搜索树的最大深度
void Init()
{
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
{
cur[i][j]=0;
}
}
void PrintQP() //打印当棋盘格局的函数
{
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
cout< cout< }
}
int CheckWin() //有人赢了吗?返回0表示没有人赢,返回-1表示人赢了,返回1表示计算机赢了
{
for(int i=0;i<3;i++)
{
if(cur[i][0]==1&&cur[i][1]==1&&cur[i][2]==1)return 1;
if(cur[i][0]==-1&&cur[i][1]==-1&&cur[i][2]==-1)return -1;
}
for(i=0;i<3;i++)
{
if(cur[0][i]==1&&cur[1][i]==1&&cur[2][i]==1)return 1;
if(cur[0][i]==-1&&cur[1][i]==-1&&cur[2][i]==-1)return -1;
}
if((cur[0][0]==1&&cur[1][1]==1&&cur[2][2]==1)||(cur[2][0]==1&&cur[1][1]==1&&cur[0][2]==1))return 1;
if((cur[0][0]==-1&&cur[1][1]==-1&&cur[2][2]==-1)||(cur[2][0]==-1&&cur[1][1]==-1&&cur[0][2]==-1))return -1;
return 0;
}
int value()//评估函数
{
p=0;
q=0;
//将棋盘中的空格填满自己的棋子,既将棋盘数组中的0变为1
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
if(cur[i][j]==0)tmpQP[i][j]=1;
else tmpQP[i][j]=cur[i][j];
//电脑一方
//计算每一行中有多少行的棋子连成3个的
for(i=0;i<3;i++)
p+=(tmpQP[i][0]+tmpQP[i][1]+tmpQP[i][2])/3;
//计算每一列中有多少列的棋子连成3个的
for(i=0;i<3;i++)
p+=(tmpQP[0][i]+tmpQP[1][i]+tmpQP[2][i])/3;
//斜行有没有连成3个的?
p+=(tmpQP[0][0]+tmpQP[1][1]+tmpQP[2][2])/3;
p+=(tmpQP[2][0]+tmpQP[1][1]+tmpQP[0][2])/3;
//将棋盘中的空格填满对方的棋子,既将棋盘数组中的0变为-1
for(i=0;i<3;i++)
for(int j=0;j<3;j++)
if(cur[i][j]==0)tmpQP[i][j]=-1;
else tmpQP[i][j]=cur[i][j];
//对方
//计算每一行中有多少行的棋子连成3个的
for(i=0;i<3;i++)
q+=(tmpQP[i][0]+tmpQP[i][1]+tmpQP[i][2])/3;
//计算每一列中有多少列的棋子连成3个的
for(i=0;i<3;i++)
q+=(tmpQP[0][i]+tmpQP[1][i]+tmpQP[2][i])/3;
//斜行有没有连成3个的?
q+=(tmpQP[0][0]+tmpQP[1][1]+tmpQP[2][2])/3;
q+=(tmpQP[2][0]+tmpQP[1][1]+tmpQP[0][2])/3;
return p+q;
}
int cut(int &valint depbool max) //主算法部分,实现A-B剪枝的算法,val为上一层的评价值,dep为搜索深度,max记录上一层是否为极大层
{
if(dep==depth || dep+num==9) //如果搜索深度达到最大深度,或者深度加上当前棋子数已经达到9,就直接调用评价函数
{
return value();
}
int ijflagtemp;
bool out=false; //out记录是否剪枝,初始为false
if(CheckWin()==1) //如果用户玩家输了,就置上一层的评价值为无穷(用很大的值代表无穷)
{
val=10000;
return 0;
}
if(max) //如果上一层是极大层,本曾则需要是极小层,记录flag为无穷大;反之,则为记录为负无穷大
flag=10000; //flag记录本层节点的极值
else
flag=-10000;
for(i=0;i<3 && !out;i++) //两重循环,遍历棋盘所有位置
{
for(j=0;j<3 && !out;j++)
{
if(cur[i][j]==0) //如果该位置上没有棋子
{
if(max) //并且为上一层为极大层,即本层为极小层轮到用户玩家走了。
{
cur[i][j]=-1; //该位置填上用户玩家棋子
if(CheckWin()==-1) //如果用户玩家赢了
temp=-10000; //置棋盘评价值为负
评论
共有 条评论