?? 數據結構——0x88著法產生方法.htm
字號:
<DT> 而<FONT face="Times New Roman">0x88</FONT>機制恰恰可以解決這個問題。用一個<FONT
face="Times New Roman">16x8</FONT>的棋盤,就得到一個標志位,你就能知道棋子是否到了右邊那個沒用的棋盤上,因為在這個棋盤上<FONT
face="Times New Roman">0x08</FONT>位置為<FONT
face="Times New Roman">1</FONT>。例如<FONT
face="Times New Roman">h1</FONT>標號是<FONT
face="Times New Roman">7</FONT>,加<FONT face="Times New Roman">1</FONT>后就是<FONT
face="Times New Roman">8</FONT>,而<FONT
face="Times New Roman">0x08</FONT>位變成了<FONT
face="Times New Roman">1</FONT>。左邊的實棋盤上沒有一格的<FONT
face="Times New Roman">0x08</FONT>位是<FONT
face="Times New Roman">1</FONT>,而右邊的虛棋盤每個格子的<FONT
face="Times New Roman">0x08</FONT>位都是<FONT
face="Times New Roman">1</FONT>。如果你在<FONT
face="Times New Roman">a3</FONT>并且要朝左走,你會到達<FONT
face="Times New Roman">p2</FONT>,這是在虛棋盤上,<FONT
face="Times New Roman">0x08</FONT>位是<FONT face="Times New Roman">1</FONT>。
<DT> 可以把<FONT face="Times New Roman">0x08</FONT>的檢測和<FONT
face="Times New Roman">0x80</FONT>的檢測結合起來<FONT
face="Times New Roman">(</FONT>原來的<FONT
face="Times New Roman">0x40</FONT>變成了<FONT
face="Times New Roman">0x80</FONT>,因為現在棋盤變成<FONT
face="Times New Roman">128</FONT>個格子了<FONT
face="Times New Roman">)</FONT>,并且兩次測試要同時完成。把<FONT
face="Times New Roman">0x80</FONT>和<FONT
face="Times New Roman">0x08</FONT>結合起來就是<FONT
face="Times New Roman">0x88</FONT>,這就是這套方案的名稱。
<DT> 如果你知道我在說什么,你就明白<FONT
face="Times New Roman">0x88</FONT>是怎樣運作的。你的著法產生的循環就應該寫成下面的樣子:
<DD>
<DD><FONT face=宋體>while (!(index & 0x88)) {</FONT>
<DD> <FONT face=宋體>GenerateMove(index);</FONT>
<DD> <FONT face=宋體>index += delta;</FONT>
<DD><FONT face=宋體>}</FONT>
<DT>
<DT> 這就非常簡潔了,你可以這么寫:
<DD>
<DD><FONT face=宋體>void GenerateMoves(int square, int * ptab) {</FONT>
<DD> <FONT face=宋體>for (; *ptab; ptab++) {</FONT>
<DD> <FONT face=宋體>int index;</FONT>
<DD> <FONT face=宋體>for (index = square; !(index & 0x88); index += *ptab)
{</FONT>
<DD> <FONT face=宋體>GenerateMove(index);</FONT>
<DD> }
<DD> <FONT face=宋體>}</FONT>
<DD><FONT face=宋體>}</FONT>
<DD><FONT face=宋體>int argdBishop[] = { 17, 15, -17, -15, 0 };</FONT>
<DD><FONT face=宋體>void GenerateBishopMoves(int square) {</FONT>
<DD> <FONT face=宋體>GenerateMove(square, argdBishop);</FONT>
<DD><FONT face=宋體>}</FONT>
<DT>
<DT> 這樣寫就非常快了,并且代碼很短。車或者后跟象的區別只是表中的數據不同罷了,因此你可以花很短的時間把其他棋子的代碼加上,而且不需要任何改動。
<DT> 當然,你仍然需要為兵和王車易位另寫代碼,但每個體系都得如此。<FONT
face="Times New Roman">0x88</FONT>體系能給你一點幫助,可是代碼寫出來仍然很丑。
<DT>
<DT><FONT face=楷體_GB2312 size=5><STRONG>獎勵</STRONG></FONT>
<DT>
<DT> <FONT face="Times New Roman">0x88</FONT>體系還可以快速判斷攻擊,這就是要使用<FONT
face="Times New Roman">16x8</FONT>棋盤的另一個原因。如果你將兩格子的號碼相減,你會得到兩個格子之間的關系。
<DT> 例如,如果兩個格子減下來是<FONT
face="Times New Roman">1</FONT>,那么第二個格子就在第一個格子的左邊。如果減下來是<FONT
face="Times New Roman">16</FONT>,那么第二個格子就在第一個格子的上面。
<DT> 這在<FONT face="Times New Roman">8x8</FONT>棋盤上是做不到的。<FONT
face="Times New Roman">d1 </FONT><FONT face=Symbol>-</FONT><FONT
face="Times New Roman"> c1 = 1</FONT>確實如此,但是<FONT face="Times New Roman">a2 -
h1</FONT>也是<FONT face="Times New Roman">1</FONT>。這個“回圈”問題可以在<FONT
face="Times New Roman">128</FONT>個格子的棋盤上解決。
<DT> 你在寫判斷將軍或者一個子是否在捉另一個子的函數時,可以利用以上這個技巧。
<DT> 你可以用一個大約<FONT face="Times New Roman">257</FONT>個元素<FONT
face="Times New Roman">(</FONT><FONT face=Symbol>-</FONT><FONT
face="Times New Roman">128 ~
+128)</FONT>的數組,里面存放一些代表棋子的位域,來說明哪些棋子能在某兩格間移動,而移動的增量就是數組的指標。你可以用少于<FONT
face="Times New Roman">257</FONT>個的元素,但是我沒有嘗試過。
<DT> 例如在增量為<FONT face="Times New Roman">1</FONT>的元素里,應該有王、后、車的位置是置<FONT
face="Times New Roman">1</FONT>的。如果增量是<FONT
face="Times New Roman">17</FONT>,那么置<FONT
face="Times New Roman">1</FONT>的是王、后、象和白兵。
<DT> 這樣就可以寫出比較快的檢查將軍的程序了。你把攻擊子的格子和目標格子相減得到增量,加上<FONT
face="Times New Roman">128</FONT>以避免負的指標,然后去找預先計算好的攻擊數組,看看是否符合這個攻擊子的類型,以確認它有可能一步到達目標格。
<DT> 如果你確認這個子可能到達目標格,那么你還要檢查它是否是長兵器<FONT
face="Times New Roman">(</FONT>后、車或象<FONT
face="Times New Roman">)</FONT>。如果不是,那就完成判斷了,否則你要沿著從攻擊子到目標格的射線去找有沒有阻擋的棋子。
<DT> 我不想提供這個程序的代碼,因為它很容易寫。這個程序的速度是比較快的。
<DT>
<DT> 原文:<A href="http://www.seanet.com/~brucemo/topics/0x88.htm"
target=_blank><FONT
face="Times New Roman">http://www.seanet.com/~brucemo/topics/0x88.htm</FONT></A>
<DT> 譯者:黃晨 <FONT face="Times New Roman">(</FONT><A
href="mailto:webmaster@elephantbase.net"><FONT
face="Times New Roman">webmaster@elephantbase.net</FONT></A><FONT
face="Times New Roman">)</FONT>
<DT> 類型:全譯 </DT></DL>
<DIR>
<LI>上一篇 <A
href="http://www.elephantbase.net/computer/struct_movegen.htm">數據結構——著法生成器</A>
<LI>下一篇 <A
href="http://www.elephantbase.net/computer/struct_zobrist.htm">數據結構——<FONT
face="Times New Roman">Zobrist</FONT>鍵值</A>
<LI>返 回 <A href="http://www.elephantbase.net/computer.htm">象棋百科全書——電腦象棋</A>
</LI></DIR>
<DIV align=center>
<CENTER>
<TABLE border=0>
<TBODY>
<TR>
<TD>
<P align=center><A href="http://www.elephantbase.net/" target=_blank><IMG
height=31 src="數據結構——0x88著法產生方法_files/elephantbase.gif" width=88
border=0></A></P></TD></TR>
<TR>
<TD><A href="http://www.elephantbase.net/" target=_blank><FONT face=Arial
size=2><STRONG>www.elephantbase.net</STRONG></FONT></A></TD></TR></TBODY></TABLE></CENTER></DIV></BODY></HTML>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -