예제 #1
0
파일: cchess.cpp 프로젝트: gucong/robotxq
// 生成文本棋盘(红子用()表示,黑子用[]表示)
void BoardText(char *szBoard, const PositionStruct &pos, bool bAnsi) {
  char *lpBoard;
  int i, j, pc;

  lpBoard = szBoard;
  if (bAnsi) {
    lpBoard += sprintf(lpBoard, "\33[0m");
  }
  for (i = 0; i < 19; i ++) {
    if (i % 2 == 0) {
      for (j = FILE_LEFT; j <= FILE_RIGHT; j ++) {
        pc = pos.ucpcSquares[COORD_XY(j, i / 2 + RANK_TOP)];
        if ((pc & SIDE_TAG(0)) != 0) {
          lpBoard += sprintf(lpBoard, bAnsi ? "(\33[1;31m%.2s\33[0m)" :
              "(%.2s)", (const char *) &lpcwPiece2Word[0][PIECE_TYPE(pc)]);
        } else if ((pc & SIDE_TAG(1)) != 0) {
          lpBoard += sprintf(lpBoard, bAnsi ? "[\33[1;32m%.2s\33[0m]" :
              "[%.2s]", (const char *) &lpcwPiece2Word[1][PIECE_TYPE(pc)]);
        } else {
          lpBoard += sprintf(lpBoard, "%.4s", lpcszBoardStr[i] + (j - FILE_LEFT) * 4);
        }
      }
      lpBoard += sprintf(lpBoard, "\r\n");
    } else {
      lpBoard += sprintf(lpBoard, "%s\r\n", lpcszBoardStr[i]);
    }
  }
}
예제 #2
0
a_window DoWndIOOpen( address *addr, mad_type_handle mth )
{
    io_window   *io;
    int         i;

    if( IOData.num_types == 0 )
        return( NULL );
    io = WndMustAlloc( sizeof( io_window ) );
    io->list = WndMustAlloc( sizeof( io_location ) );
    io->num_rows = 1;
    io->list->addr = *addr;
    io->list->type = PIECE_TYPE( MENU_IO_FIRST_TYPE );
    if( mth != MAD_NIL_TYPE_HANDLE ) {
        for( i = 0; i < IOData.num_types; i++ ) {
            if( IOData.info[i].mth == mth ) {
                break;
            }
        }
        if( i != IOData.num_types ) {
            io->list->type = i;
        }
    }
    io->list->value.ud = 0;
    io->list->value_known = false;
    return( DbgWndCreate( LIT_DUI( WindowIO_Ports ), &IOInfo, WND_IO, io, &IOIcon ) );
}
예제 #3
0
파일: test.c 프로젝트: anthonyfok/gmchess
void ToFen(char *szFen)  {
  int i, j, k, pc;
  char *lpFen;

  lpFen = szFen;
  for (i = RANK_TOP; i <= RANK_BOTTOM; i ++) {
    k = 0;
    for (j = FILE_LEFT; j <= FILE_RIGHT; j ++) {
      pc = Square[COORD_XY(j, i)];
      if (pc != 0) {
        if (k > 0) {
          *lpFen = k + '0';
          lpFen ++;
          k = 0;
        }
        *lpFen = PIECE_BYTE(PIECE_TYPE(pc)) ;
        //*lpFen = PIECE_BYTE(PIECE_TYPE(pc)) + (pc < 32 ? 0 : 'a' - 'A');
        lpFen ++;
      } else {
        k ++;
      }
    }
    if (k > 0) {
      *lpFen = k + '0';
      lpFen ++;
    }
    *lpFen = '/';
    lpFen ++;
  }
  *(lpFen - 1) = ' '; // 把最后一个'/'替换成' '
  *lpFen = 'w';//(this->sdPlayer == 0 ? 'w' : 'b');
  lpFen ++;
  *lpFen = '\0';
}
예제 #4
0
파일: cchess.cpp 프로젝트: gucong/robotxq
BOOL WINAPI CchessCanPromote(PositionStruct *lppos, LONG sq) {
  int pt;
  if (PreEval.bPromotion && lppos->CanPromote() && CAN_PROMOTE(sq)) {
    pt = PIECE_TYPE(lppos->ucpcSquares[sq]);
    return pt == ADVISOR_TYPE || pt == BISHOP_TYPE;
  }
  return FALSE;
}
예제 #5
0
static void IOAddNewAddr( a_window wnd, address *addr, int type )
{
    io_window   *io = WndIO( wnd );
    int         row;
    io_location *curr;

    row = io->num_rows;
    io->num_rows++;
    io->list = WndMustRealloc( io->list, io->num_rows * sizeof( io_location ) );
    curr = &io->list[row];
    curr->type = PIECE_TYPE( type );
    curr->addr = *addr;
    curr->value_known = false;
}
예제 #6
0
static void add_quiet_moves(list_t * list, const board_t * board) {

   int me;
   const sq_t * ptr;
   int from, to;
   int piece;

   ASSERT(list!=NULL);
   ASSERT(board!=NULL);

   me = board->turn;

   // piece moves

   for (ptr = &board->piece[me][0]; (from=*ptr) != SquareNone; ptr++) {

      piece = board->square[from];

      switch (PIECE_TYPE(piece)) {

      case Knight64:

         to = from - 33;
         if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from - 31;
         if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from - 18;
         if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from - 14;
         if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from + 14;
         if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from + 18;
         if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from + 31;
         if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from + 33;
         if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to));

         break;

      case Bishop64:

         for (to = from-17; board->square[to] == Empty; to -= 17) {
            LIST_ADD(list,MOVE_MAKE(from,to));
         }

         for (to = from-15; board->square[to] == Empty; to -= 15) {
            LIST_ADD(list,MOVE_MAKE(from,to));
         }

         for (to = from+15; board->square[to] == Empty; to += 15) {
            LIST_ADD(list,MOVE_MAKE(from,to));
         }

         for (to = from+17; board->square[to] == Empty; to += 17) {
            LIST_ADD(list,MOVE_MAKE(from,to));
         }

         break;

      case Rook64:

         for (to = from-16; board->square[to] == Empty; to -= 16) {
            LIST_ADD(list,MOVE_MAKE(from,to));
         }

         for (to = from-1; board->square[to] == Empty; to -= 1) {
            LIST_ADD(list,MOVE_MAKE(from,to));
         }

         for (to = from+1; board->square[to] == Empty; to += 1) {
            LIST_ADD(list,MOVE_MAKE(from,to));
         }

         for (to = from+16; board->square[to] == Empty; to += 16) {
            LIST_ADD(list,MOVE_MAKE(from,to));
         }

         break;

      case Queen64:

         for (to = from-17; board->square[to] == Empty; to -= 17) {
            LIST_ADD(list,MOVE_MAKE(from,to));
         }

         for (to = from-16; board->square[to] == Empty; to -= 16) {
            LIST_ADD(list,MOVE_MAKE(from,to));
         }

         for (to = from-15; board->square[to] == Empty; to -= 15) {
            LIST_ADD(list,MOVE_MAKE(from,to));
         }

         for (to = from-1; board->square[to] == Empty; to -= 1) {
            LIST_ADD(list,MOVE_MAKE(from,to));
         }

         for (to = from+1; board->square[to] == Empty; to += 1) {
            LIST_ADD(list,MOVE_MAKE(from,to));
         }

         for (to = from+15; board->square[to] == Empty; to += 15) {
            LIST_ADD(list,MOVE_MAKE(from,to));
         }

         for (to = from+16; board->square[to] == Empty; to += 16) {
            LIST_ADD(list,MOVE_MAKE(from,to));
         }

         for (to = from+17; board->square[to] == Empty; to += 17) {
            LIST_ADD(list,MOVE_MAKE(from,to));
         }

         break;

      case King64:

         to = from - 17;
         if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from - 16;
         if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from - 15;
         if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from - 1;
         if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from + 1;
         if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from + 15;
         if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from + 16;
         if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from + 17;
         if (board->square[to] == Empty) LIST_ADD(list,MOVE_MAKE(from,to));

         break;

      default:

         ASSERT(false);
         break;
      }
   }

   // pawn moves

   if (COLOUR_IS_WHITE(me)) {

      for (ptr = &board->pawn[me][0]; (from=*ptr) != SquareNone; ptr++) {

         // non promotes

         if (SQUARE_RANK(from) != Rank7) {
            to = from + 16;
            if (board->square[to] == Empty) {
               ASSERT(!SQUARE_IS_PROMOTE(to));
               LIST_ADD(list,MOVE_MAKE(from,to));
               if (SQUARE_RANK(from) == Rank2) {
                  to = from + 32;
                  if (board->square[to] == Empty) {
                     ASSERT(!SQUARE_IS_PROMOTE(to));
                     LIST_ADD(list,MOVE_MAKE(from,to));
                  }
               }
            }
         }
      }

   } else { // black

      for (ptr = &board->pawn[me][0]; (from=*ptr) != SquareNone; ptr++) {

         // non promotes

         if (SQUARE_RANK(from) != Rank2) {
            to = from - 16;
            if (board->square[to] == Empty) {
               ASSERT(!SQUARE_IS_PROMOTE(to));
               LIST_ADD(list,MOVE_MAKE(from,to));
               if (SQUARE_RANK(from) == Rank7) {
                  to = from - 32;
                  if (board->square[to] == Empty) {
                     ASSERT(!SQUARE_IS_PROMOTE(to));
                     LIST_ADD(list,MOVE_MAKE(from,to));
                  }
               }
            }
         }
      }
   }
}
예제 #7
0
static void add_captures(list_t * list, const board_t * board) {

   int me, opp;
   int opp_flag;
   const sq_t * ptr;
   int from, to;
   int piece, capture;

   ASSERT(list!=NULL);
   ASSERT(board!=NULL);

   me = board->turn;
   opp = COLOUR_OPP(me);

   opp_flag = COLOUR_FLAG(opp);

   // piece captures

   for (ptr = &board->piece[me][0]; (from=*ptr) != SquareNone; ptr++) {

      piece = board->square[from];

      switch (PIECE_TYPE(piece)) {

      case Knight64:

         to = from - 33;
         if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from - 31;
         if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from - 18;
         if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from - 14;
         if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from + 14;
         if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from + 18;
         if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from + 31;
         if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from + 33;
         if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         break;

      case Bishop64:

         for (to = from-17; (capture=board->square[to]) == Empty; to -= 17)
            ;
         if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         for (to = from-15; (capture=board->square[to]) == Empty; to -= 15)
            ;
         if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         for (to = from+15; (capture=board->square[to]) == Empty; to += 15)
            ;
         if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         for (to = from+17; (capture=board->square[to]) == Empty; to += 17)
            ;
         if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         break;

      case Rook64:

         for (to = from-16; (capture=board->square[to]) == Empty; to -= 16)
            ;
         if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         for (to = from-1; (capture=board->square[to]) == Empty; to -= 1)
            ;
         if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         for (to = from+1; (capture=board->square[to]) == Empty; to += 1)
            ;
         if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         for (to = from+16; (capture=board->square[to]) == Empty; to += 16)
            ;
         if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         break;

      case Queen64:

         for (to = from-17; (capture=board->square[to]) == Empty; to -= 17)
            ;
         if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         for (to = from-16; (capture=board->square[to]) == Empty; to -= 16)
            ;
         if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         for (to = from-15; (capture=board->square[to]) == Empty; to -= 15)
            ;
         if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         for (to = from-1; (capture=board->square[to]) == Empty; to -= 1)
            ;
         if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         for (to = from+1; (capture=board->square[to]) == Empty; to += 1)
            ;
         if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         for (to = from+15; (capture=board->square[to]) == Empty; to += 15)
            ;
         if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         for (to = from+16; (capture=board->square[to]) == Empty; to += 16)
            ;
         if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         for (to = from+17; (capture=board->square[to]) == Empty; to += 17)
            ;
         if (FLAG_IS(capture,opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         break;

      case King64:

         to = from - 17;
         if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from - 16;
         if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from - 15;
         if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from - 1;
         if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from + 1;
         if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from + 15;
         if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from + 16;
         if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         to = from + 17;
         if (FLAG_IS(board->square[to],opp_flag)) LIST_ADD(list,MOVE_MAKE(from,to));

         break;

      default:

         ASSERT(false);
         break;
      }
   }

   // pawn captures

   if (COLOUR_IS_WHITE(me)) {

      for (ptr = &board->pawn[me][0]; (from=*ptr) != SquareNone; ptr++) {

         to = from + 15;
         if (FLAG_IS(board->square[to],opp_flag)) add_pawn_move(list,from,to);

         to = from + 17;
         if (FLAG_IS(board->square[to],opp_flag)) add_pawn_move(list,from,to);

         // promote

         if (SQUARE_RANK(from) == Rank7) {
            to = from + 16;
            if (board->square[to] == Empty) {
               add_promote(list,MOVE_MAKE(from,to));
            }
         }
      }

   } else { // black

      for (ptr = &board->pawn[me][0]; (from=*ptr) != SquareNone; ptr++) {

         to = from - 17;
         if (FLAG_IS(board->square[to],opp_flag)) add_pawn_move(list,from,to);

         to = from - 15;
         if (FLAG_IS(board->square[to],opp_flag)) add_pawn_move(list,from,to);

         // promote

         if (SQUARE_RANK(from) == Rank2) {
            to = from - 16;
            if (board->square[to] == Empty) {
               add_promote(list,MOVE_MAKE(from,to));
            }
         }
      }
   }
}
예제 #8
0
파일: cchess.cpp 프로젝트: gucong/robotxq
// 将内部着法表示转换为纵线符号
uint32_t Move2File(int mv, const PositionStruct &pos) {
  int i, j, sq, pc, pt, nPieceNum;
  int xSrc, ySrc, xDst, yDst;
  int nFileList[9], nPieceList[5];
  C4dwStruct Ret;

  if (SRC(mv) == 0 || DST(mv) == 0) {
    return 0x20202020;
  }
  pc = pos.ucpcSquares[SRC(mv)];
  if (pc == 0) {
    return 0x20202020;
  }
  pt = PIECE_TYPE(pc);
  Ret.c[0] = PIECE_BYTE(pt);
  if (pos.sdPlayer == 0) {
    xSrc = FILESQ_FILE_X(SQUARE_FILESQ(SRC(mv)));
    ySrc = FILESQ_RANK_Y(SQUARE_FILESQ(SRC(mv)));
    xDst = FILESQ_FILE_X(SQUARE_FILESQ(DST(mv)));
    yDst = FILESQ_RANK_Y(SQUARE_FILESQ(DST(mv)));
  } else {
    xSrc = FILESQ_FILE_X(SQUARE_FILESQ(SQUARE_FLIP(SRC(mv))));
    ySrc = FILESQ_RANK_Y(SQUARE_FILESQ(SQUARE_FLIP(SRC(mv))));
    xDst = FILESQ_FILE_X(SQUARE_FILESQ(SQUARE_FLIP(DST(mv))));
    yDst = FILESQ_RANK_Y(SQUARE_FILESQ(SQUARE_FLIP(DST(mv))));
  }
  if (pt >= KING_TYPE && pt <= BISHOP_TYPE) {
    Ret.c[1] = Digit2Byte(xSrc);
  } else {
    for (i = 0; i < 9; i ++) {
      nFileList[i] = 0;
    }
    j = (pt == PAWN_TYPE ? 5 : 2);
    for (i = 0; i < j; i ++) {
      sq = FILESQ_SIDE_PIECE(pos, FIRST_PIECE(pt, i));
      if (sq != -1) {
        nFileList[FILESQ_FILE_X(sq)] ++;
      }
    }
    // 提示:处理“两条的纵线上有多个兵(卒)”的问题上,可参阅"File2Move()"函数。
    if (nFileList[xSrc] > 1) {
      nPieceNum = 0;
      for (i = 0; i < j; i ++) {
        sq = FILESQ_SIDE_PIECE(pos, FIRST_PIECE(pt, i));
        if (sq != -1) {
          if (nFileList[FILESQ_FILE_X(sq)] > 1) {
            nPieceList[nPieceNum] = FIRST_PIECE(pt, i);
            nPieceNum ++;
          }
        }
      }
      for (i = 0; i < nPieceNum - 1; i ++) {
        for (j = nPieceNum - 1; j > i; j --) {
          if (FILESQ_SIDE_PIECE(pos, nPieceList[j - 1]) > FILESQ_SIDE_PIECE(pos, nPieceList[j])) {
            SWAP(nPieceList[j - 1], nPieceList[j]);
          }
        }
      }
      sq = FILESQ_COORD_XY(xSrc, ySrc);
      for (i = 0; i < nPieceNum; i ++) {
        if (FILESQ_SIDE_PIECE(pos, nPieceList[i]) == sq) {
          break;
        }
      }
      Ret.c[1] = (nPieceNum == 2 && i == 1 ? ccPos2Byte[2 + DIRECT_TO_POS] :
          ccPos2Byte[nPieceNum > 3 ? i : i + DIRECT_TO_POS]);
    } else {
      Ret.c[1] = Digit2Byte(xSrc);
    }
  }
  if (pt >= ADVISOR_TYPE && pt <= KNIGHT_TYPE) {
    if (SRC(mv) == DST(mv)) {
      Ret.c[2] = '=';
      Ret.c[3] = 'P';
    } else {
      Ret.c[2] = (yDst > ySrc ? '-' : '+');
      Ret.c[3] = Digit2Byte(xDst);
    }
  } else {
    Ret.c[2] = (yDst == ySrc ? '.' : yDst > ySrc ? '-' : '+');
    Ret.c[3] = (yDst == ySrc ? Digit2Byte(xDst) : Digit2Byte(ABS(ySrc - yDst) - 1));
  }
  return Ret.dw;
}
예제 #9
0
OVL_EXTERN void     IOMenuItem( a_window wnd, gui_ctl_id id, wnd_row row, wnd_piece piece )
{
    io_window   *io = WndIO( wnd );
    address     addr;
    bool        ok;
    item_mach   item;
    io_location *curr;
    mad_radix   old_radix;

    /* unused parameters */ (void)piece;

    if( row < io->num_rows && row >= 0 ) {
        curr = &io->list[row];
    } else {
        curr = NULL;
    }
    switch( id ) {
    case MENU_INITIALIZE:
        if( curr == NULL ) {
            WndMenuGrayAll( wnd );
        } else {
            WndMenuEnableAll( wnd );
        }
        WndMenuEnable( wnd, MENU_IO_NEW_ADDRESS, true );
        break;
    case MENU_IO_DELETE:
        io->num_rows--;
        memcpy( &io->list[row], &io->list[row + 1],
                ( io->num_rows - row ) * sizeof( io_location ) );
        WndNoSelect( wnd );
        WndSetRepaint( wnd );
        break;
    case MENU_IO_NEW_ADDRESS:
        addr = NilAddr;
        if( !DlgGivenAddr( LIT_DUI( New_Port_Addr ), &addr ) )
            return;
        WndRowDirty( wnd, io->num_rows );
        IOAddNewAddr( wnd, &addr, MENU_IO_FIRST_TYPE );
        WndScrollBottom( wnd );
        break;
    case MENU_IO_MODIFY:
        if( row >= io->num_rows || row < 0 )
            break;
        if( piece == PIECE_VALUE ) {
            old_radix = NewCurrRadix( IOData.info[curr->type].piece_radix );
            item.ud = curr->value_known ? curr->value.ud : 0;
            ok = DlgMadTypeExpr( TxtBuff, &item, IOData.info[curr->type].mth );
            if( ok ) {
                curr->value = item;
                curr->value_known = true;
            }
            NewCurrRadix( old_radix );
        } else {
            addr = curr->addr;
            if( !DlgGivenAddr( LIT_DUI( New_Port_Addr ), &addr ) )
                return;
            curr->addr = addr;
            curr->value_known = false;
        }
        WndRowDirty( wnd, row );
        break;
    case MENU_IO_READ:
        curr->value_known = true;
        if( ItemGetMAD( &curr->addr, &curr->value, IT_IO, IOData.info[curr->type].mth ) == IT_NIL ) {
            curr->value_known = false;
        }
        WndPieceDirty( wnd, row, PIECE_VALUE );
        break;
    case MENU_IO_WRITE:
        if( curr->value_known ) {
            ItemPutMAD( &curr->addr, &curr->value, IT_IO, IOData.info[curr->type].mth );
        }
        break;
    default:
        curr->type = PIECE_TYPE( id );
        WndZapped( wnd );
        break;
    }
}
예제 #10
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];
    }
  }
}