【国象AI】棋子移动

数据结构为64位棋盘

  • pos 0-63 代表在哪个格子
  • Bit64 mask[64]; 把0-63格子转到64位

_Bit64_ move_Pawn[2][64];

//初始化
for (int pos = 0; pos < 64; pos++)
    {
        pos_bit = mask[pos];

        move_Pawn[WHITE_SIDE][pos] = ((pos_bit & 0x00FFFFFFFFFFFF00) >> 8) | ((pos_bit & 0x00FF000000000000) >> 16);
        move_Pawn[BLACK_SIDE][pos] = ((pos_bit & 0x00FFFFFFFFFFFF00) << 8) | ((pos_bit & 0x000000000000FF00) << 16);
//移动
        if (WHITE_SIDE == color)
        {
            final_position = move_Pawn[WHITE_SIDE][pos];
            //去除掉前方一格被挡仍允许走两格的情况
            final_position &= (~(((White_All.GetData() | Black_All.GetData()) & mask[pos - 8]) >> 8));
            //去除掉前方被敌方棋子阻挡仍允许直线吃子的情况
            final_position &= ~(Black_All.GetData());
            //斜向吃子,排除<<7引起的同行A列H列互吃的BUG
            final_position |= ((posbit & (_Bit64_)0x7F7F7F7F7F7F7F7F) >> 7 | (posbit & (_Bit64_)0xFEFEFEFEFEFEFEFE) >> 9) & Black_All.GetData();
            //过路兵判定
            if (En_passant != NONE && pos >> 3 == 3)
            {
                if ((pos & 7) == En_passant - 1)
                    final_position |= mask[pos] >> 7;
                else if ((pos & 7) == En_passant + 1)
                    final_position |= mask[pos] >> 9;
            }
        }

int knightsq[8] = { -17, -15, -6, 10, 17, 15, 6, -10 };

//初始化
for (int pos = 0; pos < 64; pos++){
tempN = 0;
    for (int k = 0; k < KNIGHT_POSSIBLE_MOVE; k++)
        {
            new_pos = pos + knightsq[k];
            if (new_pos >= 0 && new_pos < 64)
            {
                /* 马所在的格子的行数/列数与它下一步可以走的格子的行数/列数之间的差须小于3 */
                if ((((pos >> 3) - (new_pos >> 3))*((pos >> 3) - (new_pos >> 3)) +
                    ((pos & 7) - (new_pos & 7))*((pos & 7) - (new_pos & 7))) == 5)
                    tempN |= mask[new_pos];
            }
        }
        move_Knight[pos] = tempN;
}
//移动
final_position = move_Knight[pos];

这里还记录一个是旋转90度的棋盘

//初始化
static const short getline_shift[64] = { 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24, 24, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 40, 40, 40, 48, 48, 48, 48, 48, 48, 48, 48, 56, 56, 56, 56, 56, 56, 56, 56 };
static const short getline_shift_trans[64] = { 0, 8, 16, 24, 32, 40, 48, 56, 0, 8, 16, 24, 32, 40, 48, 56, 0, 8, 16, 24, 32, 40, 48, 56, 0, 8, 16, 24, 32, 40, 48, 56, 0, 8, 16, 24, 32, 40, 48, 56, 0, 8, 16, 24, 32, 40, 48, 56, 0, 8, 16, 24, 32, 40, 48, 56, 0, 8, 16, 24, 32, 40, 48, 56 };
//移动

        final_position |= rank_attacks[pos][((White_All.GetData() | Black_All.GetData()) >> getline_shift[pos]) & 255];
        final_position |= file_attacks[pos][((White_All_trans.GetData() | Black_All_trans.GetData()) >> getline_shift_trans[pos]) & 255];

旋转45、-45的棋盘

//初始化
static const short length_A8H1_diag[64] = { 8, 7, 6, 5, 4, 3, 2, 1, 7, 8, 7, 6, 5, 4, 3, 2, 6, 7, 8, 7, 6, 5, 4, 3, 5, 6, 7, 8, 7, 6, 5, 4, 4, 5, 6, 7, 8, 7, 6, 5, 3, 4, 5, 6, 7, 8, 7, 6, 2, 3, 4, 5, 6, 7, 8, 7, 1, 2, 3, 4, 5, 6, 7, 8 };
static const short length_H8A1_diag[64] = { 1, 2, 3, 4, 5, 6, 7, 8, 2, 3, 4, 5, 6, 7, 8, 7, 3, 4, 5, 6, 7, 8, 7, 6, 4, 5, 6, 7, 8, 7, 6, 5, 5, 6, 7, 8, 7, 6, 5, 4, 6, 7, 8, 7, 6, 5, 4, 3, 7, 8, 7, 6, 5, 4, 3, 2, 8, 7, 6, 5, 4, 3, 2, 1 };
static const short shade_A8H1[64] = { 255, 127, 63, 31, 15, 7, 3, 1, 127, 255, 127, 63, 31, 15, 7, 3, 63, 127, 255, 127, 63, 31, 15, 7, 31, 63, 127, 255, 127, 63, 31, 15, 15, 31, 63, 127, 255, 127, 63, 31, 7, 15, 31, 63, 127, 255, 127, 63, 3, 7, 15, 31, 63, 127, 255, 127, 1, 3, 7, 15, 31, 63, 127, 255 };
static const short shade_H8A1[64] = { 1, 3, 7, 15, 31, 63, 127, 255, 3, 7, 15, 31, 63, 127, 255, 127, 7, 15, 31, 63, 127, 255, 127, 63, 15, 31, 63, 127, 255, 127, 63, 31, 31, 63, 127, 255, 127, 63, 31, 15, 63, 127, 255, 127, 63, 31, 15, 7, 127, 255, 127, 63, 31, 15, 7, 3, 255, 127, 63, 31, 15, 7, 3, 1 };
static const _Pos_ start_pos_A8H1[64] = { 28, 21, 15, 10, 6, 3, 1, 0, 36, 28, 21, 15, 10, 6, 3, 1, 43, 36, 28, 21, 15, 10, 6, 3, 49, 43, 36, 28, 21, 15, 10, 6, 54, 49, 43, 36, 28, 21, 15, 10, 58, 54, 49, 43, 36, 28, 21, 15, 61, 58, 54, 49, 43, 36, 28, 21, 63, 61, 58, 54, 49, 43, 36, 28 };
static const _Pos_ start_pos_H8A1[64] = { 0, 1, 3, 6, 10, 15, 21, 28, 1, 3, 6, 10, 15, 21, 28, 36, 3, 6, 10, 15, 21, 28, 36, 43, 6, 10, 15, 21, 28, 36, 43, 49, 10, 15, 21, 28, 36, 43, 49, 54, 15, 21, 28, 36, 43, 49, 54, 58, 21, 28, 36, 43, 49, 54, 58, 61, 28, 36, 43, 49, 54, 58, 61, 63 };


    /* 象或后在A8-H1方向移动的预先计算 */
    for (int pos = 0; pos < 64; pos++)
    {
        //求出当前格子在所在斜线中是第几格
        const short index = (((pos >> 3) >(pos & 7)) ? (pos & 7) : (pos >> 3));

        //传入的pattern中的有效位数应不高于pos所在的斜线长度
        for (int pattern = 0; pattern < (1 << length_A8H1_diag[pos]); pattern++)
        {
            //计算从这个格子朝左上方走的着法
            tempx = pos >> 3;
            tempy = pos & 7;
            pos_bit = mask[pos];
            pattern_bit = 1 << index;           //获取当前位置在棋形pattern中的位,通过移动pattern_bit判断斜线中是否与棋子冲突
            while (1)
            {
                pos_bit = pos_bit >> 9;
                pattern_bit = pattern_bit >> 1;

                if (--tempx < 0 || --tempy < 0)
                    break;
                else                            //未越界
                    diag_A8H1_attacks[pos][pattern] |= pos_bit;
                if (pattern_bit & pattern)      //与棋子冲突
                    break;
            }

            //计算从这个格子朝右下方走的着法
            //.....
            }
        }
    }

    /* 象或后在H8-A1方向移动的预先计算 */
    //.....
    }
//移动
        final_position |= diag_A8H1_attacks[pos][((White_All_L45.GetData() | Black_All_L45.GetData()) >> start_pos_A8H1[pos]) & (shade_A8H1[pos])];
        final_position |= diag_H8A1_attacks[pos][((White_All_R45.GetData() | Black_All_R45.GetData()) >> start_pos_H8A1[pos]) & (shade_H8A1[pos])];

车+象

int kingsq[KING_POSSIBLE_MOVE] = { -9, -8, -7, -1, 1, 7, 8, 9 };
//初始化
for (int pos = 0; pos < 64; pos++){
    tempK = 0;
    for (int k = 0; k < KING_POSSIBLE_MOVE; k++)
        {
            new_pos = pos + kingsq[k];
            if (new_pos >= 0 && new_pos < 64)
            {
                if (((((pos >> 3) - (new_pos >> 3))*((pos >> 3) - (new_pos >> 3))) <= 1) &&
                    ((((pos & 7) - (new_pos & 7))*((pos & 7) - (new_pos & 7))) <= 1))
                    tempK |= mask[new_pos];
            }
        }
        move_King[pos] = tempK;
}
//移动
final_position = move_King[pos];
//对于王还有被将等情况的判断

后面

可移动棋子最后要去掉被己方棋子占据的格子

@三三学长 学长负责了很大一部分的优化和调试

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值