象棋人機對戰
阿新 • • 發佈:2019-01-03
象棋主要演算法程式碼
Eveluation.h
Eveluation.cpp
這一對檔案定義並實現了估值核心類。
#if !defined(AFX_EVELUATION_H__2AF7A221_CB28_11D5_AEC7_5254AB2E22C7__INCLUDED_) #define AFX_EVELUATION_H__2AF7A221_CB28_11D5_AEC7_5254AB2E22C7__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define BASEVALUE_PAWN 100 #define BASEVALUE_BISHOP 250 #define BASEVALUE_ELEPHANT 250 #define BASEVALUE_CAR 500 #define BASEVALUE_HORSE 350 #define BASEVALUE_CANON 350 #define BASEVALUE_KING 10000 #define FLEXIBILITY_PAWN 15 #define FLEXIBILITY_BISHOP 1 #define FLEXIBILITY_ELEPHANT 1 #define FLEXIBILITY_CAR 6 #define FLEXIBILITY_HORSE 12 #define FLEXIBILITY_CANON 6 #define FLEXIBILITY_KING 0 class CEveluation { public: CEveluation(); virtual ~CEveluation(); virtual int Eveluate(BYTE position[10][9], BOOL bIsRedTurn); protected: int GetRelatePiece(BYTE position[10][9],int j, int i); BOOL CanTouch(BYTE position[10][9], int nFromX, int nFromY, int nToX, int nToY); void AddPoint(int x, int y); int GetBingValue(int x, int y, BYTE CurSituation[][9]); int m_BaseValue[15]; int m_FlexValue[15]; short m_AttackPos[10][9]; BYTE m_GuardPos[10][9]; BYTE m_FlexibilityPos[10][9]; int m_chessValue[10][9]; int nPosCount; POINT RelatePos[20]; }; #endif // !defined(AFX_EVELUATION_H__2AF7A221_CB28_11D5_AEC7_5254AB2E22C7__INCLUDED_)
// Eveluation.cpp: implementation of the CEveluation class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "chess.h" #include "Eveluation.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif const int BA0[10][9]= { {0, 0, 0, 0, 0, 0, 0, 0, 0}, {90,90,110,120,120,120,110,90,90}, {90,90,110,120,120,120,110,90,90}, {70,90,110,110,110,110,110,90,70}, {70,70,70, 70, 70, 70, 70,70,70}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, }; const int BA1[10][9]= { {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {70,70,70, 70, 70,70, 70,70, 70}, {70,90,110,110,110,110,110,90,70}, {90,90,110,120,120,120,110,90,90}, {90,90,110,120,120,120,110,90,90}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, }; int CEveluation:: GetBingValue(int x, int y, BYTE CurSituation[][9]) { if (CurSituation[y][x] == R_PAWN) return BA0[y][x]; if (CurSituation[y][x] == B_PAWN) return BA1[y][x]; return 0; } ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CEveluation::CEveluation() { m_BaseValue[B_KING] = BASEVALUE_KING; m_BaseValue[B_CAR] = BASEVALUE_CAR; m_BaseValue[B_HORSE] = BASEVALUE_HORSE; m_BaseValue[B_BISHOP] = BASEVALUE_BISHOP; m_BaseValue[B_ELEPHANT] = BASEVALUE_ELEPHANT; m_BaseValue[B_CANON] = BASEVALUE_CANON; m_BaseValue[B_PAWN] = BASEVALUE_PAWN; m_BaseValue[R_KING] = BASEVALUE_KING; m_BaseValue[R_CAR] = BASEVALUE_CAR; m_BaseValue[R_HORSE] = BASEVALUE_HORSE; m_BaseValue[R_BISHOP] = BASEVALUE_BISHOP; m_BaseValue[R_ELEPHANT] = BASEVALUE_ELEPHANT; m_BaseValue[R_CANON] = BASEVALUE_CANON; m_BaseValue[R_PAWN] = BASEVALUE_PAWN; m_FlexValue[B_KING] = FLEXIBILITY_KING; m_FlexValue[B_CAR] = FLEXIBILITY_CAR; m_FlexValue[B_HORSE] = FLEXIBILITY_HORSE; m_FlexValue[B_BISHOP] = FLEXIBILITY_BISHOP; m_FlexValue[B_ELEPHANT] = FLEXIBILITY_ELEPHANT; m_FlexValue[B_CANON] = FLEXIBILITY_CANON; m_FlexValue[B_PAWN] = FLEXIBILITY_PAWN; m_FlexValue[R_KING] = FLEXIBILITY_KING; m_FlexValue[R_CAR] = FLEXIBILITY_CAR; m_FlexValue[R_HORSE] = FLEXIBILITY_HORSE; m_FlexValue[R_BISHOP] = FLEXIBILITY_BISHOP; m_FlexValue[R_ELEPHANT] = FLEXIBILITY_ELEPHANT; m_FlexValue[R_CANON] = FLEXIBILITY_CANON; m_FlexValue[R_PAWN] = FLEXIBILITY_PAWN; } CEveluation::~CEveluation() { } int count=0; 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 ; } } void CEveluation::AddPoint(int x, int y) { RelatePos[nPosCount].x = x; RelatePos[nPosCount].y = y; nPosCount++; } int CEveluation::GetRelatePiece(BYTE position[10][9], int j, int i) { nPosCount = 0; BYTE nChessID; BYTE flag; int x,y; nChessID = position[i][j]; switch(nChessID) { case R_KING: case B_KING: for (y = 0; y < 3; y++) for (x = 3; x < 6; x++) if (CanTouch(position, j, i, x, y)) AddPoint(x, y); for (y = 7; y < 10; y++) for (x = 3; x < 6; x++) if (CanTouch(position, j, i, x, y)) AddPoint(x, y); break; case R_BISHOP: for (y = 7; y < 10; y++) for (x = 3; x < 6; x++) if (CanTouch(position, j, i, x, y)) AddPoint(x, y); break; case B_BISHOP: for (y = 0; y < 3; y++) for (x = 3; x < 6; x++) if (CanTouch(position, j, i, x, y)) AddPoint(x, y); break; case R_ELEPHANT: case B_ELEPHANT: x=j+2; y=i+2; if(x < 9 && y < 10 && CanTouch(position, j, i, x, y)) AddPoint(x, y); x=j+2; y=i-2; if(x < 9 && y>=0 && CanTouch(position, j, i, x, y)) AddPoint(x, y); x=j-2; y=i+2; if(x>=0 && y < 10 && CanTouch(position, j, i, x, y)) AddPoint(x, y); x=j-2; y=i-2; if(x>=0 && y>=0 && CanTouch(position, j, i, x, y)) AddPoint(x, y); break; case R_HORSE: case B_HORSE: x=j+2; y=i+1; if((x < 9 && y < 10) &&CanTouch(position, j, i, x, y)) AddPoint(x, y); x=j+2; y=i-1; if((x < 9 && y >= 0) &&CanTouch(position, j, i, x, y)) AddPoint(x, y); x=j-2; y=i+1; if((x >= 0 && y < 10) &&CanTouch(position, j, i, x, y)) AddPoint(x, y); x=j-2; y=i-1; if((x >= 0 && y >= 0) &&CanTouch(position, j, i, x, y)) AddPoint(x, y); x=j+1; y=i+2; if((x < 9 && y < 10) &&CanTouch(position, j, i, x, y)) AddPoint(x, y); x=j-1; y=i+2; if((x >= 0 && y < 10) &&CanTouch(position, j, i, x, y)) AddPoint(x, y); x=j+1; y=i-2; if((x < 9 && y >= 0) &&CanTouch(position, j, i, x, y)) AddPoint(x, y); x=j-1; y=i-2; if((x >= 0 && y >= 0) &&CanTouch(position, j, i, x, y)) AddPoint(x, y); break; case R_CAR: case B_CAR: x=j+1; y=i; while(x < 9) { if( NOCHESS == position[y][x] ) AddPoint(x, y); else { AddPoint(x, y); break; } x++; } x = j-1; y = i; while(x >= 0) { if( NOCHESS == position[y][x] ) AddPoint(x, y); else { AddPoint(x, y); break; } x--; } x=j; y=i+1;// while(y < 10) { if( NOCHESS == position[y][x]) AddPoint(x, y); else { AddPoint(x, y); break; } y++; } x = j; y = i-1;//よ while(y>=0) { if( NOCHESS == position[y][x]) AddPoint(x, y); else { AddPoint(x, y); break; } y--; } break; case R_PAWN: y = i - 1; x = j; if(y >= 0) AddPoint(x, y); if(i < 5) { y=i; x=j+1; if(x < 9 ) AddPoint(x, y); x=j-1; if(x >= 0 ) AddPoint(x, y); } break; case B_PAWN: y = i + 1; x = j; if(y < 10 ) AddPoint(x, y); if(i > 4) { y=i; x=j+1; if(x < 9) AddPoint(x, y); x=j-1; if(x >= 0) AddPoint(x, y); } break; case B_CANON: case R_CANON: x=j+1; // y=i; flag=FALSE; while(x < 9) { if( NOCHESS == position[y][x] ) { if(!flag) AddPoint(x, y); } else { if(!flag) flag=TRUE; else { AddPoint(x, y); break; } } x++; } x=j-1; flag=FALSE; while(x>=0) { if( NOCHESS == position[y][x] ) { if(!flag) AddPoint(x, y); } else { if(!flag) flag=TRUE; else { AddPoint(x, y); break; } } x--; } x=j; y=i+1; flag=FALSE; while(y < 10) { if( NOCHESS == position[y][x] ) { if(!flag) AddPoint(x, y); } else { if(!flag) flag=TRUE; else { AddPoint(x, y); break; } } y++; } y=i-1; // flag=FALSE; while(y>=0) { if( NOCHESS == position[y][x] ) { if(!flag) AddPoint(x, y); } else { if(!flag) flag=TRUE; else { AddPoint(x, y); break; } } y--; } break; default: break; } return nPosCount ; } BOOL CEveluation::CanTouch(BYTE position[10][9], int nFromX, int nFromY, int nToX, int nToY) { int i, j; int nMoveChessID, nTargetID; if (nFromY == nToY && nFromX == nToX) return FALSE;//目的與源相同 nMoveChessID = position[nFromY][nFromX]; nTargetID = position[nToY][nToX]; switch(nMoveChessID) { case B_KING: 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(nToX - nFromX) > 1) return FALSE;//將帥只走一步直線: } break; case R_BISHOP: if (nToY < 7 || nToX > 5 || nToX < 3) return FALSE;//士出九宮 if (abs(nFromY - nToY) != 1 || abs(nToX - nFromX) != 1) return FALSE; //士走斜線 break; case B_BISHOP: //黑士 if (nToY > 2 || nToX > 5 || nToX < 3) return FALSE;//士出九宮 if (abs(nFromY - nToY) != 1 || abs(nToX - nFromX) != 1) return FALSE; //士走斜線 break; case R_ELEPHANT://紅象 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_ELEPHANT://黑象 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_PAWN: //黑兵 if(nToY < nFromY) return FALSE;//兵不回頭 if( nFromY < 5 && nFromY == nToY) return FALSE;//兵過河前只能直走 if(nToY - nFromY + abs(nToX - nFromX) > 1) return FALSE;//兵只走一步直線: break; case R_PAWN: //紅兵 if(nToY > nFromY) return FALSE;//兵不回頭 if( nFromY > 4 && nFromY == nToY) return FALSE;//兵過河前只能直走 if(nFromY - nToY + abs(nToX - nFromX) > 1) return FALSE;//兵只走一步直線: break; case R_KING: 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(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] != (BYTE)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 nCount=0; if(nFromY == nToY) { if(nFromX < nToX) { for(i=nFromX+1;i<nToX;i++) if(position[nFromY][i]!=NOCHESS) nCount++; if(nCount != 1) return FALSE; } else { for(i=nToX+1;i<nFromX;i++) if(position[nFromY][i] != NOCHESS) nCount++; if(nCount!=1) return FALSE; } } else { if(nFromY<nToY) { for(j=nFromY+1;j<nToY;j++) if(position[j][nFromX]!=NOCHESS) nCount++; if(nCount!=1) return FALSE; } else { for(j=nToY+1;j<nFromY;j++) if(position[j][nFromX] != NOCHESS) nCount++; if(nCount!=1) return FALSE; } } } //以上是炮吃子時================================ break; default: return FALSE; } return TRUE; }
MoveGenerator.h
MoveGenerator.cpp
這一對檔案定義並實現了走法產生器。
// ////////////////////////////////////////////////////////////////////// #if !defined(AFX_MOVEGENERATOR_H__54A88FC2_CAFC_11D5_AEC7_5254AB2E22C7__INCLUDED_) #define AFX_MOVEGENERATOR_H__54A88FC2_CAFC_11D5_AEC7_5254AB2E22C7__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CMoveGenerator { public: CMoveGenerator(); virtual ~CMoveGenerator(); static BOOL IsValidMove(BYTE position[10][9], int nFromX, int nFromY, int nToX, int nToY); int CreatePossibleMove(BYTE position[10][9], int nPly,int nSide); CHESSMOVE m_MoveList[10][80]; protected: void Gen_KingMove(BYTE position[10][9], int i, int j, int nPly); void Gen_RBishopMove(BYTE position[10][9], int i, int j, int nPly); void Gen_BBishopMove(BYTE position[10][9], int i, int j, int nPly); void Gen_ElephantMove(BYTE position[10][9], int i, int j, int nPly); void Gen_HorseMove(BYTE position[10][9], int i, int j, int nPly); void Gen_CarMove(BYTE position[10][9], int i, int j, int nPly); void Gen_RPawnMove(BYTE position[10][9], int i, int j, int nPly); void Gen_BPawnMove(BYTE position[10][9], int i, int j, int nPly); void Gen_CanonMove(BYTE position[10][9], int i, int j, int nPly); int AddMove(int nFromX,int nToX, int nFromY, int nToY,int nPly); int m_nMoveCount; }; #endif // !defined(AFX_MOVEGENERATOR_H__54A88FC2_CAFC_11D5_AEC7_5254AB2E22C7__INCLUDED_)
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "chess.h"
#include "MoveGenerator.h"
#ifdef _DEBUG
#undef THIS_FILE
static BYTE THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMoveGenerator::CMoveGenerator()
{
}
CMoveGenerator::~CMoveGenerator()
{
}
int CMoveGenerator::AddMove(int nFromX, int nFromY, int nToX, int nToY,int nPly)
{
m_MoveList[nPly][m_nMoveCount].From.x = nFromX;
m_MoveList[nPly][m_nMoveCount].From.y = nFromY;
m_MoveList[nPly][m_nMoveCount].To.x = nToX;
m_MoveList[nPly][m_nMoveCount].To.y = nToY;
m_nMoveCount++;
return m_nMoveCount;
}
int CMoveGenerator::CreatePossibleMove(BYTE position[10][9], int nPly, int nSide)
{
int nChessID;
int i,j;
m_nMoveCount = 0;
for (i = 0; i < 10; i++)
for (j = 0; j < 9; j++)
{
if (position[i][j] != NOCHESS)
{
nChessID = position[i][j];
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;
}
void CMoveGenerator::Gen_KingMove(BYTE position[10][9], int i, int j, int nPly)
{
int x, y;
for (y = 0; y < 3; y++)
for (x = 3; x < 6; x++)
if (IsValidMove(position, j, i, x, y))
AddMove(j, i, x, y, nPly);
for (y = 7; y < 10; y++)
for (x = 3; x < 6; x++)
if (IsValidMove(position, j, i, x, y))
AddMove(j, i, x, y, nPly);
}
void CMoveGenerator::Gen_RBishopMove(BYTE position[10][9], int i, int j, int nPly)
{
int x, y;
for (y = 7; y < 10; y++)
for (x = 3; x < 6; x++)
if (IsValidMove(position, j, i, x, y))
AddMove(j, i, x, y, nPly);
}
void CMoveGenerator::Gen_BBishopMove(BYTE position[10][9], int i, int j, int nPly)
{
int x, y;
for (y = 0; y < 3; y++)
for (x = 3; x < 6; x++)
if (IsValidMove(position, j, i, x, y))
AddMove(j, i, x, y, nPly);
}
void CMoveGenerator::Gen_ElephantMove(BYTE position[10][9], int i, int j, int nPly)
{
int x, y;
x=j+2;
y=i+2;
if(x < 9 && y < 10 && IsValidMove(position, j, i, x, y))
AddMove(j, i, x, y, nPly);
x=j+2;
y=i-2;
if(x < 9 && y>=0 && IsValidMove(position, j, i, x, y))
AddMove(j, i, x, y, nPly);
x=j-2;
y=i+2;
if(x>=0 && y < 10 && IsValidMove(position, j, i, x, y))
AddMove(j, i, x, y, nPly);
x=j-2;
y=i-2;
if(x>=0 && y>=0 && IsValidMove(position, j, i, x, y))
AddMove(j, i, x, y, nPly);
}
void CMoveGenerator::Gen_HorseMove(BYTE position[10][9], int i, int j, int nPly)
{
int x, y;
x=j+2;
y=i+1;
if((x < 9 && y < 10) &&IsValidMove(position, j, i, x, y))
AddMove(j, i, x, y, nPly);
x=j+2;
y=i-1;
if((x < 9 && y >= 0) &&IsValidMove(position, j, i, x, y))
AddMove(j, i, x, y, nPly);
x=j-2;
y=i+1;
if((x >= 0 && y < 10) &&IsValidMove(position, j, i, x, y))
AddMove(j, i, x, y, nPly);
x=j-2;
y=i-1;
if((x >= 0 && y >= 0) &&IsValidMove(position, j, i, x, y))
AddMove(j, i, x, y, nPly);
x=j+1;
y=i+2;
if((x < 9 && y < 10) &&IsValidMove(position, j, i, x, y))
AddMove(j, i, x, y, nPly);
x=j-1;
y=i+2;
if((x >= 0 && y < 10) &&IsValidMove(position, j, i, x, y))
AddMove(j, i, x, y, nPly);
x=j+1;
y=i-2;
if((x < 9 && y >= 0) &&IsValidMove(position, j, i, x, y))
AddMove(j, i, x, y, nPly);
x=j-1;
y=i-2;
if((x >= 0 && y >= 0) &&IsValidMove(position, j, i, x, y))
AddMove(j, i, x, y, nPly);
}
void CMoveGenerator::Gen_RPawnMove(BYTE position[10][9], int i, int j, int nPly)
{
int x, y;
int nChessID;
nChessID = position[i][j];
y = i - 1;
x = j;
if(y > 0 && !IsSameSide(nChessID, position[y][x]))
AddMove(j, i, x, y, nPly);
if(i < 5)
{
y=i;
x=j+1;
if(x < 9 && !IsSameSide(nChessID, position[y][x]))
AddMove(j, i, x, y, nPly);
x=j-1;
if(x >= 0 && !IsSameSide(nChessID, position[y][x]))
AddMove(j, i, x, y, nPly);
}
}
void CMoveGenerator::Gen_BPawnMove(BYTE position[10][9], int i, int j, int nPly)
{
int x, y;
int nChessID;
nChessID = position[i][j];
y = i + 1;
x = j;
if(y < 10 && !IsSameSide(nChessID, position[y][x]))
AddMove(j, i, x, y, nPly);
if(i > 4)
{
y=i;
x=j+1;
if(x < 9 && !IsSameSide(nChessID, position[y][x]))
AddMove(j, i, x, y, nPly);
x=j-1;
if(x >= 0 && !IsSameSide(nChessID, position[y][x]))
AddMove(j, i, x, y, nPly);
}
}
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);
else
{
if(!IsSameSide(nChessID, position[y][x]))
AddMove(j, i, x, y, nPly);
break;
}
x++;
}
x = j-1;
y = i;
while(x >= 0)
{
if( NOCHESS == position[y][x] )
AddMove(j, i, x, y, nPly);
else
{
if(!IsSameSide(nChessID, position[y][x]))
AddMove(j, i, x, y, nPly);
break;
}
x--;
}
x=j;
y=i+1;//
while(y < 10)
{
if( NOCHESS == position[y][x])
AddMove(j, i, x, y, nPly);
else
{
if(!IsSameSide(nChessID, position[y][x]))
AddMove(j, i, x, y, nPly);
break;
}
y++;
}
x = j;
y = i-1;//
while(y>=0)
{
if( NOCHESS == position[y][x])
AddMove(j, i, x, y, nPly);
else
{
if(!IsSameSide(nChessID, position[y][x]))
AddMove(j, i, x, y, nPly);
break;
}
y--;
}
}
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);
}
else
{
if(!flag)
flag=TRUE;
else
{
if(!IsSameSide(nChessID, position[y][x]))
AddMove(j, i, x, y, nPly);
break;
}
}
x++;
}
x=j-1;
flag=FALSE;
while(x>=0)
{
if( NOCHESS == position[y][x] )
{
if(!flag)
AddMove(j, i, x, y, nPly);
}
else
{
if(!flag)
flag=TRUE;
else
{
if(!IsSameSide(nChessID, position[y][x]))
AddMove(j, i, x, y, nPly);
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);
}
else
{
if(!flag)
flag=TRUE;
else
{
if(!IsSameSide(nChessID, position[y][x]))
AddMove(j, i, x, y, nPly);
break;
}
}
y++;
}
y=i-1; //
flag=FALSE;
while(y>=0)
{
if( NOCHESS == position[y][x] )
{
if(!flag)
AddMove(j, i, x, y, nPly);
}
else
{
if(!flag)
flag=TRUE;
else
{
if(!IsSameSide(nChessID, position[y][x]))
AddMove(j, i, x, y, nPly);
break;
}
}
y--;
}
}
BOOL CMoveGenerator::IsValidMove(BYTE position[10][9], int nFromX, int nFromY, int nToX, int nToY)
{
int i, j;
int nMoveChessID, nTargetID;
if (nFromY == nToY && nFromX == nToX)
return FALSE;//目的與源相同
nMoveChessID = position[nFromY][nFromX];
nTargetID = position[nToY][nToX];
if (IsSameSide(nMoveChessID, nTargetID))
return FALSE;//不能吃自己的棋
switch(nMoveChessID)
{
case B_KING:
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(nToX - nFromX) > 1)
return FALSE;//將帥只走一步直線:
}
break;
case R_BISHOP:
if (nToY < 7 || nToX > 5 || nToX < 3)
return FALSE;//士出九宮
if (abs(nFromY - nToY) != 1 || abs(nToX - nFromX) != 1)
return FALSE; //士走斜線
break;
case B_BISHOP: //黑士
if (nToY > 2 || nToX > 5 || nToX < 3)
return FALSE;//士出九宮
if (abs(nFromY - nToY) != 1 || abs(nToX - nFromX) != 1)
return FALSE; //士走斜線
break;
case R_ELEPHANT://紅象
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_ELEPHANT://黑象
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_PAWN: //黑兵
if(nToY < nFromY)
return FALSE;//兵不回頭
if( nFromY < 5 && nFromY == nToY)
return FALSE;//兵過河前只能直走
if(nToY - nFromY + abs(nToX - nFromX) > 1)
return FALSE;//兵只走一步直線:
break;
case R_PAWN: //紅兵
if(nToY > nFromY)
return FALSE;//兵不回頭
if( nFromY > 4 && nFromY == nToY)
return FALSE;//兵過河前只能直走
if(nFromY - nToY + abs(nToX - nFromX) > 1)
return FALSE;//兵只走一步直線:
break;
case R_KING:
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(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 count=0;
if(nFromY == nToY)
{
if(nFromX < nToX)
{
for(i=nFromX+1;i<nToX;i++)
if(position[nFromY][i]!=NOCHESS)
count++;
if(count != 1)
return FALSE;
}
else
{
for(i=nToX+1;i<nFromX;i++)
if(position[nFromY][i] != NOCHESS)
count++;
if(count!=1)
return FALSE;
}
}
else
{
if(nFromY<nToY)
{
for(j=nFromY+1;j<nToY;j++)
if(position[j][nFromX]!=NOCHESS)
count++;
if(count!=1)
return FALSE;
}
else
{
for(j=nToY+1;j<nFromY;j++)
if(position[j][nFromX] != NOCHESS)
count++;
if(count!=1)
return FALSE;
}
}
}
break;
default:
return FALSE;
}
return TRUE;
}
完整原始碼,資源以及執行exe連結http://download.csdn.net/download/zhangxiaoyu_sy/9939114