五子棋游戏C语言AI智能算法设计
近来发现编制五子棋游戏很有趣,尤其是AI智能算法很烧脑。网上介绍有什么贪心算法,剪枝算法,博弈树算法等等,不一而足。
对于人机对战的电脑智能应子算法,参阅很多五子棋书籍棋谱和五子棋竞赛的对抗棋谱。我感到白棋的后手防御算法很难取胜,棋界有黑棋高手先手必胜一说。算法么想了很多,既然是人工智能下棋就得按人的思路来算计。棋书阐述有许多思路和棋局解说。如活四冲四,嵌五,活三嵌四,活二嵌二。这些是高级棋手的总结。我就按此思路用加权计权方法来表现此类各种情况。
下面程序代码写出了基本算法。代码是function testAIq ( )。
另外代码中有一算法测试的方法autotest( ) 可供参考。
此测试黑白双方用同一算法互斗难分胜负,这就像周伯通双手互搏,难分高下。想来要另写白棋防守算法,设置白棋VS黑棋才可看出哪个算法好。我的思路是博弈双方的白棋后手防守点也就是黑棋的加权高分点,白棋加权高分点就是进攻点。我就以计算的高分点为AI下子点。
还有一种说法五子棋博弈要算杀,算杀就是计算必杀之局,如嵌四加活三,冲四加活三,嵌五加活三,嵌五加冲四,这些就是必杀局,就是必胜法宝。算杀的最高境界是做杀,预判算出必杀点提前几子做出必杀局。此谓奕道高手中的高手,乃高高手也。此种算法也就是编程界的高手,是谓大咖也。我望之有些高仰,自感境界还没到。锲而不舍,持之以恒,努力吧。
为了摆谱,就在游戏程序上添加了复盘功能。程序没退出就能复现出上一次的盘面。另外还加了记录功能和显示下子序号,每盘棋都打印黑白双方下子记录,界面上也显示记录。有一点就是程序退出记录也就没了。解决的方法是把记录存为文本文件,需要时可作为复盘数据。也可以采用截屏方法保存棋局图片,以便以后复盘研究。
完整的源码可参阅我在本站的博文《五子棋游戏程序禁手设置算法》。
此博文是有禁手设置算法的完整的游戏程序源码。
还有精彩的AI对战演示功能设计autotest( ){ } 用于测试算法。
//**************************************
//**** 五子棋 Gobang AI
//**** 人机对战 AI 设计
//**************************************
Canvas cs; //画布
int dx,dy; //draw X, Y
int i,j,t,a; //t = times
int pn[225]; // pn 0=" " , 1=black , 2=white
int n; // 225 棋子编码号
int px,py; // piece x,y
int dn,dn1 ; //下子计数
int isDo; //游戏操作控制 1=可下子,0=不可下
int B,W,k; //detect win Black White
string cordp,cordp1; //record pn & G9
int cord; //record switch
int mode; //0=人人,1=人机
int wn;
int sn;
int dwn[120]; //记录,下子60回合120子为和棋
int col,row ;
int cn,kn; //show record num
int gn ; //game round number
int fudat[200]; //复盘数据
int fusum; //复盘记录总数
int sd; //复盘
int jqn[255]; //计权数
int jqf,jqfn ; //计权分,优选点位码
int js[255]; //禁手设置
int jsset ; //s8 show restrict mark
//**********
//AI智能下子算法求解方案:
//(一) 四连情况,黑棋下子,黑冲四嵌五,白必应子,若白无活四 022220 冲四 22220 02222 和嵌五 22022 22202 20222 则必应,有则先着取胜
//(二) 三连情况,黑棋下子,黑成活三嵌四,
// 若白无活三 02220 嵌四 2022 2202 则必应,
// 有则先着下子成活四
//(三) 二连情况,黑棋下子,
// 有活二 01100 嵌三 01010 基本都是这样,
// 二连应子:抢先手原则,白棋先找自己的活二嵌三
// 先下子成活三嵌四
//(四) 开局应首子,定标黑子 pn113,白应首子
// 大多棋 谱是 应上 pn98,上右 pn99,暂定此
// 白应起首三子:按棋谱法
//黑白双方博弈,加权计分,黑攻方进攻点就是白守方
//防守点。计分累加标记此点,乃此算法要点。
//将下面 testAIq ()算法分二部分,来测试一下
autotest (){
//用于检测AI智能下子算法 testAIq ()
//黑白棋用同一个算法下子很难区分算法的优劣,
//要设计二种算法分别以黑棋VS白棋才能显示出
//算法的优劣。下面代码只可检测算法的可行性。
s7="游戏模式:对战演示";
if (isDo==0||dn>120) return ; //结束标志,测试120子
if (mode==1) return ; //双人模式可演示
wn=wn+1 ;
if (dn==0) { //设定首子黑先天元位
n=113; black_do () ;
n=82 ; wn=0 ; //变换n 加以检测
white_do () ;
cs.Update () ; }
testAIq () ; //智能计权取得下子点位
if (wn>1) wn=0 ; //轮流下子
if (wn==1) white_do () ; //白棋下子
if (wn==0) black_do () ; //黑棋下子
detect () ;
}//autotest ()
testAIq (){
//人机对战AI选子,加权计算
for (i=1;i