五子棋是所有棋类博弈中比较简单的了,这里介绍的也只是一种非常基本的AI策略。其实,包括之前的AI贪吃蛇,感觉这两个AI其实体现的都是一种建模思想,把一个现实中的问题模型化,抽象化,得到其一般特征,再设计数据结构及算法。
首先,要意识到一件事情,我们可以用一个三维数组记录所有的获胜局势,比如
再如:
这种获胜局势是有限可数的,所以,AI的关键一步就是得到这个三维数组:
1 //统计所有可能的赢法,需要好好理解
2 for (var i = 0; i < 15; i++){
3 for (var j = 0; j < 11; j++){
4 for (var k = 0; k < 5; k++){
5 wins[i][j+k][count] = true;
6 }
7 count++;
8 }
9 }
10 for (var i = 0; i < 11; i++){
11 for (var j = 0; j < 15; j++){
12 for (var k = 0; k < 5; k++){
13 wins[i+k][j][count] = true;
14 }
15 count++;
16 }
17 }
18 for (var i = 0; i < 11; i++){
19 for (var j = 0; j < 11; j++){
20 for (var k = 0; k < 5; k++){
21 wins[i+k][j+k][count] = true;
22 }
23 count++;
24 }
25 }
26 for (var i = 0; i < 11; i++){
27 for (var j = 14; j > 3; j--){
28 for (var k = 0; k < 5; k++){
29 wins[i+k][j-k][count] = true;
30 }
31 count++;
32 }
33 }
34 //共 572 赢法
现在,关键是如何利用这个三维数组,其实很多机器博弈其实就是在打分,再把棋子下到分高(或分低)的地方,比如以下红色位置,如果没有棋子,应该 给一个较高分,因为在下一个白棋子就赢了,但是如果下了一个黑棋子,那么,上面的第一种赢法无论如何也不可能了,所以直接设置为零分。所以在设置两个一位数组,记录每种赢法的得分,再查找棋盘上哪些位置可以实现这种赢法,给这些位置加分,最后从所有位置中,找出分最高的落子即可。而且,一种赢法上的落子越多,就越接近获胜,所以分数应该越高。
1 for (var i = 0; i < 15; i++){
2 for (var j = 0; j < 15; j++){
3 if (0 == chessBoard[i][j]){//no chessman
4 for (var k = 0; k <count; k++){
5 if (wins[i][j][k]){
6 if (1 == myWin[k]){
7 myScore[i][j] += 200;
8 } else if (2 == myWin[k]){
9 myScore[i][j] += 400;
10 } else if (3 == myWin[k]){
11 myScore[i][j] += 2000;
12 } else if (4 == myWin[k]){
13 myScore[i][j] += 10000;
14 }
15 if (1 == computerWin[k]){
16 computerScore[i][j] += 320;
17 } else if (2 == computerWin[k]){
18 computerScore[i][j] += 420;
19 } else if (3 == computerWin[k]){
20 computerScore[i][j] += 4200;
21 } else if (4 == computerWin[k]){
22 computerScore[i][j] += 20000;
23 }
24 }
25 }
26 if (myScore[i][j] > max){
27 max = myScore[i][j];
28 u = i;
29 v = j;
30 } else if (myScore[i][j] == max){
31 if (computerScore[i][j] > computerScore[u][v]){
32 u = i;
33 v = j;
34 }
35 }
36 if (computerScore [i][j] > max){
37 max = computerScore[i][j];
38 u = i;
39 v = j;
40 } else if (computerScore[i][j] == max){
41 if (myScore[i][j] > myScore[u][v]){
42 u = i;
43 v = j;
44 }
45 }
46 }
47 }
最后,只需要统计每落子一次是否有一方赢了即可,这里谈及了AI核心思想,其他部分比如判断胜负,交替落子等逻辑可以找到很多学习资料。
总结,AI看似高大上,但是其实际是对实际问题的高度抽象、模型化以及大量计算(正是计算机的优势)。如果能缜密地设计好编码思路,那么效率就会很高,比如昨天写的贪吃蛇,很多情况没想到,所以总是陷入困境,当代码量增加,逻辑结构变的复杂时,一定要事先规划,或者说,设计模式。自己要突破目前的瓶颈期可能要学习一下这方面的东西了!!!
此外,还利用Hbuilder生成了APP,首先是自己这么想了,然后还真找到办法实现了,所以创意,眼界,技术,同样重要。
完整代码点这里
小记。