⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cchessevaluate.h

📁 中国象棋人机对弈
💻 H
📖 第 1 页 / 共 2 页
字号:
							AddPointToQueue( 2, 4 );

						if( ! HaveMan(3, 1) )
							AddPointToQueue( 2, 0 );

						if( ! HaveMan(5, 3) )
							AddPointToQueue( 6, 4 );

						if( ! HaveMan(5, 1) )
							AddPointToQueue( 6, 0 );
					}
					else if( x == 6 )
					{
						if( y == 4 )
						{
							if( ! HaveMan(5, 3) )
								AddPointToQueue( 4, 2 );

							if( ! HaveMan(7, 3) )
								AddPointToQueue( 8, 2 );
						}
						else //  y == 0 
						{
							if( ! HaveMan(5, 1) )
								AddPointToQueue( 4, 2 );

							if( ! HaveMan(7, 1) )
								AddPointToQueue( 8, 2 );
						}	
					}
					else // x == 8
					{
						if( ! HaveMan(7, 3) )
							AddPointToQueue( 6, 4 );

						if( ! HaveMan(7, 1) )
							AddPointToQueue( 6, 0 );
					}

					break;


				case BLACK_X:

					if( x == 0 )
					{
						if( ! HaveMan(1, 6) )
							AddPointToQueue( 2, 5 );

						if( ! HaveMan(1, 8) )
							AddPointToQueue( 2, 9 );
					}
					else if( x == 2 )
					{
						if( y == 5 )
						{
							if( ! HaveMan(1, 6) )
								AddPointToQueue( 0, 7 );

							if( ! HaveMan(3, 6) )
								AddPointToQueue( 4, 7 );
						}
						else // y == 9 
						{
							if( ! HaveMan(1, 8) )
								AddPointToQueue( 0, 7 );

							if( ! HaveMan(3, 8) )
								AddPointToQueue( 4, 7 );
						}	
					}
					else if( x == 4 )
					{
						if( ! HaveMan(3, 6) )
							AddPointToQueue( 2, 5 );

						if( ! HaveMan(3, 8) )
							AddPointToQueue( 2, 9 );

						if( ! HaveMan(5, 6) )
							AddPointToQueue( 6, 5 );

						if( ! HaveMan(5, 8) )
							AddPointToQueue( 6, 9 );
					}
					else if( x == 6 )
					{
						if( y == 5 )
						{
							if( ! HaveMan(5, 6) )
								AddPointToQueue( 4, 7 );

							if( ! HaveMan(7, 6) )
								AddPointToQueue( 8, 7 );
						}
						else // y == 9 
						{
							if( ! HaveMan(5, 8) )
								AddPointToQueue( 4, 7 );

							if( ! HaveMan(7, 8) )
								AddPointToQueue( 8, 7 );
						}	
					}
					else // x == 8
					{
						if( ! HaveMan(7, 6) )
							AddPointToQueue( 6, 5 );

						if( ! HaveMan(7, 8) )
							AddPointToQueue( 6, 9 );
					}

					break;


				case RED_S:

					if( x == 3 )
					{
						AddPointToQueue( 4, 1 );
					}
					else if( x == 4 )
					{
						AddPointToQueue( 3, 2 );

						AddPointToQueue( 3, 0 );

						AddPointToQueue( 5, 2 );

						AddPointToQueue( 5, 0 );
					}
					else //  x == 5
					{
						AddPointToQueue( 4, 1 );
					}

					break;


				case BLACK_S:

					if( x == 3 )
					{
						AddPointToQueue( 4, 8 );
					}
					else if( x == 4 )
					{
						AddPointToQueue( 3, 7 );

						AddPointToQueue( 3, 9 );

						AddPointToQueue( 5, 7 );

						AddPointToQueue( 5, 9 );
					}
					else // x == 5
					{
						AddPointToQueue( 4, 8 );
					}

					break;


				case RED_B:

					//向前
					if( y < 9 )
						AddPointToQueue( x, y + 1 );

					if( y >= 5 ) //兵已过河
					{
						//向左
						if( x > 0 )
							AddPointToQueue( x - 1, y );

						//向右
						if( x < 8 )
							AddPointToQueue( x + 1, y );
					}

					break;


				case BLACK_B:

					//向前
					if( y > 0 )
						AddPointToQueue( x, y - 1 );

					if( y <= 4 ) //兵已过河
					{
						//向右
						if( x > 0 )
							AddPointToQueue( x - 1, y );

						//向左
						if( x < 8 )
							AddPointToQueue( x + 1, y );
					}

					break;

				}	// end switch

			
				for( i = 0; i < nPointCount; i ++ )
				{
					nTargetType = CChessBoard[ PointList[i].x ][ PointList[i].y ]; //保存目标位置的棋子状况

//++++++++++++++求得棋子的机动性价值++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
					// 目标位置为空,机动性加分
					if( nTargetType == 0 )
					{
						if( fSide == RED )
							nMobilityVal[fSide] += MobilityValues[nCChessID];
						else
							nMobilityVal[fSide] += MobilityValues[nCChessID - 7];
					}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


					// 目标位置为对方棋子,将信息存入RelationOfMan中的UnderAttack
					else if( SideOfMan[nTargetType] != fSide )
					{
						//对王受攻击的情况作单独处理
						if( nTargetType == RED_K )	
						{
							if( fWhoseTurn == BLACK )	// 红帅即将被将死
							{
								return MaxValue - 10;	// 返回失败极值(已验证应为 MaxValue )
								// 减去10表示此种情况稍好于王已经被吃的情况
							}
							else						// 仅仅是将军而已,关系值扣一点分
							{
								nRelationVal[RED] -= 20;
								continue;
							}

						}
						if( nTargetType == BLACK_K )	
						{
							if( fWhoseTurn == RED )		// 黑将即将被将死
							{
								return MaxValue - 10;	// 返回失败极值(已验证应为 MaxValue )
								// 减去10表示此种情况稍好于王已经被吃的情况
							}
							else						// 仅仅是将军而已,关系值扣一点分
							{
								nRelationVal[BLACK] -= 20;
								continue;
							}
						}

						RelationOfMan[ PointList[i].x ][ PointList[i].y ]
						.nCChessID	=	nTargetType ;

						RelationOfMan[ PointList[i].x ][ PointList[i].y ]
						.UnderAttack[RelationOfMan[ PointList[i].x ][ PointList[i].y ].nUAttackCount ++]
							=	nCChessID ;

					}

					// 目标位置为己方棋子,将信息存入RelationOfMan中的UnderGuard
					else // if( SideOfMan[nTargetType] == fSide )
					{
						// 若受保护的是王,则不进行处理。因为王受保护毫无意义
						if( nTargetType == RED_K || nTargetType == BLACK_K )
							continue;

						RelationOfMan[ PointList[i].x ][ PointList[i].y ]
						.nCChessID	=	nTargetType ;

						RelationOfMan[ PointList[i].x ][ PointList[i].y ]
						.UnderGurad[RelationOfMan[ PointList[i].x ][ PointList[i].y ].nUGuardCount ++]
							=	nCChessID ;
					}

				}	// end for( i = 0; i < nPointCount; i ++ )

			}	// end if( CChessBoard[x][y] != 0 )

		}	// end for x 0 to 8, y 0 to 9


//++++++++++++++求得棋子的关系价值(受攻击和受保护)++++++++++++++++++++++++++++++++++++++++++++++++++++++
	for( x = 0; x <= 8; x ++ )
		for( y = 0; y <= 9; y ++ )
		{
			int nAttack	= 0;		//用于记录攻击方总子力
			int nGuard	= 0;		//用于记录保护方总子力
			int nMinAttack	= 777;	//用于记录攻击方最小子力
			int nMaxAttack	= 0;	//用于记录攻击方最大子力
			//int nMinGuard	= 777;	//用于记录保护方最小子力
			int nMaxGuard	= 0;	//用于记录保护方最大子力
			int nflagValue	= 777;	//用于表记是否有攻击方子力低于被攻击者,若有则其值为攻击方中最低子力

			int nUnitValue;// 单位价值

			if( RelationOfMan[x][y].nCChessID != 0 )
			{
				nCChessID = RelationOfMan[x][y].nCChessID;
				fSide = SideOfMan[nCChessID];

				 nUnitValue = BasicValues[nCChessID] >> 3;	// 单位价值取基本价值的1/8


				// 统计攻击方的子力
				for( i = 0; i < RelationOfMan[x][y].nUAttackCount; i ++ )
				{
					// 查看是否有攻击者子力小于被攻击者子力,若有记录其中子力最小的
					if( BasicValues[ RelationOfMan[x][y].UnderAttack[i] ] < BasicValues[nCChessID] 
						&& BasicValues[ RelationOfMan[x][y].UnderAttack[i] ] < nflagValue )
					{
							nflagValue =  BasicValues[ RelationOfMan[x][y].UnderAttack[i] ] ;
					}
					
					if( BasicValues[ RelationOfMan[x][y].UnderAttack[i] ] < nMinAttack )
						nMinAttack = BasicValues[ RelationOfMan[x][y].UnderAttack[i] ];

					if( BasicValues[ RelationOfMan[x][y].UnderAttack[i] ] > nMaxAttack )
						nMaxAttack = BasicValues[ RelationOfMan[x][y].UnderAttack[i] ];

					nAttack += BasicValues[ RelationOfMan[x][y].UnderAttack[i] ];
				}

				// 统计防守方的子力
				for( i = 0; i < RelationOfMan[x][y].nUGuardCount; i ++ )
				{
					//if( BasicValues[ RelationOfMan[x][y].UnderGurad[i] ] < nMinGuard )
					//	nMinGuard = BasicValues[ RelationOfMan[x][y].UnderGurad[i] ];

					if( BasicValues[ RelationOfMan[x][y].UnderGurad[i] ] > nMaxGuard )
						nMaxGuard = BasicValues[ RelationOfMan[x][y].UnderGurad[i] ];

					nGuard += BasicValues[ RelationOfMan[x][y].UnderGurad[i] ];
				}


				if( nAttack == 0 )	// 没受攻击,而是只有保护
				{
					nRelationVal[fSide] += 5 * RelationOfMan[x][y].nUGuardCount ;
				}
				else				// 遭受攻击
				{
					if( nGuard == 0)	// 没有保护
					{
						if( fWhoseTurn != fSide )	// 轮到对方行棋
						{
							nRelationVal[fSide] -= 5 * nUnitValue ;
						}
						else						// 轮到己方行棋
						{
							nRelationVal[fSide] -=  nUnitValue ;
						}
					}
					else				// 有保护
					{
						// 攻击者子力小于被攻击者子力,对方将愿意换子
						if( nflagValue != 777 )	
						{
							if( fWhoseTurn != fSide )	// 轮到对方行棋
							{
								nRelationVal[fSide]		-= 5 * nUnitValue ;
								nRelationVal[1 - fSide]	-= 5 * ( nflagValue >> 3 );
							}
							else						// 轮到己方行棋
							{
								nRelationVal[fSide]		-=  nUnitValue ;
								nRelationVal[1 - fSide]	-=  ( nflagValue >> 3 );
							}
						}
						// 多攻击\单保护的情况并且攻击者最小子力小于被攻击者子力与保护者子力之和
						//,则对方可能以一子换两子
						else if( RelationOfMan[x][y].nUGuardCount == 1 
								&& RelationOfMan[x][y].nUAttackCount > 1 
								&& nMinAttack < BasicValues[nCChessID] + nGuard )
						{
							if( fWhoseTurn != fSide )	// 轮到对方行棋
							{
								nRelationVal[fSide]		-= 5 * nUnitValue ;
								nRelationVal[fSide]		-= 5 * ( nGuard >> 3 );

								nRelationVal[1 - fSide]	-= 5 * ( nMinAttack >> 3 );
							}
							else						// 轮到己方行棋
							{
								nRelationVal[fSide]		-=  nUnitValue ;
								nRelationVal[fSide]		-=  ( nGuard >> 3 );

								nRelationVal[1 - fSide]	-=  ( nMinAttack >> 3 );
							}
						}
						// 三攻击\两保护的情况并且攻击者子力较小的二者之和小于被攻击者子力与保护者子力之和
						//,则对方可能以两子换三子
						else if( RelationOfMan[x][y].nUGuardCount == 2 
								&& RelationOfMan[x][y].nUAttackCount == 3 
								&& ( nAttack - nMaxAttack ) < ( BasicValues[nCChessID] + nGuard ) )
						{
							if( fWhoseTurn != fSide )	// 轮到对方行棋
							{
								nRelationVal[fSide]		-= 5 * nUnitValue ;
								nRelationVal[fSide]		-= 5 * ( nGuard >> 3 );

								nRelationVal[1 - fSide]	-= 5 * ( ( nAttack - nMaxAttack ) >> 3 );
							}
							else						// 轮到己方行棋
							{
								nRelationVal[fSide]		-=  nUnitValue ;
								nRelationVal[fSide]		-=  ( nGuard >> 3 );

								nRelationVal[1 - fSide]	-=  ( ( nAttack - nMaxAttack ) >> 3 );
							}
						}
						// 攻击方与保护方数量相同并且攻击者子力小于被攻击者子力与保护者子力之和
						//再减去保护者中最大子力,则对方可能以n子换n子
						else if( RelationOfMan[x][y].nUAttackCount == RelationOfMan[x][y].nUGuardCount  
								 && nAttack < BasicValues[nCChessID] + nGuard - nMaxGuard )
						{
							if( fWhoseTurn != fSide )	// 轮到对方行棋
							{
								nRelationVal[fSide]		-= 5 * nUnitValue ;
								nRelationVal[fSide]		-= 5 * ( ( nGuard - nMaxGuard ) >> 3 );

								nRelationVal[1 - fSide]	-= 5 * ( nAttack >> 3 );
							}
							else						// 轮到己方行棋
							{
								nRelationVal[fSide]		-=  nUnitValue ;
								nRelationVal[fSide]		-=  ( ( nGuard - nMaxGuard ) >> 3 );

								nRelationVal[1 - fSide]	-=  ( nAttack >> 3 );
							}
						}
						else
						{
							//上述情况已基本涵盖最常见情况,因而其它情况暂时不做考虑
						}

					}	// end 有保护

				}	// end 遭受攻击

			}	// end if( RelationOfMan[x][y].nCChessID != 0 )

		}	// end for x 0 to 8, y 0 to 9
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


	// 统计红方总分值
	RedValues	= nBasicVal[RED] + nPositionVal[RED]
					+ nMobilityVal[RED] + nRelationVal[RED] ;

	// 统计黑方总分值
	BlackValues	= nBasicVal[BLACK] + nPositionVal[BLACK] 
					+ nMobilityVal[BLACK] + nRelationVal[BLACK] ;


	if( fWhoseTurn == RED )
		return ( RedValues - BlackValues )  + rand()%3 ;	//此处 +rand()%X 是通过加一个不会对分值
	else													//造成大的影响的随机量以期电脑在应对同
		return ( BlackValues - RedValues )  + rand()%3 ;	//一种下法时不会每次都有相同的回应。
															//这样做以及X取3是否合适还有待实践检验……
}

inline void AddPointToQueue( BYTE x, BYTE y )
{
	PointList[nPointCount].x = x ;
	PointList[nPointCount].y = y ;

	nPointCount ++;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -