作者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