?? cchessmove.h
字號:
// CChessMove.h
#include "CChessDef.h"
/////////////////// Data Define ////////////////////////////////////////////////
CCHESSMOVE MoveList[12][80] ; // 存儲產生的著法隊列
int nMoveCount ; // 存儲當前搜索深度已產生的著法數
/////////////////// 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 值坐標,不碰面則返回-1。
// 其中x, y分別為當前走棋方的王所在位置坐標,fSide為當前走棋方
int IsKingFaceToFace( int x, int y, int fSide );
// 產生fSide方所有著法,返回產生的著法總數。nDepth為當前搜索深度,用于傳給AddMoveToQueue函數
int GenerateMove( int fSide, int nDepth );
// 將產生的著法加入著法隊列。nDepth為當前搜索深度
inline void AddMoveToQueue( POINT ptFrom, POINT ptTo, int nDepth );
// 將產生的著法加入著法隊列。nDepth為當前搜索深度
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 值坐標
}
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 值坐標
}
}
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點方向
ptTo.x = ptFrom.x - 1 ;
ptTo.y = ptFrom.y + 2 ;
if( ptTo.x >= 0 && ! HaveFriend( ptTo, fSide ) )
AddMoveToQueue( ptFrom, ptTo, nDepth );
//1點方向
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點方向
ptTo.x = ptFrom.x + 2 ;
ptTo.y = ptFrom.y + 1 ;
if( ptTo.y <= 9 && ! HaveFriend( ptTo, fSide ) )
AddMoveToQueue( ptFrom, ptTo, nDepth );
//4點方向
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點方向
ptTo.x = ptFrom.x + 1 ;
ptTo.y = ptFrom.y - 2 ;
if( ptTo.x <= 8 && ! HaveFriend( ptTo, fSide ) )
AddMoveToQueue( ptFrom, ptTo, nDepth );
//7點方向
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點方向
ptTo.x = ptFrom.x - 2 ;
ptTo.y = ptFrom.y - 1 ;
if( ptTo.y >= 0 && ! HaveFriend( ptTo, fSide ) )
AddMoveToQueue( ptFrom, ptTo, nDepth );
//10點方向
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點方向
ptTo.x = ptFrom.x - 1 ;
ptTo.y = ptFrom.y + 2 ;
if( ptTo.x >= 0 && ! HaveFriend( ptTo, fSide ) )
AddMoveToQueue( ptFrom, ptTo, nDepth );
//7點方向
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點方向
ptTo.x = ptFrom.x + 2 ;
ptTo.y = ptFrom.y + 1 ;
if( ptTo.y <= 9 && ! HaveFriend( ptTo, fSide ) )
AddMoveToQueue( ptFrom, ptTo, nDepth );
//10點方向
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點方向
ptTo.x = ptFrom.x + 1 ;
ptTo.y = ptFrom.y - 2 ;
if( ptTo.x <= 8 && ! HaveFriend( ptTo, fSide ) )
AddMoveToQueue( ptFrom, ptTo, nDepth );
//1點方向
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點方向
ptTo.x = ptFrom.x - 2 ;
ptTo.y = ptFrom.y - 1 ;
if( ptTo.y >= 0 && ! HaveFriend( ptTo, fSide ) )
AddMoveToQueue( ptFrom, ptTo, nDepth );
//4點方向
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; //標志尚未發現中間子
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 ) )
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -