算法过程如下,输入计算棋气的起始子,检查我方棋子其周边的空白,并查看此空白是否已经计算过气了,如果没有计算过气加一,如果已经计算则略过,进而递归调用计算我方棋子上下左右子的气,最后算法会返回棋串的子数和气数。算法注释十分详尽。
这个计算棋子气的算法,参考,结合我们自身的应用需要优化和修改。这篇博文介绍了更多关于围棋的算法,有兴趣的朋友可以进一步阅读。
原文suanqi函数会重复计算已经计算过的棋串效率不高,应该对已经算过气的函数不在重复算气,并且我们需要知道棋串的长度。
1 #include <iostream>
2 #include <utility>
3
4 #define EDGE 19
5 int go[EDGE][EDGE];//棋盘数据,0为黑棋,1为白棋,2为空白
6 int gokong[EDGE][EDGE]; //0=该空点未曾计算过气,1=已计算,避免重复计算公气
7 int gozi[EDGE][EDGE]; //0=该子未计算串气,1=已计算,避免重复计算同一个子的气
8 int goqi; //此棋串气数
9 int goziLength;//此棋串子数
10 int g_gozi[EDGE][EDGE];
11
12 void str_qi(int x,int y,int hb)
13 {
14 //本函数计算 x,y 处的hb颜色棋子的气
15 gozi[x][y]=1; //标记本子已经计算过气
16 goziLength++;
17 /////右临子
18 if (x+1<=19)//如果没有超出棋盘边线
19 {
20 if ((go[x+1][y]==2)&&(gokong[x+1][y]==0))
21 //如果右临点为空并且该点未曾计算过气则
22 {
23 goqi++; //气数加一
24 gokong[x+1][y]=1; //标记本空点已经计算过气
25 }
26 else if ((go[x+1][y]==hb)&&(gozi[x+1][y]==0))
27 //否则如果右临点为和本子同色子并且该子未曾计算过气则
28 str_qi(x+1,y,hb); //递归调用到右临子
29 }
30 /////左临子
31 if (x-1>=1) //果没有超出棋盘边线
32 {
33 if ((go[x-1][y]==2)&&(gokong[x-1][y]==0))
34 //如果左临点为空并且该点未曾计算过气则
35 {
36 goqi++; //气数加一
37 gokong[x-1][y]=1; //标记本空点已经计算过气
38 }
39 else if ((go[x-1][y]==hb)&&(gozi[x-1][y]==0))
40 //否则如果左临点为和本子同色子并且该子未曾计算过气则
41 str_qi(x-1,y,hb); //递归调用到左临子
42 }
43 ////下临子
44 if (y-1>=1)//如果没有超出棋盘边线
45 {
46 if ((go[x][y-1]==2)&&(gokong[x][y-1]==0))
47 //如果下临点为空并且该点未曾计算过气则
48 {
49 goqi++; //气数加一
50 gokong[x][y-1]=1; //标记本空点已经计算过气
51 }
52 else if ((go[x][y-1]==hb)&&(gozi[x][y-1]==0))
53 //否则如果下临子点为和本子同色子并且该子未曾计算过气则
54 str_qi(x,y-1,hb); //递归调用到下临子
55 }
56 ////上临点
57 if (y+1<=19)//如果没有超出棋盘边线
58 {
59 if ((go[x][y+1]==2)&&(gokong[x][y+1]==0))
60 //如果上临点为空并且该点未曾计算过气则
61 {
62 goqi++; //气数加一
63 gokong[x][y+1]=1; //标记本空点已经计算过气
64 }
65 else if ((go[x][y+1]==hb)&&(gozi[x][y+1]==0))
66 //否则如果上临点为和本子同色子并且该子未曾计算过气则
67 str_qi(x,y+1,hb); //递归调用到上临子
68 }
69 }
70
71 std::pair<int,int> str_lib(int x,int y, int hb)
72 {
73
74 for (int i = 1; i <= 19; i++)
75 for (int j = 1; j <= 19; j++)
76 {
77 gozi[i][j] = 0; //初始化变量,表示该子未计算串气
78 gokong[i][j] = 0; //初始化变量,表示该空点未计算串气
79 }
80 goqi=0; //棋串气初值
81 goziLength=0;//棋串初始子数
82 str_qi(x,y,hb); //调用串气子程序
83 for(int i=0;i<EDGE;i++)
84 for(int j=0;j<EDGE;j++){
85 if(gozi[i][j]==1)
86 g_gozi[i][j]=1;
87 }
88 return std::make_pair<int,int>(goqi,goziLength);
89 }
90
91 void suanqi()
92 {
93 int qq;
94 for (int i = 0; i <EDGE; i++)
95 for (int j = 0; j <EDGE; j++)
96 {
97 go[i][j]=qipan[i][j].color;//初始化go数组
98 }
99 for (int i = 0; i <EDGE; i++)
100 for (int j = 0; j <EDGE; j++)
101 {
102 if (go[i][j]!=2&&g_gozi[i][j]==0)//仅处理未计算过的棋串
103 {
104
105 qq=str_lib(i,j,go[i][j]).first;
106 qipan[i][j].qs=qq;
107 }
108 }
109 }