示例#1
0
void ChessBoard::generatePawnMoves(ChessBoard& board, int sqSrc, Moves& mvs)
{
    int sqDst;

    if (board.m_sdPlayer != SQ_SIDE(sqSrc))
    {
        sqDst = sqSrc - 1;
        if (IN_BOARD(sqDst) && board.canMove(board, sqSrc, sqDst))
        {
            mvs.append(ChessBoard::mv(sqSrc, sqDst));
        }
        sqDst = sqSrc + 1;
        if (IN_BOARD(sqDst) && board.canMove(board, sqSrc, sqDst))
        {
            mvs.append(ChessBoard::mv(sqSrc, sqDst));
        }
    }


    if (board.m_sdPlayer==0)
    {
        sqDst = sqSrc - 16;
    }
    else{
        sqDst = sqSrc + 16;
    }
    if (IN_BOARD(sqDst) && board.canMove(board, sqSrc, sqDst))
    {
        mvs.append(ChessBoard::mv(sqSrc, sqDst));
    }
}
示例#2
0
文件: movegen.c 项目: phenri/Claudia
inline int BlackPawnMoves(const BOARD *board, SQUARE orig, MOVE *poss_moves, int nmoves, char noncaptures)
{
    SQUARE dest = orig + ROW_DOWN;
    if(noncaptures && IN_BOARD(dest) && board->squares[dest] == EMPTY){
        if(ROW(dest) == FIRST_ROW){
            if(poss_moves) poss_moves[nmoves] = Move(B_QUEEN, dest, orig);
            nmoves++;
            if(poss_moves) poss_moves[nmoves] = Move(B_KNIGHT, dest, orig);
            nmoves++;
            if(poss_moves) poss_moves[nmoves] = Move(B_ROOK, dest, orig);
            nmoves++;
            if(poss_moves) poss_moves[nmoves] = Move(B_BISHOP, dest, orig);
            nmoves++;
        }else{
            if(poss_moves) poss_moves[nmoves] = Move(0, dest, orig);
            nmoves++;
            if(ROW(dest) == SIXTH_ROW){
                dest = dest + ROW_DOWN;
                if(IN_BOARD(dest)){
                    if(board->squares[dest] == EMPTY){
                        if(poss_moves) poss_moves[nmoves] = Move(0, dest, orig);
                        nmoves++;
                    }
                }
            }
        }
    }
    for(int i = 0; b_pawn_capture[i]; i++){
        dest = orig + b_pawn_capture[i];
        if(IN_BOARD(dest)){
            if(board->squares[dest] == EMPTY){
                if(dest == board->en_passant){
                    if(poss_moves) poss_moves[nmoves] = Move(0, dest, orig);
                    nmoves++;
                }
            }else if(GET_COLOR(board->squares[dest])){
                if(ROW(dest) == FIRST_ROW){
                    if(poss_moves) poss_moves[nmoves] = Move(B_QUEEN, dest, orig);   
                    nmoves++;
                    if(poss_moves) poss_moves[nmoves] = Move(B_KNIGHT, dest, orig);
                    nmoves++;
                    if(poss_moves) poss_moves[nmoves] = Move(B_ROOK, dest, orig);
                    nmoves++;
                    if(poss_moves) poss_moves[nmoves] = Move(B_BISHOP, dest, orig);
                    nmoves++;
                }else{
                    if(poss_moves) poss_moves[nmoves] = Move(0, dest, orig);
                    nmoves++;
                }
            }
        }
    }
    return nmoves;
}
示例#3
0
文件: movegen.c 项目: phenri/Claudia
inline int WhitePawnMoves(const BOARD *board, SQUARE orig, MOVE *poss_moves, int nmoves, char noncaptures)
{
    SQUARE dest = orig + ROW_UP;
    if(noncaptures && IN_BOARD(dest) && board->squares[dest] == EMPTY){
        if(ROW(dest) == EIGHT_ROW){            /*Promotions.*/
            if(poss_moves) poss_moves[nmoves] = Move(W_QUEEN, dest, orig);
            nmoves++;
            if(poss_moves) poss_moves[nmoves] = Move(W_KNIGHT, dest, orig);
            nmoves++;
            if(poss_moves) poss_moves[nmoves] = Move(W_ROOK, dest, orig);
            nmoves++;
            if(poss_moves) poss_moves[nmoves] = Move(W_BISHOP, dest, orig);
            nmoves++;
        }else{
            if(poss_moves) poss_moves[nmoves] = Move(0, dest, orig);
            nmoves++;
            if(ROW(dest) == THIRD_ROW){
                dest = dest + ROW_UP;
                if(IN_BOARD(dest) && board->squares[dest] == EMPTY){
                    if(poss_moves) poss_moves[nmoves] = Move(0, dest, orig);
                    nmoves++;
                }
            }
        }
    }
    for(int i = 0; w_pawn_capture[i]; i++){
        dest = orig + w_pawn_capture[i];
        if(IN_BOARD(dest)){
            if(board->squares[dest] == EMPTY){
                if(dest == board->en_passant){        /*Captures en Passant.*/
                    if(poss_moves) poss_moves[nmoves] = Move(0, dest, orig);
                    nmoves++;
                }
            }else if(GET_COLOR(board->squares[dest]) == BLACK){
                if(ROW(dest) == EIGHT_ROW){
                    if(poss_moves) poss_moves[nmoves] = Move(W_QUEEN, dest, orig);
                    nmoves++;
                    if(poss_moves) poss_moves[nmoves] = Move(W_KNIGHT, dest, orig);
                    nmoves++;
                    if(poss_moves) poss_moves[nmoves] = Move(W_ROOK, dest, orig);
                    nmoves++;
                    if(poss_moves) poss_moves[nmoves] = Move(W_BISHOP, dest, orig);
                    nmoves++;
                }else{
                    if(poss_moves) poss_moves[nmoves] = Move(0, dest, orig);
                    nmoves++;
                }
            }
        }
    }
    return nmoves;
}
示例#4
0
文件: movegen.c 项目: phenri/Claudia
inline int NonSlidingMoves(const BOARD *board, SQUARE orig, MOVE *poss_moves, int nmoves, char noncaptures)
{
    PIECE p = board->squares[orig];
    for(const SQUARE *d = deltas[p]; *d; d++){
        SQUARE dest = orig + *d;
        if(IN_BOARD(dest)){
            if(board->squares[dest] == EMPTY){
                if(noncaptures){
                    if(poss_moves) poss_moves[nmoves] = Move(0, dest, orig);
                    nmoves++;
                }
            }else if(GET_COLOR(board->squares[dest]) != GET_COLOR(p)){
                if(poss_moves) poss_moves[nmoves] = Move(0, dest, orig);
                nmoves++;
            }
        }
    }
    return nmoves;
}
示例#5
0
文件: movegen.c 项目: phenri/Claudia
inline int SlidingMoves(const BOARD *board, SQUARE orig, MOVE *poss_moves, int nmoves, char noncaptures)
{
    PIECE p = board->squares[orig];
    for(const SQUARE *d = deltas[p]; *d; d++){
        for(SQUARE dest = orig + *d; IN_BOARD(dest); dest += *d){
            if(board->squares[dest] == EMPTY){
                if(noncaptures){
                    if(poss_moves) poss_moves[nmoves] = Move(0, dest, orig);
                    nmoves++;
                }
            }else if(GET_COLOR(board->squares[dest]) != GET_COLOR(p)) { 
                /*Different color Piece, capture, stop sliding.*/
                if(poss_moves) poss_moves[nmoves] = Move(0, dest, orig);
                nmoves++;
                break;
            }else break;        /*same color piece, stop sliding.*/
        }
    }
    return nmoves;
}
示例#6
0
void ChessBoard::generateBishopMoves(ChessBoard& board, int sqSrc, Moves& mvs)
{
    static const int ccBishopDelta[4] = {-34, -30, 30, 34};
    static const int ccBishopPin[4] = {-17, -15, 15, 17};
    for(int i=0; i<4; i++)
    {
        int sqDst = sqSrc + ccBishopDelta[i];
        if (!IN_BOARD(sqDst)) continue;
        int sqPin = sqSrc + ccBishopPin[i];
        if (board.m_data[sqPin]) continue;
        if (SAME_HALF(sqSrc, sqDst))
        {
            if (board.isInBoard(sqDst) && board.canMove(board, sqSrc, sqDst))
            {
                mvs.append(ChessBoard::mv(sqSrc, sqDst));
            }
        }

    }
}
示例#7
0
void ChessBoard::generateKnightMoves(ChessBoard& board, int sqSrc, Moves& mvs)
{
    static const int ccKingDelta[4] = {-16, -1, 1, 16};
    static const int ccKnightDelta[4][2] = {{-33, -31}, {-18, 14}, {-14, 18}, {31, 33}};
    for (int i=0; i<4; i++)
    {
        int sqPin = sqSrc + ccKingDelta[i];
        if (IN_BOARD(sqPin) && board.m_data[sqPin]==0)
        {
            //马腿没有东西
            for(int j=0; j<2; j++)
            {
                int sqDst = sqSrc + ccKnightDelta[i][j];
                if (board.isInBoard(sqDst) && board.canMove(board, sqSrc, sqDst))
                {
                    mvs.append(ChessBoard::mv(sqSrc, sqDst));
                }
            }
        }
    }
}
示例#8
0
void ChessBoard::generateCannonMoves(ChessBoard& board, int sqSrc, Moves& mvs)
{
    static const int delta[4] = {-16, -1, 1, 16};
    for(int i=0; i<4; i++)
    {
        int sqDst = sqSrc;
        bool skiped = false;
        while (true)
        {
            sqDst += delta[i];
            if (!IN_BOARD(sqDst)) break;
            if (!board.m_data[sqDst])
            {
                if (!skiped)
                {
                    mvs.append(ChessBoard::mv(sqSrc, sqDst));
                }
            }
            else{
                if (!skiped)
                {
                    skiped = true;
                }
                else{
                    int pc = board.m_data[sqDst];
                    if (pc!=0)
                    {
                        if (board.canMove(board, sqSrc, sqDst))
                        {
                            mvs.append(ChessBoard::mv(sqSrc, sqDst));
                        }
                    }
                    break;
                }
            }
        }
    }
}
示例#9
0
void ChessBoard::generateRookMoves(ChessBoard& board, int sqSrc, Moves& mvs)
{
    static const int delta[4] = {-16, -1, 1, 16};
    for(int i=0; i<4; i++)
    {
        int sqDst = sqSrc;
        while (true)
        {
            sqDst += delta[i];
            if (!IN_BOARD(sqDst)) break;
            if (!board.m_data[sqDst])
            {                
                mvs.append(ChessBoard::mv(sqSrc, sqDst));
            }
            else{
                if (board.canMove(board, sqSrc, sqDst))
                {
                    mvs.append(ChessBoard::mv(sqSrc, sqDst));
                }
                break;
            }
        }
    }
}
BOOL _PositionStruct::Checked() const {
  int i, j, sqSrc, sqDst;
  int pcSelfSide, pcOppSide, pcDst, nDelta;
  pcSelfSide = SIDE_TAG(sdPlayer);
  pcOppSide = OPP_SIDE_TAG(sdPlayer);

  for (sqSrc = 0; sqSrc < 256; sqSrc ++) {
    if (ucpcSquares[sqSrc] != pcSelfSide + PIECE_KING) {
      continue;
    }

    if (ucpcSquares[SQUARE_FORWARD(sqSrc, sdPlayer)] == pcOppSide + PIECE_PAWN) {
      return TRUE;
    }
    for (nDelta = -1; nDelta <= 1; nDelta += 2) {
      if (ucpcSquares[sqSrc + nDelta] == pcOppSide + PIECE_PAWN) {
        return TRUE;
      }
    }

    for (i = 0; i < 4; i ++) {
      if (ucpcSquares[sqSrc + ccAdvisorDelta[i]] != 0) {
        continue;
      }
      for (j = 0; j < 2; j ++) {
        pcDst = ucpcSquares[sqSrc + ccKnightCheckDelta[i][j]];
        if (pcDst == pcOppSide + PIECE_KNIGHT) {
          return TRUE;
        }
      }
    }
    
    for (i = 0; i < 4; i ++) {
      nDelta = ccKingDelta[i];
      sqDst = sqSrc + nDelta;
      while (IN_BOARD(sqDst)) {
        pcDst = ucpcSquares[sqDst];
        if (pcDst != 0) {
          if (pcDst == pcOppSide + PIECE_ROOK || pcDst == pcOppSide + PIECE_KING) {
            return TRUE;
          }
          break;
        }
        sqDst += nDelta;
      }
      sqDst += nDelta;
      while (IN_BOARD(sqDst)) {
        int pcDst = ucpcSquares[sqDst];
        if (pcDst != 0) {
          if (pcDst == pcOppSide + PIECE_CANNON) {
            return TRUE;
          }
          break;
        }
        sqDst += nDelta;
      }
    }
    return FALSE;
  }
  return FALSE;
}
int _PositionStruct::GenerateMovesFrom(int sqSrc, int *mvs, BOOL bCapture) const {
  int i, j, nGenMoves, nDelta, sqDst;
  int pcSelfSide, pcOppSide, pcSrc, pcDst;

  nGenMoves = 0;
  pcSelfSide = SIDE_TAG(sdPlayer);
  pcOppSide = OPP_SIDE_TAG(sdPlayer);
  if (sqSrc >= 0 && sqSrc < 256) {

    pcSrc = ucpcSquares[sqSrc];
    if ((pcSrc & pcSelfSide) == 0) {
      return nGenMoves;
    }

    switch (pcSrc - pcSelfSide) {
    case PIECE_KING:
      for (i = 0; i < 4; i ++) {
        sqDst = sqSrc + ccKingDelta[i];
        if (!IN_FORT(sqDst)) {
          continue;
        }
        pcDst = ucpcSquares[sqDst];
        if (bCapture ? (pcDst & pcOppSide) != 0 : (pcDst & pcSelfSide) == 0) {
          mvs[nGenMoves] = MOVE(sqSrc, sqDst);
          nGenMoves ++;
        }
      }
      break;
    case PIECE_ADVISOR:
      for (i = 0; i < 4; i ++) {
        sqDst = sqSrc + ccAdvisorDelta[i];
        if (!IN_FORT(sqDst)) {
          continue;
        }
        pcDst = ucpcSquares[sqDst];
        if (bCapture ? (pcDst & pcOppSide) != 0 : (pcDst & pcSelfSide) == 0) {
          mvs[nGenMoves] = MOVE(sqSrc, sqDst);
          nGenMoves ++;
        }
      }
      break;
    case PIECE_BISHOP:
      for (i = 0; i < 4; i ++) {
        sqDst = sqSrc + ccAdvisorDelta[i];
        if (!(IN_BOARD(sqDst) && HOME_HALF(sqDst, sdPlayer) && ucpcSquares[sqDst] == 0)) {
          continue;
        }
        sqDst += ccAdvisorDelta[i];
        pcDst = ucpcSquares[sqDst];
        if (bCapture ? (pcDst & pcOppSide) != 0 : (pcDst & pcSelfSide) == 0) {
          mvs[nGenMoves] = MOVE(sqSrc, sqDst);
          nGenMoves ++;
        }
      }
      break;
    case PIECE_KNIGHT:
      for (i = 0; i < 4; i ++) {
        sqDst = sqSrc + ccKingDelta[i];
        if (ucpcSquares[sqDst] != 0) {
          continue;
        }
        for (j = 0; j < 2; j ++) {
          sqDst = sqSrc + ccKnightDelta[i][j];
          if (!IN_BOARD(sqDst)) {
            continue;
          }
          pcDst = ucpcSquares[sqDst];
          if (bCapture ? (pcDst & pcOppSide) != 0 : (pcDst & pcSelfSide) == 0) {
            mvs[nGenMoves] = MOVE(sqSrc, sqDst);
            nGenMoves ++;
          }
        }
      }
      break;
    case PIECE_ROOK:
      for (i = 0; i < 4; i ++) {
        nDelta = ccKingDelta[i];
        sqDst = sqSrc + nDelta;
        while (IN_BOARD(sqDst)) {
          pcDst = ucpcSquares[sqDst];
          if (pcDst == 0) {
            if (!bCapture) {
              mvs[nGenMoves] = MOVE(sqSrc, sqDst);
              nGenMoves ++;
            }
          } else {
            if ((pcDst & pcOppSide) != 0) {
              mvs[nGenMoves] = MOVE(sqSrc, sqDst);
              nGenMoves ++;
            }
            break;
          }
          sqDst += nDelta;
        }
      }
      break;
    case PIECE_CANNON:
      for (i = 0; i < 4; i ++) {
        nDelta = ccKingDelta[i];
        sqDst = sqSrc + nDelta;
        while (IN_BOARD(sqDst)) {
          pcDst = ucpcSquares[sqDst];
          if (pcDst == 0) {
            if (!bCapture) {
              mvs[nGenMoves] = MOVE(sqSrc, sqDst);
              nGenMoves ++;
            }
          } else {
            break;
          }
          sqDst += nDelta;
        }
        sqDst += nDelta;
        while (IN_BOARD(sqDst)) {
          pcDst = ucpcSquares[sqDst];
          if (pcDst != 0) {
            if ((pcDst & pcOppSide) != 0) {
              mvs[nGenMoves] = MOVE(sqSrc, sqDst);
              nGenMoves ++;
            }
            break;
          }
          sqDst += nDelta;
        }
      }
      break;
    case PIECE_PAWN:
      sqDst = SQUARE_FORWARD(sqSrc, sdPlayer);
      if (IN_BOARD(sqDst)) {
        pcDst = ucpcSquares[sqDst];
        if (bCapture ? (pcDst & pcOppSide) != 0 : (pcDst & pcSelfSide) == 0) {
          mvs[nGenMoves] = MOVE(sqSrc, sqDst);
          nGenMoves ++;
        }
      }
      if (AWAY_HALF(sqSrc, sdPlayer)) {
        for (nDelta = -1; nDelta <= 1; nDelta += 2) {
          sqDst = sqSrc + nDelta;
          if (IN_BOARD(sqDst)) {
            pcDst = ucpcSquares[sqDst];
            if (bCapture ? (pcDst & pcOppSide) != 0 : (pcDst & pcSelfSide) == 0) {
              mvs[nGenMoves] = MOVE(sqSrc, sqDst);
              nGenMoves ++;
            }
          }
        }
      }
      break;
    }
  }
  return nGenMoves;
}
示例#12
0
void PreGenInit(void) {
  int i, j, k, n, sqSrc, sqDst;
  RC4Struct rc4;
  SlideMoveStruct smv;
  SlideMaskStruct sms;

  // 首先初始化Zobrist键值表
  rc4.InitZero();
  PreGen.zobrPlayer.InitRC4(rc4);
  for (i = 0; i < 14; i ++) {
    for (j = 0; j < 256; j ++) {
      PreGen.zobrTable[i][j].InitRC4(rc4);
    }
  }

  // 然后初始化屏蔽位行和屏蔽位列
  // 注:位行和位列不包括棋盘以外的位,所以就会频繁使用"+/- RANK_TOP/FILE_LEFT"
  for (sqSrc = 0; sqSrc < 256; sqSrc ++) {
    if (IN_BOARD(sqSrc)) {
      PreGen.wBitRankMask[sqSrc] = 1 << (FILE_X(sqSrc) - FILE_LEFT);
      PreGen.wBitFileMask[sqSrc] = 1 << (RANK_Y(sqSrc) - RANK_TOP);
    } else {
      PreGen.wBitRankMask[sqSrc] = 0;
      PreGen.wBitFileMask[sqSrc] = 0;
    }
  }

  // 然后生成车炮横向的预置数组(数组的应用参阅"pregen.h")
  for (i = 0; i < 9; i ++) {
    for (j = 0; j < 512; j ++) {
      // 初始化借助于“位行”的车和炮的着法预生成数组,包括以下几个步骤:
      // 1. 初始化临时变量"SlideMoveTab",假设没有着法,用起始格填充
      smv.ucNonCap[0] = smv.ucNonCap[1] = smv.ucRookCap[0] = smv.ucRookCap[1] =
      smv.ucCannonCap[0] = smv.ucCannonCap[1] = smv.ucSuperCap[0] = smv.ucSuperCap[1] = i + FILE_LEFT;
      sms.wNonCap = sms.wRookCap = sms.wCannonCap = sms.wSuperCap = 0;
      // 提示:参阅"pregen.h",...[0]表示最大一格,向右移动和下移动都用[0],反之亦然
      // 2. 考虑向右移动的目标格,填充...[0],
      for (k = i + 1; k <= 8; k ++) {
        if ((j & (1 << k)) != 0) {
          smv.ucRookCap[0] = FILE_DISP(k + FILE_LEFT);
          sms.wRookCap |= 1 << k;
          break;
        }
        smv.ucNonCap[0] = FILE_DISP(k + FILE_LEFT);
        sms.wNonCap |= 1 << k;
      }
      for (k ++; k <= 8; k ++) {
        if ((j & (1 << k)) != 0) {
          smv.ucCannonCap[0] = FILE_DISP(k + FILE_LEFT);
          sms.wCannonCap |= 1 << k;
          break;
        }
      }
      for (k ++; k <= 8; k ++) {
        if ((j & (1 << k)) != 0) {
          smv.ucSuperCap[0] = FILE_DISP(k + FILE_LEFT);
          sms.wSuperCap |= 1 << k;
          break;
        }
      }
      // 3. 考虑向左移动的目标格,填充...[1]
      for (k = i - 1; k >= 0; k --) {
        if ((j & (1 << k)) != 0) {
          smv.ucRookCap[1] = FILE_DISP(k + FILE_LEFT);
          sms.wRookCap |= 1 << k;
          break;
        }
        smv.ucNonCap[1] = FILE_DISP(k + FILE_LEFT);
        sms.wNonCap |= 1 << k;
      }
      for (k --; k >= 0; k --) {
        if ((j & (1 << k)) != 0) {
          smv.ucCannonCap[1] = FILE_DISP(k + FILE_LEFT);
          sms.wCannonCap |= 1 << k;
          break;
        }
      }
      for (k --; k >= 0; k --) {
        if ((j & (1 << k)) != 0) {
          smv.ucSuperCap[1] = FILE_DISP(k + FILE_LEFT);
          sms.wSuperCap |= 1 << k;
          break;
        }
      }
      // 4. 为"smv"和"sms"的值作断言
      __ASSERT_BOUND_2(3, smv.ucNonCap[1], smv.ucNonCap[0], 11);
      __ASSERT_BOUND_2(3, smv.ucRookCap[1], smv.ucRookCap[0], 11);
      __ASSERT_BOUND_2(3, smv.ucCannonCap[1], smv.ucCannonCap[0], 11);
      __ASSERT_BOUND_2(3, smv.ucSuperCap[1], smv.ucSuperCap[0], 11);
      __ASSERT_BITRANK(sms.wNonCap);
      __ASSERT_BITRANK(sms.wRookCap);
      __ASSERT_BITRANK(sms.wCannonCap);
      __ASSERT_BITRANK(sms.wSuperCap);
      // 5. 将临时变量"smv"和"sms"拷贝到着法预生成数组中
      PreGen.smvRankMoveTab[i][j] = smv;
      PreGen.smsRankMaskTab[i][j] = sms;
    }
  }

  // 然后生成车炮纵向的预置数组(数组的应用参阅"pregen.h")
  for (i = 0; i < 10; i ++) {
    for (j = 0; j < 1024; j ++) {
      // 初始化借助于“位列”的车和炮的着法预生成数组,包括以下几个步骤:
      // 1. 初始化临时变量"smv",假设没有着法,用起始格填充
      smv.ucNonCap[0] = smv.ucNonCap[1] = smv.ucRookCap[0] = smv.ucRookCap[1] =
      smv.ucCannonCap[0] = smv.ucCannonCap[1] = smv.ucSuperCap[0] = smv.ucSuperCap[1] = (i + RANK_TOP) * 16;
      sms.wNonCap = sms.wRookCap = sms.wCannonCap = sms.wSuperCap = 0;
      // 2. 考虑向下移动的目标格,填充...[0]
      for (k = i + 1; k <= 9; k ++) {
        if ((j & (1 << k)) != 0) {
          smv.ucRookCap[0] = RANK_DISP(k + RANK_TOP);
          sms.wRookCap |= 1 << k;
          break;
        }
        smv.ucNonCap[0] = RANK_DISP(k + RANK_TOP);
        sms.wNonCap |= 1 << k;
      }
      for (k ++; k <= 9; k ++) {
        if ((j & (1 << k)) != 0) {
          smv.ucCannonCap[0] = RANK_DISP(k + RANK_TOP);
          sms.wCannonCap |= 1 << k;
          break;
        }
      }
      for (k ++; k <= 9; k ++) {
        if ((j & (1 << k)) != 0) {
          smv.ucSuperCap[0] = RANK_DISP(k + RANK_TOP);
          sms.wSuperCap |= 1 << k;
          break;
        }
      }
      // 3. 考虑向上移动的目标格,填充...[1]
      for (k = i - 1; k >= 0; k --) {
        if ((j & (1 << k)) != 0) {
          smv.ucRookCap[1] = RANK_DISP(k + RANK_TOP);
          sms.wRookCap |= 1 << k;
          break;
        }
        smv.ucNonCap[1] = RANK_DISP(k + RANK_TOP);
        sms.wNonCap |= 1 << k;
      }
      for (k --; k >= 0; k --) {
        if ((j & (1 << k)) != 0) {
          smv.ucCannonCap[1] = RANK_DISP(k + RANK_TOP);
          sms.wCannonCap |= 1 << k;
          break;
        }
      }
      for (k --; k >= 0; k --) {
        if ((j & (1 << k)) != 0) {
          smv.ucSuperCap[1] = RANK_DISP(k + RANK_TOP);
          sms.wSuperCap |= 1 << k;
          break;
        }
      }
      // 4. 为"smv"和"sms"的值作断言
      __ASSERT_BOUND_2(3, smv.ucNonCap[1] >> 4, smv.ucNonCap[0] >> 4, 12);
      __ASSERT_BOUND_2(3, smv.ucRookCap[1] >> 4, smv.ucRookCap[0] >> 4, 12);
      __ASSERT_BOUND_2(3, smv.ucCannonCap[1] >> 4, smv.ucCannonCap[0] >> 4, 12);
      __ASSERT_BOUND_2(3, smv.ucSuperCap[1] >> 4, smv.ucSuperCap[0] >> 4, 12);
      __ASSERT_BITFILE(sms.wNonCap);
      __ASSERT_BITFILE(sms.wRookCap);
      __ASSERT_BITFILE(sms.wCannonCap);
      __ASSERT_BITFILE(sms.wSuperCap);
      // 5. 将临时变量"smv"和"sms"拷贝到着法预生成数组中
      PreGen.smvFileMoveTab[i][j] = smv;
      PreGen.smsFileMaskTab[i][j] = sms;
    }
  }

  // 接下来生成着法预生成数组,连同将军预判数组
  for (sqSrc = 0; sqSrc < 256; sqSrc ++) {
    if (IN_BOARD(sqSrc)) {
      // 生成帅(将)的着法预生成数组
      n = 0;
      for (i = 0; i < 4; i ++) {
        sqDst = sqSrc + cnKingMoveTab[i];
        if (IN_FORT(sqDst)) {
          PreGen.ucsqKingMoves[sqSrc][n] = sqDst;
          n ++;
        }
      }
      __ASSERT(n <= 4);
      PreGen.ucsqKingMoves[sqSrc][n] = 0;
      // 生成仕(士)的着法预生成数组
      n = 0;
      for (i = 0; i < 4; i ++) {
        sqDst = sqSrc + cnAdvisorMoveTab[i];
        if (IN_FORT(sqDst)) {
          PreGen.ucsqAdvisorMoves[sqSrc][n] = sqDst;
          n ++;
        }
      }
      __ASSERT(n <= 4);
      PreGen.ucsqAdvisorMoves[sqSrc][n] = 0;
      // 生成相(象)的着法预生成数组,包括象眼数组
      n = 0;
      for (i = 0; i < 4; i ++) {
        sqDst = sqSrc + cnBishopMoveTab[i];
        if (IN_BOARD(sqDst) && SAME_HALF(sqSrc, sqDst)) {
          PreGen.ucsqBishopMoves[sqSrc][n] = sqDst;
          PreGen.ucsqBishopPins[sqSrc][n] = BISHOP_PIN(sqSrc, sqDst);
          n ++;
        }
      }
      __ASSERT(n <= 4);
      PreGen.ucsqBishopMoves[sqSrc][n] = 0;
      // 生成马的着法预生成数组,包括马腿数组
      n = 0;
      for (i = 0; i < 8; i ++) {
        sqDst = sqSrc + cnKnightMoveTab[i];
        if (IN_BOARD(sqDst)) {
          PreGen.ucsqKnightMoves[sqSrc][n] = sqDst;
          PreGen.ucsqKnightPins[sqSrc][n] = KNIGHT_PIN(sqSrc, sqDst);
          n ++;
        }
      }
      __ASSERT(n <= 8);
      PreGen.ucsqKnightMoves[sqSrc][n] = 0;
      // 生成兵(卒)的着法预生成数组
      for (i = 0; i < 2; i ++) {
        n = 0;
        sqDst = SQUARE_FORWARD(sqSrc, i);
        sqDst = sqSrc + (i == 0 ? -16 : 16);
        if (IN_BOARD(sqDst)) {
          PreGen.ucsqPawnMoves[i][sqSrc][n] = sqDst;
          n ++;
        }
        if (AWAY_HALF(sqSrc, i)) {
          for (j = -1; j <= 1; j += 2) {
            sqDst = sqSrc + j;
            if (IN_BOARD(sqDst)) {
              PreGen.ucsqPawnMoves[i][sqSrc][n] = sqDst;
              n ++;
            }
          }
        }
        __ASSERT(n <= 3);
        PreGen.ucsqPawnMoves[i][sqSrc][n] = 0;
      }
    }
  }

  // 最后清空局面预评价结构
  memset(&PreEval, 0, sizeof(PreEvalStruct));
  PreEval.bPromotion = false; // 缺省是不允许升变的
}
示例#13
0
int AttackingPieces(const BOARD *board, SQUARE square, COLOR attacking_color, SQUARE *attacking_sqs)
{
  int attackers = 0;
  SQUARE attacking_sq = 0;
  
  PIECE N_attacker, B_attacker, R_attacker, Q_attacker, K_attacker;
  
  if (attacking_color) {
    for (int i = 0; w_pawn_capture[i]; i++) {
      attacking_sq = square - w_pawn_capture[i];
      if (IN_BOARD(attacking_sq) && board->squares[attacking_sq] == W_PAWN) {
        if (attacking_sqs) attacking_sqs[attackers++] = attacking_sq;
        else return 1;
      }
    }
    N_attacker = W_KNIGHT, B_attacker = W_BISHOP, R_attacker = W_ROOK,
    Q_attacker = W_QUEEN, K_attacker = W_KING;
  } else {
    for (int i = 0; b_pawn_capture[i]; i++) {
      attacking_sq = square - b_pawn_capture[i];
      if (IN_BOARD(attacking_sq) && board->squares[attacking_sq] == B_PAWN) {
        if (attacking_sqs) attacking_sqs[attackers++] = attacking_sq;
        else return 1;
      }
    }
    N_attacker = B_KNIGHT, B_attacker = B_BISHOP, R_attacker = B_ROOK,
    Q_attacker = B_QUEEN, K_attacker = B_KING;
  }

  for (int i = 0; knight_delta[i]; i++) {
    attacking_sq = square + knight_delta[i];
    if (IN_BOARD(attacking_sq)) {
      if (board->squares[attacking_sq] == N_attacker) {
        if (attacking_sqs) attacking_sqs[attackers++] = attacking_sq;
        else return 1;
      }
    }
  }

  for (int i = 0; bishop_delta[i]; i++) {
    for (attacking_sq = square + bishop_delta[i]; IN_BOARD(attacking_sq); attacking_sq += bishop_delta[i]) {
      if (board->squares[attacking_sq] == EMPTY) {
        continue;
      } else if (board->squares[attacking_sq] == B_attacker) {
        if (attacking_sqs) attacking_sqs[attackers++] = attacking_sq;
        else return 1;
        break;
      } else if (board->squares[attacking_sq] == Q_attacker) {
        if (attacking_sqs) attacking_sqs[attackers++] = attacking_sq;
        else return 1;
        break;
      } else break; /*Piece other than bishop/queen, or different color, stop sliding*/
    }
  }

  for (int i = 0; rook_delta[i]; i++) {
    for (attacking_sq = square + rook_delta[i]; IN_BOARD(attacking_sq); attacking_sq += rook_delta[i]) {
      if (board->squares[attacking_sq] == EMPTY) {
        continue;
      } else if (board->squares[attacking_sq] == R_attacker) {
        if (attacking_sqs) attacking_sqs[attackers++] = attacking_sq;
        else return 1;
        break;
      } else if (board->squares[attacking_sq] == Q_attacker) {
        if (attacking_sqs) attacking_sqs[attackers++] = attacking_sq;
        else return 1;
        break;
      } else break;
    }
  }
  
  for (int i = 0; king_delta[i]; i++) {
    attacking_sq = square + king_delta[i];
    if (IN_BOARD(attacking_sq)) {
      if (board->squares[attacking_sq] == K_attacker) {
        if (attacking_sqs) attacking_sqs[attackers++] = attacking_sq;
        else return 1;
        break;
      }
    }
  }
  return attackers;
}
示例#14
0
bool ChessBoard::isChecked()
{
    //qDebug()<<"Enter isChecked";
    // 找到棋盘上的帅(将),再做以下判断:
    int pcKing = PIECE_KING + (m_sdPlayer + 1) * 8;
    //qDebug()<<"pcKing="<<pcKing;


    for (int sqSrc = 0; sqSrc < 256; sqSrc ++)
    {
      if (m_data[sqSrc]!=pcKing)
      {
        continue;
      }


      // 1. 判断是否被对方的兵(卒)将军
      int pcOppPawn = PIECE_PAWN + (2 - m_sdPlayer) * 8;
      static const int delta[2][4] = {{-1, 1, -16},{-1, 1, 16}};
      for(int i=0; i<4; i++)
      {
          int sqDst = sqSrc + delta[m_sdPlayer][i];
          if (m_data[sqDst]==pcOppPawn)
          {
              //qDebug()<<"pawn IsChecked true";
              return true;
          }
      }
      // 2. 判断是否被对方的马将军(以仕(士)的步长当作马腿)
      int pcOppKnight = PIECE_KNIGHT + (2 - m_sdPlayer) * 8;
      static const int ccPinDelta[4] = {-17, -15, 15, 17};
      static const int ccKnightDelta[4][2] = {{-33, -18}, {-31, -14}, {14, 31}, {18, 33}};

      for (int i=0; i<4; i++)
      {
          //qDebug()<<"kinght PinDelta="<<ccPinDelta[i];
          int sqPin = sqSrc + ccPinDelta[i];
          if (m_data[sqPin]) continue;
          for (int j=0; j<2; j++)
          {
              int sqDst = sqSrc + ccKnightDelta[i][j];
              if (m_data[sqDst]==pcOppKnight)
              {
                  //qDebug()<<"knight IsChecked true";
                  return true;
              }
          }

      }

      // 3. 判断是否被对方的车或炮将军(包括将帅对脸)
      int pcOppRook = PIECE_ROOK + (2 - m_sdPlayer) * 8;
      int pcOppCannon = PIECE_CANNON + (2 - m_sdPlayer) * 8;
      int pcOppKing = PIECE_KING + (2 - m_sdPlayer) * 8;

      static const int rookDelta[4] = {-16, -1, 1, 16};
      for(int i=0; i<4; i++)
      {

          int sqDst = sqSrc;
          bool skiped = false;
          while (true)
          {
              sqDst += rookDelta[i];
              if (!IN_BOARD(sqDst)) break;
              int pcDst = m_data[sqDst];
              if (!skiped && (pcDst==pcOppRook || pcDst==pcOppKing))
              {
                  //qDebug()<<"rook IsChecked true";
                  return true;
              }            
              if (pcDst)
              {
                  if (!skiped)
                  {
                    skiped = true;
                  }
                  else{
                      if (pcDst==pcOppCannon)
                      {
                          //qDebug()<<"cannon IsChecked true";
                          return true;
                      }
                      break;
                  }
              }
          }
      }
    }
    return false;
}
示例#15
0
void PositionStruct::PreEvaluate(void) {
  int i, sq, nMidgameValue, nWhiteAttacks, nBlackAttacks, nWhiteSimpleValue, nBlackSimpleValue;
  uint8_t ucvlPawnPiecesAttacking[256], ucvlPawnPiecesAttackless[256];

  if (!bInit) {
    bInit = true;
    // 初始化"PreEvalEx.cPopCnt16"数组,只需要初始化一次
    for (i = 0; i < 65536; i ++) {
      PreEvalEx.cPopCnt16[i] = PopCnt16(i);
    }
  }

  // 首先判断局势处于开中局还是残局阶段,方法是计算各种棋子的数量,按照车=6、马炮=3、其它=1相加。
  nMidgameValue = PopCnt32(this->dwBitPiece & BOTH_BITPIECE(ADVISOR_BITPIECE | BISHOP_BITPIECE | PAWN_BITPIECE)) * OTHER_MIDGAME_VALUE;
  nMidgameValue += PopCnt32(this->dwBitPiece & BOTH_BITPIECE(KNIGHT_BITPIECE | CANNON_BITPIECE)) * KNIGHT_CANNON_MIDGAME_VALUE;
  nMidgameValue += PopCnt32(this->dwBitPiece & BOTH_BITPIECE(ROOK_BITPIECE)) * ROOK_MIDGAME_VALUE;
  // 使用二次函数,子力很少时才认为接近残局
  nMidgameValue = (2 * TOTAL_MIDGAME_VALUE - nMidgameValue) * nMidgameValue / TOTAL_MIDGAME_VALUE;
  __ASSERT_BOUND(0, nMidgameValue, TOTAL_MIDGAME_VALUE);
  PreEval.vlAdvanced = (TOTAL_ADVANCED_VALUE * nMidgameValue + TOTAL_ADVANCED_VALUE / 2) / TOTAL_MIDGAME_VALUE;
  __ASSERT_BOUND(0, PreEval.vlAdvanced, TOTAL_ADVANCED_VALUE);
  for (sq = 0; sq < 256; sq ++) {
    if (IN_BOARD(sq)) {
      PreEval.ucvlWhitePieces[0][sq] = PreEval.ucvlBlackPieces[0][SQUARE_FLIP(sq)] = (uint8_t)
          ((cucvlKingPawnMidgameAttacking[sq] * nMidgameValue + cucvlKingPawnEndgameAttacking[sq] * (TOTAL_MIDGAME_VALUE - nMidgameValue)) / TOTAL_MIDGAME_VALUE);
      PreEval.ucvlWhitePieces[3][sq] = PreEval.ucvlBlackPieces[3][SQUARE_FLIP(sq)] = (uint8_t)
          ((cucvlKnightMidgame[sq] * nMidgameValue + cucvlKnightEndgame[sq] * (TOTAL_MIDGAME_VALUE - nMidgameValue)) / TOTAL_MIDGAME_VALUE);
      PreEval.ucvlWhitePieces[4][sq] = PreEval.ucvlBlackPieces[4][SQUARE_FLIP(sq)] = (uint8_t)
          ((cucvlRookMidgame[sq] * nMidgameValue + cucvlRookEndgame[sq] * (TOTAL_MIDGAME_VALUE - nMidgameValue)) / TOTAL_MIDGAME_VALUE);
      PreEval.ucvlWhitePieces[5][sq] = PreEval.ucvlBlackPieces[5][SQUARE_FLIP(sq)] = (uint8_t)
          ((cucvlCannonMidgame[sq] * nMidgameValue + cucvlCannonEndgame[sq] * (TOTAL_MIDGAME_VALUE - nMidgameValue)) / TOTAL_MIDGAME_VALUE);
      ucvlPawnPiecesAttacking[sq] = PreEval.ucvlWhitePieces[0][sq];
      ucvlPawnPiecesAttackless[sq] = (uint8_t)
          ((cucvlKingPawnMidgameAttackless[sq] * nMidgameValue + cucvlKingPawnEndgameAttackless[sq] * (TOTAL_MIDGAME_VALUE - nMidgameValue)) / TOTAL_MIDGAME_VALUE);
    }
  }
  for (i = 0; i < 16; i ++) {
    PreEvalEx.vlHollowThreat[i] = cvlHollowThreat[i] * (nMidgameValue + TOTAL_MIDGAME_VALUE) / (TOTAL_MIDGAME_VALUE * 2);
    __ASSERT_BOUND(0, PreEvalEx.vlHollowThreat[i], cvlHollowThreat[i]);
    PreEvalEx.vlCentralThreat[i] = cvlCentralThreat[i];
  }

  // 然后判断各方是否处于进攻状态,方法是计算各种过河棋子的数量,按照车马2炮兵1相加。
  nWhiteAttacks = nBlackAttacks = 0;
  for (i = SIDE_TAG(0) + KNIGHT_FROM; i <= SIDE_TAG(0) + ROOK_TO; i ++) {
    if (this->ucsqPieces[i] != 0 && BLACK_HALF(this->ucsqPieces[i])) {
      nWhiteAttacks += 2;
    }
  }
  for (i = SIDE_TAG(0) + CANNON_FROM; i <= SIDE_TAG(0) + PAWN_TO; i ++) {
    if (this->ucsqPieces[i] != 0 && BLACK_HALF(this->ucsqPieces[i])) {
      nWhiteAttacks ++;
    }
  }
  for (i = SIDE_TAG(1) + KNIGHT_FROM; i <= SIDE_TAG(1) + ROOK_TO; i ++) {
    if (this->ucsqPieces[i] != 0 && WHITE_HALF(this->ucsqPieces[i])) {
      nBlackAttacks += 2;
    }
  }
  for (i = SIDE_TAG(1) + CANNON_FROM; i <= SIDE_TAG(1) + PAWN_TO; i ++) {
    if (this->ucsqPieces[i] != 0 && WHITE_HALF(this->ucsqPieces[i])) {
      nBlackAttacks ++;
    }
  }
  // 如果本方轻子数比对方多,那么每多一个轻子(车算2个轻子)威胁值加2。威胁值最多不超过8。
  nWhiteSimpleValue = PopCnt16(this->wBitPiece[0] & ROOK_BITPIECE) * 2 + PopCnt16(this->wBitPiece[0] & (KNIGHT_BITPIECE | CANNON_BITPIECE));
  nBlackSimpleValue = PopCnt16(this->wBitPiece[1] & ROOK_BITPIECE) * 2 + PopCnt16(this->wBitPiece[1] & (KNIGHT_BITPIECE | CANNON_BITPIECE));
  if (nWhiteSimpleValue > nBlackSimpleValue) {
    nWhiteAttacks += (nWhiteSimpleValue - nBlackSimpleValue) * 2;
  } else {
    nBlackAttacks += (nBlackSimpleValue - nWhiteSimpleValue) * 2;
  }
  nWhiteAttacks = MIN(nWhiteAttacks, TOTAL_ATTACK_VALUE);
  nBlackAttacks = MIN(nBlackAttacks, TOTAL_ATTACK_VALUE);
  PreEvalEx.vlBlackAdvisorLeakage = TOTAL_ADVISOR_LEAKAGE * nWhiteAttacks / TOTAL_ATTACK_VALUE;
  PreEvalEx.vlWhiteAdvisorLeakage = TOTAL_ADVISOR_LEAKAGE * nBlackAttacks / TOTAL_ATTACK_VALUE;
  __ASSERT_BOUND(0, nWhiteAttacks, TOTAL_ATTACK_VALUE);
  __ASSERT_BOUND(0, nBlackAttacks, TOTAL_ATTACK_VALUE);
  __ASSERT_BOUND(0, PreEvalEx.vlBlackAdvisorLeakage, TOTAL_ADVISOR_LEAKAGE);
  __ASSERT_BOUND(0, PreEvalEx.vlBlackAdvisorLeakage, TOTAL_ADVISOR_LEAKAGE);
  for (sq = 0; sq < 256; sq ++) {
    if (IN_BOARD(sq)) {
      PreEval.ucvlWhitePieces[1][sq] = PreEval.ucvlWhitePieces[2][sq] = (uint8_t) ((cucvlAdvisorBishopThreatened[sq] * nBlackAttacks +
          (PreEval.bPromotion ? cucvlAdvisorBishopPromotionThreatless[sq] : cucvlAdvisorBishopThreatless[sq]) * (TOTAL_ATTACK_VALUE - nBlackAttacks)) / TOTAL_ATTACK_VALUE);
      PreEval.ucvlBlackPieces[1][sq] = PreEval.ucvlBlackPieces[2][sq] = (uint8_t) ((cucvlAdvisorBishopThreatened[SQUARE_FLIP(sq)] * nWhiteAttacks +
          (PreEval.bPromotion ? cucvlAdvisorBishopPromotionThreatless[SQUARE_FLIP(sq)] : cucvlAdvisorBishopThreatless[SQUARE_FLIP(sq)]) * (TOTAL_ATTACK_VALUE - nWhiteAttacks)) / TOTAL_ATTACK_VALUE);
      PreEval.ucvlWhitePieces[6][sq] = (uint8_t) ((ucvlPawnPiecesAttacking[sq] * nWhiteAttacks +
          ucvlPawnPiecesAttackless[sq] * (TOTAL_ATTACK_VALUE - nWhiteAttacks)) / TOTAL_ATTACK_VALUE);
      PreEval.ucvlBlackPieces[6][sq] = (uint8_t) ((ucvlPawnPiecesAttacking[SQUARE_FLIP(sq)] * nBlackAttacks +
          ucvlPawnPiecesAttackless[SQUARE_FLIP(sq)] * (TOTAL_ATTACK_VALUE - nBlackAttacks)) / TOTAL_ATTACK_VALUE);
    }
  }
  for (i = 0; i < 16; i ++) {
    PreEvalEx.vlWhiteBottomThreat[i] = cvlBottomThreat[i] * nBlackAttacks / TOTAL_ATTACK_VALUE;
    PreEvalEx.vlBlackBottomThreat[i] = cvlBottomThreat[i] * nWhiteAttacks / TOTAL_ATTACK_VALUE;
  }

  // 检查预评价是否对称
#ifndef NDEBUG
  for (sq = 0; sq < 256; sq ++) {
    if (IN_BOARD(sq)) {
      for (i = 0; i < 7; i ++) {
        __ASSERT(PreEval.ucvlWhitePieces[i][sq] == PreEval.ucvlWhitePieces[i][SQUARE_MIRROR(sq)]);
        __ASSERT(PreEval.ucvlBlackPieces[i][sq] == PreEval.ucvlBlackPieces[i][SQUARE_MIRROR(sq)]);
      }
    }
  }
  for (i = FILE_LEFT; i <= FILE_RIGHT; i ++) {
    __ASSERT(PreEvalEx.vlWhiteBottomThreat[i] == PreEvalEx.vlWhiteBottomThreat[FILE_FLIP(i)]);
    __ASSERT(PreEvalEx.vlBlackBottomThreat[i] == PreEvalEx.vlBlackBottomThreat[FILE_FLIP(i)]);
  }
#endif

  // 调整不受威胁方少掉的仕(士)相(象)分值
  this->vlWhite = ADVISOR_BISHOP_ATTACKLESS_VALUE * (TOTAL_ATTACK_VALUE - nBlackAttacks) / TOTAL_ATTACK_VALUE;
  this->vlBlack = ADVISOR_BISHOP_ATTACKLESS_VALUE * (TOTAL_ATTACK_VALUE - nWhiteAttacks) / TOTAL_ATTACK_VALUE;
  // 如果允许升变,那么不受威胁的仕(士)相(象)分值就少了一半
  if (PreEval.bPromotion) {
    this->vlWhite /= 2;
    this->vlBlack /= 2;
  }
  // 最后重新计算子力位置分
  for (i = 16; i < 32; i ++) {
    sq = this->ucsqPieces[i];
    if (sq != 0) {
      __ASSERT_SQUARE(sq);
      this->vlWhite += PreEval.ucvlWhitePieces[PIECE_TYPE(i)][sq];
    }
  }
  for (i = 32; i < 48; i ++) {
    sq = this->ucsqPieces[i];
    if (sq != 0) {
      __ASSERT_SQUARE(sq);
      this->vlBlack += PreEval.ucvlBlackPieces[PIECE_TYPE(i)][sq];
    }
  }
}