_inline bool IsCenterOfRedCircle(int x, int y, int NoSnapShot, bool bUnchangedAreaInBlack) { SnapShotData &SS = GtSnapShotData[NoSnapShot]; #ifdef ASSERT ASSERT(SS.IsInSnapShotRelative(x-22, y-13)); ASSERT(SS.IsInSnapShotRelative(x+23, y+13)); #endif if (!IsRed(SS.SSGetPixelRelative(x-19, y)) || !IsRed(SS.SSGetPixelRelative(x+20, y)) || !IsRed(SS.SSGetPixelRelative(x-18, y)) || !IsRed(SS.SSGetPixelRelative(x+19, y)) || !IsRed(SS.SSGetPixelRelative(x-17, y)) || !IsRed(SS.SSGetPixelRelative(x+18, y)) || !IsRed(SS.SSGetPixelRelative(x, y-9)) || !IsRed(SS.SSGetPixelRelative(x, y+9)) || !IsRed(SS.SSGetPixelRelative(x, y+8)) ) return false; if (!bUnchangedAreaInBlack) return true; // Pas d'autres tests dans ce cas (risque d'erreur nettement accru) if ( !IsBlack(SS.SSGetPixelRelative(x, y-13)) || !IsBlack(SS.SSGetPixelRelative(x, y+13)) || !IsBlack(SS.SSGetPixelRelative(x-22, y)) || !IsBlack(SS.SSGetPixelRelative(x+23, y)) ) return false; for (int Xr=x-13; Xr<=x+14; Xr++) if (!IsBlack(SS.SSGetPixelRelative(Xr, y))) return false; for (int Yr=y-5; Yr<=y+4; Yr++) if (!IsBlack(SS.SSGetPixelRelative(x, Yr))) return false; return true; }
int Evaluation::ValueAndPosition(Board & cur, PLAYER who) { int R_value = 0, B_value = 0; BDPOINT index; for (index = 0x33; index <= 0xcb; index++) { if (cur.position[index] == NONE || cur.position[index] == OUT) { continue; } //棋子价值评估与子力位置评估 if (IsRed(cur.position[index])) { if (cur.numOfChess >= 28) { R_value += kindValue[START_STATE][cur.position[index]]; } else if (cur.numOfChess >= 14) { R_value += kindValue[MID_STATE][cur.position[index]]; } else { R_value += kindValue[END_STATE][cur.position[index]]; } R_value += posValue[cur.position[index]][index]; } else { if (cur.numOfChess >= 28) { B_value += kindValue[START_STATE][(CHESSMAN)(NONE - (cur.position[index]))]; } else if (cur.numOfChess >= 14) { B_value += kindValue[MID_STATE][(CHESSMAN)(NONE - (cur.position[index]))]; } else { B_value += kindValue[END_STATE][(CHESSMAN)(NONE - (cur.position[index]))]; } B_value += posValue[(CHESSMAN)(NONE - (cur.position[index]))][(BDPOINT)(0xfe - index)]; } } //返回双方棋子位置评估值的差值 if (who == RED) { return (R_value - B_value); } else { return (B_value - R_value); } }
HASHNUM Hashnum::GetHash(CHESSMAN chess, BDPOINT point) { if (chess == NONE) { return (HASHNUM)0; } else { return IsRed(chess) ? hash[chess - (CHESSMAN)1][point] : hash[(CHESSMAN)7 + (CHESSMAN)~chess][point]; } }
int Evaluation::GetAnPScore(BDPOINT point, CHESSMAN chess) { int score; if (IsRed(chess)) { score = posValue[chess][point]; } else { score = posValue[(CHESSMAN)(NONE - chess)][(BDPOINT)(0xfe - point)]; } //棋子威胁、保护评估值相对于子力位置评估值的大小 score >>= 4; if (score < 5) { score = 5; } return score; }
int CEveluation::Eveluate(BYTE position[10][9], BOOL bIsRedTurn) { int i, j, k; int nChessType, nTargetType; count++; memset(m_chessValue,0, 360); memset(m_AttackPos,0, 180); memset(m_GuardPos,0, 90); memset(m_FlexibilityPos, 0, 90); for(i = 0; i < 10; i++) for(j = 0; j < 9; j++) { if(position[i][j] != NOCHESS) { nChessType = position[i][j]; GetRelatePiece(position, j, i); for (k = 0; k < nPosCount; k++) { nTargetType = position[RelatePos[k].y][RelatePos[k].x]; if (nTargetType == NOCHESS) { m_FlexibilityPos[i][j]++; } else { if (IsSameSide(nChessType, nTargetType)) { m_GuardPos[RelatePos[k].y][RelatePos[k].x]++; }else { m_AttackPos[RelatePos[k].y][RelatePos[k].x]++; m_FlexibilityPos[i][j]++; switch (nTargetType) { case R_KING: if (!bIsRedTurn) return 18888; break; case B_KING: if (bIsRedTurn) return 18888; break; default: m_AttackPos[RelatePos[k].y][RelatePos[k].x] += (30 + (m_BaseValue[nTargetType] - m_BaseValue[nChessType])/10)/10; break; } } } } } } for(i = 0; i < 10; i++) for(j = 0; j < 9; j++) { if(position[i][j] != NOCHESS) { nChessType = position[i][j]; m_chessValue[i][j]++; m_chessValue[i][j] += m_FlexValue[nChessType] * m_FlexibilityPos[i][j]; m_chessValue[i][j] += GetBingValue(j, i, position); } } int nHalfvalue; for(i = 0; i < 10; i++) for(j = 0; j < 9; j++) { if(position[i][j] != NOCHESS) { nChessType = position[i][j]; nHalfvalue = m_BaseValue[nChessType]/16; m_chessValue[i][j] += m_BaseValue[nChessType]; if (IsRed(nChessType)) { if (m_AttackPos[i][j]) { if (bIsRedTurn) { if (nChessType == R_KING) { m_chessValue[i][j]-= 20; } else { m_chessValue[i][j] -= nHalfvalue * 2; if (m_GuardPos[i][j]) m_chessValue[i][j] += nHalfvalue; } } else { if (nChessType == R_KING) return 18888; m_chessValue[i][j] -= nHalfvalue*10; if (m_GuardPos[i][j]) m_chessValue[i][j] += nHalfvalue*9; } m_chessValue[i][j] -= m_AttackPos[i][j]; } else { if (m_GuardPos[i][j]) m_chessValue[i][j] += 5; } } else { if (m_AttackPos[i][j]) { if (!bIsRedTurn) { if (nChessType == B_KING) { m_chessValue[i][j]-= 20; } else { m_chessValue[i][j] -= nHalfvalue * 2; if (m_GuardPos[i][j]) m_chessValue[i][j] += nHalfvalue; } } else { if (nChessType == B_KING) return 18888; m_chessValue[i][j] -= nHalfvalue*10; if (m_GuardPos[i][j]) m_chessValue[i][j] += nHalfvalue*9; } m_chessValue[i][j] -= m_AttackPos[i][j]; } else { if (m_GuardPos[i][j]) m_chessValue[i][j] += 5; } } } } int nRedValue = 0; int nBlackValue = 0; for(i = 0; i < 10; i++) for(j = 0; j < 9; j++) { nChessType = position[i][j]; // if (nChessType == R_KING || nChessType == B_KING) // m_chessValue[i][j] = 10000; if (nChessType != NOCHESS) { if (IsRed(nChessType)) { nRedValue += m_chessValue[i][j]; } else { nBlackValue += m_chessValue[i][j]; } } } if (bIsRedTurn) { return nRedValue - nBlackValue; } else { return nBlackValue-nRedValue ; } }
//nPly指明当前搜索的层数,每层将走法存在不同的位置,以免覆盖 //nSide指明产生哪一方的走法,TRUE为红方,FALSE是黑方 int CMoveGenerator::CreatePossibleMove(BYTE position[][9],int nPly,int nSide,int nUserChessColor) { int nChessID; int i,j; m_nMoveCount=0; m_nUserChessColor=nUserChessColor; for(j=0;j<9;j++) for(i=0;i<10;i++) { if(position[i][j]!=NOCHESS) { nChessID=position[i][j]; if(nUserChessColor==REDCHESS) { if(!nSide && IsRed(nChessID)) continue;//如要产生黑棋走法,跳过红棋 if(nSide && IsBlack(nChessID)) continue;//如要产生红棋走法,跳过黑棋 } else { if(nSide && IsRed(nChessID)) continue;//如要产生黑棋走法,跳过红棋 if(!nSide && IsBlack(nChessID)) continue;//如要产生红棋走法,跳过黑棋 } switch(nChessID) { case R_KING://红帅 case B_KING://黑将 Gen_KingMove(position,i,j,nPly); break; case R_BISHOP://红士 Gen_RBishopMove(position,i,j,nPly); break; case B_BISHOP://黑士 Gen_BBishopMove(position,i,j,nPly); break; case R_ELEPHANT://红相 case B_ELEPHANT://黑象 Gen_ElephantMove(position,i,j,nPly); break; case R_HORSE://红马 case B_HORSE://黑马 Gen_HorseMove(position,i,j,nPly); break; case R_CAR://红车 case B_CAR://黑车 Gen_CarMove(position,i,j,nPly); break; case R_PAWN://红兵 Gen_RPawnMove(position,i,j,nPly); break; case B_PAWN://黑卒 Gen_BPawnMove(position,i,j,nPly); break; case B_CANON://黑炮 case R_CANON://红炮 Gen_CanonMove(position,i,j,nPly); break; default: break; } } } return m_nMoveCount; }
int CEveluation::Eveluate(BYTE position[8][8], BOOL bIsRedTurn) { int i, j, k; int nChessType, nTargetType; count++; //初始化临时变量 memset(m_chessValue,0, 256); memset(m_AttackPos,0, 128); memset(m_GuardPos,0, 64); memset(m_FlexibilityPos, 0, 64); for(i = 0; i < 8; i++) for(j = 0; j < 8; j++) { if(position[i][j] != NOCHESS) { nChessType = position[i][j]; GetRelatePiece(position, i, j);//y x for (k = 0; k < nPosCount; k++) { nTargetType = position[RelatePos[k].y][RelatePos[k].x]; if (nTargetType == NOCHESS) { m_FlexibilityPos[i][j]++; //灵活性增加 } else { if (IsSameSide(nChessType, nTargetType)) { m_GuardPos[RelatePos[k].y][RelatePos[k].x]++; }else { m_AttackPos[RelatePos[k].y][RelatePos[k].x]++; m_FlexibilityPos[i][j]++; switch (nTargetType) { case R_KING: if (!bIsRedTurn)//若是红王受攻击,黑方走下一步 则返回失败极值 return 18888; break; case B_KING: if (bIsRedTurn)//若是黑王受攻击,红方走下一步 则返回失败极值 return 18888; break; default://其它棋子,加上威胁分 m_AttackPos[RelatePos[k].y][RelatePos[k].x] += (30 + (m_BaseValue[nTargetType] - m_BaseValue[nChessType])/10)/10; break; } } } } } } //下面统计扫描到的数据 for(i = 0; i < 8; i++) for(j = 0; j < 8; j++) { if(position[i][j] != NOCHESS) { nChessType = position[i][j]; m_chessValue[i][j]++; //加上灵活性分 值 m_chessValue[i][j] += m_FlexValue[nChessType] * m_FlexibilityPos[i][j]; //加上兵的附加值 m_chessValue[i][j] += GetBingValue(j, i, position); } } //下面统计扫描到的数据 int nHalfvalue; for(i = 0; i < 8; i++) for(j = 0; j <8; j++) { if(position[i][j] != NOCHESS) { nChessType = position[i][j]; //棋子的基本价值的1/16作为威胁/保护的增量 nHalfvalue = m_BaseValue[nChessType]/16; //每个棋子的基本价值入总价值 m_chessValue[i][j] += m_BaseValue[nChessType]; if (IsRed(nChessType)) { if (m_AttackPos[i][j])//当前红棋被威胁 { if (bIsRedTurn)//如果轮到红棋走 { if (nChessType == R_KING) { m_chessValue[i][j]-= 20;//如果是红王价值减20 } else//其它棋子 { m_chessValue[i][j] -= nHalfvalue * 2; if (m_GuardPos[i][j])//被保护 m_chessValue[i][j] += nHalfvalue; } } else//当前红棋被威胁 轮到黑棋走 { if (nChessType == R_KING) return 18888;//失败 被将死 m_chessValue[i][j] -= nHalfvalue*10; if (m_GuardPos[i][j]) m_chessValue[i][j] += nHalfvalue*9; } //加上被威胁差 ///防止一个兵威胁一个车,而估值函数没有反应 m_chessValue[i][j] -= m_AttackPos[i][j]; } else//没有受到威胁 { if (m_GuardPos[i][j])//受到了保护,加上一点分吧 m_chessValue[i][j] += 5; } } else//黑棋 同理 { if (m_AttackPos[i][j]) { if (!bIsRedTurn) { if (nChessType == B_KING) { m_chessValue[i][j]-= 20; } else { m_chessValue[i][j] -= nHalfvalue * 2; if (m_GuardPos[i][j]) m_chessValue[i][j] += nHalfvalue; } } else { if (nChessType == B_KING) return 18888; m_chessValue[i][j] -= nHalfvalue*10; if (m_GuardPos[i][j]) m_chessValue[i][j] += nHalfvalue*9; } m_chessValue[i][j] -= m_AttackPos[i][j]; } else { if (m_GuardPos[i][j]) m_chessValue[i][j] += 5; } } } } //以上是统计了每一个棋子的总价值 //下面统计红黑双方的总分 int nRedValue = 0; int nBlackValue = 0; for(i = 0; i < 8; i++) for(j = 0; j < 8; j++) { nChessType = position[i][j]; // if (nChessType == R_KING || nChessType == B_KING) // m_chessValue[i][j] = 10000; if (nChessType != NOCHESS) { if (IsRed(nChessType))//把红方的值加总 { nRedValue += m_chessValue[i][j]; } else//把黑方的值加总 { nBlackValue += m_chessValue[i][j]; } } } //返回估值 if (bIsRedTurn) { return nRedValue - nBlackValue; } else { return nBlackValue-nRedValue ; } }
//位移步调 //马的位移步调 //from MoveGenerator.cpp //extern int movex[9],movey[9],moveknightx[9],moveknighty[9]; //列举相关位置 //包括可以走到位置和可以保护的位置 // int CEveluation::GetRelatePiece(BYTE position[8][8], int i, int j)//y x { nPosCount = 0;//在AddPoint中增加 BYTE nChessID; // BYTE flag; int k,x,y; nChessID = position[i][j]; switch(nChessID) { case R_KING: case B_KING: for(k=1;k<9;k++) { x=j+movex[k]; y=i+movey[k]; if(x>=0&&x<8&&y>=0&&y<8) AddPoint(x, y); } break; case R_BISHOP: case B_BISHOP: for(k=2;k<9;k+=2) { x=j+movex[k]; y=i+movey[k]; while(x>=0&&x<8&&y>=0&&y<8) { if(NOCHESS==position[y][x]) AddPoint(x,y); else//碰上了第一个棋子 { AddPoint(x, y); break; } x+=movex[k]; y+=movey[k]; } } break; case R_KNIGHT: case B_KNIGHT: for(k=1;k<9;k++) { x=j+moveknightx[k]; y=i+moveknighty[k]; if(x>=0&&x<8&&y>=0&&y<8) AddPoint(x, y); } break; case R_ROOK: case B_ROOK: for(k=1;k<9;k+=2) { x=j+movex[k]; y=i+movey[k]; while(x>=0&&x<8&&y>=0&&y<8) { if(NOCHESS==position[y][x]) AddPoint(x,y); else//碰上了第一个棋子 { AddPoint(x, y); break; } x+=movex[k]; y+=movey[k]; } } break; case B_PAWN: x=i; y=j+1;//向前一步走 if(y<8&&NOCHESS==position[y][x]) AddPoint(x,y); y=j+2;//向前二步走 if(j==1&&y<8&&NOCHESS==position[y][x]) AddPoint(x,y); x=i-1; y=j+1;//向左前吃子 if(x>=0&&y<8&&IsRed(position[y][x])) AddPoint(x,y); x=i+1; y=j+1;//向右前吃子 if(x<8&&y<8&&IsRed(position[y][x])) AddPoint(x,y); break; case R_PAWN: x=i; y=j-1;//向前一步走 if(y>=0&&NOCHESS==position[y][x]) AddPoint(x,y); y=j-2;//向前二步走 if(j==6&&y>=0&&NOCHESS==position[y][x]) AddPoint(x,y); x=i-1; y=j-1;//向左前吃子 if(x>=0&&y>=0&&IsRed(position[y][x])) AddPoint(x,y); x=i+1; y=j-1;//向右前吃子 if(x<8&&y>=0&&IsRed(position[y][x])) AddPoint(x,y); break; case B_QUEEN: case R_QUEEN: for(k=1;k<9;k+=1) { x=j+movex[k]; y=i+movey[k]; while(x>=0&&x<8&&y>=0&&y<8) { if(NOCHESS==position[y][x]) AddPoint(x,y); else//碰上了第一个棋子 { AddPoint(x, y); break; } x+=movex[k]; y+=movey[k]; } } break; default: break; } return nPosCount ; }