[MMX指令版]黑白棋行动力的计算

前言:这个东西老早就应该贴了,因为我已经在Nowcan的Blog帖子里说过了,一直没贴是因为没有心情,或者觉得自己还没有整理得足够好,现在先发未经过整理的上来冲冲数先吧。

这段代码是WZebra的作者Gunnar Andersson写的,作用是计算《黑白棋》双方的行动力,其中使用了bitboard技术和MMX指令,作者说他已经考虑了指令配对,请不要随意修改代码的先后顺序,除非你真的确定你是对的。原来的代码是gcc下的汇编格式,我把他转换过来而已,这个是在VC++ 6.0编译的版本,希望对你有点用处。

另:由于是很久很久以前弄的,大概有快2,3年了吧(当时我的汇编也不怎么样),所以你会看到头和尾的int count处理不是很科学(也许这样比较直观一些),其实你可以让他更有效率,我也懒得改了,修改一下代码会更快一点儿,留给你自己去做了,其实相当简单的。

static unsigned __int64 dir_mask0;
static unsigned __int64 dir_mask1;
static unsigned __int64 dir_mask2;
static unsigned __int64 dir_mask3;
static unsigned __int64 dir_mask4;
static unsigned __int64 dir_mask5;
static unsigned __int64 dir_mask6;
static unsigned __int64 dir_mask7;
static unsigned __int64 c0f;
static unsigned __int64 c33;
static unsigned __int64 c55;

void init_mmx( void )
{
    dir_mask0 = 0x007e7e7e7e7e7e00;
    dir_mask1 = 0x00ffffffffffff00;
    dir_mask2 = 0x007e7e7e7e7e7e00;
    dir_mask3 = 0x7e7e7e7e7e7e7e7e;
    dir_mask4 = 0x7e7e7e7e7e7e7e7e;
    dir_mask5 = 0x007e7e7e7e7e7e00;
    dir_mask6 = 0x00ffffffffffff00;
    dir_mask7 = 0x007e7e7e7e7e7e00;
    c0f = 0x0f0f0f0f0f0f0f0f;
    c33 = 0x3333333333333333;
    c55 = 0x5555555555555555;
}

typedef struct {
    unsigned long high;
    unsigned long low;
} BitBoard;

int bitboard_mobility( const BitBoard my_bits, const BitBoard opp_bits )
{
    unsigned int count;

    __asm {

        /* Ready for init data */
        mov     ebx, my_bits.high       ;
        mov     ecx, my_bits.low        ;
        mov     edi, opp_bits.high      ;
        mov     esi, opp_bits.low       ;

        //
        movd    mm0, ebx                ;
        psllq   mm0, 32                 ;
        movd    mm3, ecx                ;
        por     mm0, mm3                ; mm0 is BitBoard of my_bits
        movd    mm1, edi                ;
        psllq   mm1, 32                 ;
        movd    mm4, esi                ;
        por     mm1, mm4                ; mm1 is BitBoard of opp_bits
        pxor    mm2, mm2                ; mm2 <- 0x0000000000000000

        /* shift=-9   rowDelta=-1   colDelta=-1 */
        /* shift=+9   rowDelta=+1   colDelta=+1 */

        /* Disc #1, flip direction 0. */
        /* Disc #1, flip direction 7. */
        movq    mm3, mm1                ; mm3 <- opp_bits
        movq    mm4, mm0                ; mm4 <- my_bits
        movq    mm6, mm0                ; mm6 <- backup of my_bits
        pand    mm3, dir_mask0          ; 0x007e7e7e7e7e7e00
                                        ; dir_mask0 of value:
                                        ;   00000000
                                        ;   01111110
                                        ;   01111110
                                        ;   01111110
                                        ;   01111110
                                        ;   01111110
                                        ;   01111110
                                        ;   00000000
        push    esi                     ;
        psllq   mm4, 9                  ;
        psrlq   mm6, 9                  ;
        push    edi                     ;
        pand    mm4, mm3                ;
        pand    mm6, mm3                ;
        push    ecx                     ;

        /* Disc #2, flip direction 0. */
        /* Disc #2, flip direction 7. */
        movq    mm5, mm4                ;
        movq    mm7, mm6                ;
        psllq   mm5, 9                  ;
        psrlq   mm7, 9                  ;
        push    ebx                     ;
        pand    mm5, mm3                ;
        pand    mm7, mm3                ;
        and     edi, 0x7e7e7e7e         ; 0x7e7e7e7e
        and     esi, 0x7e7e7e7e         ; 0x7e7e7e7e
                                        ; value of:
                                        ; 011111110
                                        ; 011111110
                                        ; 011111110
                                        ; 011111110
        por     mm4, mm5                ;
        por     mm6, mm7                ;
        shl     ebx, 1                  ;
        shl     ecx, 1                  ;

        /* Disc #3, flip direction 0. */
        /* Disc #3, flip direction 7. */
        movq    mm5, mm4                ;
        movq    mm7, mm6                ;
        and     ebx, edi                ;
        and     ecx, esi                ;
        psllq   mm5, 9                  ;
        psrlq   mm7, 9                  ;
        mov     eax, ebx                ;
        mov     edx, ecx                ;
        pand    mm5, mm3                ;
        pand    mm7, mm3                ;
        shl     edx, 1                  ;
        shl     eax, 1                  ;
        por     mm4, mm5                ;
        por     mm6, mm7                ;
        and     eax, edi                ;
        and     edx, esi                ;

        /* Disc #4, flip direction 0. */
        /* Disc #4, flip direction 7. */
        movq    mm5, mm4                ;
        movq    mm7, mm6                ;
        or      ebx, eax                ;
        or      ecx, edx                ;
        psllq   mm5, 9                  ;
        psrlq   mm7, 9                  ;
        mov     eax, ebx                ;
        mov     edx, ecx                ;
        pand    mm5, mm3                ;
        pand    mm7, mm3                ;
        shl     edx, 1                  ;
        shl     eax, 1                  ;
        por     mm4, mm5                ;
        por     mm6, mm7                ;
        and     eax, edi                ;
        and     edx, esi                ;

        /* Disc #5, flip direction 0. */
        /* Disc #5, flip direction 7. */
        movq    mm5, mm4                ;
        movq    mm7, mm6                ;
        or      ebx, eax                ;
        or      ecx, edx                ;
        psllq   mm5, 9                  ;
        psrlq   mm7, 9                  ;
        mov     eax, ebx                ;
        mov     edx, ecx                ;
        pand    mm5, mm3                ;
        pand    mm7, mm3                ;
        shl     edx, 1                  ;
        shl     eax, 1                  ;
        por     mm4, mm5                ;
        por     mm6, mm7                ;
        and     eax, edi                ;
        and     edx, esi                ;

        /* Disc #6, flip direction 0. */
        /* Disc #6, flip direction 7. */
        movq    mm5, mm4                ;
        movq    mm7, mm6                ;
        or      ebx, eax                ;
        or      ecx, edx                ;
        psrlq   mm7, 9                  ;
        psllq   mm5, 9                  ;
        mov     eax, ebx                ;
        mov     edx, ecx                ;
        pand    mm5, mm3                ;
        pand    mm7, mm3                ;
        shl     edx, 1                  ;
        shl     eax, 1                  ;
        por     mm4, mm5                ;
        por     mm6, mm7                ;
        and     eax, edi                ;
        and     edx, esi                ;
        psllq   mm4, 9                  ;
        psrlq   mm6, 9                  ;
        or      ebx, eax                ;
        or      ecx, edx                ;
        por     mm2, mm4                ;
        por     mm2, mm6                ;
        mov     eax, ebx                ;
        mov     edx, ecx                ;

        /* shift=-8   rowDelta=-1   colDelta=0 */
        /* shift=+8   rowDelta=1   colDelta=0 */

        /* Disc #1, flip direction 1. */
        /* Disc #1, flip direction 6. */
        movq    mm3, mm1                ;
        movq    mm4, mm0                ;
        movq    mm6, mm0                ;
        pand    mm3, dir_mask1          ; 0x00ffffffffffff00;
                                        ; dir_mask1 of value:
                                        ;   00000000
                                        ;   11111111
                                        ;   11111111
                                        ;   11111111
                                        ;   11111111
                                        ;   11111111
                                        ;   11111111
                                        ;   00000000
        psllq   mm4, 8                  ;
        psrlq   mm6, 8                  ;
        shl     edx, 1                  ;
        shl     eax, 1                  ;
        pand    mm4, mm3                ;
        pand    mm6, mm3                ;
        and     eax, edi                ;
        and     edx, esi                ;
        /* Disc #2, flip direction 1. */
        /* Disc #2, flip direction 6. */
        movq    mm5, mm4                ;
        movq    mm7, mm6                ;
        or      ebx, eax                ;
        or      ecx, edx                ;
        psllq   mm5, 8                  ;
        psrlq   mm7, 8                  ;
        shl     ebx, 1                  ;
        shl     ecx, 1                  ;
        pand    mm5, mm3                ;
        pand    mm7, mm3                ;
        por     mm4, mm5                ;
        por     mm6, mm7                ;

        /* serialize here: add horizontal shl flips. */

        movd    mm5, ebx                ;
        psllq   mm5, 32                 ;
        movd    mm7, ecx                ;
        por     mm5, mm7                ;
        por     mm2, mm5                ;

        /* Disc #3, flip direction 1. */
        /* Disc #3, flip direction 6. */
        movq    mm5, mm4                ;
        movq    mm7, mm6                ;
        psllq   mm5, 8                  ;
        psrlq   mm7, 8                  ;
        pop     ebx                     ;
        pand    mm5, mm3                ;
        pand    mm7, mm3                ;
        pop     ecx                     ;
        por     mm4, mm5                ;
        por     mm6, mm7                ;
        push    ecx                     ;

        /* Disc #4, flip direction 1. */
        /* Disc #4, flip direction 6. */
        movq    mm5, mm4                ;
        movq    mm7, mm6                ;
        push    ebx                     ;
        psllq   mm5, 8                  ;
        psrlq   mm7, 8                  ;
        shr     ebx, 1                  ;
        shr     ecx, 1                  ;
        pand    mm5, mm3                ;
        pand    mm7, mm3                ;
        and     ebx, edi                ;
        and     ecx, esi                ;
        por     mm4, mm5                ;
        por     mm6, mm7                ;

        /* Disc #5, flip direction 1. */
        /* Disc #5, flip direction 6. */
        movq    mm5, mm4                ;
        movq    mm7, mm6                ;
        psllq   mm5, 8                  ;
        psrlq   mm7, 8                  ;
        mov     eax, ebx                ;
        mov     edx, ecx                ;
        pand    mm5, mm3                ;
        pand    mm7, mm3                ;
        shr     eax, 1                  ;
        shr     edx, 1                  ;
        por     mm4, mm5                ;
        por     mm6, mm7                ;
        and     eax, edi                ;
        and     edx, esi                ;

        /* Disc #6, flip direction 1. */
        /* Disc #6, flip direction 6. */
        movq    mm5, mm4                ;
        movq    mm7, mm6                ;
        or      ebx, eax                ;
        or      ecx, edx                ;
        psllq   mm5, 8                  ;
        psrlq   mm7, 8                  ;
        mov     eax, ebx                ;
        mov     edx, ecx                ;
        pand    mm5, mm3                ;
        pand    mm7, mm3                ;
        shr     eax, 1                  ;
        shr     edx, 1                  ;
        por     mm4, mm5                ;
        por     mm6, mm7                ;
        and     eax, edi                ;
        and     edx, esi                ;
        psllq   mm4, 8                  ;
        psrlq   mm6, 8                  ;
        or      ebx, eax                ;
        or      ecx, edx                ;
        por     mm2, mm4                ;
        por     mm2, mm6                ;

        /* shift=-7   rowDelta=-1   colDelta=1 */
        /* shift=+7   rowDelta=1   colDelta=-1 */

        /* Disc #1, flip direction 2. */
        /* Disc #1, flip direction 5. */
        movq    mm3, mm1                ;
        movq    mm4, mm0                ;
        movq    mm6, mm0                ;
        pand    mm3, dir_mask2          ; 0x007e7e7e7e7e7e00;
                                        ; dir_mask2 of value:
                                        ;   00000000
                                        ;   01111110
                                        ;   01111110
                                        ;   01111110
                                        ;   01111110
                                        ;   01111110
                                        ;   01111110
                                        ;   00000000
        psllq   mm4, 7                  ;
        psrlq   mm6, 7                  ;
        mov     eax, ebx                ;
        mov     edx, ecx                ;
        pand    mm4, mm3                ;
        pand    mm6, mm3                ;
        shr     eax, 1                  ;
        shr     edx, 1                  ;

        /* Disc #2, flip direction 2. */
        /* Disc #2, flip direction 5. */
        movq    mm5, mm4                ;
        movq    mm7, mm6                ;
        and     eax, edi                ;
        and     edx, esi                ;
        psllq   mm5, 7                  ;
        psrlq   mm7, 7                  ;
        or      ebx, eax                ;
        or      ecx, edx                ;
        pand    mm5, mm3                ;
        pand    mm7, mm3                ;
        mov     eax, ebx                ;
        mov     edx, ecx                ;
        por     mm4, mm5                ;
        por     mm6, mm7                ;
        shr     eax, 1                  ;
        shr     edx, 1                  ;

        /* Disc #3, flip direction 2. */
        /* Disc #3, flip direction 5. */
        movq    mm5, mm4                ;
        movq    mm7, mm6                ;
        and     eax, edi                ;
        and     edx, esi                ;
        psllq   mm5, 7                  ;
        psrlq   mm7, 7                  ;
        or      ebx, eax                ;
        or      ecx, edx                ;
        pand    mm5, mm3                ;
        pand    mm7, mm3                ;
        mov     eax, ebx                ;
        mov     edx, ecx                ;
        por     mm4, mm5                ;
        por     mm6, mm7                ;
        shr     eax, 1                  ;
        shr     edx, 1                  ;

        /* Disc #4, flip direction 2. */
        /* Disc #4, flip direction 5. */
        movq    mm5, mm4                ;
        movq    mm7, mm6                ;
        and     eax, edi                ;
        and     edx, esi                ;
        psllq   mm5, 7                  ;
        psrlq   mm7, 7                  ;
        or      ebx, eax                ;
        or      ecx, edx                ;
        pand    mm5, mm3                ;
        pand    mm7, mm3                ;
        mov     eax, ebx                ;
        mov     edx, ecx                ;
        por     mm4, mm5                ;
        por     mm6, mm7                ;
        shr     eax, 1                  ;
        shr     edx, 1                  ;

        /* Disc #5, flip direction 2. */
        /* Disc #5, flip direction 5. */
        movq    mm5, mm4                ;
        movq    mm7, mm6                ;
        and     eax, edi                ;
        and     edx, esi                ;
        psllq   mm5, 7                  ;
        psrlq   mm7, 7                  ;
        or      ebx, eax                ;
        or      ecx, edx                ;
        pand    mm5, mm3                ;
        pand    mm7, mm3                ;
        shr     ebx, 1                  ;
        shr     ecx, 1                  ;
        por     mm4, mm5                ;
        por     mm6, mm7                ;

        /* serialize here: add horizontal shr flips. */

        movd    mm5, ebx                ;
        psllq   mm5, 32                 ;
        movd    mm7, ecx                ;
        por     mm5, mm7                ;
        por     mm2, mm5                ;
        pop     ebx                     ;

        /* Disc #6, flip direction 2. */
        /* Disc #6, flip direction 5. */
        movq    mm5, mm4                ;
        movq    mm7, mm6                ;
        psllq   mm5, 7                  ;
        psrlq   mm7, 7                  ;
        pop     ecx                     ;
        pand    mm5, mm3                ;
        pand    mm7, mm3                ;
        pop     edi                     ;
        por     mm4, mm5                ;
        por     mm6, mm7                ;
        pop     esi                     ;
        psllq   mm4, 7                  ;
        psrlq   mm6, 7                  ;
        por     mm2, mm4                ;
        por     mm2, mm6                ;

        /* mm2 is the pseudo-feasible moves at this point. */
        /* Let mm7 be the feasible moves, i.e., mm2 restricted to empty squares. */

        movq    mm7, mm0                ;
        por     mm7, mm1                ;
        pandn   mm7, mm2                ;

        /* Count the moves, i.e., the number of bits set in mm7. */

        movq    mm1, mm7                ;
        psrld   mm7, 1                  ;
        pand    mm7, c55                ; c55 = 0x5555555555555555
        psubd   mm1, mm7                ;
        movq    mm7, mm1                ;
        psrld   mm1, 2                  ;
        pand    mm7, c33                ; c33 = 0x3333333333333333;
        pand    mm1, c33                ; c33 = 0x3333333333333333;
        paddd   mm7, mm1                ;
        movq    mm1, mm7                ;
        psrld   mm7, 4                  ;
        paddd   mm7, mm1                ;
        pand    mm7, c0f                ; c0f = 0x0f0f0f0f0f0f0f0f;

        movq    mm1, mm7                ;
        psrld   mm7, 8                  ;
        paddd   mm7, mm1                ;
        movq    mm1, mm7                ;
        psrld   mm7, 16                 ;
        paddd   mm7, mm1                ;
        movq    mm1, mm7                ;
        psrlq   mm7, 32                 ;
        paddd   mm7, mm1                ;
        movd    eax, mm7                ;
        and     eax, 63                 ;
        mov     count, eax              ;

        //
        emms                            ;
    }
    return count;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
•Alpha-Beta剪枝(Alpha-Beta pruning) 对于一般的最大最小搜索,即使每一步只有很少的下法,搜索的位置也会增长非常快;在大多数的中局棋形中,每步平均有十个位置可以下棋,于是假设搜索九步(程序术语称为搜索深度为九),就要搜索十亿个位置(十的九次方),极大地限制了电脑的棋。于是采用了一个方法,叫“alpha-beta剪枝”,它大为减少了检测的数目,提高电脑搜索的速度。各种各样的这种算法用于所有的强Othello程序。(同样用于其他棋类游戏,如国际象棋和跳棋)。为了搜索九步,一个好的程序只用搜索十万到一百万个位置,而不是没用前的十亿次。 •估值 这是一个程序中最重要的部分,如果这个模块太弱,则就算算法再好也没有用。我将要叙述三种不同的估值函数范例。我相信,大多数的Othello程序都可以归结于此。 棋格表:这种算法的意思是,不同的棋格有不同的值,角的值大而角旁边的格子值要小。忽视对称的话,棋盘上有10个不同的位置,每个格子根据三种可能性赋值:黑棋、白棋和空。更有经验的逼近是在游戏的不同阶段对格子赋予不同的值。例如,角在开局阶段和中局开始阶段比终局阶段更重要。采用这种算法的程序总是很弱(我这样认为),但另一方面,它很容易实现,于是许多程序开始采用这种逼近。 基于行动的估值:这种更久远的接近有很强的全局观,而不像棋格表那样局部化。观察表明,许多人类玩者努获得最大的行动(可下棋的数目)和潜在行动(临近对手棋子的空格,见技巧篇)。如果代码有效率的话,可以很快发现,它们提高棋很多。 基于模的估值 :正如上面提及的,许多中等量的程序经常合并一些边角判断的知识,最大行动和潜在行动是全局特性,但是他们可以被切割成局部配置,再加在一起。棋子最少化也是如此。这导致了以下的概括:在估值函数中仅用局部配置(模),这通常用单独计算每一行、一列、斜边和角落判断,再加在一起来实现。 估值合并:一般程序的估值基于许多的参数,如行动、潜在行动、余裕手、边角判断、稳定子。但是怎么样将他们合并起来得到一个估值呢?一般采用线性合并。设a1,a2,a3,a4为参数,则估值s:=n1*a1+n2*a2+n3*a3+n4*a4。其中n1,n2,n3,n4为常数,术语叫“权重”(weight),它决定了参数的重要性,它们取决于统计值。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值