在StdAfx.h文件中添加
#define SIZE 15 //棋盘是15*15
#define CHESS_WHITE ‘W’ //白棋
#define CHESS_BLACK ‘B’ //黑棋
#define SPACE ‘ ‘ //空位置
#define CHESS_COMPUTER ‘B’ //这里程序中设置计算机执黑(计算机没你聪明嘛)
核心类如下:
class CFiveChess
{
protected:
charm_cArr[SIZE][SIZE];//存放棋盘的棋子信息,'B'表示黑棋,'W'表示白棋,' '(空格)表示未知
intm_nCurrentX,m_nCurrentY;//当前棋子下落点的坐标,没下一步就以该点判断是否赢棋,这样能够起到很大的优化效果
public:
CFiveChess();//构造函数
intm_nCount;//记录已经下了多少步棋,下满225步就和棋
voidInitArr(); //初始化棋盘
voidSetArr(int row,int col,char cPlayer);//给m_cArr[row][col]设置值
charGetArr(int row,int col);//读取m_cArr[row][col]的值
voidSetCurrentPoint(int row,int col);//设置当前下落点
charJudegeWin(char cChessFlag);//判断cChessFlag(黑白棋标志)棋是否赢了
//下面是人机对战的核心成员
protected:
intcomputer[SIZE][SIZE],people[SIZE][SIZE];//记录每个未下过棋子的点的价值,取价值最大点下,利用贪心的思想
//为了加入几种有策略的下法,只能将下面的棋型放在类中声明了
//对各种棋型的数量进行统计
//分别是成5,活4,冲4,活3,冲3,活2,冲2,活1,冲1(死5,死4,死3,死2,死1没必要统计),准活3,准冲3,准冲4(命名一点都不专业)
intcheng5,huo4,chong4,huo3,chong3,huo2,chong2,huo1,chong1,zhunhuo3,zhunchong3,zhunchong4;//每下一步都要统计这些棋型的数量,以便计算机能够做出最优决策
public:
intm_nGrade;//人机对战的3种等级,这个可以略掉,加着玩玩的
intm_CX,m_CY;//计算机的落棋点
voidComputerPlay(char cComputer,char cPeople);//计算机下棋,第一个参数表示计算机执哪种棋,第二个参数表示人执的棋
voidSearch(int row,int col,char cChessFlag,int state[SIZE][SIZE]);//行,列,棋的黑白标志,价值数组
intPracticalScore(int num[],int border[][2],char cChessFlag);//4个方向上相连的数量,两端是否为空格,棋子标志;两端只有一个空格就是“冲”棋型,两个空格就是“活”棋型,没有就是“死”棋型,这些都影响这个点对于计算机下棋的价值
};
//我下五子棋的时候也不喜欢什么什么禁手规则,很多人也不知道,所以在这里不设置有禁手和无禁手了,一律计算机执黑。其实禁手规则的设置很简单,执黑者有三三,四四,三四四和长连禁手。这里可以根据上面添加的棋型的数量来判断即可,例如,可构成两个活3的点就是三三禁手,黑棋是不能下这个点的,那么可在调用完函数后将这个点的价值设为0即可。
//人机对弈,AI算法必须保证如下条件,其他的可以根据个人的下棋想法来添加相应代码
/*
必须满足的条件:
1,首先判断自己是否成5,若是,则成5,赢了
2,否则判断对手是否成5,若是,则阻止
3,否则判断自己是否活4,若是,我就不废话了
4,否则判断自己是否活3+冲4,……
5,否则判断对手是否活4,……
6,否则判断对手是否活3+冲4,……
7,否则判断自己是否活3+活3,……
……
执行的优先级别如下:
A:成5
B:活4
B:活3+冲4,冲4+冲4
C:活3+活3
D:活3
D:活2+活2
D:活2+冲3
E:活2
……
另外:同级别的棋型,计算机的价值比人的高(当然是优先执行自己的啦),当然也可以用防守的策略,在分值较低的情况下先执行人的位置(表示这个点的价值是对于人而言的)。
冲1比活1好,五子棋的AI算法最后以守为攻为妙,毕竟计算机不能像人一样给别人设圈套,测试的时候这个五子棋的AI水平也不低哦。
此AI的思路全是个人下棋的经验中能够表达出来的一部分,所以有些棋型的赋值方案并不是很完美,希望参考该代码者能够自己想出更优秀的解决方案。
*/
上面是类部分的介绍,对于其成员函数的介绍就不做多解释了,人人对弈的很简单,下面介绍人机对弈的函数以及加入的相关策略性选择法。
//以下是人机对战函数
void CFiveChess::ComputerPlay(charcComputer,char cPeople)
{
intmaxComputer=0,maxPeople=0;//计算机和人的状态矩阵的最大值
//(即maxComputer是计算机最有价值点的值,maxPeople是人最有价值点的值,初始化为0
intnRow,nCol;
intcx,cy,px,py;
for(nRow=0;nRow<SIZE;nRow++)//初始化价值数组
for(nCol=0;nCol<SIZE;nCol++)
computer[nRow][nCol]=people[nRow][nCol]=0;
for(nRow=0;nRow<SIZE;nRow++)
for(nCol=0;nCol<SIZE;nCol++)
if(m_cArr[nRow][nCol]==SPACE)//取未知点来搜索,求得该点的价值
{
Search(nRow,nCol,cComputer,computer);
Search(nRow,nCol,cPeople,people);
}
//3种等级,一种是比较人机各自的最大值后再取其中的最大值,另两种是把人机的相加然后取其最大值
if(m_nGrade==1)
{
for(nRow=0;nRow<SIZE;nRow++)
for(nCol=0;nCol<SIZE;nCol++)
{
if(computer[nRow][nCol]>maxComputer)//找出computer的最大值点
{
maxComputer=computer[nRow][nCol];
cx=nRow;
cy=nCol;
}
if(people[nRow][nCol]>maxPeople)//找出people的最大值点
{
maxPeople=people[nRow][nCol];
px=nRow;
py=nCol;
}
}
if(maxComputer>=maxPeople)
{
m_CX=cx;
m_CY=cy;
}
else
{
m_CX=px;
m_CY=py;
}
}
if(m_nGrade==2 || m_nGrade==3)
{
for(nRow=0;nRow<SIZE;nRow++)
for(nCol=0;nCol<SIZE;nCol++)
computer[nRow][nCol]+=people[nRow][nCol];
for(nRow=0;nRow<SIZE;nRow++)
for(nCol=0;nCol<SIZE;nCol++)
if(computer[nRow][nCol]>maxComputer)
{
maxComputer=computer[nRow][nCol];
m_CX=nRow;
m_CY=nCol;
}
}
//经过上述步骤后,m_cArr[m_CX][m_CY]是最有价值的一点,好不容易选出来的,计算机将在这一点落子
}
//下面是搜索函数,对点(row,col)的各个方向搜索,统计添加棋型的数量
void CFiveChess::Search(int row,intcol,char cChessFlag,int state[SIZE][SIZE])
{
charAnother;//另一方
intnum[4],border[4][2];//—,|,\,/,四个方向
intmax=0,temp=0;//max为该点m_cArr[row][col]的最大价值
inti,j;
if(cChessFlag==CHESS_BLACK)
Another=CHESS_WHITE;
else
Another=CHESS_BLACK;
//横向
border[0][0]=border[0][1]=1;//初始化必须为1,因为下面没有判断边界
num[0]=0;
//右
for(i=col+1;i<SIZE;i++)
{
if(m_cArr[row][i]==cChessFlag)
{
num[0]++;
continue;
}
if(m_cArr[row][i]==Another)
{
border[0][1]=1;
break;
}
if(m_cArr[row][i]==SPACE)
{
border[0][1]=0;
break;
}
}
//左
for(i=col-1;i>=0;i--)
{
if(m_cArr[row][i]==cChessFlag)
{
num[0]++;
continue;
}
if(m_cArr[row][i]==Another)
{
border[0][0]=1;
break;
}
if(m_cArr[row][i]==SPACE)
{
border[0][0]=0;
break;
}
}
//纵向
border[1][0]=border[1][1]=1;num[1]=0;
//上
for(i=row-1;i>=0;i--)
{
if(m_cArr[i][col]==cChessFlag)
{
num[1]++;
continue;
}
if(m_cArr[i][col]==Another)
{
border[1][0]=1;
break;
}
if(m_cArr[i][col]==SPACE)
{
border[1][0]=0;
break;
}
}
//下
for(i=row+1;i<SIZE;i++)
{
if(m_cArr[i][col]==cChessFlag)
{
num[1]++;
continue;
}
if(m_cArr[i][col]==Another)
{
border[1][1]=1;
break;
}
if(m_cArr[i][col]==SPACE)
{
border[1][1]=0;
break;
}
}
//'\'方向
border[2][0]=border[2][1]=1;num[2]=0;
//上
for(i=row-1,j=col-1;i>=0&& j>=0;i--,j--)
{
if(m_cArr[i][j]==cChessFlag)
{
num[2]++;
continue;
}
if(m_cArr[i][j]==Another)
{
border[2][0]=1;
break;
}
if(m_cArr[i][j]==SPACE)
{
border[2][0]=0;
break;
}
}
//下
for(i=row+1,j=col+1;i<SIZE&& j<SIZE;i++,j++)
{
if(m_cArr[i][j]==cChessFlag)
{
num[2]++;
continue;
}
if(m_cArr[i][j]==Another)
{
border[2][1]=1;
break;
}
if(m_cArr[i][j]==SPACE)
{
border[2][1]=0;
break;
}
}
//'/'方向
border[3][0]=border[3][1]=1;num[3]=0;
//上
for(i=row-1,j=col+1;i>=0&& j<SIZE;i--,j++)
{
if(m_cArr[i][j]==cChessFlag)
{
num[3]++;
continue;
}
if(m_cArr[i][j]==Another)
{
border[3][0]=1;
break;
}
if(m_cArr[i][j]==SPACE)
{
border[3][0]=0;
break;
}
}
//下
for(i=row+1,j=col-1;i<SIZE&& j>=0;i++,j--)
{
if(m_cArr[i][j]==cChessFlag)
{
num[3]++;
continue;
}
if(m_cArr[i][j]==Another)
{
border[3][1]=1;
break;
}
if(m_cArr[i][j]==SPACE)
{
border[3][1]=0;
break;
}
}
cheng5=huo4=chong4=huo3=chong3=huo2=chong2=huo1=chong1=zhunhuo3=zhunchong3=zhunchong4=0;//放在这里初始化
//为了让计算机下棋有策略一点,将下面几种棋型也加入
//B表示cChessFlag,W表示Another,S表示空格,X为价值统计点(假设落子点)
//棋型1,2 将 S B B S X S和 S X S B B S 当做准活3处理
//棋型3,4 将 W B B S X S和 S X S B B W 当做准冲3处理
//棋型5,6 将 W B B B S X和 X S B B B W 当做准冲4处理
//棋型7,8 将 S X B S B S和 S B S B X S 当做准活3处理
//棋型9,10 将 S B X S B S和 S B S X B S 当做准活3处理
//棋型11,12将 W B X B S B和 B S B X B W 当做准冲4处理
// 棋型13,14将 W B B X S B和 B S X B B W 当做准冲4处理
//一个准活3的价值小于活3,两个准活3的价值等于两个活3
//一个准冲3的价值小于冲3,两个准冲3的价值等于两个冲3
//一个准冲4的价值微小于冲4,两个准冲4等于两个冲4
//
//下面的代码敲的纠结死人,NND,一不小心就错了,写完这些策略后,调试的最好方法就是和计算机多下几盘棋,其实计算机的落子点是确定的,可以人为的计算出来。
//横
if(col-4>=0&& col+1<SIZE) //棋型1
if(m_cArr[row][col+1]==SPACE&& m_cArr[row][col-1]==SPACE && m_cArr[row][col-2]==cChessFlag
&&m_cArr[row][col-3]==cChessFlag && m_cArr[row][col-4]==SPACE)
zhunhuo3++;
if(col-1>=0&& col+4<SIZE)//棋型2
if(m_cArr[row][col-1]==SPACE&& m_cArr[row][col+1]==SPACE && m_cArr[row][col+2]==cChessFlag
&&m_cArr[row][col+3]==cChessFlag && m_cArr[row][col+4]==SPACE)
zhunhuo3++;
if(col-4>=0&& col+1<SIZE) //棋型3
if(m_cArr[row][col+1]==SPACE&& m_cArr[row][col-1]==SPACE && m_cArr[row][col-2]==cChessFlag
&&m_cArr[row][col-3]==cChessFlag && m_cArr[row][col-4]==Another)
zhunchong3++;
if(col-1>=0&& col+4<SIZE)//棋型4
if(m_cArr[row][col-1]==SPACE&& m_cArr[row][col+1]==SPACE && m_cArr[row][col+2]==cChessFlag
&&m_cArr[row][col+3]==cChessFlag && m_cArr[row][col+4]==Another)
zhunchong3++;
if(col-5>=0&& col<SIZE)//棋型5
if(m_cArr[row][col-1]==SPACE&& m_cArr[row][col-2]==cChessFlag &&m_cArr[row][col-3]==cChessFlag
&&m_cArr[row][col-4]==cChessFlag && m_cArr[row][col-5]==Another)
zhunchong4++;
if(col>=0&& col+5<SIZE)//棋型6
if(m_cArr[row][col+1]==SPACE&& m_cArr[row][col+2]==cChessFlag &&m_cArr[row][col+3]==cChessFlag
&&m_cArr[row][col+4]==cChessFlag && m_cArr[row][col+5]==Another)
zhunchong4++;
if(col-1>=0&& col+4<SIZE) //棋型7
if(m_cArr[row][col+4]==SPACE&& m_cArr[row][col+3]==cChessFlag && m_cArr[row][col+2]==SPACE
&&m_cArr[row][col+1]==cChessFlag && m_cArr[row][col-1]==SPACE)
zhunhuo3++;
if(col-4>=0&& col+1<SIZE) //棋型8
if(m_cArr[row][col+1]==SPACE&& m_cArr[row][col-1]==cChessFlag && m_cArr[row][col-2]==SPACE
&&m_cArr[row][col-3]==cChessFlag && m_cArr[row][col-4]==SPACE)
zhunhuo3++;
if(col-2>=0&& col+3<SIZE)//棋型9
if(m_cArr[row][col-2]==SPACE&& m_cArr[row][col-1]==cChessFlag && m_cArr[row][col+1]==SPACE
&&m_cArr[row][col+2]==cChessFlag && m_cArr[row][col+3]==SPACE)
zhunhuo3++;
if(col-3>=0&& col+2<SIZE)//棋型10
if(m_cArr[row][col-3]==SPACE&& m_cArr[row][col-2]==cChessFlag && m_cArr[row][col-1]==SPACE
&&m_cArr[row][col+1]==cChessFlag && m_cArr[row][col+2]==SPACE)
zhunhuo3++;
if(col-2>=0&& col+3<SIZE)//棋型11
if(m_cArr[row][col-2]==Another&& m_cArr[row][col-1]==cChessFlag &&m_cArr[row][col+1]==cChessFlag
&&m_cArr[row][col+2]==SPACE && m_cArr[row][col+3]==cChessFlag)
zhunchong4++;
if(col-3>=0&& col+2<SIZE)//棋型12
if(m_cArr[row][col-3]==cChessFlag&& m_cArr[row][col-2]==SPACE && m_cArr[row][col-1]==cChessFlag
&&m_cArr[row][col+1]==cChessFlag && m_cArr[row][col+2]==Another)
zhunchong4++;
if(col-3>=0&& col+2<SIZE)//棋型13
if(m_cArr[row][col-3]==Another&& m_cArr[row][col-2]==cChessFlag &&m_cArr[row][col-1]==cChessFlag
&&m_cArr[row][col+1]==SPACE && m_cArr[row][col+2]==cChessFlag)
zhunchong4++;
if(col-2>=0&& col+3<SIZE) //棋型14
if(m_cArr[row][col-2]==cChessFlag&& m_cArr[row][col-1]==SPACE && m_cArr[row][col+1]==cChessFlag
&&m_cArr[row][col+2]==cChessFlag && m_cArr[row][col+3]==Another)
zhunchong4++;
//竖
if(row-4>=0&& row+1<SIZE) //棋型1
if(m_cArr[row+1][col]==SPACE&& m_cArr[row-1][col]==SPACE && m_cArr[row-2][col]==cChessFlag
&&m_cArr[row-3][col]==cChessFlag && m_cArr[row-4][col]==SPACE)
zhunhuo3++;
if(row-1>=0&& row+4<SIZE)//棋型2
if(m_cArr[row-1][col]==SPACE&& m_cArr[row+1][col]==SPACE && m_cArr[row+2][col]==cChessFlag
&&m_cArr[row+3][col]==cChessFlag && m_cArr[row+4][col]==SPACE)
zhunhuo3++;
if(row-4>=0&& row+1<SIZE) //棋型3
if(m_cArr[row+1][col]==SPACE&& m_cArr[row-1][col]==SPACE && m_cArr[row-2][col]==cChessFlag
&&m_cArr[row-3][col]==cChessFlag && m_cArr[row-4][col]==Another)
zhunchong3++;
if(row-1>=0&& row+4<SIZE)//棋型4
if(m_cArr[row-1][col]==SPACE&& m_cArr[row+1][col]==SPACE && m_cArr[row+2][col]==cChessFlag
&&m_cArr[row+3][col]==cChessFlag && m_cArr[row+4][col]==Another)
zhunchong3++;
if(row-5>=0&& row<SIZE)//棋型5
if(m_cArr[row-1][col]==SPACE&& m_cArr[row-2][col]==cChessFlag &&m_cArr[row-3][col]==cChessFlag
&&m_cArr[row-4][col]==cChessFlag && m_cArr[row-5][col]==Another)
zhunchong4++;
if(row>=0&& row+5<SIZE)//棋型6
if(m_cArr[row+1][col]==SPACE&& m_cArr[row+2][col]==cChessFlag &&m_cArr[row+3][col]==cChessFlag
&&m_cArr[row+4][col]==cChessFlag && m_cArr[row+5][col]==Another)
zhunchong4++;
if(row-1>=0&& row+4<SIZE)//棋型7
if(m_cArr[row-1][col]==SPACE&& m_cArr[row+1][col]==cChessFlag && m_cArr[row+2][col]==SPACE
&&m_cArr[row+3][col]==cChessFlag && m_cArr[row+4][col]==SPACE)
zhunhuo3++;
if(row-4>=0&& row+1<SIZE)//棋型8
if(m_cArr[row-4][col]==SPACE&& m_cArr[row-3][col]==cChessFlag && m_cArr[row-2][col]==SPACE
&&m_cArr[row-1][col]==cChessFlag && m_cArr[row+1][col]==SPACE)
zhunhuo3++;
if(row-2>=0&& row+3<SIZE)//棋型9
if(m_cArr[row-2][col]==SPACE&& m_cArr[row-1][col]==cChessFlag && m_cArr[row+1][col]==SPACE
&&m_cArr[row+2][col]==cChessFlag && m_cArr[row+3][col]==SPACE)
zhunhuo3++;
if(row-3>=0&& row+2<SIZE)//棋型10
if(m_cArr[row-3][col]==SPACE&& m_cArr[row-2][col]==cChessFlag && m_cArr[row-1][col]==SPACE
&&m_cArr[row+1][col]==cChessFlag && m_cArr[row+2][col]==SPACE)
zhunhuo3++;
if(row-2>=0&& row+3<SIZE)//棋型11
if(m_cArr[row-2][col]==Another&& m_cArr[row-1][col]==cChessFlag &&m_cArr[row+1][col]==cChessFlag
&&m_cArr[row+2][col]==SPACE && m_cArr[row+3][col]==cChessFlag)
zhunchong4++;
if(row-3>=0&& row+2<SIZE)//棋型12
if(m_cArr[row-3][col]==cChessFlag&& m_cArr[row-2][col]==SPACE && m_cArr[row-1][col]==cChessFlag
&&m_cArr[row+1][col]==cChessFlag && m_cArr[row+2][col]==Another)
zhunchong4++;
if(row-3>=0&& row+2<SIZE)//棋型13
if(m_cArr[row-3][col]==Another&& m_cArr[row-2][col]==cChessFlag &&m_cArr[row-1][col]==cChessFlag
&&m_cArr[row+1][col]==SPACE && m_cArr[row+2][col]==cChessFlag)
zhunchong4++;
if(row-2>=0&& row+3<SIZE)//棋型14
if(m_cArr[row-2][col]==cChessFlag&& m_cArr[row-1][col]==SPACE && m_cArr[row+1][col]==cChessFlag
&&m_cArr[row+2][col]==cChessFlag && m_cArr[row+3][col]==Another)
zhunchong4++;
//'\'
if(row-4>=0&& row+1<SIZE && col-4>=0 && col+1<SIZE) //棋型1
if(m_cArr[row+1][col+1]==SPACE&& m_cArr[row-1][col-1]==SPACE &&m_cArr[row-2][col-2]==cChessFlag
&&m_cArr[row-3][col-3]==cChessFlag && m_cArr[row-4][col-4]==SPACE)
zhunhuo3++;
if(row-1>=0&& row+4<SIZE && col-1>=0 && col+4<SIZE)//棋型2
if(m_cArr[row-1][col-1]==SPACE&& m_cArr[row+1][col+1]==SPACE &&m_cArr[row+2][col+2]==cChessFlag
&&m_cArr[row+3][col+3]==cChessFlag && m_cArr[row+4][col+4]==SPACE)
zhunhuo3++;
if(row-4>=0&& row+1<SIZE && col-4>=0 && col+1<SIZE) //棋型3
if(m_cArr[row+1][col+1]==SPACE&& m_cArr[row-1][col-1]==SPACE &&m_cArr[row-2][col-2]==cChessFlag
&&m_cArr[row-3][col-3]==cChessFlag && m_cArr[row-4][col-4]==Another)
zhunchong3++;
if(row-1>=0&& row+4<SIZE && col-1>=0 && col+4<SIZE)//棋型4
if(m_cArr[row-1][col-1]==SPACE&& m_cArr[row+1][col+1]==SPACE &&m_cArr[row+2][col+2]==cChessFlag
&&m_cArr[row+3][col+3]==cChessFlag && m_cArr[row+4][col+4]==Another)
zhunchong3++;
if(row-5>=0&& row<SIZE && col-5>=0 && col<SIZE)//棋型5
if(m_cArr[row-1][col-1]==SPACE&& m_cArr[row-2][col-2]==cChessFlag &&m_cArr[row-3][col-3]==cChessFlag
&&m_cArr[row-4][col-4]==cChessFlag && m_cArr[row-5][col-5]==Another)
zhunchong4++;
if(row>=0&& row+5<SIZE && col>=0 && col+5<SIZE)//棋型6
if(m_cArr[row+1][col+1]==SPACE&& m_cArr[row+2][col+2]==cChessFlag &&m_cArr[row+3][col+3]==cChessFlag
&&m_cArr[row+4][col+4]==cChessFlag && m_cArr[row+5][col+5]==Another)
zhunchong4++;
if(row-1>=0&& row+4<SIZE && col-1>=0 && col+4<SIZE)//棋型7
if(m_cArr[row-1][col-1]==SPACE&& m_cArr[row+1][col+1]==cChessFlag &&m_cArr[row+2][col+2]==SPACE
&&m_cArr[row+3][col+3]==cChessFlag && m_cArr[row+4][col+4]==SPACE)
zhunhuo3++;
if(row-4>=0&& row+1<SIZE && col-4>=0 && col+1<SIZE)//棋型8
if(m_cArr[row-4][col-4]==SPACE&& m_cArr[row-3][col-3]==cChessFlag &&m_cArr[row-2][col-2]==SPACE
&&m_cArr[row-1][col-1]==cChessFlag && m_cArr[row+1][col+1]==SPACE)
zhunhuo3++;
if(row-2>=0&& row+3<SIZE && col-2>=0 && col+3<SIZE)//棋型9
if(m_cArr[row-2][col-2]==SPACE&& m_cArr[row-1][col-1]==cChessFlag &&m_cArr[row+1][col+1]==SPACE
&&m_cArr[row+2][col+2]==cChessFlag && m_cArr[row+3][col+3]==SPACE)
zhunhuo3++;
if(row-3>=0&& row+2<SIZE && col-3>=0 && col+2<SIZE)//棋型10
if(m_cArr[row-3][col-3]==SPACE&& m_cArr[row-2][col-2]==cChessFlag &&m_cArr[row-1][col-1]==SPACE
&&m_cArr[row+1][col+1]==cChessFlag && m_cArr[row+2][col+2]==SPACE)
zhunhuo3++;
if(row-2>=0&& row+3<SIZE && col-2>=0 && col+3<SIZE)//棋型11
if(m_cArr[row-2][col-2]==Another&& m_cArr[row-1][col-1]==cChessFlag &&m_cArr[row+1][col+1]==cChessFlag
&&m_cArr[row+2][col+2]==SPACE && m_cArr[row+3][col+3]==cChessFlag)
zhunchong4++;
if(row-3>=0&& row+2<SIZE && col-3>=0 && col+2<SIZE)//棋型12
if(m_cArr[row-3][col-3]==cChessFlag&& m_cArr[row-2][col-2]==SPACE &&m_cArr[row-1][col-1]==cChessFlag
&&m_cArr[row+1][col+1]==cChessFlag && m_cArr[row+2][col+2]==Another)
zhunchong4++;
if(row-3>=0&& row+2<SIZE && col-3>=0 && col+2<SIZE)//棋型13
if(m_cArr[row-3][col-3]==Another&& m_cArr[row-2][col-2]==cChessFlag &&m_cArr[row-1][col-1]==cChessFlag
&&m_cArr[row+1][col+1]==SPACE && m_cArr[row+2][col+2]==cChessFlag)
zhunchong4++;
if(row-2>=0&& row+3<SIZE && col-2>=0 && col+3<SIZE)//棋型14
if(m_cArr[row-2][col-2]==cChessFlag&& m_cArr[row-1][col-1]==SPACE &&m_cArr[row+1][col+1]==cChessFlag
&&m_cArr[row+2][col+2]==cChessFlag && m_cArr[row+3][col+3]==Another)
zhunchong4++;
//'/'
if(row-1>=0&& row+4<SIZE && col-4>=0 && col+1<SIZE) //棋型1
if(m_cArr[row-1][col+1]==SPACE&& m_cArr[row+1][col-1]==SPACE &&m_cArr[row+2][col-2]==cChessFlag
&&m_cArr[row+3][col-3]==cChessFlag && m_cArr[row+4][col-4]==SPACE)
zhunhuo3++;
if(row-4>=0&& row+1<SIZE && col-1>=0 && col+4<SIZE)//棋型2
if(m_cArr[row+1][col-1]==SPACE&& m_cArr[row-1][col+1]==SPACE &&m_cArr[row-2][col+2]==cChessFlag
&&m_cArr[row-3][col+3]==cChessFlag && m_cArr[row-4][col+4]==SPACE)
zhunhuo3++;
if(row-1>=0&& row+4<SIZE && col-4>=0 && col+1<SIZE) //棋型3
if(m_cArr[row-1][col+1]==SPACE&& m_cArr[row+1][col-1]==SPACE &&m_cArr[row+2][col-2]==cChessFlag
&&m_cArr[row+3][col-3]==cChessFlag && m_cArr[row+4][col-4]==Another)
zhunchong3++;
if(row-4>=0&& row+1<SIZE && col-1>=0 && col+4<SIZE)//棋型4
if(m_cArr[row+1][col-1]==SPACE&& m_cArr[row-1][col+1]==SPACE &&m_cArr[row-2][col+2]==cChessFlag
&&m_cArr[row-3][col+3]==cChessFlag && m_cArr[row-4][col+4]==Another)
zhunchong3++;
if(row>=0&& row+5<SIZE && col-5>=0 && col<SIZE)//棋型5
if(m_cArr[row+1][col-1]==SPACE&& m_cArr[row+2][col-2]==cChessFlag && m_cArr[row+3][col-3]==cChessFlag
&&m_cArr[row+4][col-4]==cChessFlag && m_cArr[row+5][col-5]==Another)
zhunchong4++;
if(row-5>=0&& row<SIZE && col>=0 && col+5<SIZE)//棋型6
if(m_cArr[row-1][col+1]==SPACE&& m_cArr[row-2][col+2]==cChessFlag && m_cArr[row-3][col+3]==cChessFlag
&&m_cArr[row-4][col+4]==cChessFlag && m_cArr[row-5][col+5]==Another)
zhunchong4++;
if(row-4>=0&& row+1<SIZE && col-1>=0 && col+4<SIZE)//棋型7
if(m_cArr[row+1][col-1]==SPACE&& m_cArr[row-1][col+1]==cChessFlag && m_cArr[row-2][col+2]==SPACE
&&m_cArr[row-3][col+3]==cChessFlag && m_cArr[row-4][col+4]==SPACE)
zhunhuo3++;
if(row-1>=0&& row+4<SIZE && col-4>=0 && col+1<SIZE)//棋型8
if(m_cArr[row-1][col+1]==SPACE&& m_cArr[row+1][col-1]==cChessFlag && m_cArr[row+2][col-2]==SPACE
&&m_cArr[row+3][col-3]==cChessFlag && m_cArr[row+4][col-4]==SPACE)
zhunhuo3++;
if(row-3>=0&& row+2<SIZE && col-2>=0 && col+3<SIZE)//棋型9
if(m_cArr[row-3][col+3]==SPACE&& m_cArr[row-2][col+2]==cChessFlag && m_cArr[row-1][col+1]==SPACE
&&m_cArr[row+1][col-1]==cChessFlag && m_cArr[row+2][col-2]==SPACE)
zhunhuo3++;
if(row-2>=0&& row+3<SIZE && col-3>=0 && col+2<SIZE)//棋型10
if(m_cArr[row-2][col+2]==SPACE&& m_cArr[row-1][col+1]==cChessFlag && m_cArr[row+1][col-1]==SPACE
&&m_cArr[row+2][col-2]==cChessFlag && m_cArr[row+3][col-3]==SPACE)
zhunhuo3++;
if(row-3>=0&& row+2<SIZE && col-2>=0 && col+3<SIZE)//棋型11
if(m_cArr[row-3][col+3]==cChessFlag&& m_cArr[row-2][col+2]==SPACE &&m_cArr[row-1][col+1]==cChessFlag
&&m_cArr[row+1][col-1]==cChessFlag && m_cArr[row+2][col-2]==Another)
zhunchong4++;
if(row-2>=0&& row+3<SIZE && col-3>=0 && col+2<SIZE)//棋型12
if(m_cArr[row-2][col+2]==Another&& m_cArr[row-1][col+1]==cChessFlag &&m_cArr[row+1][col-1]==cChessFlag
&&m_cArr[row+2][col-2]==SPACE && m_cArr[row+3][col-3]==cChessFlag)
zhunchong4++;
if(row-2>=0&& row+3<SIZE && col-3>=0 && col+2<SIZE)//棋型13
if(m_cArr[row-2][col+2]==cChessFlag&& m_cArr[row-1][col+1]==SPACE &&m_cArr[row+1][col-1]==cChessFlag
&&m_cArr[row+2][col-2]==cChessFlag && m_cArr[row+3][col-3]==Another)
zhunchong4++;
if(row-3>=0&& row+2<SIZE && col-2>=0 && col+3<SIZE)//棋型14
if(m_cArr[row-3][col+3]==Another&& m_cArr[row-2][col+2]==cChessFlag &&m_cArr[row-1][col+1]==cChessFlag
&&m_cArr[row+1][col-1]==SPACE && m_cArr[row+2][col-2]==cChessFlag)
zhunchong4++;
/
temp=PracticalScore(num,border,cChessFlag);
max+=temp;
if(max>state[row][col])
state[row][col]=max;
}
//下面是实际的评分函数,并统计基本棋型
int CFiveChess::PracticalScore(intnum[],int border[][2],char cChessFlag)
{
inti;
for(i=0;i<4;i++)
{
if(num[i]>=4)//成5
{
cheng5++;break;//只需一个成5就行
}
if(num[i]==3&& border[i][0]==0 && border[i][1]==0)
{
huo4++;break;
}
elseif(num[i]==3 && (border[i][0]&&border[i][1])==0 )
chong4++;
if(num[i]==2&& border[i][0]==0 && border[i][1]==0)
huo3++;
elseif(num[i]==2 && (border[i][0]&&border[i][1])==0)
chong3++;
if(num[i]==1&& border[i][0]==0 && border[i][1]==0)
huo2++;
elseif(num[i]==1 && (border[i][0]&&border[i][1])==0)
chong2++;
if(num[i]==0&& border[i][0]==0 && border[i][1]==0)
huo1++;
elseif(num[i]==0 && (border[i][0]&&border[i][1])==0)
chong1++;
}
//计算机和人的棋局评分标准不同,应该偏向计算机,例如,计算机和人同时都可以成5的时候,应该保证执行计算机成5,
//为了防止玩家赢了一盘后再根据原有的棋路走棋必赢,所以对于分值较小的的棋型采用随机化处理其分值
//共3个等级,最高一个等级强调防守(和前两个等级只改变一点点,尽管胜率差不多,但下起来精彩一些,呵呵,切忌,防守不能过度,过犹不及啊)
intmax=1; //若为0则会产生bug,下到只有几个空格时,这些空格的分值有可能都为0,以致计算机在重复的点落子,所以将空格的价值设为1较好
if(cChessFlag==CHESS_COMPUTER)//计算机
{
if(cheng5>0)
max+=5000000;
if(huo4>0)
max+=200000;
if(huo3>0&& chong4>0)
max+=200000;
if(huo3>0&& zhunchong4>0)
max+=200000;
if(zhunhuo3>0&& zhunchong4>0)
max+=200000;
if(chong4>1)
max+=200000;
if(zhunchong4>1)
max+=200000;
if(huo3>1)
max+=8000;
if(zhunhuo3>1)
max+=8000;
if(huo3>0&& zhunhuo3>0)
max+=8000;
if(chong4>0)
max+=505;
if(zhunchong4>0&& m_nGrade==3)//
max+=507;
elseif(zhunchong4>0)
max+=503;
if(huo3>0)
max+=500;
if(zhunhuo3>0)
max+=495;
if(huo2>1)
max+=200;
if(huo2>0&& chong3>0)
max+=120;
if(chong3>1)
max+=70;
if(zhunchong3>1)
max+=70;
if(huo2>0)
max+=(22+rand()%5);
if(chong3>0)
max+=(20+rand()%5);
if(zhunchong3>0)
max+=(17+rand()%5);
if(chong2>1)
max+=(15+rand()%5);
if(chong2>0)
max+=(9+rand()%5);
if(chong1>0)
max+=3;
}
else//人
{
if(cheng5>0)
max+=1000000;
if(huo4>0)
max+=40000;
if(huo3>0&& chong4>0)
max+=40000;
if(huo3>0&& zhunchong4>0)
max+=40000;
if(zhunhuo3>0&& zhunchong4>0)
max+=40000;
if(chong4>1)
max+=40000;
if(zhunchong4>1)
max+=40000;
if(huo3>1)
max+=1900;
if(zhunhuo3>1)
max+=1900;
if(huo3>0&& zhunhuo3>0)
max+=1900;
if(huo3>0&& m_nGrade==3)//
max+=500;
elseif(huo3>0)
max+=450;
if(zhunhuo3>0&& m_nGrade==3)//
max+=495;
elseif(zhunhuo3>0)
max+=445;
if(chong4>0)
max+=350;
if(zhunchong4>0&& m_nGrade==3)//
max+=352;
elseif(zhunchong4>0)
max+=349;
if(huo2>1)
max+=150;
if(huo2>0 && chong3>0)
max+=110;
if(chong3>1&& m_nGrade==3)//
max+=70;
elseif(chong3>1)
max+=60;
if(zhunchong3>1)
max+=60;
if(huo2>0)
max+=(16+rand()%5);
if(chong3>0)
max+=(15+rand()%5);
if(zhunchong3>0)
max+=(12+rand()%5);
if(chong2>1)
max+=(10+rand()%5);
if(chong2>0)
max+=(8+rand()%5);
if(chong1>0)
max+=2;
}
returnmax;
}
//上面的分值分配一般是前面大的1/4略小,为什么要这样设置呢?那是因为下棋的最佳策略是:即使这点可构成4个活三(最多4个),也不如另一点可构成1个活4强,因为构成活4后只需一步就可赢棋,构成4个活三的话还需要两步才能赢,万一下这两步的过程中由于某些原因而让对手赢了呢,每下一步棋势都是会发生变化的。其他的类推……
看完上面的文字之后,或许你已经有了基本的思路了,现在你可以自己尝试去写了,如果要参考,下面是代码的下载地址。
五子棋(人人和人机对弈):http://download.csdn.net/detail/aihahaheihei/4076078
另外附上几个完全原创的代码
俄罗斯方块:http://download.csdn.net/detail/aihahaheihei/4076057
计算器(计算表达式的):http://download.csdn.net/detail/aihahaheihei/4076071
贪吃蛇:http://download.csdn.net/detail/aihahaheihei/4076048
上面的程序都是基于MFC的。
请记住,学会与人分享自己的资源……
本着学习的精神,基本的已经说完了。
弱弱的再吱一声:如果你做的五子棋几盘就被别人下赢了,你的面子往何处放?哥实在不能这样,好歹还得再泡MM的,所以我就给五子棋的添加了个递归深搜并模拟玩家下棋(也可通过递归实现,当然得剪枝,否则电脑承受不了这么大的运算量),固然棋力强大了很多,相信大家都会dfs深度递归搜索,代码我就不上传了。其实还可以利用多线程技术来更深度的递归搜索,只是很复杂,本人能力有限,不扯了。
以上仅献给已逝去的青春。