赞
踩
我查找了大量的网上资料,结合自己编程实践,走了很多弯路,总结了一些关于五子棋ai的经验以供大家参考借鉴。
对于五子棋ai,大部分人想到的是做一个评估函数。这里的评估函数网上大概有两种,但是很多人会弄混淆。
第一种我称为K函数(只是一个代号,与第二种相区别),是对一个可走的空位子进行打分,如果ai白子落在这个空位置的分数越高,说明这个位置就越好,每次ai走棋就找到一个最好的空位置就行了。
第二种我称为F函数,是对现在的棋盘局面进行打分。 ai白子首先找所有可以走的空位置,模拟走了这个位置以后,用f函数进行局面评分,如果走了这样的一个空位置的得分越高,说明这个位置就越好,每次ai走棋就找这样一个分数最高的位置。
那么你可能就要问了,这两个评估函数有什么区别呢?区别非常大!如果你只是想实现一个只看一步的ai,那么你可以用K函数也可以用F函数。但是如果你想要实现基于博弈树的极大极小搜索和α-β剪枝算法的“聪明”ai,就只能用F函数,因为博弈树必须要对局面打分,而不是对位置打分。如果你明白了这一点,那么接下来就好办了。
怎么对局势有一个比较准确的估计呢?我查阅了大量资料。五子棋的局势无非就是对棋型个数和权重的统计。(对某一方而言的)
我分为8种:
1.连5或者长连
2.活4(有两个位置可以形成连5)
3.冲4(有一个位置可以形成连5)
还有其他情况,比如边界,总之再下一步(只能是1步而不是2步)就能连5的就是冲4。
4.活3(走一步可以形成活4)
5.眠3(走一步可以形成冲4)
6.活2(走一步可以形成活3):形状自行脑补
7.眠2(走一步可以形成眠3)
8.活1(走一步可以形成活2)
我用六元组(一条直线上连续六个位置的状态)来表示棋型,通过检查棋盘上所有六元组来得分。最容易漏掉的地方是边界,比如如果一个斜线只有5个位置也有可能连5、但六元组没考虑进来等等问题,办法是用一个更大的、包括了边界的数组保存棋盘和边界信息。
用一个棋型辨识数组保存所有棋型。
#define C_NONE 0//棋子:黑子,白子,无子 #define C_BLACK 1 #define C_WHITE 2 //棋型代号 下标 权重 #define OTHER 0//0,其他棋型不考虑 #define WIN 1//100000,白赢 #define LOSE 2//-10000000 #define FLEX4 3//50000,白活4 #define flex4 4//-80000 #define BLOCK4 5//400 #define block4 6//-80000 #define FLEX3 7//400 #define flex3 8//-8000 #define BLOCK3 9//20 #define block3 10//-40 #define FLEX2 11//20 #define flex2 12//-40 #define BLOCK2 13//1 #define block2 14//-2 #define FLEX1 15//1 #define flex1 16//-2 int tuple6type[4][4][4][4][4][4];//棋型辨识数组,0无子,1黑子,2白子,3边界
需要对这个数组进行初始化。
void chessAi::init_tuple6type(){ memset(tuple6type,0,sizeof (tuple6type));//全部设为0 //白连5,ai赢 tuple6type[2][2][2][2][2][2]=WIN; tuple6type[2][2][2][2][2][0]=WIN; tuple6type[0][2][2][2][2][2]=WIN; tuple6type[2][2][2][2][2][1]=WIN; tuple6type[1][2][2][2][2][2]=WIN; tuple6type[3][2][2][2][2][2]=WIN;//边界考虑 tuple6type[2][2][2][2][2][3]=WIN; //黑连5,ai输 tuple6type[1][1][1][1][1][1]=LOSE; tuple6type[1][1][1][1][1][0]=LOSE; tuple6type[0][1][1][1][1][1]=LOSE; tuple6type[1][1][1][1][1][2]=LOSE; tuple6type[2][1][1][1][1][1]=LOSE; tuple6type[3][1][1][1][1][1]=LOSE; tuple6type[1][1][1][1][1][3]=LOSE; //白活4 tuple6type[0][2][2][2][2][0]=FLEX4; //黑活4 tuple6type[0][1][1][1][1][0]=flex4; //白活3 tuple6type[0][2][2][2][0][0]=FLEX3; tuple6type[0][0][2][2][2][0]=FLEX3; tuple6type[0][2][0][2][2][0]=FLEX3; tuple6type[0][2][2][0][2][0]=FLEX3; //黑活3 tuple6type[0][1][1][1][0][0]=flex3; tuple6type[0][0][1][1][1][0]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。