作者DreamYeh (天使)
看板FCK-GARDEN
标题[星月] PTT 五子棋程式解析(二)
时间Wed Apr 2 21:54:53 2008
=============================
对於这个大专案,要怎麽去做解析,光是看到一大堆程式码,
当然是会有所却步的。
但是身为棋国一份子,总是要有一个够逻辑的解决办法,我们
最後目的是要提供自己专业知识,协助站长做出良好的以禁解禁程
式判断的。
我们似乎不需要很了解这个程式是怎麽运作的,但了解整个程
式运作原理,我们的确可以加入一些我们知道的五子棋棋规在这个
程式里面。
比方说,增加
国际规则RIF。不过这的确扯远了,我们这边
仅试图去解析出,禁点判断规则而已。
因此,我们就从程式的结束点开始解析吧!
即使不是程式设计者,我相信参透这个过程也是相当快乐的!
希望也能带一些了解五子棋规则,但对程式不了解的朋友进行了解
。
让我们看看如何去解析程式终点,我们很快注意到这个变数
style,他定义如下:
/* 例外=F 错误=E 有子=D 连五=C 连六=B 双四=A 四四=9 三三=8 */
/* 四三=7 活四=6 断四=5 死四=4 活三=3 断三=2 保留=1 无效=0 */
棋国人开始兴奋了,这个是我们都很了解的东西,现在透过
了解这个变数,就可以知道程式运作基本原理。
我们很快注意到这个副函式-
ChessGameResult
chkwin(int style, int limit)
{
if (style == 0x0c)
return CHESS_RESULT_WIN;
else if (limit == 0) {
if (style == 0x0b)
return CHESS_RESULT_WIN;
return CHESS_RESULT_CONTINUE;
}
if ((style < 0x0c) && (style > 0x07))
return CHESS_RESULT_LOST;
return CHESS_RESULT_CONTINUE;
}
这里显然是程式判断胜负准位地方,我们很快注意到limit这个变数
当style=0b (长连) 时候,如果这变数为0,判定为胜,否则继续
我们可以简单知道
limit代表是否有禁点的规则
从後面
if ((style < 0x0c) && (style > 0x07)) return CHESS_RESULT_CONTINUE;
更是可以这样判断出来 因为这几个style都是黑禁情况(三三四四长连)
那这样一来style这变数就很重要了
他是怎麽来的呢? 让我们看看
这边我加上简单注解
static int
getstyle(board_t ku, int x, int y, int color, int limit)
{
int i, j, dir[4], style;
if ((x < 0) || (x >= BRDSIZ) || (y < 0) || (y >= BRDSIZ))
int i, j, dir[4], style;
if ((x < 0) || (x >= BRDSIZ) || (y < 0) || (y >= BRDSIZ))
return 0x0f;
//边界判断
if (ku[x][y] != BBLANK)
return 0x0d;
//空点判断
// (-1,1), (0,1), (1,0), (1,1)
for (i = 0; i < 4; i++)
//四个方向
dir[i] = dirchk(ku, x, y, color, limit, i ? (i >> 1) : -1, i ? (i &
qsort(dir, 4, sizeof(int), (QCAST)intrevcmp);
//做简单排序
if ((style = dir[0]) >= 2) {
for (i = 1, j = 6 + (limit ? 1 : 0); i < 4; i++) {
if ((style > j) || (dir[i] < 2))
break;
if (dir[i] > 3)
style = 9;
//四四
else if ((style < 7) && (style > 3))
style = 7;
//四三
else
style = 8;
//三三
}
}
return style;
}
这边逻辑很简单,就是下某个子之後,就以这颗子为主,
去判断他四个方位(直线横线以及两条斜线) 去看看他们有几个三、四
这样我们可以得到四个方位分别有几个三几个四
比方说,假设我下出四三,那dir就会={4,3,0,0}
假设我下出四四 dir={4,4,0,0}
排序用意在於,抓出最多连子的线,将之排在前面,这样我们仅要针对连子
最多线去分析即可。
这边不做连五判断,我们可以知道这个函式最後返回的就是
是否已经走出三三、四四的情况
当然如果走出这些情况,ptt系统就会秀字出来
这些经过长期验证,是没有问题的。
--
对解析本程式有兴趣朋友,欢迎来信敝人信箱。
--
— 请多指教喔!!
/\●/\ ))
(( / /▲\ \
\\
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 118.169.79.199
1F:推 thomaski:赶快推避免别人说我们笨... 59.115.185.42 04/02 22:36
2F:推 seabat:所以这个程式不能判断以禁解禁的部份 123.195.22.53 04/02 22:59
3F:→ seabat:最根本的方法就是从判断是不是活三开始改起 123.195.22.53 04/02 22:59
4F:推 musicring:最根本的办法就是黑21以後所有禁手解除140.117.160.148 04/02 23:20
5F:→ musicring:不然黑棋到後期还要因为前期太威所做的140.117.160.148 04/02 23:21
6F:→ musicring:禁手限制绊脚 这样似乎不太公平140.117.160.148 04/02 23:22
7F:推 minolala:好辛苦;) 218.168.179.89 04/03 00:31