?? treesearch.cpp
字號:
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 + -