博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
位棋盘表示法中车和炮的着法生成
阅读量:7231 次
发布时间:2019-06-29

本文共 5350 字,大约阅读时间需要 17 分钟。

这里没有采用Magic Bitboard技术,采用了4个方向扫描最高1位或最低1位的办法,效率虽然比magic bitboard低一点,但代码还是比较容易理解的。

 

 

occupied

attacks = PRESET_RAY_NORTH[fromPos];

blockers = attacks & occupied;

9

8

7

6

5

4

3

2

1

0

000000000

001000000

001100100

000000000

001001000

000000000

000000000

010010110

000000000

001000000

ABCDEFGHI

001000000

001000000

001000000

001000000

001000000

001000000

001000000

000000000

000000000

000000000

ABCDEFGHI

000000000

001000000

001000000

000000000

001000000

000000000

000000000

000000000

000000000

000000000

ABCDEFGHI

 

一个位棋盘,1表示有棋子占据,0表示无棋子。这里的fromPos是C2位置。

C2格子的正北面的格子都可以攻击到

blockingPos = blockers.GetLowestBit( );

此例中表示C5格阻碍了车的前进

 

 

 

PRESET_RAY_NORTH[blockingPos]

attacks ^= PRESET_RAY_NORTH[blockingPos];

 

9

8

7

6

5

4

3

2

1

0

001000000

001000000

001000000

001000000

000000000

000000000

000000000

000000000

000000000

000000000

ABCDEFGHI

000000000

000000000

000000000

000000000

001000000

001000000

001000000

000000000

000000000

000000000

ABCDEFGHI

上面一系列的位运算处理了正北方可以攻击到的位置,同理再处理东面、南面和西面的情况,就可以得到所有可以攻击到的格子的位棋盘

 

C5格正北方的格子

异或后,正好就是位于C2格子的车向北方前进时可以攻击到的所有位置的位棋盘

 

 

1 /*! 车的着法生成  2 * \param fromPos 出发位置  3 * \param occupied 棋子占据情况的位棋盘  4 * \return 可到达位置组成一个位棋盘  5 */  6 BitBoard MoveGenerator::RookAttacks( int fromPos, BitBoard occupied )  7 {  8     int        blockingPos;  9     BitBoard   attacks, partAttacks, blockers; 10 11     12     // 向北扫描13     attacks = PRESET_RAY_NORTH[fromPos]; 14     blockers = attacks & occupied; 15     if ( blockers.H | blockers.L) 16     { 17         blockingPos = blockers.GetLowestBit( ); 18         attacks ^= PRESET_RAY_NORTH[blockingPos]; // mask off beyond blocking square 19     } 20 21  22     // 向东扫描 23     partAttacks = PRESET_RAY_EAST[fromPos]; 24     blockers = partAttacks & occupied; 25     if ( blockers.H | blockers.L) 26     { 27         blockingPos = blockers.GetLowestBit( ); 28         partAttacks ^= PRESET_RAY_EAST[blockingPos]; 29     } 30     attacks |= partAttacks;  31     32     // 向南扫描33     partAttacks = PRESET_RAY_SOUTH[fromPos]; 34     blockers = partAttacks & occupied; 35     if ( blockers.H | blockers.L) 36     { 37         blockingPos = blockers.GetHighestBit(  ); 38         partAttacks ^= PRESET_RAY_SOUTH[blockingPos]; 39     } 40     attacks |= partAttacks; 41 42     // 向西扫描43     partAttacks = PRESET_RAY_WEST[fromPos]; 44     blockers = partAttacks & occupied; 45     if ( blockers.H | blockers.L)  46     { 47         blockingPos = blockers.GetHighestBit(  ); 48         partAttacks ^= PRESET_RAY_WEST[blockingPos]; 49     } 50 51     return attacks | partAttacks; 52 }

 

 

炮的着法生成可以类似的处理,但要处理吃子的情况。

 

 

occupied

attacks = PRESET_RAY_NORTH[fromPos];

blockers = attacks & occupied;

9

8

7

6

5

4

3

2

1

0

000000000

001000000

001100100

000000000

001001000

000000000

000000000

010010110

000000000

001000000

ABCDEFGHI

001000000

001000000

001000000

001000000

001000000

001000000

001000000

000000000

000000000

000000000

ABCDEFGHI

000000000

001000000

001000000

000000000

000000000

000000000

000000000

000000000

000000000

000000000

ABCDEFGHI

 

一个位棋盘,1表示有棋子占据,0表示无棋子。这里的fromPos是C2位置。

C2格子的正北面的格子都可以走到

blockingPos = blockers.GetLowestBitWithReset( );

此例中表示C5格阻碍了炮的前进,同时要把此位置0

 

 

 

PRESET_RAY_NORTH_SELF[blockingPos]

attacks ^= PRESET_RAY_NORTH

_SELF[blockingPos];

如果有吃子的话
eatPos = blockers.GetLowestBit( );
此例中为C7。
attacks.SetBit(eatPos);
 

9

8

7

6

5

4

3

2

1

0

001000000

001000000

001000000

001000000

001000000

000000000

000000000

000000000

000000000

000000000

ABCDEFGHI

000000000

000000000

000000000

000000000

000000000

001000000

001000000

000000000

000000000

000000000

ABCDEFGHI

000000000

000000000

001000000

000000000

000000000

001000000

001000000

000000000

000000000

000000000

ABCDEFGHI

上面一系列的位运算处理了正北方可以移动到或攻击到的位置,同理再处理东面、南面和西面的情况,就可以得到所有可以生成所有着法。

 

C5正北方的格子,包括C5位置

异或后,正好就是位于C2格子的炮向北方前进时可以移动到的所有位置的位棋盘

   

 

1 attacks = PRESET_RAY_NORTH[fromPos];  2 blockers = attacks & occupied;  3 if ( blockers.H | blockers.L)  4 {  5     blockingPos = blockers.GetLowestBitWithReset(  );  6     attacks ^= PRESET_RAY_NORTH_SELF[blockingPos]; // mask off beyond blocking square  7     if ( blockers.H | blockers.L) {  8         eatPos = blockers.GetLowestBit(  );  9         attacks.SetBit(eatPos); 10     } 11 } 12 13 partAttacks = PRESET_RAY_EAST[fromPos]; 14 blockers = partAttacks & occupied; 15 if ( blockers.H | blockers.L) 16 { 17     blockingPos = blockers.GetLowestBitWithReset(  ); 18     partAttacks ^= PRESET_RAY_EAST_SELF[blockingPos]; 19     if ( blockers.H | blockers.L) { 20         eatPos = blockers.GetLowestBit( ); 21         partAttacks.SetBit(eatPos); 22     } 23 } 24 attacks |= partAttacks; 25 26 partAttacks = PRESET_RAY_SOUTH[fromPos]; 27 blockers = partAttacks & occupied; 28 if ( blockers.H | blockers.L) 29 { 30     blockingPos = blockers.GetHighestBitWithReset(  ); 31     partAttacks ^= PRESET_RAY_SOUTH_SELF[blockingPos]; 32     if ( blockers.H | blockers.L) { 33         eatPos = blockers.GetHighestBit(  ); 34         partAttacks.SetBit(eatPos); 35     } 36 } 37 attacks |= partAttacks; 38 39 40 partAttacks = PRESET_RAY_WEST[fromPos]; 41 blockers = partAttacks & occupied; 42 if ( blockers.H | blockers.L)  43 { 44     blockingPos = blockers.GetHighestBitWithReset(  ); 45     partAttacks ^= PRESET_RAY_WEST_SELF[blockingPos]; 46     if ( blockers.H | blockers.L) { 47         eatPos = blockers.GetHighestBit( ); 48         partAttacks.SetBit(eatPos); 49     } 50 } 51 52 return attacks | partAttacks;

 

 

转载地址:http://imsfm.baihongyu.com/

你可能感兴趣的文章
设计模式开篇 - 简单工厂模式
查看>>
Spring MVC 注解和XML的区别
查看>>
利用Swoole实现PHP+websocket直播,即使通讯代码,及linux下swoole安装基本配置
查看>>
Elastic学习第一天遇到的问题以及添加的一些操作
查看>>
Python lambda介绍
查看>>
BSON与JSON的区别
查看>>
文件系统存储数据,与数据库系统存储数据的差别
查看>>
linux之awk
查看>>
第九章 接口
查看>>
XCode4.2.1 使用NavigationController实现View切换
查看>>
如何让NSURLConnection在子线程中运行
查看>>
es6-Generator
查看>>
Python3.6单例模式报错TypeError: object() takes no parameters的解决方法
查看>>
HTML常用标记(选择性,不全)
查看>>
用一辈子去领悟的22条生活真谛
查看>>
1968: [Ahoi2005]COMMON 约数研究
查看>>
discuz 启用html code 显示问题
查看>>
A1027. Colors in Mars (20)
查看>>
[SRM568]DisjointSemicircles
查看>>
9个很有发展潜力的PHP开源项目
查看>>