⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 treesearch.cpp

📁 《C++Builder程序设计范例--中国象棋》配书盘自述文件
💻 CPP
📖 第 1 页 / 共 2 页
字号:

static short capmovgen(SQUARETYPE newsq, PARAMTYPE *P)
{
    INDEXTYPE i;

    MoveTable[Depth].content = ChessBoard[newsq].piece;
    MoveTable[Depth].spe = 0;
    MoveTable[Depth].newpos1 = newsq;
     for (i = PawnNumber[Player]; i >= 0; i--)
	if (PieceTable[Player][i].ipiece != empty)
            if (PieceAttacks(PieceTable[Player][i].ipiece, Player,
		    PieceTable[Player][i].isquare, newsq))
            {
                MoveTable[Depth].oldpos = PieceTable[Player][i].isquare;
                MoveTable[Depth].movpiece = PieceTable[Player][i].ipiece;
                if (loopbody(P)) return 1;
            }
    return 0;
}
              

/*
 在老的位置生成非吃子移动
 */

static short noncapmovgen(SQUARETYPE oldsq, PARAMTYPE *P)
{
    DIRTYPE dir;
    int direction;
    EDGESQUARETYPE newsq;
    int tmpBishopDir, tmpKnightDir;

    MoveTable[Depth].spe = 0;
    MoveTable[Depth].oldpos = oldsq;
    MoveTable[Depth].movpiece = ChessBoard[oldsq].piece;
    MoveTable[Depth].content = empty;
    switch (MoveTable[Depth].movpiece)
    {
	case king :  /*王每次直走一格,且不能超出九宫*/
		 for (dir = 3; dir >= 0; dir--)
		 {
	        newsq = MoveTable[Depth].oldpos + DirectionTab[dir] ;
		 if ((newsq<=0x98) && (newsq>=0))
		if (((newsq>>4)<10) && ((newsq % 16)<9)
		    && ((newsq | 0xff)>=0))
		   if (ChessBoard[MoveTable[Depth].oldpos].color == red)
			if (( newsq  >=0) && ( newsq  <= 0x28)
			    && ((newsq % 16) >=3) && ((newsq % 16) <=5))
			  if (ChessBoard[newsq].piece == empty)
				{
				MoveTable[Depth].newpos1 = newsq;
				if (loopbody(P))
				  return 1;
				}
		  }
		  for (dir = 3; dir >= 0; dir--)
		  {
		  newsq = MoveTable[Depth].oldpos + DirectionTab[dir] ;
		  if ((newsq<=0x98) && (newsq>=0))
		if (((newsq>>4)<10) && ((newsq % 16)<9)
		    && ((newsq | 0xff) >=0))
		  if (ChessBoard[MoveTable[Depth].oldpos].color == black)
			if (( newsq >= 0x70) && (( newsq ) <= 0x98)
			    && ((newsq % 16) >=3) && ((newsq % 16) <=5))
				if (ChessBoard[newsq].piece == empty)
				{
				MoveTable[Depth].newpos1 = newsq;
				if (loopbody(P))
				  return 1;
				}
		  }
		 break;
	case assist :  /*士每次斜走一格,且不能超出九宫*/
		  for (dir = 3; dir >= 0; dir--)
		  {
		 newsq = MoveTable[Depth].oldpos + AssistDir[dir];
		if ((newsq<=0x98) && (newsq>=0))
		if (((newsq>>4)<10) && ((newsq % 16)< 9)
		    && ((newsq | 0xff) >=0))
		  if (ChessBoard[MoveTable[Depth].oldpos].color == red)
			if (( newsq  >=0) && ( newsq <= 0x28)
			    && ((newsq % 16) >=3) && ((newsq % 16) <=5))
				if (ChessBoard[newsq].piece == empty)
				{
				MoveTable[Depth].newpos1 = newsq;
				if (loopbody(P))
				return 1;
				}
		 } ;
        for (dir = 3; dir >= 0; dir--)
				{
		 newsq = MoveTable[Depth].oldpos + AssistDir[dir];
		if ((newsq<=0x98) && (newsq>=0))
		if (((newsq>>4)<10) && ((newsq % 16)< 9)
		    && ((newsq | 0xff) >=0))
		  if (ChessBoard[MoveTable[Depth].oldpos].color == black)
			if (( newsq  >= 0x70) && ( newsq <= 0x98)
			    && ((newsq % 16) >=3) && ((newsq % 16) <=5))
			if (ChessBoard[newsq].piece == empty)
			{
			MoveTable[Depth].newpos1 = newsq;
			if (loopbody(P))
			return 1;
			}
	            	       }
	 break;
	case bishop :  /*象走田字路,且田心无棋子*/
		  for (dir = 3; dir >= 0; dir--)
                  {
		newsq = MoveTable[Depth].oldpos + BishopDir[dir];
		    {
		if  (BishopDir[dir]== 0x1E)
			 tmpBishopDir = 0x0F;
		if  (BishopDir[dir]== -0x1E)
			 tmpBishopDir= -0x0F;
		if  (BishopDir[dir]== 0x22)
			 tmpBishopDir= 0x11;
		if  (BishopDir[dir]== -0x22)
			 tmpBishopDir= -0x11;
		    }
	       if ((newsq<=0x98) && (newsq>=0))
		if (((newsq>>4)<10) && ((newsq % 16)< 9)
		    && ((newsq | 0xff) >=0))
		  if (ChessBoard[MoveTable[Depth].oldpos].color == red)
		   if (( ChessBoard[newsq -  tmpBishopDir].piece == empty ))
			if (( newsq >=0) && ( newsq <= 0x48))
			 if (ChessBoard[newsq].piece == empty)
			        {
				   MoveTable[Depth].newpos1 = newsq;
				       if (loopbody(P))
				         return 1;
		                }
		  }
	    for (dir = 3; dir >= 0; dir--)
               {
	       newsq = MoveTable[Depth].oldpos + BishopDir[dir];
					{
		if  (BishopDir[dir]== 0x1E)
			 tmpBishopDir = 0x0F;
		if  (BishopDir[dir]== -0x1E)
			 tmpBishopDir= -0x0F;
		if  (BishopDir[dir]== 0x22)
			 tmpBishopDir= 0x11;
		if  (BishopDir[dir]== -0x22)
			 tmpBishopDir= -0x11;
					}
	       if ((newsq<=0x98) && (newsq>=0))
		if (((newsq>>4)<10) && ((newsq % 16)< 9)
		     && ((newsq | 0xff) >=0))
		  if (ChessBoard[MoveTable[Depth].oldpos].color == black)
		   if (((newsq - tmpBishopDir)<=0x98) && ((newsq - tmpBishopDir)>=0))
			if ((((newsq - tmpBishopDir)>>4)<10) && (((newsq - tmpBishopDir) % 16)< 9)
			    && (((newsq - tmpBishopDir) | 0xff) >=0))
		     if (( ChessBoard[newsq - tmpBishopDir].piece == empty ))
			if (( newsq >= 0x50) && ( newsq <= 0x98))
			 if (ChessBoard[newsq].piece == empty)
			     {
			       MoveTable[Depth].newpos1 = newsq;
				if (loopbody(P))
				return 1;
			     }
                  }
	  break;
         case knight :    /*马走日字路,且不能有躄脚子*/
            for (dir = 7; dir >= 0; dir--)
            {
	       newsq = MoveTable[Depth].oldpos + KnightDir[dir];

	       	if  ( KnightDir[dir]== 0x0E)
		    tmpKnightDir= 0x0F;
	      	if  ( KnightDir[dir]== -0x0E)
		    tmpKnightDir= -0x0F;
	      	if  ( KnightDir[dir]== 0x12)
		    tmpKnightDir = 0x11;
	     	if  ( KnightDir[dir]== -0x12)
		    tmpKnightDir = -0x11;
	      	if  ( KnightDir[dir]== 0x1F)
		    tmpKnightDir = 0x0F;
		if  (KnightDir[dir]== -0x1F)
		    tmpKnightDir = -0x0F;
		if  ( KnightDir[dir]== 0x21)
		    tmpKnightDir = 0x11;
	     	if  ( KnightDir[dir]== -0x21)
		    tmpKnightDir = -0x11;

    if ((newsq<=0x98) && (newsq>=0))
      if (((newsq>>4)<10) && ((newsq % 16)< 9)
		    && ((newsq | 0xff) >=0))
	if (((newsq - tmpKnightDir)<=0x98) && ((newsq - tmpKnightDir)>=0))
	   if ((((newsq - tmpKnightDir)/16)<10) && (((newsq - tmpKnightDir) % 16)< 9)
		       && (((newsq - tmpKnightDir) | 0xff) >=0))
	      if ( ChessBoard[newsq - tmpKnightDir].piece == empty )
		       if (ChessBoard[newsq].piece == empty)
                    {
                        MoveTable[Depth].newpos1 = newsq;
                        if (loopbody(P))
                            return 1;
                    }
	    }
            break;

       /*车、炮可以连续走子*/
        case rook  :
	case gunner :
	    for (dir = 3; dir >= 0; dir--)
            {
                direction = DirectionTab[dir];
		   newsq = MoveTable[Depth].oldpos + direction;
		while (((newsq>>4)<10) && ((newsq % 16)<9)
		      && (newsq<=0x98) && (newsq>=0) && ((newsq | 0xff) >=0))
                {
                    if (ChessBoard[newsq].piece != empty) goto TENS;
                    MoveTable[Depth].newpos1 = newsq;
                    if (loopbody(P))
                        return 1;

                    newsq = MoveTable[Depth].newpos1 + direction;
                }
TENS:
                continue;
	    }
            break;
        case pawn :
            /*  加x10意味着棋子向前走一格 */
	 MoveTable[Depth].newpos1 = MoveTable[Depth].oldpos + 0x10 ;
	     if ((MoveTable[Depth].newpos1<=0x98) && (MoveTable[Depth].newpos1>=0))
		  if (((MoveTable[Depth].newpos1>>4)<10) && ((MoveTable[Depth].newpos1 % 16)< 9)
		      && ((MoveTable[Depth].newpos1 | 0xff) >=0))
			if (ChessBoard[MoveTable[Depth].oldpos].color == red)
			  if (MoveTable[Depth].oldpos  >= 0x30 )
		           if (ChessBoard[MoveTable[Depth].newpos1].piece == empty)
			      if (loopbody(P))
				return 1;

           /*  加1意味着棋子向右走一格 */
	  MoveTable[Depth].newpos1 = MoveTable[Depth].oldpos + 1 ;
	       if ((MoveTable[Depth].newpos1<=0x98) && (MoveTable[Depth].newpos1>=0))
		  if (((MoveTable[Depth].newpos1>>4)<10) && ((MoveTable[Depth].newpos1 % 16)< 9)
		      && ((MoveTable[Depth].newpos1 | 0xff) >=0))
			if (ChessBoard[MoveTable[Depth].oldpos].color == red)
			  if (MoveTable[Depth].oldpos  >= 0x50 )
		 	      if (ChessBoard[MoveTable[Depth].newpos1].piece == empty)
				   if (loopbody(P))
			        	return 1;

          /*  减1意味着棋子向左走一格 */
	  MoveTable[Depth].newpos1 = MoveTable[Depth].oldpos - 1 ;
	     if ((MoveTable[Depth].newpos1<=0x98) && (MoveTable[Depth].newpos1>=0))
		if (((MoveTable[Depth].newpos1>>4)<10) && ((MoveTable[Depth].newpos1 % 16)< 9)
		    && ((MoveTable[Depth].newpos1 | 0xff) >=0))
		 if (ChessBoard[MoveTable[Depth].oldpos].color == red)
			if (MoveTable[Depth].oldpos  >= 0x50 )
			  if (ChessBoard[MoveTable[Depth].newpos1].piece == empty)
				 if (loopbody(P))
			        	return 1;


            /*  减x10意味着棋子向后走一格 */
	    MoveTable[Depth].newpos1 = MoveTable[Depth].oldpos - 0x10 ;
	      if ((MoveTable[Depth].newpos1<=0x98) && (MoveTable[Depth].newpos1>=0))
		  if (((MoveTable[Depth].newpos1>>4)<10) && ((MoveTable[Depth].newpos1 % 16)< 9)
		      && ((MoveTable[Depth].newpos1 | 0xff) >=0))
			if (ChessBoard[MoveTable[Depth].oldpos].color == black)
			  if (MoveTable[Depth].oldpos  <= 0x68 )
		           if (ChessBoard[MoveTable[Depth].newpos1].piece == empty)
			      if (loopbody(P))
				return 1;

              /*  加1意味着棋子向右走一格 */
	   MoveTable[Depth].newpos1 = MoveTable[Depth].oldpos + 1 ;
	      if ((MoveTable[Depth].newpos1<=0x98) && (MoveTable[Depth].newpos1>=0))
		  if (((MoveTable[Depth].newpos1>>4)<10) && ((MoveTable[Depth].newpos1 % 16)< 9)
		      && ((MoveTable[Depth].newpos1 | 0xff) >=0))
			if (ChessBoard[MoveTable[Depth].oldpos].color == black)
			  if (MoveTable[Depth].oldpos  <= 0x48 )
				if (ChessBoard[MoveTable[Depth].newpos1].piece == empty)
				 if (loopbody(P))
				return 1;
          /*  减1意味着棋子向左走一格 */
	   MoveTable[Depth].newpos1 = MoveTable[Depth].oldpos - 1 ;
	     if ((MoveTable[Depth].newpos1<=0x98) && (MoveTable[Depth].newpos1>=0))
		if (((MoveTable[Depth].newpos1>>4)<10) && ((MoveTable[Depth].newpos1 % 16)< 9)
		    && ((MoveTable[Depth].newpos1 | 0xff) >=0))
		  if (ChessBoard[MoveTable[Depth].oldpos].color == black)
			if (MoveTable[Depth].oldpos  <= 0x48 )
			  if (ChessBoard[MoveTable[Depth].newpos1].piece == empty)
			     if (loopbody(P))
				return 1;
	 } /*  switch  */
    return 0;
}



/*
 在分析之前生成下一个移动。
 按以下顺序生成移动:
 主要变化
 吃子
 将军
 常规移动
 */

static void searchmovgen(PARAMTYPE *P)
{
    INDEXTYPE index;

    /*  从主要变化中生成移动  */
    if (P->bestpath[Depth].movpiece != empty)
    {
        MoveTable[Depth] = P->bestpath[Depth];
        P->S->movgentype = mane;
        if (loopbody(P)) return;
    }
    if (MoveTable[Depth - 1].movpiece != empty)
        if (MoveTable[Depth - 1].movpiece != king)
        {
            P->S->movgentype = specialcap;
            if (capmovgen(MoveTable[Depth - 1].newpos1, P)) return;
        }
    P->S->movgentype = norml;
    for (index = 0; index <= PawnNumber[Opponent]; index++)
        if (PieceTable[Opponent][index].ipiece != empty)
            if (MoveTable[Depth-1].movpiece == empty ||
                    PieceTable[Opponent][index].isquare !=
                    MoveTable[Depth-1].newpos1)
                if (capmovgen(PieceTable[Opponent][index].isquare, P))
                    return;

    if (!P->S->capturesearch)                /*  非吃子  */
    {
        for (index = PawnNumber[Player]; index >= 0; index--)
	    if (PieceTable[Player][index].ipiece != empty)
                if (noncapmovgen(PieceTable[Player][index].isquare, P)) return;
    }
}


/*
 执行搜索
 入口:
     Player 指下一次移动的玩家
     MoveTable[Depth-1] 表包含上一次移动
     alpha, beta 指示搜索宽度
     ply 意指搜索深度
     inf 包含各种信息
 出口:
     Bestpath 包括最好的变化
     search 包括对玩家的估值
 */

static MAXTYPE search(MAXTYPE alpha, MAXTYPE beta, int ply, INFTYPE *inf,
    MOVETYPE *bestpath)
{
    SEARCHTYPE S;
    PARAMTYPE P;
    /*  如果ply <= 0且没有将军,执行吃子搜索  */
    S.capturesearch = ((ply <= 0) && !CheckTable[Depth-1]);
    if (S.capturesearch)  /*  初始化最大值  */
    {
        S.maxval = -inf->evaluation;
        if (alpha < S.maxval)
        {
            alpha = S.maxval;
            if (S.maxval >= beta) goto STOP;
        }
    }
    else
        S.maxval = -(LOSEVALUE - Depth*DEPTHFACTOR);
    P.alpha = alpha;
    P.beta = beta;
    P.ply = ply;
    P.inf = inf;
    P.bestpath = bestpath;
    P.S = &S;
    searchmovgen(&P);   /*  搜索循环  */
    if (SkipSearch) goto STOP;
    if (S.maxval == -(LOSEVALUE - Depth * DEPTHFACTOR))  /* 检查无子可动局面*/
        if (!Attacks(Opponent, PieceTable[Player][0].isquare))
        {
            S.maxval = 0;
            goto STOP;
        }
STOP:
    return S.maxval;
}


/*
 *  开始搜索
 */

static MAXTYPE callsearch(MAXTYPE alpha, MAXTYPE beta)
{
    MAXTYPE maxval;

    startinf.principvar = (MainPath[0].movpiece != empty);
    LegalMoves = 0;
    maxval = search(alpha, beta, MaxDepth, &startinf, &MainPath[0]);
    if (!LegalMoves)
        MainEvaluat = maxval;
    return maxval;
}


/*
 *  检查搜索时间是否已到
 */

inline short timeused(void)
{
    short tu = 0;

    if (Analysis && !SingleStep)
    {
        StopTime(&ChessClock);
        tu = (ChessClock.totaltime >= WantedTime);
    }
    return tu;
}


/*
 *  调整搜索
 */

void SearchMove(int maxlevel)
{
    MAXTYPE maxval;
    double calcpvtime;
    InitTime(&ChessClock);
    StartTime(&ChessClock);
    InitNode(&Nodes);
    SkipSearch = 0;
    RemoveKillMove();
    CalcPVTable();
    StopTime(&ChessClock);
    calcpvtime = ChessClock.totaltime;
    startinf.value = startinf.evaluation = -RootValue;
    MaxDepth = 0;
    MainPath[0] = ZeroMove;
    MainEvaluat = RootValue;
    alphawindow = MAXINT;
    ComputerThinking = true;
    do
    {
        /*  更改最大值变量  */
        if (MaxDepth <= 1) repeatevalu = MainEvaluat;
        alphawindow = min(alphawindow, MainEvaluat - 0x80);
        if (Level == matesearch)
	{
	    alphawindow = 0x6000;
            if (MaxDepth > 0) MaxDepth++;
        }
        MaxDepth++;
       	maxval = callsearch(alphawindow, 0x7F00);  /*  执行搜索  */
        if (maxval <= alphawindow && !SkipSearch && Level != matesearch &&
                LegalMoves > 0)
        {
            /*  如果局面值低于最大窗口值就重复搜索 */
            MainEvaluat = alphawindow;
	    maxval = callsearch(-0x7F00, alphawindow - TOLERANCE * 2);
            LegalMoves = 2;
	}
    } while (!SkipSearch && !timeused() && (MaxDepth < maxlevel) &&
	    (LegalMoves > 1) &&
	    (abs(MainEvaluat) < MATEVALUE - 24 * DEPTHFACTOR));
   ComputerThinking = false;
   StopTime(&ChessClock);

   if (Analysis)
      PrintNodes(&Nodes, (ChessClock.totaltime - calcpvtime));
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -