日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

[转载] 中国象棋软件-引擎实现(三)着法生成

發(fā)布時(shí)間:2023/12/13 综合教程 28 生活家
生活随笔 收集整理的這篇文章主要介紹了 [转载] 中国象棋软件-引擎实现(三)着法生成 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

我們的程序需要讓電腦能夠在輪到它走子的時(shí)候執(zhí)行一個它認(rèn)為對它最有利的著法,那前提就是它要有諸多(也可能是唯一)可供選擇的著法,提供所有可選著法的“清單”就是我們的著法生成器所要完成的。之后用搜索函數(shù)來搜索“清單”,并用局面評估函數(shù)來逐一打分,最后就可以選擇“最佳”著法并實(shí)施了。

在著法生成器中,我采用的基本思想就是遍歷整個棋盤(一個接一個地看棋盤上的每個位置點(diǎn)),當(dāng)發(fā)現(xiàn)有當(dāng)前下棋方的棋子時(shí)就根據(jù)它是何種棋子而相應(yīng)地找出其所有合法著法,然后存入著法隊(duì)列。

這里談到的“合法著法”包括以下幾點(diǎn):
1、各棋子按其行子規(guī)則行子。諸如馬跳“日”字、象走“田”字、士在九宮內(nèi)斜行等等(這里需要特別注意的是卒的行子規(guī)則隨其所在位置不同而會發(fā)生變化——過河后可以左右平移)。
2、行子不能越出棋盤界限。當(dāng)然所有子都不能走到棋盤的外面,同時(shí)某些特定的子還有自己的行棋界限,如將、士不能出九宮,象不能過河。
3、行子的半路上不能有子阻攔(除了炮隔子打子之外)以及行子的目的點(diǎn)不能有本方棋子(當(dāng)然不能自己吃自己了)。
4、將帥不能碰面(本程序中只認(rèn)為將帥碰面是非法的,而其它“送死”的著法并不非法,只是產(chǎn)生敗局罷了)

產(chǎn)生了著法后要將其存入著法隊(duì)列以供搜索之用,由于搜索會搜索多層(即考慮雙方你來我往好幾步,這樣才有利于對局面進(jìn)行評估而盡可能避免“目光短淺”

),所以在存著法隊(duì)列的時(shí)候還要同時(shí)存儲該著法所屬的搜索層數(shù)。因此我將著法隊(duì)列定義為二維數(shù)組MoveList[12][80],第一個下標(biāo)為層數(shù),第二個下標(biāo)為每一層的全部著法數(shù)。

關(guān)于搜索層數(shù),考慮到當(dāng)前大多數(shù)機(jī)器的配置以及層數(shù)對電腦水平的影響我給數(shù)組下標(biāo)設(shè)定為12,實(shí)際使用的是1到11(搜索層數(shù)的增加會顯著提高電腦的下棋水平。但有關(guān)實(shí)驗(yàn)數(shù)據(jù)表明,當(dāng)搜索層數(shù)大于8、9之后電腦下棋水平將主要依賴于局面評估部分。我的迅馳1.5,736M內(nèi)存的筆記本只能搜索5層,再多將導(dǎo)致搜索時(shí)間達(dá)到無法容忍的地步,而我們指導(dǎo)老師的雙CPU的機(jī)器搜索到11層也很輕松)。

而對每一層的著法數(shù),也就是當(dāng)前下棋方針對某一局面的所有合法著法,在象棋實(shí)戰(zhàn)中一般最多也就五六十種。定義第二個數(shù)組下標(biāo)為80,基本上可以保證安全。

下面是CChessMove.h的代碼。其中CCHESSMOVE類型和POINT類型分別是在前面一篇CChessDef.h中定義的走法的結(jié)構(gòu)體以及棋盤上的點(diǎn)的結(jié)構(gòu)體。
在GenerateMove函數(shù)中存在著較大范圍的代碼冗余,像

//==========生成紅車的著法
case RED_J:
……
break;
//==========生成黑車的著法
case BLACK_J:
……
break;

之類的代碼段完全可以并到一起寫成

//==========生成車的著法
case RED_J:            // fall through
case BLACK_J:
……
break;

的形式,之所以分開寫是由我最初的設(shè)計(jì)思想導(dǎo)致的(我原本計(jì)劃不遍歷棋盤而是遍歷所有棋子,后來發(fā)現(xiàn)這樣做得不償失所以又中途改成遍歷棋盤了)。而當(dāng)最初的方案被否決并修改后,我覺得既然已經(jīng)分開寫了,這樣也不會影響最后程序的執(zhí)行效率,結(jié)合注釋分開寫反而讀起來更加清楚,所以也就沒改。由此導(dǎo)致的代碼冗余,如果哪位朋友看了覺得不爽,還望海涵 : )

// CChessMove.h    

#include "CChessDef.h"    

/////////////////// Data Define ///////////////////////////////////////////////    

CCHESSMOVE MoveList[12][80] ;  // 存儲產(chǎn)生的著法隊(duì)列
int nMoveCount  ;        // 存儲當(dāng)前搜索深度已產(chǎn)生的著法數(shù)    

/////////////////// Function Prototype ////////////////////////////////////////    

// 判斷ptPosition處是否有同一方的子,若有返回true,否則返回false
inline bool HaveFriend( POINT ptPosition, int fSide );    

// 判斷 x, y 處是否有同一方的子,若有返回true,否則返回false
inline bool HaveFriend( BYTE x, BYTE y, int fSide );    

// 判斷ptPosition處是否有子,若有返回true,否則返回false
inline bool HaveMan( POINT ptPosition );    

// 判斷 x, y 處是否有子,若有返回true,否則返回false
inline bool HaveMan( BYTE x, BYTE y );    

// 檢查將帥是否碰面,若碰面返回對方王的 y 值坐標(biāo),不碰面則返回-1。
//  其中x, y分別為當(dāng)前走棋方的王所在位置坐標(biāo),fSide為當(dāng)前走棋方
int IsKingFaceToFace( int x, int y, int fSide );    

// 產(chǎn)生fSide方所有著法,返回產(chǎn)生的著法總數(shù)。nDepth為當(dāng)前搜索深度,
//用于傳給AddMoveToQueue函數(shù)
int GenerateMove( int fSide, int nDepth );    

// 將產(chǎn)生的著法加入著法隊(duì)列。nDepth為當(dāng)前搜索深度
inline void AddMoveToQueue( POINT ptFrom, POINT ptTo, int nDepth );    

// 將產(chǎn)生的著法加入著法隊(duì)列。nDepth為當(dāng)前搜索深度
inline void AddMoveToQueue( POINT ptFrom, BYTE x, BYTE y, int nDepth );    

////////////////// Programmer-Defined Function ////////////////////////////////    

inline bool HaveFriend( POINT ptPosition, int fSide )
{
  if( CChessBoard[ptPosition.x][ptPosition.y] == 0 )
    return false;
  else if( SideOfMan[ CChessBoard[ptPosition.x][ptPosition.y] ] == fSide )
    return true;
  else
    return false;
}    

inline bool HaveFriend( BYTE x, BYTE y, int fSide )
{
  if( CChessBoard[x][y] == 0 )
    return false;
  else if( SideOfMan[ CChessBoard[x][y] ] == fSide )
    return true;
  else
    return false;
}    

inline bool HaveMan( POINT ptPosition )
{
  if( CChessBoard[ptPosition.x][ptPosition.y] == 0 )
    return false;
  else
    return true;
}    

inline bool HaveMan( BYTE x, BYTE y )
{
  if( CChessBoard[x][y] == 0 )
    return false;
  else
    return true;
}    

int IsKingFaceToFace( int x, int y, int fSide )
{
  bool bMayKingFaceToFace = false;
  int i, j ;    

  if( fSide == RED )
  {
    for( i = 9; i >= 7; i -- )  // 檢查黑將是否在同列
    {
      if(  CChessBoard[x][i] == BLACK_K )
      {
        bMayKingFaceToFace = true;
        break;
      }
    }    

    if( bMayKingFaceToFace == false )
      return -1;    

    for( j = y + 1; j <= i - 1 ; j ++ )  // 黑將在同列,檢查中間是否有隔擋
    {
      if( CChessBoard[x][j] != 0 )  // 有其他子
        return -1;
    }    

    return i;  // 將帥碰面,返回黑將的 y 值坐標(biāo)
  }
  else // fSide == BLACK
  {
    for( i = 0; i <= 2; i ++ )  // 檢查紅帥是否在同列
    {
      if(  CChessBoard[x][i] == RED_K )
      {
        bMayKingFaceToFace = true;
        break;
      }
    }    

    if( bMayKingFaceToFace == false )
      return -1;    

    for( j = y - 1; j >= i + 1 ; j -- )  // 紅帥在同列,檢查中間是否有隔擋
    {
      if( CChessBoard[x][j] != 0 )  // 有其他子
        return -1;
    }    

    return i;  // 將帥碰面,返回紅帥的 y 值坐標(biāo)
  }    

}    

int GenerateMove( int fSide, int nDepth )
{
  BYTE    nCChessID ;
  POINT  ptFrom , ptTo , ptHalf ;
  int i;    

  nMoveCount = 0;    

  int x, y;
  for( x = 0; x <= 8; x ++ )
    for( y = 0; y <= 9; y ++ )
    {
      if( CChessBoard[x][y] != 0 )
      {
        nCChessID = CChessBoard[x][y];
        if( SideOfMan[ nCChessID ] != fSide )//該子顏色與所要生成著法的顏色不同
          continue;    

        ptFrom.x = x ;
        ptFrom.y = y ;    

        switch( nCChessID )
        {    

//==========生成紅帥的著法
        case RED_K:    

          // 將帥碰面
          i = IsKingFaceToFace( ptFrom.x, ptFrom.y, fSide );
          if( i != -1 )
            AddMoveToQueue( ptFrom, ptFrom.x, i, nDepth );    

          //縱向
          ptTo.x = ptFrom.x ;    

          //向前
          ptTo.y = ptFrom.y + 1 ;
          if(( ptTo.y <= 2 ) && ( ! HaveFriend( ptTo, fSide ) ))
            AddMoveToQueue( ptFrom, ptTo, nDepth );    

          //向后
          ptTo.y = ptFrom.y - 1 ;
          if(( ptTo.y >= 0 ) && ( ! HaveFriend( ptTo, fSide ) ))
            AddMoveToQueue( ptFrom, ptTo, nDepth );    

          //橫向
          ptTo.y = ptFrom.y ;    

          //向左
          ptTo.x = ptFrom.x - 1 ;
          if(( ptTo.x >= 3 ) && ( ! HaveFriend( ptTo, fSide ) )
            && ( IsKingFaceToFace( ptTo.x, ptTo.y, fSide ) == -1 ) )
            AddMoveToQueue( ptFrom, ptTo, nDepth );    

          //向右
          ptTo.x = ptFrom.x + 1 ;
          if(( ptTo.x <= 5 ) && ( ! HaveFriend( ptTo, fSide ) )
            && ( IsKingFaceToFace( ptTo.x, ptTo.y, fSide ) == -1 ) )
            AddMoveToQueue( ptFrom, ptTo, nDepth );    

          break;    

//==========生成黑將的著法
        case BLACK_K:    

          // 將帥碰面
          i = IsKingFaceToFace( ptFrom.x, ptFrom.y, fSide );
          if( i != -1 )
            AddMoveToQueue( ptFrom, ptFrom.x, i, nDepth );    

          //縱向
          ptTo.x = ptFrom.x ;    

          //向前
          ptTo.y = ptFrom.y - 1 ;
          if(( ptTo.y >= 7 ) && ( ! HaveFriend( ptTo, fSide ) ))
            AddMoveToQueue( ptFrom, ptTo, nDepth );    

          //向后
          ptTo.y = ptFrom.y + 1 ;
          if(( ptTo.y <= 9 ) && ( ! HaveFriend( ptTo, fSide ) ))
            AddMoveToQueue( ptFrom, ptTo, nDepth );    

          //橫向
          ptTo.y = ptFrom.y ;    

          //向左
          ptTo.x = ptFrom.x + 1 ;
          if(( ptTo.x <= 5 ) && ( ! HaveFriend( ptTo, fSide ) )
            && ( IsKingFaceToFace( ptTo.x, ptTo.y, fSide ) == -1 ) )
            AddMoveToQueue( ptFrom, ptTo, nDepth );    

          //向右
          ptTo.x = ptFrom.x - 1 ;
          if(( ptTo.x >= 3 ) && ( ! HaveFriend( ptTo, fSide ) )
            && ( IsKingFaceToFace( ptTo.x, ptTo.y, fSide ) == -1 ) )
            AddMoveToQueue( ptFrom, ptTo, nDepth );    

          break;    

//==========生成紅車的著法
        case RED_J:      

          //縱向
          ptTo.x = ptFrom.x ;    

          //向前
          for( ptTo.y = ptFrom.y + 1; ptTo.y <= 9; ptTo.y ++ )
          {
            if( HaveMan( ptTo ) )
            {
              if( ! HaveFriend( ptTo, fSide ) )
                AddMoveToQueue( ptFrom, ptTo, nDepth );    

              break;
            }
            AddMoveToQueue( ptFrom, ptTo, nDepth );
          }    

          //向后
          for( ptTo.y = ptFrom.y - 1; ptTo.y >= 0; ptTo.y -- )
          {
            if( HaveMan( ptTo ) )
            {
              if( ! HaveFriend( ptTo, fSide ) )
                AddMoveToQueue( ptFrom, ptTo, nDepth );    

              break;
            }
            AddMoveToQueue( ptFrom, ptTo, nDepth );
          }    

          //橫向
          ptTo.y = ptFrom.y ;    

          //向左
          for( ptTo.x = ptFrom.x - 1; ptTo.x >= 0; ptTo.x -- )
          {
            if( HaveMan( ptTo ) )
            {
              if( ! HaveFriend( ptTo, fSide ) )
                AddMoveToQueue( ptFrom, ptTo, nDepth );    

              break;
            }
            AddMoveToQueue( ptFrom, ptTo, nDepth );
          }    

          //向右
          for( ptTo.x = ptFrom.x + 1; ptTo.x <= 8; ptTo.x ++ )
          {
            if( HaveMan( ptTo ) )
            {
              if( ! HaveFriend( ptTo, fSide ) )
                AddMoveToQueue( ptFrom, ptTo, nDepth );    

              break;
            }
            AddMoveToQueue( ptFrom, ptTo, nDepth );
          }    

          break;    

//==========生成黑車的著法
        case BLACK_J:    

          //縱向
          ptTo.x = ptFrom.x ;    

          //向前
          for( ptTo.y = ptFrom.y - 1; ptTo.y >= 0; ptTo.y -- )
          {
            if( HaveMan( ptTo ) )
            {
              if( ! HaveFriend( ptTo, fSide ) )
                AddMoveToQueue( ptFrom, ptTo, nDepth );    

              break;
            }
            AddMoveToQueue( ptFrom, ptTo, nDepth );
          }    

          //向后
          for( ptTo.y = ptFrom.y + 1; ptTo.y <= 9; ptTo.y ++ )
          {
            if( HaveMan( ptTo ) )
            {
              if( ! HaveFriend( ptTo, fSide ) )
                AddMoveToQueue( ptFrom, ptTo, nDepth );    

              break;
            }
            AddMoveToQueue( ptFrom, ptTo, nDepth );
          }    

          //橫向
          ptTo.y = ptFrom.y ;    

          //向左
          for( ptTo.x = ptFrom.x + 1; ptTo.x <= 8; ptTo.x ++ )
          {
            if( HaveMan( ptTo ) )
            {
              if( ! HaveFriend( ptTo, fSide ) )
                AddMoveToQueue( ptFrom, ptTo, nDepth );    

              break;
            }
            AddMoveToQueue( ptFrom, ptTo, nDepth );
          }    

          //向右
          for( ptTo.x = ptFrom.x - 1; ptTo.x >= 0; ptTo.x -- )
          {
            if( HaveMan( ptTo ) )
            {
              if( ! HaveFriend( ptTo, fSide ) )
                AddMoveToQueue( ptFrom, ptTo, nDepth );    

              break;
            }
            AddMoveToQueue( ptFrom, ptTo, nDepth );
          }    

          break;    

//==========生成紅馬的著法
        case RED_M:    

          //ptHalf用來存儲馬腿的位置,以判斷該位置是否有子憋馬腿    

          ptHalf.x = ptFrom.x ;
          ptHalf.y = ptFrom.y + 1 ;
          if( ptHalf.y <= 8 && ! HaveMan( ptHalf ) )
          {
            //11點(diǎn)方向
            ptTo.x = ptFrom.x - 1 ;
            ptTo.y = ptFrom.y + 2 ;
            if( ptTo.x >= 0 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );    

            //1點(diǎn)方向
            ptTo.x = ptFrom.x + 1 ;
            ptTo.y = ptFrom.y + 2 ;
            if( ptTo.x <= 8 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );
          }    

          ptHalf.x = ptFrom.x + 1 ;
          ptHalf.y = ptFrom.y ;
          if( ptHalf.x <= 7 && ! HaveMan( ptHalf ) )
          {
            //2點(diǎn)方向
            ptTo.x = ptFrom.x + 2 ;
            ptTo.y = ptFrom.y + 1 ;
            if( ptTo.y <= 9 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );    

            //4點(diǎn)方向
            ptTo.x = ptFrom.x + 2 ;
            ptTo.y = ptFrom.y - 1 ;
            if( ptTo.y >= 0 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );
          }    

          ptHalf.x = ptFrom.x ;
          ptHalf.y = ptFrom.y - 1 ;
          if( ptHalf.y >= 1 && ! HaveMan( ptHalf ) )
          {
            //5點(diǎn)方向
            ptTo.x = ptFrom.x + 1 ;
            ptTo.y = ptFrom.y - 2 ;
            if( ptTo.x <= 8 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );    

            //7點(diǎn)方向
            ptTo.x = ptFrom.x - 1 ;
            ptTo.y = ptFrom.y - 2 ;
            if( ptTo.x >= 0 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );
          }    

          ptHalf.x = ptFrom.x - 1 ;
          ptHalf.y = ptFrom.y ;
          if( ptHalf.x >= 1 && ! HaveMan( ptHalf ) )
          {
            //8點(diǎn)方向
            ptTo.x = ptFrom.x - 2 ;
            ptTo.y = ptFrom.y - 1 ;
            if( ptTo.y >= 0 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );    

            //10點(diǎn)方向
            ptTo.x = ptFrom.x - 2 ;
            ptTo.y = ptFrom.y + 1 ;
            if( ptTo.y <= 9 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );
          }    

          break;    

//==========生成黑馬的著法
        case BLACK_M:    

          //ptHalf用來存儲馬腿的位置,以判斷該位置是否有子憋馬腿    

          ptHalf.x = ptFrom.x ;
          ptHalf.y = ptFrom.y + 1 ;
          if( ptHalf.y <= 8 && ! HaveMan( ptHalf ) )
          {
            //5點(diǎn)方向
            ptTo.x = ptFrom.x - 1 ;
            ptTo.y = ptFrom.y + 2 ;
            if( ptTo.x >= 0 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );    

            //7點(diǎn)方向
            ptTo.x = ptFrom.x + 1 ;
            ptTo.y = ptFrom.y + 2 ;
            if( ptTo.x <= 8 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );
          }    

          ptHalf.x = ptFrom.x + 1 ;
          ptHalf.y = ptFrom.y ;
          if( ptHalf.x <= 7 && ! HaveMan( ptHalf ) )
          {
            //8點(diǎn)方向
            ptTo.x = ptFrom.x + 2 ;
            ptTo.y = ptFrom.y + 1 ;
            if( ptTo.y <= 9 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );    

            //10點(diǎn)方向
            ptTo.x = ptFrom.x + 2 ;
            ptTo.y = ptFrom.y - 1 ;
            if( ptTo.y >= 0 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );
          }    

          ptHalf.x = ptFrom.x ;
          ptHalf.y = ptFrom.y - 1 ;
          if( ptHalf.y >= 1 && ! HaveMan( ptHalf ) )
          {
            //11點(diǎn)方向
            ptTo.x = ptFrom.x + 1 ;
            ptTo.y = ptFrom.y - 2 ;
            if( ptTo.x <= 8 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );    

            //1點(diǎn)方向
            ptTo.x = ptFrom.x - 1 ;
            ptTo.y = ptFrom.y - 2 ;
            if( ptTo.x >= 0 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );
          }    

          ptHalf.x = ptFrom.x - 1 ;
          ptHalf.y = ptFrom.y ;
          if( ptHalf.x >= 1 && ! HaveMan( ptHalf ) )
          {
            //2點(diǎn)方向
            ptTo.x = ptFrom.x - 2 ;
            ptTo.y = ptFrom.y - 1 ;
            if( ptTo.y >= 0 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );    

            //4點(diǎn)方向
            ptTo.x = ptFrom.x - 2 ;
            ptTo.y = ptFrom.y + 1 ;
            if( ptTo.y <= 9 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );
          }    

          break;    

//==========生成紅炮的著法
        case RED_P:    

          //ptHalf用來存儲炮是否有隔子打子的中間子    

          //縱向
          ptTo.x = ptFrom.x ;    

          //向前
          ptHalf.x = -1;  //標(biāo)志尚未發(fā)現(xiàn)中間子
          for( ptTo.y = ptFrom.y + 1; ptTo.y <= 9; ptTo.y ++ )
          {
            if( ptHalf.x == -1 ) // 無中間子
            {
              if( ! HaveMan( ptTo ) )
              {
                AddMoveToQueue( ptFrom, ptTo, nDepth );
              }
              else // if( HaveMan( ptTo ) )
              {
                ptHalf.x = ptTo.x ;
                ptHalf.y = ptTo.y ;
              }
            }
            else // 已有中間子
            {
              if( HaveMan( ptTo ) )
              {
                if( ! HaveFriend( ptTo, fSide ) )
                  AddMoveToQueue( ptFrom, ptTo, nDepth );    

                break;
              }
            }    

          }    

          //向后
          ptHalf.x = -1;  //標(biāo)志尚未發(fā)現(xiàn)中間子
          for( ptTo.y = ptFrom.y - 1; ptTo.y >= 0; ptTo.y -- )
          {
            if( ptHalf.x == -1 ) // 無中間子
            {
              if( ! HaveMan( ptTo ) )
              {
                AddMoveToQueue( ptFrom, ptTo, nDepth );
              }
              else // if( HaveMan( ptTo ) )
              {
                ptHalf.x = ptTo.x ;
                ptHalf.y = ptTo.y ;
              }
            }
            else // 已有中間子
            {
              if( HaveMan( ptTo ) )
              {
                if( ! HaveFriend( ptTo, fSide ) )
                  AddMoveToQueue( ptFrom, ptTo, nDepth );    

                break;
              }
            }    

          }    

          //橫向
          ptTo.y = ptFrom.y ;    

          //向左
          ptHalf.x = -1;  //標(biāo)志尚未發(fā)現(xiàn)中間子
          for( ptTo.x = ptFrom.x - 1; ptTo.x >= 0; ptTo.x -- )
          {
            if( ptHalf.x == -1 ) // 無中間子
            {
              if( ! HaveMan( ptTo ) )
              {
                AddMoveToQueue( ptFrom, ptTo, nDepth );
              }
              else // if( HaveMan( ptTo ) )
              {
                ptHalf.x = ptTo.x ;
                ptHalf.y = ptTo.y ;
              }
            }
            else // 已有中間子
            {
              if( HaveMan( ptTo ) )
              {
                if( ! HaveFriend( ptTo, fSide ) )
                  AddMoveToQueue( ptFrom, ptTo, nDepth );    

                break;
              }
            }    

          }    

          //向右
          ptHalf.x = -1;  //標(biāo)志尚未發(fā)現(xiàn)中間子
          for( ptTo.x = ptFrom.x + 1; ptTo.x <= 8; ptTo.x ++ )
          {
            if( ptHalf.x == -1 ) // 無中間子
            {
              if( ! HaveMan( ptTo ) )
              {
                AddMoveToQueue( ptFrom, ptTo, nDepth );
              }
              else // if( HaveMan( ptTo ) )
              {
                ptHalf.x = ptTo.x ;
                ptHalf.y = ptTo.y ;
              }
            }
            else // 已有中間子
            {
              if( HaveMan( ptTo ) )
              {
                if( ! HaveFriend( ptTo, fSide ) )
                  AddMoveToQueue( ptFrom, ptTo, nDepth );    

                break;
              }
            }    

          }    

          break;    

//==========生成黑炮的著法
        case BLACK_P:    

          //ptHalf用來存儲炮是否有隔子打子的中間子    

          //縱向
          ptTo.x = ptFrom.x ;    

          //向后
          ptHalf.x = -1;  //標(biāo)志尚未發(fā)現(xiàn)中間子
          for( ptTo.y = ptFrom.y + 1; ptTo.y <= 9; ptTo.y ++ )
          {
            if( ptHalf.x == -1 ) // 無中間子
            {
              if( ! HaveMan( ptTo ) )
              {
                AddMoveToQueue( ptFrom, ptTo, nDepth );
              }
              else // if( HaveMan( ptTo ) )
              {
                ptHalf.x = ptTo.x ;
                ptHalf.y = ptTo.y ;
              }
            }
            else // 已有中間子
            {
              if( HaveMan( ptTo ) )
              {
                if( ! HaveFriend( ptTo, fSide ) )
                  AddMoveToQueue( ptFrom, ptTo, nDepth );    

                break;
              }
            }    

          }    

          //向前
          ptHalf.x = -1;  //標(biāo)志尚未發(fā)現(xiàn)中間子
          for( ptTo.y = ptFrom.y - 1; ptTo.y >= 0; ptTo.y -- )
          {
            if( ptHalf.x == -1 ) // 無中間子
            {
              if( ! HaveMan( ptTo ) )
              {
                AddMoveToQueue( ptFrom, ptTo, nDepth );
              }
              else // if( HaveMan( ptTo ) )
              {
                ptHalf.x = ptTo.x ;
                ptHalf.y = ptTo.y ;
              }
            }
            else // 已有中間子
            {
              if( HaveMan( ptTo ) )
              {
                if( ! HaveFriend( ptTo, fSide ) )
                  AddMoveToQueue( ptFrom, ptTo, nDepth );    

                break;
              }
            }    

          }    

          //橫向
          ptTo.y = ptFrom.y ;    

          //向右
          ptHalf.x = -1;  //標(biāo)志尚未發(fā)現(xiàn)中間子
          for( ptTo.x = ptFrom.x - 1; ptTo.x >= 0; ptTo.x -- )
          {
            if( ptHalf.x == -1 ) // 無中間子
            {
              if( ! HaveMan( ptTo ) )
              {
                AddMoveToQueue( ptFrom, ptTo, nDepth );
              }
              else // if( HaveMan( ptTo ) )
              {
                ptHalf.x = ptTo.x ;
                ptHalf.y = ptTo.y ;
              }
            }
            else // 已有中間子
            {
              if( HaveMan( ptTo ) )
              {
                if( ! HaveFriend( ptTo, fSide ) )
                  AddMoveToQueue( ptFrom, ptTo, nDepth );    

                break;
              }
            }    

          }    

          //向左
          ptHalf.x = -1;  //標(biāo)志尚未發(fā)現(xiàn)中間子
          for( ptTo.x = ptFrom.x + 1; ptTo.x <= 8; ptTo.x ++ )
          {
            if( ptHalf.x == -1 ) // 無中間子
            {
              if( ! HaveMan( ptTo ) )
              {
                AddMoveToQueue( ptFrom, ptTo, nDepth );
              }
              else // if( HaveMan( ptTo ) )
              {
                ptHalf.x = ptTo.x ;
                ptHalf.y = ptTo.y ;
              }
            }
            else // 已有中間子
            {
              if( HaveMan( ptTo ) )
              {
                if( ! HaveFriend( ptTo, fSide ) )
                  AddMoveToQueue( ptFrom, ptTo, nDepth );    

                break;
              }
            }    

          }    

          break;    

//==========生成紅相的著法
        case RED_X:    

          if( ptFrom.x == 0 )
          {
            if( ! HaveFriend(2, 4, fSide) && ! HaveMan(1, 3) )
              AddMoveToQueue( ptFrom, 2, 4, nDepth );    

            if( ! HaveFriend(2, 0, fSide) && ! HaveMan(1, 1) )
              AddMoveToQueue( ptFrom, 2, 0, nDepth );
          }
          else if( ptFrom.x == 2 )
          {
            if( ptFrom.y == 4 )
            {
              if( ! HaveFriend(0, 2, fSide) && ! HaveMan(1, 3) )
                AddMoveToQueue( ptFrom, 0, 2, nDepth );    

              if( ! HaveFriend(4, 2, fSide) && ! HaveMan(3, 3) )
                AddMoveToQueue( ptFrom, 4, 2, nDepth );
            }
            else // ptFrom.y == 0
            {
              if( ! HaveFriend(0, 2, fSide) && ! HaveMan(1, 1) )
                AddMoveToQueue( ptFrom, 0, 2, nDepth );    

              if( ! HaveFriend(4, 2, fSide) && ! HaveMan(3, 1) )
                AddMoveToQueue( ptFrom, 4, 2, nDepth );
            }
          }
          else if( ptFrom.x == 4 )
          {
            if( ! HaveFriend(2, 4, fSide) && ! HaveMan(3, 3) )
              AddMoveToQueue( ptFrom, 2, 4, nDepth );    

            if( ! HaveFriend(2, 0, fSide) && ! HaveMan(3, 1) )
              AddMoveToQueue( ptFrom, 2, 0, nDepth );    

            if( ! HaveFriend(6, 4, fSide) && ! HaveMan(5, 3) )
              AddMoveToQueue( ptFrom, 6, 4, nDepth );    

            if( ! HaveFriend(6, 0, fSide) && ! HaveMan(5, 1) )
              AddMoveToQueue( ptFrom, 6, 0, nDepth );
          }
          else if( ptFrom.x == 6 )
          {
            if( ptFrom.y == 4 )
            {
              if( ! HaveFriend(4, 2, fSide) && ! HaveMan(5, 3) )
                AddMoveToQueue( ptFrom, 4, 2, nDepth );    

              if( ! HaveFriend(8, 2, fSide) && ! HaveMan(7, 3) )
                AddMoveToQueue( ptFrom, 8, 2, nDepth );
            }
            else // ptFrom.y == 0
            {
              if( ! HaveFriend(4, 2, fSide) && ! HaveMan(5, 1) )
                AddMoveToQueue( ptFrom, 4, 2, nDepth );    

              if( ! HaveFriend(8, 2, fSide) && ! HaveMan(7, 1) )
                AddMoveToQueue( ptFrom, 8, 2, nDepth );
            }
          }
          else // x == 8
          {
            if( ! HaveFriend(6, 4, fSide) && ! HaveMan(7, 3) )
              AddMoveToQueue( ptFrom, 6, 4, nDepth );    

            if( ! HaveFriend(6, 0, fSide) && ! HaveMan(7, 1) )
              AddMoveToQueue( ptFrom, 6, 0, nDepth );
          }    

          break;    

//==========生成黑象的著法
        case BLACK_X:    

          if( ptFrom.x == 0 )
          {
            if( ! HaveFriend(2, 5, fSide) && ! HaveMan(1, 6 ) )
              AddMoveToQueue( ptFrom, 2, 5, nDepth );    

            if( ! HaveFriend(2, 9, fSide) && ! HaveMan(1, 8 ) )
              AddMoveToQueue( ptFrom, 2, 9, nDepth );
          }
          else if( ptFrom.x == 2 )
          {
            if( ptFrom.y == 5 )
            {
              if( ! HaveFriend(0, 7, fSide) && ! HaveMan(1, 6 ) )
                AddMoveToQueue( ptFrom, 0, 7, nDepth );    

              if( ! HaveFriend(4, 7, fSide) && ! HaveMan(3, 6 ) )
                AddMoveToQueue( ptFrom, 4, 7, nDepth );
            }
            else // ptFrom.y == 9
            {
              if( ! HaveFriend(0, 7, fSide) && ! HaveMan(1, 8 ) )
                AddMoveToQueue( ptFrom, 0, 7, nDepth );    

              if( ! HaveFriend(4, 7, fSide) && ! HaveMan(3, 8 ) )
                AddMoveToQueue( ptFrom, 4, 7, nDepth );
            }
          }
          else if( ptFrom.x == 4 )
          {
            if( ! HaveFriend(2, 5, fSide) && ! HaveMan(3, 6 ) )
              AddMoveToQueue( ptFrom, 2, 5, nDepth );    

            if( ! HaveFriend(2, 9, fSide) && ! HaveMan(3, 8 ) )
              AddMoveToQueue( ptFrom, 2, 9, nDepth );    

            if( ! HaveFriend(6, 5, fSide) && ! HaveMan(5, 6 ) )
              AddMoveToQueue( ptFrom, 6, 5, nDepth );    

            if( ! HaveFriend(6, 9, fSide) && ! HaveMan(5, 8 ) )
              AddMoveToQueue( ptFrom, 6, 9, nDepth );
          }
          else if( ptFrom.x == 6 )
          {
            if( ptFrom.y == 5 )
            {
              if( ! HaveFriend(4, 7, fSide) && ! HaveMan(5, 6 ) )
                AddMoveToQueue( ptFrom, 4, 7, nDepth );    

              if( ! HaveFriend(8, 7, fSide) && ! HaveMan(7, 6 ) )
                AddMoveToQueue( ptFrom, 8, 7, nDepth );
            }
            else // ptFrom.y == 9
            {
              if( ! HaveFriend(4, 7, fSide) && ! HaveMan(5, 8 ) )
                AddMoveToQueue( ptFrom, 4, 7, nDepth );    

              if( ! HaveFriend(8, 7, fSide) && ! HaveMan(7, 8 ) )
                AddMoveToQueue( ptFrom, 8, 7, nDepth );
            }
          }
          else // x == 8
          {
            if( ! HaveFriend(6, 5, fSide) && ! HaveMan(7, 6 ) )
              AddMoveToQueue( ptFrom, 6, 5, nDepth );    

            if( ! HaveFriend(6, 9, fSide) && ! HaveMan(7, 8 ) )
              AddMoveToQueue( ptFrom, 6, 9, nDepth );
          }    

          break;    

//==========生成紅仕的著法
        case RED_S:    

          if( ptFrom.x == 3 )
          {
            if( ! HaveFriend( 4, 1, fSide ) )
              AddMoveToQueue( ptFrom,  4, 1, nDepth );
          }
          else if( ptFrom.x == 4 )
          {
            if( ! HaveFriend( 3, 2, fSide ) )
              AddMoveToQueue( ptFrom,  3, 2, nDepth );    

            if( ! HaveFriend( 3, 0, fSide ) )
              AddMoveToQueue( ptFrom,  3, 0, nDepth );    

            if( ! HaveFriend( 5, 2, fSide ) )
              AddMoveToQueue( ptFrom,  5, 2, nDepth );    

            if( ! HaveFriend( 5, 0, fSide ) )
              AddMoveToQueue( ptFrom,  5, 0, nDepth );
          }
          else //  ptFrom.x == 5
          {
            if( ! HaveFriend( 4, 1, fSide ) )
              AddMoveToQueue( ptFrom,  4, 1, nDepth );
          }    

          break;    

//==========生成黑士的著法
        case BLACK_S:    

          if( ptFrom.x == 3 )
          {
            if( ! HaveFriend( 4, 8, fSide ) )
              AddMoveToQueue( ptFrom,  4, 8, nDepth );
          }
          else if( ptFrom.x == 4 )
          {
            if( ! HaveFriend( 3, 7, fSide ) )
              AddMoveToQueue( ptFrom,  3, 7, nDepth );    

            if( ! HaveFriend( 3, 9, fSide ) )
              AddMoveToQueue( ptFrom,  3, 9, nDepth );    

            if( ! HaveFriend( 5, 7, fSide ) )
              AddMoveToQueue( ptFrom,  5, 7, nDepth );    

            if( ! HaveFriend( 5, 9, fSide ) )
              AddMoveToQueue( ptFrom,  5, 9, nDepth );
          }
          else //  ptFrom.x == 5
          {
            if( ! HaveFriend( 4, 8, fSide ) )
              AddMoveToQueue( ptFrom,  4, 8, nDepth );
          }    

          break;    

//==========生成紅兵的著法
        case RED_B:    

          //向前
          ptTo.x = ptFrom.x ;
          ptTo.y = ptFrom.y + 1 ;
          if( ptTo.y <=9 && ! HaveFriend( ptTo, fSide ) )
            AddMoveToQueue( ptFrom, ptTo, nDepth );    

          if( ptFrom.y >= 5 ) //兵已過河
          {
            ptTo.y = ptFrom.y ;    

            //向左
            ptTo.x = ptFrom.x - 1 ;
            if( ptTo.x >=0 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );    

            //向右
            ptTo.x = ptFrom.x + 1 ;
            if( ptTo.x <=8 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );
          }    

          break;    

//==========生成黑卒的著法
        case BLACK_B:    

          //向前
          ptTo.x = ptFrom.x ;
          ptTo.y = ptFrom.y - 1 ;
          if( ptTo.y >=0 && ! HaveFriend( ptTo, fSide ) )
            AddMoveToQueue( ptFrom, ptTo, nDepth );    

          if( ptFrom.y <= 4 ) //兵已過河
          {
            ptTo.y = ptFrom.y ;    

            //向右
            ptTo.x = ptFrom.x - 1 ;
            if( ptTo.x >=0 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );    

            //向左
            ptTo.x = ptFrom.x + 1 ;
            if( ptTo.x <=8 && ! HaveFriend( ptTo, fSide ) )
              AddMoveToQueue( ptFrom, ptTo, nDepth );
          }    

          break;    

        }  // end switch    

      }  // end if( CChessBoard[x][y] != 0 )    

    }  // end for x 0 to 8, y 0 to 9    

  return nMoveCount;  // 返回當(dāng)前深度的走法總數(shù)
}    

inline void AddMoveToQueue( POINT ptFrom, POINT ptTo, int nDepth )
{
  MoveList[nDepth][nMoveCount].ptFrom.x = ptFrom.x ;
  MoveList[nDepth][nMoveCount].ptFrom.y = ptFrom.y ;
  MoveList[nDepth][nMoveCount].ptTo.x = ptTo.x ;
  MoveList[nDepth][nMoveCount].ptTo.y = ptTo.y ;    

  nMoveCount ++;
}    

inline void AddMoveToQueue( POINT ptFrom, BYTE x, BYTE y, int nDepth )
{
  MoveList[nDepth][nMoveCount].ptFrom.x = ptFrom.x ;
  MoveList[nDepth][nMoveCount].ptFrom.y = ptFrom.y ;
  MoveList[nDepth][nMoveCount].ptTo.x = x ;
  MoveList[nDepth][nMoveCount].ptTo.y = y ;    

  nMoveCount ++;
}    

// end of CChessMove.h

總結(jié)

以上是生活随笔為你收集整理的[转载] 中国象棋软件-引擎实现(三)着法生成的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。