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

📄 movegener.cpp

📁 程序功能很多
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        cnt++;
    return cnt;
}


/*
   在没有发生和棋前计算棋格被占据的次数
   movetab[back..Depth] 包含先前的移动
   当 immediate 设置时,只有接连重复才算。
   连续三次局面重复算是和棋
 */

REPEATTYPE Repetition(short immediate)
{
    DEPTHTYPE lastdep, compdep, tracedep, checkdep, samedepth;
    SQUARETYPE tracesq, checksq;
    REPEATTYPE repeatcount;

    repeatcount = 1;
    lastdep = samedepth = DEPTHTYPE(Depth + 1);  /*  当前位置的深度  */
    compdep = DEPTHTYPE(samedepth - 4);        /*  与第一次棋子位置进行比较  */

    /*
    MoveTable[lastdep..Depth]包含了先前相关的移动
      */
    while (RepeatMove(&MoveTable[lastdep - 1]) && (compdep < lastdep ||
                 !immediate))
        lastdep--;
    if (compdep < lastdep)
        return repeatcount;
    checkdep = samedepth;
    do
    {
        checkdep--;
        checksq = MoveTable[checkdep].newpos1;
        for (tracedep = DEPTHTYPE(checkdep + 2); tracedep < samedepth; tracedep += DEPTHTYPE(2))
				if (MoveTable[tracedep].oldpos == checksq) goto TENMOV;

        /*  回溯移动,看是否以前出现过悔棋 */
        tracedep = checkdep;
        tracesq = MoveTable[tracedep].oldpos;
        do
        {
            if (tracedep-2 < lastdep) return repeatcount;
            tracedep -= (DEPTHTYPE)2;
            /* 检查棋子先前是否移动过 */
            if (tracesq == MoveTable[tracedep].newpos1) tracesq =
                    MoveTable[tracedep].oldpos;
        } while (tracesq != checksq || tracedep > compdep + 1);
        if (tracedep < compdep)    /*  调整比较的深度  */
        {
            compdep = tracedep;
            if ((samedepth - compdep) % 2 == 1)
            {
                if (compdep == lastdep) return repeatcount;
                compdep --;
            }                                    
            checkdep = samedepth;
        }
        /*
        在同一深度和比较深度之间进行移动检查,决定是否能找到重复局面
         */
TENMOV :   if (checkdep <= compdep)
        {
            repeatcount++;
            if (compdep - 2 < lastdep) return repeatcount;
            checkdep = samedepth = compdep;
            compdep -= (DEPTHTYPE)2;
        }
    } while (1);
}



/*
  把生成的移动保存在缓冲区
 */

static void Generate()
{
    BufCount++;
    Buffer[BufCount] = Next;
}



/*
根据棋子表生成吃子移动
 */

static void CapMovGen()
{
    INDEXTYPE i;
    Next.content = ChessBoard[Next.newpos1].piece;
      for (i = PawnNumber[Player]; i >= 0; i--)
	if (PieceTable[Player][i].ipiece != empty)
          if (PieceAttacks(PieceTable[Player][i].ipiece, Player,
                PieceTable[Player][i].isquare, Next.newpos1))
          {
	      Next.oldpos = PieceTable[Player][i].isquare;
              Next.movpiece = PieceTable[Player][i].ipiece;
              Generate();
          }
}

/*
根据棋子原先的位置生成非吃子移动
 */

static void NonCapMovGen()
{
    DIRTYPE  first, last, dir;
    int direction;
    EDGESQUARETYPE  newsq;
    int tmpBishopDir,tmpKnightDir;

    Next.spe = 0;
    Next.movpiece = ChessBoard[Next.oldpos].piece;
    Next.content = empty;
    switch (Next.movpiece)
    {
     /*  生成几个方向的非吃子移动。兵未过河时,只有一个方向;过河后,有三个方向 */
	case pawn :
	 newsq = Next.oldpos + 0x10;
	 if (((newsq)<=0x98) && (newsq >= 0 ))
	  if (((newsq>>4)<10) && ((newsq % 16)<9) && ((newsq | 0xff)>=0))
	    if  (ChessBoard[Next.oldpos].color == red)
	      if (( newsq >= 0x40) && ( newsq  <= 0x98))
		 if (ChessBoard[newsq].piece == empty)
		    {
		      Next.newpos1 = newsq;
		      Generate();
		    }
	 newsq = Next.oldpos + 1;
	 if (((newsq)<=0x98) && (newsq >= 0 ))
	  if (((newsq>>4)<10) && ((newsq % 16)<9) && ((newsq | 0xff)>=0))
	    if  (ChessBoard[Next.oldpos].color == red)
	      if (( newsq >= 0x50) && ( newsq  <= 0x98))
		 if (ChessBoard[newsq].piece == empty)
		    {
		      Next.newpos1 = newsq;
		      Generate();
		    }
	 newsq = Next.oldpos - 1;
	 if (((newsq)<=0x98) && (newsq >= 0 ))
	  if (((newsq>>4)<10) && ((newsq % 16)<9) && ((newsq | 0xff)>=0))
	    if  (ChessBoard[Next.oldpos].color == red)
	      if (( newsq >= 0x50) && ( newsq  <= 0x98))
		 if (ChessBoard[newsq].piece == empty)
		    {
		      Next.newpos1 = newsq;
		      Generate();
		    }
	 newsq = Next.oldpos - 0x10;
	 if (((newsq)<=0x98) && (newsq >= 0 ))
	  if (((newsq>>4)<10) && ((newsq % 16)<9) && ((newsq | 0xff)>=0))
	    if  (ChessBoard[Next.oldpos].color == black)
	      if (( newsq <= 0x58) && ( newsq  <= 0x98))
		 if (ChessBoard[newsq].piece == empty)
		    {
		      Next.newpos1 = newsq;
		      Generate();
		    }

	 newsq = Next.oldpos + 1;
	 if (((newsq)<=0x98) && (newsq >= 0 ))
	  if (((newsq>>4)<10) && ((newsq % 16)<9) && ((newsq | 0xff)>=0))
	    if  (ChessBoard[Next.oldpos].color == black)
	      if (( newsq <= 0x48) && ( newsq  <= 0x98))
		 if (ChessBoard[newsq].piece == empty)
		    {
		      Next.newpos1 = newsq;
		      Generate();
		    }
	 newsq = Next.oldpos - 1;
	 if (((newsq)<=0x98) && (newsq >= 0 ))
	  if (((newsq>>4)<10) && ((newsq % 16)<9) && ((newsq | 0xff)>=0))
	    if  (ChessBoard[Next.oldpos].color == black)
	      if (( newsq <= 0x48) && ( newsq  <= 0x98))
		 if (ChessBoard[newsq].piece == empty)
		    {
		      Next.newpos1 = newsq;
		      Generate();
		    }
               break;
        /*  生成王四个方向的非吃子移动 */
	case king :
	 newsq = Next.oldpos + 1;
	 if (((newsq)<=0x98) && (newsq >= 0 ))
	  if (((newsq>>4)<10) && ((newsq % 16)<9) && ((newsq | 0xff)>=0))
	    if  (ChessBoard[Next.oldpos].color == red)
	      if (( newsq >=0) && ( newsq  <= 0x28) && ((newsq % 16) >=3)
				&& ((newsq % 16) <=5))
		 if (ChessBoard[newsq].piece == empty)
		    {
		      Next.newpos1 = newsq;
		      Generate();
		    }

	 newsq = Next.oldpos - 1;
	 if (((newsq)<=0x98) && (newsq >= 0 ))
	  if (((newsq>>4)<10) && ((newsq % 16)<9) && ((newsq | 0xff)>=0))
	    if  (ChessBoard[Next.oldpos].color == red)
	      if (( newsq >=0) && ( newsq  <= 0x28) && ((newsq % 16) >=3)
				&& ((newsq % 16) <=5))
		 if (ChessBoard[newsq].piece == empty)
		    {
		      Next.newpos1 = newsq;
		      Generate();
		    }

	 newsq = Next.oldpos + 0x10;
	 if (((newsq)<=0x98) && (newsq >= 0 ))
	  if (((newsq>>4)<10) && ((newsq % 16)<9) && ((newsq | 0xff)>=0))
	    if  (ChessBoard[Next.oldpos].color == red)
	      if (( newsq >=0) && ( newsq  <= 0x28) && ((newsq % 16) >=3)
				&& ((newsq % 16) <=5))
		 if (ChessBoard[newsq].piece == empty)
		    {
		      Next.newpos1 = newsq;
		      Generate();
		    }

	 newsq = Next.oldpos - 0x10;
	 if (((newsq)<=0x98) && (newsq >= 0 ))
	  if (((newsq>>4)<10) && ((newsq % 16)<9) && ((newsq | 0xff)>=0))
	    if  (ChessBoard[Next.oldpos].color == red)
	      if (( newsq >=0) && ( newsq  <= 0x28) && ((newsq % 16) >=3)
				&& ((newsq % 16) <=5))
		 if (ChessBoard[newsq].piece == empty)
		    {
		      Next.newpos1 = newsq;
		      Generate();
		    }

	  newsq = Next.oldpos + 1;
	   if (((newsq)<=0x98) && (newsq >= 0 ))
	    if (((newsq>>4)<10) && ((newsq % 16)<9) && ((newsq | 0xff)>=0))
	        if  (ChessBoard[Next.oldpos].color == black)
		 if (( newsq >= 0x70) && ( newsq <= 0x98) && ((newsq % 16) >=3)
				&& ((newsq % 16) <=5))
		    if (ChessBoard[newsq].piece == empty)
		       {
			 Next.newpos1 = newsq;
			 Generate();
		       }

	    newsq = Next.oldpos - 1;
	   if (((newsq)<=0x98) && (newsq >= 0 ))
	    if (((newsq>>4)<10) && ((newsq % 16)<9) && ((newsq | 0xff)>=0))
	        if  (ChessBoard[Next.oldpos].color == black)
		 if (( newsq >= 0x70) && ( newsq <= 0x98) && ((newsq % 16) >=3)
				&& ((newsq % 16) <=5))
		    if (ChessBoard[newsq].piece == empty)
		       {
			 Next.newpos1 = newsq;
			 Generate();
		       }

	    newsq = Next.oldpos + 0x10;
	   if (((newsq)<=0x98) && (newsq >= 0 ))
	    if (((newsq>>4)<10) && ((newsq % 16)<9) && ((newsq | 0xff)>=0))
	        if  (ChessBoard[Next.oldpos].color == black)
		 if (( newsq >= 0x70) && ( newsq <= 0x98) && ((newsq % 16) >=3)
				&& ((newsq % 16) <=5))
		    if (ChessBoard[newsq].piece == empty)
		       {
			 Next.newpos1 = newsq;
			 Generate();
		       }

	   newsq = Next.oldpos - 0x10;
	   if (((newsq)<=0x98) && (newsq >= 0 ))
	    if (((newsq>>4)<10) && ((newsq % 16)<9) && ((newsq | 0xff)>=0))
	        if  (ChessBoard[Next.oldpos].color == black)
		 if (( newsq >= 0x70) && ( newsq <= 0x98) && ((newsq % 16) >=3)
				&& ((newsq % 16) <=5))
		    if (ChessBoard[newsq].piece == empty)
		       {
			 Next.newpos1 = newsq;
			 Generate();
		       }
	    break;

            /*  生成士四个方向的非吃子移动 */
	case assist :
	 for (dir = 3; dir >= 0; dir--)
	  {
	   newsq = Next.oldpos + AssistDir[dir];
	  if (((newsq)<=0x98) && (newsq >= 0 ))
	  if (((newsq>>4)<10) && ((newsq % 16)<9) && ((newsq | 0xff)>=0))
	    if  (ChessBoard[Next.oldpos].color == red)
	      if (( newsq  >=0) && ( newsq <= 0x28) && ((newsq % 16) >=3)
				&& ((newsq % 16) <=5))
	         if (ChessBoard[newsq].piece == empty)
		    {
		      Next.newpos1 = newsq;
		      Generate();
		    }
	  }

	 for (dir = 3; dir >= 0; dir--)
	   {
	    newsq = Next.oldpos + AssistDir[dir];
	    if (((newsq)<=0x98) && (newsq >= 0 ))
	     if (((newsq>>4)<10) && ((newsq % 16)<9) && ((newsq | 0xff)>=0))
	       if  (ChessBoard[Next.oldpos].color == black)
		 if (( newsq  >= 0x70) && ( newsq <= 0x98) && ((newsq % 16) >=3)
				&& ((newsq % 16) <=5))
		    if (ChessBoard[newsq].piece == empty)
		       {
			 Next.newpos1 = newsq;
			 Generate();
		       }
	   }
        	 break;
       /*  生成象四个方向的非吃子移动 */
	case bishop:
	   first = 3;
	   last = 0;
	  for (dir = first; dir >= last; dir--)
	    {
	     direction = BishopDir[dir];
	     newsq = Next.oldpos + direction;
		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 (((newsq-tmpBishopDir) <= 0x98) && ((newsq-tmpBishopDir) >=0))
		 if ((((newsq-tmpBishopDir)>>4)<10) && (((newsq-tmpBishopDir) % 16)< 9))
		  if (( ChessBoard[newsq -  tmpBishopDir].piece == empty ))
		    if (ChessBoard[newsq].piece == empty)
		      if (ChessBoard[Next.oldpos].color == red)
			 if (( newsq  >=0) && ( newsq <= 0x48))
			 Next.newpos1 = newsq;
			 Generate();
	    }
	 for (dir = first; dir >= last; dir--)
	     {
	       direction = BishopDir[dir];
	       newsq = Next.oldpos + direction;
	       /*  生成四个方向的非吃子移动 */
		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 (((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 (ChessBoard[newsq].piece == empty)
		      if  (ChessBoard[Next.oldpos].color == black)
			if (( newsq >= 0x50) && ( newsq  <= 0x98))
		  Next.newpos1 = newsq;
		  Generate();
		 }
		 break;

    case knight :     //马
	   for (dir = 7; dir >= 0; dir--)
	      {
		newsq = Next.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 % 16)>=0) && ((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)
                   {
		   Next.newpos1 = newsq;
		   Generate();
		   }
	      }
		 break;

	case rook :      //车
	case gunner :    //炮
	     first = 3;
	     last = 0;
	   for (dir = first; dir >= last; dir--)
	      {
	       direction = DirectionTab[dir];
	       newsq = Next.oldpos + direction;
					  /*  生成四个方向的非吃子移动 */
		while (((newsq>>4)<10) && ((newsq % 16)<9) &&
		      (newsq <= 0x98) && (newsq >=0) && ((newsq | 0xff)>=0))
		{
		if (ChessBoard[newsq].piece != empty) goto TENNMOV;
		Next.newpos1 = newsq;
		Generate();
		newsq = Next.newpos1 + direction;
		}
TENNMOV:            continue;
              }
		 break;
        }  /* switch */
}


/*
  生成移动
  生成所有可能的移动并把它们逐个放在缓冲区内
   开始:
     Player 指移动棋子的一方.
     MoveTable[Depth-1] 上一次执行过的移动.
  结束:
    缓冲区包含全部生成的移动
    生成移动的顺序:
    吃子
    非吃子
 */

void InitMovGen()
{
	 INDEXTYPE index;

	 BufCount = BufPnt = 0;
	 /*  从王开始生成吃子移动  */
      for (index = 0; index <= PawnNumber[Opponent]; index++)
		  if (PieceTable[Opponent][index].ipiece != empty)
		  {
		   Next.newpos1 = PieceTable[Opponent][index].isquare;
		   CapMovGen();
		  }

	    /*  从兵开始生成非吃子移动  */
      for (index = PawnNumber[Player]; index >= 0; index--)
        if (PieceTable[Player][index].ipiece != empty)
	{
            Next.oldpos = PieceTable[Player][index].isquare;
            NonCapMovGen();
	}
}

/*
把生成的移动一个连一个地保存在Next链表中。没有棋子可移动时生成零移动
 */

void MovGen()
{
    if (BufPnt >= BufCount)
        Next = ZeroMove;
    else
    {
        BufPnt++;
        Next = Buffer[BufPnt];
    }
}

⌨️ 快捷键说明

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