📄 数据结构——旋转的位棋盘.htm
字号:
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>24</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>24</STRONG></FONT></TD>
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>24</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>24</STRONG></FONT></TD>
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>24</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>24</STRONG></FONT></TD>
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>24</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>24</STRONG></FONT></TD></TR>
<TR>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>32</STRONG></FONT></TD>
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>32</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>32</STRONG></FONT></TD>
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>32</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>32</STRONG></FONT></TD>
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>32</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>32</STRONG></FONT></TD>
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>32</STRONG></FONT></TD></TR>
<TR>
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>40</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>40</STRONG></FONT></TD>
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>40</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>40</STRONG></FONT></TD>
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>40</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>40</STRONG></FONT></TD>
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>40</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>40</STRONG></FONT></TD></TR>
<TR>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>48</STRONG></FONT></TD>
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>48</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>48</STRONG></FONT></TD>
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>48</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>48</STRONG></FONT></TD>
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>48</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>48</STRONG></FONT></TD>
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>48</STRONG></FONT></TD></TR>
<TR>
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>56</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>56</STRONG></FONT></TD>
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>56</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>56</STRONG></FONT></TD>
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>56</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>56</STRONG></FONT></TD>
<TD align=middle bgColor=#000000><FONT face="Times New Roman"
color=#ffffff><STRONG>56</STRONG></FONT></TD>
<TD align=middle bgColor=#ffffff><FONT
face="Times New Roman"><STRONG>56</STRONG></FONT></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<DL>
<DT> 我们需要第<FONT face="Times New Roman">6</FONT>行的棋子分布情况(从第<FONT
face="Times New Roman">16</FONT>位到第<FONT
face="Times New Roman">23</FONT>位),就右移<FONT
face="Times New Roman">16</FONT>位,现在它被右移到了最低的<FONT
face="Times New Roman">8</FONT>位,我们把它与<FONT
face="Times New Roman">255(0xff</FONT>)做逻辑与运算。所得到的东西即是我们需要作为<FONT
face="Times New Roman">rank_attacks</FONT>的第二个索引号的数字。
<DT>
<DT> 第三步:索引数组<FONT face="Times New Roman">file_attacks[64][256]</FONT>。
<DT> 如何计算出<FONT
face="Times New Roman">file_attacks</FONT>位棋盘呢?还是通过索引数组。和上面一样,第一个索引号是车所在格的编号。第二个索引号是车所在列的棋子分布状态。
<DD><FONT face="Times New Roman">1</FONT>
<DD><FONT face="Times New Roman">0</FONT>
<DD><FONT face="Times New Roman">0</FONT>
<DD><FONT face="Times New Roman">0</FONT>
<DD><FONT face="Times New Roman">0</FONT>
<DD><FONT face="Times New Roman">1</FONT>
<DD><FONT face="Times New Roman">0</FONT>
<DD><FONT face="Times New Roman">1</FONT><FONT
color=#0000ff>【编者注:同样道理,这是黑方看上去的位置。】</FONT>
<DT> 要分离出这个索引号比分离<FONT
face="Times New Roman">rank_attacks</FONT>的要复杂一些。仅执行“位移”和“与”指令是无法做到的。首先,我们要把棋盘右转<FONT
face="Times New Roman">90</FONT>度<FONT color=#0000ff>【编者注:即顺时针转</FONT><FONT
face="Times New Roman" color=#0000ff>90</FONT><FONT
color=#0000ff>度。】</FONT>。因此现在它看上去应该是这个样子: </DT></DL>
<TABLE width="100%" border=0>
<TBODY>
<TR>
<TD align=middle>右转<FONT face="Times New Roman">90</FONT>度后的棋盘</TD></TR>
<TR>
<TD align=middle><IMG height=256
src="数据结构——旋转的位棋盘_files/struct_rotation8.gif"
width=256></TD></TR></TBODY></TABLE>
<DL>
<DT> 这个旋转后的棋盘是怎么得到的?你可以在开始做下一层搜索的时候构建这个棋盘,或者简单地在“走”下一步棋或“恢复”上一步棋的时候逐步更新它。下面的方法演示了如何在开始做下一层搜索时构建它。<FONT
face="Times New Roman">(</FONT>代码并不那么优雅,但较易理解……<FONT
face="Times New Roman">)</FONT>
<DD>
<DD>int r90R_map[64] = {
<DD> H8, H7, H6, H5, H4, H3, H2, H1,
<DD> G8, G7, G6, G5, G4, G3, G2, G1,
<DD> F8, F7, F6, F5, F4, F3, F2, F1,
<DD> E8, E7, E6, E5, E4, E3, E2, E1,
<DD> D8, D7, D6, D5, D4, D3, D2, D1,
<DD> C8, C7, C6, C5, C4, C3, C2, C1,
<DD> B8, B7, B6, B5, B4, B3, B2, B1,
<DD> A8, A7, A6, A5, A4, A3, A2, A1
<DD>};
<DD>BitBoard Rotated90R = 0;
<DD>for (棋盘上的每一格)(0-63) {
<DD> if (格子被占)
<DD> Rotated90R |= mask[r90R_map[square]];
<DD>}
<DT>
<DT> 这样,原来在<FONT face="Times New Roman">A8</FONT>格上的棋子被“映射”到<FONT
face="Times New Roman">H8</FONT>格上,原来在<FONT
face="Times New Roman">H8</FONT>格上的棋子则被“映射”到<FONT
face="Times New Roman">H1</FONT>格上……
<DT> 现在,我们可以对这个旋转后的位棋盘执行“位移”和“与”操作了。
<DT>
<DT> 第四步:获得<FONT face="Times New Roman">rook_attacks</FONT>位棋盘。
<DT> 得到<FONT face="Times New Roman">rank_attacks</FONT>和<FONT
face="Times New Roman">file_attacks</FONT>位棋盘后,你只要简单的对这两个位棋盘执行“与”运算就获得了记录了所有受到那个车攻击的格子的位棋盘了。
<DD>
<DD>rook_attack = rank_attack | file_attack;
<DT>
<DT><FONT face=楷体_GB2312 size=4><STRONG>用旋转的位棋盘计算受象攻击的格子</STRONG></FONT>
<DT>
<DT> 计算受象攻击的格子的方法与车类似。对应于车的把横线与竖线做“或”运算,这里我们对象所在的两条斜线做“或”运算。我们把第一条斜线<FONT
face="Times New Roman">(</FONT>就是执白时,从左上到右下这条斜线<FONT
face="Times New Roman">)</FONT>叫做<FONT
face="Times New Roman">diag_A8H1</FONT>;另一条斜线叫做<FONT
face="Times New Roman">diag_H8A1</FONT>。相对车这里还多了一步,原因是每条斜线的长度不同。先预先计算出数组<FONT
face="Times New Roman">diag_A8H1_attacks[64][256]</FONT>和<FONT
face="Times New Roman">diag_H8A1_attacks[64][256]</FONT>。<FONT
face="Times New Roman">A8</FONT>格编号为<FONT
face="Times New Roman">0</FONT>,<FONT face="Times New Roman">H8</FONT>格为<FONT
face="Times New Roman">7</FONT>,<FONT face="Times New Roman">A1</FONT>格为<FONT
face="Times New Roman">56</FONT>,<FONT face="Times New Roman">H1</FONT>格为<FONT
face="Times New Roman">63</FONT>。
<DD>
<DD>int length_A8H1_diag[64] = {
<DD> 8, 7, 6, 5, 4, 3, 2, 1,
<DD> 7, 8, 7, 6, 5, 4, 3, 2,
<DD> 6, 7, 8, 7, 6, 5, 4, 3,
<DD> 5, 6, 7, 8, 7, 6, 5, 4,
<DD> 4, 5, 6, 7, 8, 7, 6, 5,
<DD> 3, 4, 5, 6, 7, 8, 7, 6,
<DD> 2, 3, 4, 5, 6, 7, 8, 7,
<DD> 1, 2, 3, 4, 5, 6, 7, 8
<DD>};
<DD>int length_H8A1_diag[64] = {
<DD> 1, 2, 3, 4, 5, 6, 7, 8,
<DD> 2, 3, 4, 5, 6, 7, 8, 7,
<DD> 3, 4, 5, 6, 7, 8, 7, 6,
<DD> 4, 5, 6, 7, 8, 7, 6, 5,
<DD> 5, 6, 7, 8, 7, 6, 5, 4,
<DD> 6, 7, 8, 7, 6, 5, 4, 3,
<DD> 7, 8, 7, 6, 5, 4, 3, 2,
<DD> 8, 7, 6, 5, 4, 3, 2, 1
<DD>};
<DD>/* 象或后在A8-H1方向移动的预先计算 */
<DD>for (棋盘上的每一格)(0-63) {
<DD> /* 状态数会随对角线长度而变化 */
<DD> for (每条对角线的棋子分布状态)(0-(2^对角线长-1)) {
<DD> 计算该状态下被占的格子(注意某些状态不要把8个格子都考虑进去)
<DD> 计算从这个格子朝左上方走的着法
<DD> 计算从这个格子朝右下方走的着法
<DD> diag_A8H1_attacks[格子][状态] = attack_board;
<DD> }
<DD>}
<DD>/* 象或后在H8-A1方向移动的预先计算 */
<DD>for (棋盘上的每一格)(0-63) {
<DD> /* 状态数会随对角线长度而变化 */
<DD> for (每条对角线的棋子分布状态)(0-(2^diag length)-1) {
<DD> 计算该状态下被占的格子(注意某些状态不要把8个格子都考虑进去)
<DD> 计算从这个格子朝右上方走的着法
<DD> 计算从这个格子朝左下方走的着法
<DD> diag_H8A1_attacks[square][diag state] = attack_board;
<DD> }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -