//黑卒 void CMoveGenerator::Gen_BPawnMove(BYTE position[10][9],int i,int j,int nPly) { int x,y; int nChessID; nChessID=position[i][j]; if(m_nUserChessColor==REDCHESS) { y=i+1;//向前 x=j; if(y<10 && !IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]);//前方无阻碍 if(i>4)//是否已过河 { y=i; x=j+1;//右边 if(x<9 && !IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); x=j-1;//左边 if(x>=0 && !IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); } } else { y=i-1;//向前 x=j; if(y<10 && !IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]);//前方无阻碍 if(i<5)//是否已过河 { y=i; x=j+1;//右边 if(x<9 && !IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); x=j-1;//左边 if(x>=0 && !IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); } } }
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 ; } }
BOOL CMoveGenerator::IsValidMove(BYTE position[10][9], int nFromX, int nFromY, int nToX, int nToY,int nUserChessColor) { int i = 0 ,j = 0; int nMoveChessID,nTargetID; if(nFromX==nToX && nFromY==nToY) return false;//目的与源相同,非法 nMoveChessID=position[nFromY][nFromX]; nTargetID=position[nToY][nToX]; if(IsSameSide(nMoveChessID,nTargetID)) return false;//吃自己的棋,非法 switch(nMoveChessID) { case B_KING://黑将 if(nUserChessColor==REDCHESS) { if(nTargetID==R_KING)//判断是否将帅见面 { if(nFromX!=nToX)//横坐标不相等 return false;//将帅不在同一列 for(i=nFromY+1;i<nToY;i++) if(position[i][nFromX]!=NOCHESS) return false;//中间隔有棋子 } else { if(nToY>2 || nToX>5 || nToX<3) return false;//目标点在九宫之外 if(abs(nFromY-nToY)+abs(nFromX-nToX)>1) return false;//将帅只走一步直线 } } else { if(nTargetID==R_KING)//判断是否将帅见面 { if(nFromX!=nToX)//横坐标不相等 return false;//将帅不在同一列 for(i=nFromY-1;i>nToY;i--) if(position[i][nFromX]!=NOCHESS) return false;//中间隔有棋子 } else { if(nToY<7 || nToX>5 || nToX<3) return false;//目标点在九宫之外 if(abs(nFromY-nToY)+abs(nFromX-nToX)>1) return false;//将帅只走一步直线 } } break; case R_KING://红帅 if(nUserChessColor==REDCHESS) { if(nTargetID==B_KING)//判断是否将帅见面 { if(nFromX!=nToX)//横坐标不相等 return false;//将帅不在同一列 for(i=nFromY-1;i>nToY;i--) if(position[i][nFromX]!=NOCHESS) return false;//中间隔有棋子 } else { if(nToY<7 || nToX>5 || nToX<3) return false;//目标点在九宫之外 if(abs(nFromY-nToY)+abs(nFromX-nToX)>1) return false;//将帅只走一步直线 } } else { if(nTargetID==B_KING)//判断是否将帅见面 { if(nFromX!=nToX)//横坐标不相等 return false;//将帅不在同一列 for(i=nFromY+1;i<nToY;i++) if(position[i][nFromX]!=NOCHESS) return false;//中间隔有棋子 } else { if(nToY>2 || nToX>5 || nToX<3) return false;//目标点在九宫之外 if(abs(nFromY-nToY)+abs(nFromX-nToX)>1) return false;//将帅只走一步直线 } } break; case R_BISHOP://红士 if(nUserChessColor==REDCHESS) { if(nToY<7 || nToX>5 || nToX<3) return false;//士出九宫 } else { if(nToY>2 || nToX>5 || nToX<3) return false;//士出九宫 } if(abs(nFromX-nToX)!=1 || abs(nFromY-nToY)!=1) return false;//士走斜线 break; case B_BISHOP://黑士 if(nUserChessColor==REDCHESS) { if(nToY>2 || nToX>5 || nToX<3) return false;//士出九宫 } else { if(nToY<7 || nToX>5 || nToX<3) return false;//士出九宫 } if(abs(nFromX-nToX)!=1 || abs(nFromY-nToY)!=1) return false;//士走斜线 break; case R_ELEPHANT://红相 if(nUserChessColor==REDCHESS) { if(nToY<5) return false;//相不能过河 } else { if(nToY>4) return false;//相不能过河 } if(abs(nFromX-nToX)!=2 || abs(nFromY-nToY)!=2) return false;//相走田字 if(position[(nFromY +nToY)/2][(nFromX +nToX)/2]!=NOCHESS) return FALSE;//相眼被塞 break; case B_ELEPHANT://黑象 if(nUserChessColor==REDCHESS) { if(nToY>4) return false;//象不能过河 } else { if(nToY<5) return false;//象不能过河 } if(abs(nFromX-nToX)!=2 || abs(nFromY-nToY)!=2) return false;//象走田字 if(position[(nFromY +nToY)/2][(nFromX +nToX)/2]!=NOCHESS) return FALSE;//象眼被塞 break; case B_PAWN://黑卒 if(nUserChessColor==REDCHESS) { if(nToY<nFromY) return false;//卒不能回头 if(nFromY<5 && nFromY==nToY) return FALSE;//卒过河前只能直走 } else { if(nToY>nFromY) return false;//卒不能回头 if(nFromY>4 && nFromY==nToY) return FALSE;//卒过河前只能直走 } if(nToY-nFromY+abs(nToX-nFromX)>1) return FALSE;//卒只走一步直线 break; case R_PAWN://红兵 if(nUserChessColor==REDCHESS) { if(nToY>nFromY) return false;//兵不能回头 if(nFromY>4 && nFromY==nToY) return FALSE;//兵过河前只能直走 } else { if(nToY<nFromY) return false;//兵不能回头 if(nFromY<5 && nFromY==nToY) return FALSE;//兵过河前只能直走 } if(nFromY-nToY+abs(nToX-nFromX)>1) return FALSE;//兵只走一步直线 break; case B_CAR://黑车 case R_CAR://红车 if(nFromY!=nToY && nFromX!=nToX) return FALSE;//车走直线 if(nFromY==nToY) { if(nFromX<nToX) { for(i=nFromX+1;i<nToX;i++) if(position[nFromY][i]!=NOCHESS) return FALSE; } else { for(i=nToX+1;i<nFromX;i++) if(position[nFromY][i]!=NOCHESS) return FALSE; } } else { if(nFromY<nToY) { for(j=nFromY+1;j<nToY;j++) if(position[j][nFromX]!=NOCHESS) return FALSE; } else { for(j=nToY+1;j<nFromY;j++) if(position[j][nFromX]!=NOCHESS) return FALSE; } } break; case B_HORSE://黑马 case R_HORSE://红马 if(!((abs(nToX-nFromX)==1 && abs(nToY -nFromY)==2) || (abs(nToX-nFromX)==2&&abs(nToY -nFromY)==1))) return FALSE;//马走日字 if(nToX-nFromX==2) { i=nFromX+1; j=nFromY; } else if(nFromX-nToX==2) { i=nFromX-1; j=nFromY; } else if(nToY-nFromY==2) { i=nFromX; j=nFromY+1; } else if(nFromY-nToY==2) { i=nFromX; j=nFromY-1; } if(position[j][i]!=NOCHESS) return FALSE;//绊马腿 break; case B_CANON://黑炮 case R_CANON://红炮 if(nFromY!=nToY && nFromX!=nToX) return FALSE;//炮走直线 //炮吃子时经过的路线中不能有棋子 if(position[nToY][nToX]==NOCHESS) { if(nFromY==nToY) { if(nFromX<nToX) { for(i=nFromX+1;i<nToX;i++) if(position[nFromY][i]!=NOCHESS) return FALSE; } else { for(i=nToX+1;i<nFromX;i++) if(position[nFromY][i]!=NOCHESS) return FALSE; } } else { if(nFromY<nToY) { for(j=nFromY+1;j<nToY;j++) if(position[j][nFromX]!=NOCHESS) return FALSE; } else { for(j=nToY+1;j<nFromY;j++) if(position[j][nFromX]!=NOCHESS) return FALSE; } } } else//炮吃子时 { int j=0; if(nFromY==nToY) { if(nFromX<nToX) { for(i=nFromX+1;i<nToX;i++) if(position[nFromY][i]!=NOCHESS) j++; if(j!=1) return FALSE; } else { for(i=nToX+1;i<nFromX;i++) if(position[nFromY][i]!=NOCHESS) j++; if(j!=1) return FALSE; } } else { if(nFromY<nToY) { for(i=nFromY+1;i<nToY;i++) if(position[i][nFromX]!=NOCHESS) j++; if(j!=1) return FALSE; } else { for(i=nToY+1;i<nFromY;i++) if(position[i][nFromX]!=NOCHESS) j++; if(j!=1) return FALSE; } } } break; default: return false; } return true; }
//炮 void CMoveGenerator::Gen_CanonMove(BYTE position[10][9], int i, int j, int nPly) { int x,y; BOOL flag; int nChessID; nChessID=position[i][j]; //插入向右的有效的走法 x=j+1; y=i; flag=FALSE; while(x<9) { if(NOCHESS==position[y][x]) { if(!flag)//隔有棋子 AddMove(j,i,x,y,nPly,position[i][j]); } else { if(!flag)//没有隔棋子,此棋子是第一个障碍,设置标志 flag=TRUE; else //隔有棋子,此处如为敌方棋子,则可走 { if(!IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); break; } } x++;//继续下一个位置 } //插入向左的有效的走法 x=j-1; y=i; flag=FALSE; while(x>=0) { if(NOCHESS==position[y][x]) { if(!flag)//隔有棋子 AddMove(j,i,x,y,nPly,position[i][j]); } else { if(!flag)//没有隔棋子,此棋子是第一个障碍,设置标志 flag=TRUE; else //隔有棋子,此处如为敌方棋子,则可走 { if(!IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); break; } } x--;//继续下一个位置 } //插入向下的有效的走法 x=j; y=i+1; flag=FALSE; while(y<10) { if(NOCHESS==position[y][x]) { if(!flag)//隔有棋子 AddMove(j,i,x,y,nPly,position[i][j]); } else { if(!flag)//没有隔棋子,此棋子是第一个障碍,设置标志 flag=TRUE; else //隔有棋子,此处如为敌方棋子,则可走 { if(!IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); break; } } y++;//继续下一个位置 } //插入向上的有效的走法 x=j; y=i-1; flag=FALSE; while(y>=0) { if(NOCHESS==position[y][x]) { if(!flag)//隔有棋子 AddMove(j,i,x,y,nPly,position[i][j]); } else { if(!flag)//没有隔棋子,此棋子是第一个障碍,设置标志 flag=TRUE; else //隔有棋子,此处如为敌方棋子,则可走 { if(!IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); break; } } y--;//继续下一个位置 } }
//车 void CMoveGenerator::Gen_CarMove(BYTE position[10][9], int i, int j, int nPly) { int x,y; int nChessID; nChessID=position[i][j]; //插入向右的有效的走法 x=j+1; y=i; while(x<9) { if(NOCHESS==position[y][x]) AddMove(j,i,x,y,nPly,position[i][j]); else { if(!IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); break; } x++; } //插入向左的有效的走法 x=j-1; y=i; while(x>=0) { if(NOCHESS==position[y][x]) AddMove(j,i,x,y,nPly,position[i][j]); else { if(!IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); break; } x--; } //插入向下的有效的走法 x=j; y=i+1; while(y<10) { if(NOCHESS==position[y][x]) AddMove(j,i,x,y,nPly,position[i][j]); else { if(!IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); break; } y++; } //插入向上的有效的走法 x=j; y=i-1; while(y>=0) { if(NOCHESS==position[y][x]) AddMove(j,i,x,y,nPly,position[i][j]); else { if(!IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); break; } y--; } }
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 ; } }