?? 解剖大象的眼睛——中國象棋程序設計探索(十):實用程序片段.htm
字號:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0055)http://www.elephantbase.net/computer/eleeye_utility.htm -->
<HTML><HEAD><TITLE>解剖大象的眼睛——中國象棋程序設計探索(十):實用程序片段</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb_2312-80">
<META content="MSHTML 6.00.3790.536" name=GENERATOR></HEAD>
<BODY background=解剖大象的眼睛——中國象棋程序設計探索(十):實用程序片段_files/background.gif>
<DL>
<DIV align=center>
<CENTER>
<DT><FONT face=隸書 size=6>解剖大象的眼睛</FONT><FONT
size=6><STRONG>——</STRONG></FONT><FONT face=隸書 size=6>中國象棋程序設計探索</FONT>
</CENTER></DT></DIV>
<DIV align=center>
<CENTER>
<DT> </CENTER></DT></DIV>
<DIV align=center>
<CENTER>
<DT>黃晨 <FONT face="Times New Roman">*</FONT> <FONT
face="Times New Roman">2005</FONT>年<FONT
face="Times New Roman">11</FONT>月初稿,<FONT
face="Times New Roman">2006</FONT>年<FONT face="Times New Roman">1</FONT>月修訂
</CENTER></DT></DIV>
<DIV align=center>
<CENTER>
<DT><FONT face="Times New Roman">( * </FONT>聯系地址:復旦大學化學系表面化學實驗室,<FONT
face="Times New Roman">eMail</FONT>:<A
href="mailto:webmaster@elephantbase.net"><FONT
face="Times New Roman">webmaster@elephantbase.net</FONT></A><FONT
face="Times New Roman">)</FONT> </CENTER></DT></DIV>
<DT>
<DT><FONT face=Arial size=5><STRONG>(</STRONG></FONT><FONT face=楷體_GB2312
size=5><STRONG>十</STRONG></FONT><FONT face=Arial size=5><STRONG>)
</STRONG></FONT><FONT face=楷體_GB2312 size=5><STRONG>實用程序片段</STRONG></FONT>
<DT>
<DT> <FONT face="Times New Roman">ElephantEye</FONT>的源程序包里有個<FONT
face="Times New Roman"><utility></FONT>目錄,其中包含了很多實用程序片段,不僅僅是針對象棋程序的。由于程序片段中沒有中文注釋,所以這里作一下簡要的介紹。
<DT>
<DT><FONT face=Arial size=4><STRONG>10.1 Visual Basic</STRONG></FONT><FONT
face=楷體_GB2312 size=4><STRONG>下的原子語句</STRONG></FONT><FONT face=Arial
size=4><STRONG>(atom.cpp/atom.bas)</STRONG></FONT>
<DT>
<DT> <FONT face="Times New Roman">ElephantEye</FONT>的部分代碼可編譯成<FONT
face="Times New Roman">CCHESS.DLL</FONT>,成為界面程序<FONT
face="Times New Roman">ElephantBoard</FONT>的一部分。然而由于<FONT
face="Times New Roman">Visual Basic</FONT>處理數據結構的能力很弱,調用<FONT
face="Times New Roman">CCHESS.DLL</FONT>時需要調用一些低級語句<FONT
face="Times New Roman">(</FONT>例如<FONT
face="Times New Roman">QuickBasic</FONT>的<FONT
face="Times New Roman">VARPTR</FONT>、<FONT
face="Times New Roman">MKI</FONT>、<FONT
face="Times New Roman">CVI</FONT>等在<FONT face="Times New Roman">Visual
Basic</FONT>中已經淘汰的語句<FONT face="Times New Roman">)</FONT>,為此<FONT
face="Times New Roman">ElephantEye</FONT>提供了這些原子,以保證數據結構使用的便利。
<DT> 在<FONT face="Times New Roman">Visual Basic</FONT>調用<FONT
face="Times New Roman">API</FONT>函數的參數傳遞過程中,注意事項有:
<DT> <FONT face="Times New Roman">(1) </FONT>指針型變量用<FONT
face="Times New Roman">ByRef</FONT>聲明,自定義結構只能用<FONT
face="Times New Roman">ByRef(</FONT>引用方式<FONT
face="Times New Roman">)</FONT>傳遞參數;
<DT> <FONT face="Times New Roman">(2) </FONT>如果自定義結構用<FONT
face="Times New Roman">ByVal(</FONT>傳值方式<FONT
face="Times New Roman">)</FONT>傳遞參數,則必須把它們轉化為<FONT
face="Times New Roman">Visual Basic</FONT>的內部類型;
<DT> <FONT face="Times New Roman">(3) Visual Basic</FONT>的字符串類型<FONT
face="Times New Roman">(Windows</FONT>內部類型是<FONT
face="Times New Roman">BSTR)</FONT>必須用<FONT
face="Times New Roman">ByVal</FONT>傳遞參數,<FONT face="Times New Roman">Visual
Basic</FONT>會自動將其轉化為<FONT face="Times New Roman">LPCSTR</FONT>類型;
<DT> <FONT face="Times New Roman">(4) API</FONT>函數返回<FONT
face="Times New Roman">LPCSTR</FONT>類型時,在<FONT face="Times New Roman">Visual
Basic</FONT>下必須假定為<FONT face="Times New Roman">Long</FONT>類型。
<DT> 我們最感興趣的是最后一條,<FONT face="Times New Roman">LPCSTR</FONT>類型的字符串由<FONT
face="Times New Roman"><atom.bas></FONT>中的<FONT
face="Times New Roman">MkBStr</FONT>函數轉換為<FONT face="Times New Roman">Visual
Basic</FONT>的字符串類型<FONT face="Times New Roman">(BSTR)</FONT>。例如在<FONT
face="Times New Roman">Visual Basic</FONT>下調用開局編號分析器<FONT
face="Times New Roman">ECCO.DLL</FONT>,調用方式如下:
<DD>
<DD>Declare Function EccoIndex Lib "ECCO.DLL" Alias "_EccoIndex@4" (ByVal
FileMoveStr As String) As Long ' ECCO.DLL中的EccoIndex函數在Visual Basic下的接口
<DD>Declare Function EccoOpening Lib "ECCO.DLL" Alias "_EccoOpening@4" (ByVal
EccoIndex As Long) As Long ' ECCO.DLL中的EccoOpening函數在Visual Basic下的接口
<DD>EccoStr = MkL(EccoIndex("C2.5N8+7")) ' 獲得ECCO編號的字符串,這里將返回"B05"
<DD>OpeningStr = MkBStr(CvL(EccoStr)) ' 獲得上述編號對應的開局名稱,這里將返回"中炮對進左馬"
<DT>
<DT><FONT face=Arial size=4><STRONG>10.2 </STRONG></FONT><FONT face=楷體_GB2312
size=4><STRONG>匯編語言</STRONG></FONT><FONT face=Arial
size=4><STRONG>(x86asm.h)</STRONG></FONT>
<DT>
<DT> 匯編語言是為了彌補<FONT face="Times New Roman">C</FONT>語言的不足,<FONT
face="Times New Roman"><x86asm.h></FONT>主要提供以下兩方面的功能:
<DT> <FONT face="Times New Roman">(1) </FONT>操控互斥<FONT
face="Times New Roman">(Mutex)</FONT>變量的原子語句,有<FONT
face="Times New Roman">Increment</FONT>、<FONT
face="Times New Roman">Decrement</FONT>、<FONT
face="Times New Roman">Exchange</FONT>等,用于多線程的調度;
<DT> <FONT face="Times New Roman">(2) 32</FONT>位和<FONT
face="Times New Roman">64</FONT>位整數的乘除法和位移,有<FONT
face="Times New Roman">LongMulDiv</FONT>、<FONT
face="Times New Roman">LongMulMod</FONT>等,解決了“<FONT
face="Times New Roman">Int64 = Int32 x Int32</FONT>”等計算問題。
<DT> 盡管<FONT face="Times New Roman">Windows</FONT>和<FONT
face="Times New Roman">Unix</FONT>也有相應的庫函數來支持這些功能,但是匯編語言通常以內聯的形式調用,所以速度上會有優勢。
<DT>
<DT><FONT face=Arial size=4><STRONG>10.3 </STRONG></FONT><FONT face=楷體_GB2312
size=4><STRONG>空轉</STRONG></FONT><FONT face=Arial
size=4><STRONG>(idle.h)</STRONG></FONT>
<DT>
<DT> 在程序空閑期間,應該把<FONT
face="Times New Roman">CPU</FONT>資源交還給系統,這時就要調用空轉函數<FONT
face="Times New Roman">Idle()</FONT>,也可以直接調用<FONT
face="Times New Roman">Windows</FONT>或<FONT
face="Times New Roman">Unix</FONT>下都的休眠函數<FONT
face="Times New Roman">(Sleep()</FONT>或<FONT
face="Times New Roman">usleep())</FONT>。
<DT>
<DT><FONT face=Arial size=4><STRONG>10.4 </STRONG></FONT><FONT face=楷體_GB2312
size=4><STRONG>隨機數</STRONG></FONT><FONT face=Arial
size=4><STRONG>(longrand.h)</STRONG></FONT>
<DT>
<DT> <FONT face="Times New Roman">ElephantEye</FONT>在使用隨機數時,沒有用<FONT
face="Times New Roman"><stdlib.h></FONT>中的<FONT
face="Times New Roman">rand()</FONT>函數,是出于以下幾點考慮的:
<DT> <FONT face="Times New Roman">(1) rand()</FONT>函數的有效位數只有<FONT
face="Times New Roman">15</FONT>位<FONT
face="Times New Roman">(</FONT>最大數為<FONT
face="Times New Roman">0x7fff)</FONT>,這遠不能滿足程序的需要,用多個<FONT
face="Times New Roman">rand()</FONT>函數來拼湊只是權益之計;
<DT> <FONT face="Times New Roman">(2) rand()</FONT>函數的可靠性無法得到保障,因為我們不知道它的算法;
<DT> <FONT face="Times New Roman">(3) </FONT>如果以<FONT
face="Times New Roman">Zobrist</FONT>鍵值的形式來描述開局庫中的局面,那么每次給定相同的種子以后,產生的<FONT
face="Times New Roman">Zobrist</FONT>鍵值都必須相同。但各種<FONT
face="Times New Roman">C</FONT>語言的編譯器中給出的<FONT
face="Times New Roman">rand()</FONT>函數,我們無法確定其工作原理是否相同,因此也就不知道它們是否會產生相同的<FONT
face="Times New Roman">Zobrist</FONT>鍵值了。
<DT> <FONT face="Times New Roman">ElephantEye</FONT>的隨機函數包含在<FONT
face="Times New Roman"><longrand.h></FONT>中,它采用了“乘同余法”,公式是這樣的:
<DD><FONT face="Times New Roman"><EM>I</EM><SUB><EM>j</EM>+1</SUB> =
(<EM>a</EM> x <EM>I</EM><SUB><EM>j</EM></SUB>) mod <EM>m</EM></FONT>
<DT> 該公式可以用<FONT face="Times New Roman"><x86asm.h></FONT>中的<FONT
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -