【国象AI】棋子移动

来源:互联网 发布:增值税发票认证软件 编辑:程序博客网 时间:2024/06/11 21:54

数据结构为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];//对于王还有被将等情况的判断

后面

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

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

原创粉丝点击