📄 解剖大象的眼睛——中国象棋程序设计探索(二):棋盘结构和着法生成器.htm
字号:
face="Times New Roman">(3) </FONT>不吃子着法生成器。这四种来源分别代表了四种启发式算法:<FONT
face="Times New Roman">(1) </FONT>置换表启发,<FONT face="Times New Roman">(2)
</FONT>吃子启发,<FONT face="Times New Roman">(3) </FONT>杀手着法启发,<FONT
face="Times New Roman">(4) </FONT>历史表启发,这会在以后的章节中介绍。
<DT> 我们感兴趣的是杀手着法,它是以前搜索过的局面遗留下来的着法,当前的局面如果要使用这些着法,只需要做合理性的判断就可以了,如果杀手着法能产生截断,那么着法生成就没有必要了。因此,如何快速判断着法合理性,其意义可能比着法生成器还大。
<DT> <FONT face="Times New Roman">ElephantEye</FONT>判断着法合理性的程序包含在<FONT
face="Times New Roman"><position.cpp></FONT>中,它分为三个步骤:
<DT> <FONT face="Times New Roman">(1) </FONT>判断棋子是否在棋盘上存在,如果不存在那么肯定不是合理着法;
<DT> <FONT face="Times New Roman">(2)
</FONT>判断是否吃到自己一方的棋子,吃到自己棋子的着法肯定是不是合理着法;
<DT> <FONT face="Times New Roman">(3) </FONT>分兵种作额外的判断。
<DT> 我们感兴趣的是相<FONT face="Times New Roman">(</FONT>象<FONT
face="Times New Roman">)</FONT>马车炮四子的判断,其中相<FONT
face="Times New Roman">(</FONT>象<FONT
face="Times New Roman">)</FONT>的判断最简单,只需要满足<FONT
face="Times New Roman">3</FONT>个条件:
<DT> <FONT face="Times New Roman">(1) </FONT>走成象步,<FONT
face="Times New Roman">ElephantEye</FONT>里用了一个<FONT
face="Times New Roman">ccLegalMoveTab</FONT>的数组;
<DT> <FONT face="Times New Roman">(2) </FONT>没有过河,即<FONT
face="Times New Roman">((SrcSq ^ DstSq) & 0x80)</FONT> <FONT
face="Times New Roman">== 0</FONT>;
<DT> <FONT face="Times New Roman">(3) </FONT>没有被塞象眼,即<FONT
face="Times New Roman">ucpcSquares[(SrcSq + DstSq) / 2]</FONT> <FONT
face="Times New Roman">== 0</FONT>。
<DT> <FONT face="Times New Roman">ElephantEye</FONT>在马的判断上用了一个诀窍:构造了一个巧妙的数组:
<DD>
<DD>const char ccHorseLegTab[512] = {
<DD> ……
<DD> 0, 0, 0, 0, 0, 0, <FONT color=#0000ff>-16,</FONT> 0, <FONT
color=#0000ff>-16,</FONT> 0, 0, 0, 0, 0, 0, 0,
<DD> 0, 0, 0, 0, 0, <FONT color=#0000ff>-1,</FONT> 0, <FONT
color=#008000>0,</FONT> 0, <FONT color=#0000ff>1,</FONT> 0, 0, 0, 0, 0,
0,
<DD> 0, 0, 0, 0, 0, 0, <FONT color=#008000>0,</FONT> <FONT
color=#ff0000>0,</FONT> <FONT color=#008000>0,</FONT> 0, 0, 0, 0, 0, 0,
0,
<DD> 0, 0, 0, 0, 0, <FONT color=#0000ff>-1,</FONT> 0, <FONT
color=#008000>0,</FONT> 0, <FONT color=#0000ff>1,</FONT> 0, 0, 0, 0, 0,
0,
<DD> 0, 0, 0, 0, 0, 0, <FONT color=#0000ff>16,</FONT> 0, <FONT
color=#0000ff>16,</FONT> 0, 0, 0, 0, 0, 0, 0,
<DD> ……
<DD>};
<DT>
<DT> 上面的数组中,正中心的数代表马步的起始格<FONT face="Times New Roman">(</FONT>红色表示<FONT
face="Times New Roman">)</FONT>,±33、±31、±<FONT
face="Times New Roman">18</FONT>和±14是马步的增量<FONT
face="Times New Roman">(</FONT>蓝色表示<FONT
face="Times New Roman">)(</FONT>能被程序读到的就是这些位置<FONT
face="Times New Roman">)</FONT>,它们记录了马腿的增量<FONT
face="Times New Roman">(</FONT>马腿的位置用绿色表示<FONT
face="Times New Roman">)</FONT>。这样,判断合理性只需要符合两个条件:
<DT> <FONT face="Times New Roman">(1) </FONT>走成马步,即<FONT
face="Times New Roman">(Disp = ccHorseLegTab[DstSq </FONT><FONT
face=Symbol>-</FONT><FONT face="Times New Roman"> SrcSq + 256]) != 0</FONT>;
<DT> <FONT face="Times New Roman">(2) </FONT>没有被绊马腿,即<FONT
face="Times New Roman">ucpcSquares[SrcSq + Disp] == 0</FONT>。
<DT> 车和炮的判断就需要用到前面所说的位行和位列,这就需要首先要判断是否是吃子着法,然后根据不同情况作相应的判断。<FONT
face="Times New Roman">ElephantEye</FONT>中有专门的判断着法合理性的数组,也由<FONT
face="Times New Roman"><pregen.cpp></FONT>生成,结构跟前面提到的着法预产生数组类似,以车在列上吃子的着法为例,只要把<FONT
face="Times New Roman">FileMoveRookCap[...][...][0]</FONT>和<FONT
face="Times New Roman">[...][...][1]</FONT>合并成位列<FONT
face="Times New Roman">FileMaskRookCap[...][...]</FONT>,判断着法合理性的时候,只要判断该位列是否包含目标格的位列<FONT
face="Times New Roman">(1 << (y - 3))</FONT>即可。
<DT>
<DT><FONT face=Arial size=4><STRONG>2.8 </STRONG></FONT><FONT face=楷体_GB2312
size=4><STRONG>位棋盘</STRONG></FONT>
<DT>
<DT> 尽管<FONT
face="Times New Roman">ElephantEye</FONT>已经摈弃了“位棋盘”的设计,但是作为一个新兴的数据结构,尤其是“折叠位棋盘”的设计思路,还是值得一提的。“折叠位棋盘”的思想是由湖北襄樊铁路分局计算机中心的章光华提出的,首先于<FONT
face="Times New Roman">2004</FONT>年底发表在《象棋百科全书》网站的论坛上,该技术主要用来获得马和相<FONT
face="Times New Roman">(</FONT>象<FONT face="Times New Roman">)</FONT>的着法。
<DT> 这个思想的要点是:
<DT> <FONT face="Times New Roman">(1) </FONT>棋盘必须按照列的方式对每个格子编号<FONT
face="Times New Roman">(</FONT>如下图所示<FONT
face="Times New Roman">)</FONT>,格子的编号代表<FONT
face="Times New Roman">96</FONT>位位棋盘中的第几位; </DT></DL>
<DIV align=center>
<CENTER>
<TABLE border=1>
<TBODY>
<TR>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>09</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>19</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT face=Arial
color=#0000ff><STRONG>29</STRONG></FONT></TD>
<TD align=middle bgColor=#ffff00><FONT face=Arial
color=#ff0000><STRONG>39</STRONG></FONT></TD>
<TD align=middle bgColor=#ffff00><FONT
face=Arial><STRONG>49</STRONG></FONT></TD>
<TD align=middle bgColor=#ffff00><FONT face=Arial
color=#ff0000><STRONG>59</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT face=Arial
color=#0000ff><STRONG>69</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>79</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>89</STRONG></FONT></TD></TR>
<TR>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>08</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>18</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>28</STRONG></FONT></TD>
<TD align=middle bgColor=#ffff00><FONT
face=Arial><STRONG>38</STRONG></FONT></TD>
<TD align=middle bgColor=#ffff00><FONT face=Arial
color=#ff0000><STRONG>48</STRONG></FONT></TD>
<TD align=middle bgColor=#ffff00><FONT
face=Arial><STRONG>58</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>68</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>78</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>88</STRONG></FONT></TD></TR>
<TR>
<TD align=middle bgColor=#c0c0c0><FONT face=Arial
color=#0000ff><STRONG>07</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>17</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>27</STRONG></FONT></TD>
<TD align=middle bgColor=#ffff00><FONT face=Arial
color=#ff0000><STRONG>37</STRONG></FONT></TD>
<TD align=middle bgColor=#ffff00><FONT face=Arial
color=#0000ff><STRONG>47</STRONG></FONT></TD>
<TD align=middle bgColor=#ffff00><FONT face=Arial
color=#ff0000><STRONG>57</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>67</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>77</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT face=Arial
color=#0000ff><STRONG>87</STRONG></FONT></TD></TR>
<TR>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>06</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>16</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>26</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>36</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>46</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>56</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>66</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>76</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>86</STRONG></FONT></TD></TR>
<TR>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>05</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>15</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT face=Arial
color=#0000ff><STRONG>25</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>35</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>45</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>55</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT face=Arial
color=#0000ff><STRONG>65</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>75</STRONG></FONT></TD>
<TD align=middle bgColor=#c0c0c0><FONT
face=Arial><STRONG>85</STRONG></FONT></TD></TR>
<TR>
<TD align=middle bgColor=#ffffff><FONT
face=Arial><STRONG>04</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face=Arial><STRONG>14</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT face=Arial
color=#0000ff><STRONG>24</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face=Arial><STRONG>34</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face=Arial><STRONG>44</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face=Arial><STRONG>54</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT face=Arial
color=#0000ff><STRONG>64</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face=Arial><STRONG>74</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face=Arial><STRONG>84</STRONG></FONT></TD></TR>
<TR>
<TD align=middle bgColor=#ffffff><FONT
face=Arial><STRONG>03</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face=Arial><STRONG>13</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face=Arial><STRONG>23</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face=Arial><STRONG>33</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face=Arial><STRONG>43</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face=Arial><STRONG>53</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face=Arial><STRONG>63</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face=Arial><STRONG>73</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face=Arial><STRONG>83</STRONG></FONT></TD></TR>
<TR>
<TD align=middle bgColor=#ffffff><FONT face=Arial
color=#0000ff><STRONG>02</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face=Arial><STRONG>12</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face=Arial><STRONG>22</STRONG></FONT></TD>
<TD align=middle bgColor=#ffff00><FONT face=Arial
color=#ff0000><STRONG>32</STRONG></FONT></TD>
<TD align=middle bgColor=#ffff00><FONT face=Arial
color=#0000ff><STRONG>42</STRONG></FONT></TD>
<TD align=middle bgColor=#ffff00><FONT face=Arial
color=#ff0000><STRONG>52</STRONG></FONT></TD>
<TD align=middle bgColor=#ff
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -