예제 #1
0
void ICP::DcGG(void) const
{
  // Go and play to end of game

  NoParameters();
  if (IsGameOver()) ReportGameOver();
  else
  {
    do ProgMove(); while (!IsGameOver() && !stateptr->TestInterrupt());
    if (stateptr->TestInterrupt())
    {
      PrintFS(fsMsInterrupt); stateptr->ResetInterrupt();
    };
  };
}
예제 #2
0
int CAlphaBetaEngine::alphabeta(int depth, int alpha, int beta)
{
	int score;
	int Count,i;
	BYTE type;

	i = IsGameOver(CurPosition, depth);
	if (i != 0)
		return i;

	if (depth <= 0)	//叶子节点取估值
		return m_pEval->Eveluate(CurPosition, (m_nMaxDepth-depth)%2);
	
	Count = m_pMG->CreatePossibleMove(CurPosition, depth, (m_nMaxDepth-depth)%2);

	for (i=0;i<Count;i++) 
	{

		type = MakeMove(&m_pMG->m_MoveList[depth][i]);
		score = -alphabeta(depth - 1, -beta, -alpha);
		UnMakeMove(&m_pMG->m_MoveList[depth][i],type); 

		if (score > alpha)
		{
			alpha = score;
			if(depth == m_nMaxDepth)
				m_cmBestMove = m_pMG->m_MoveList[depth][i];
		}
        if (alpha >= beta) 
              break;

				
	}
	return alpha;
}
예제 #3
0
void CTetrisDlg::OnTimer(UINT_PTR nIDEvent)
{
    if(m_pBlock->canMoveDown())
    {
        m_pBlock->moveDown();
    }
    else
    {
        for(CHAR i = ROW - 1; i >= 0; --i)
        {
            if(CheckLine(i))
            {
                RemoveLine(i);
                ++i;
            }
        }
        MSG msg;
        while(::PeekMessage(&msg, m_hWnd, 0, 0, PM_REMOVE));
        if(IsGameOver(m_gameParam & 0xE0))
        {
            GameOver();
        }
        else
        {
            delete m_pBlock;
            m_pBlock = BlockFromIndex(m_gameParam & 0xE0);
            NextRandomBlock();
            m_nextColor = NextRandomColor();
        }
    }
    Invalidate(FALSE);
    CDialog::OnTimer(nIDEvent);
}
예제 #4
0
int CAlphabeta_HHEngine::AlphaBeta(int nDepth, int alpha,int beta)
{
	int score;
	int Count,i;
	BYTE type;

	i=IsGameOver(CurPosition, nDepth);
	if(i!=0)
		return i;

	if(nDepth<=0)//叶子节点取估值
		return m_pEval->Eveluate(CurPosition,(m_nMaxDepth-nDepth)%2,m_nUserChessColor);
	
	Count=m_pMG->CreatePossibleMove(CurPosition,nDepth,(m_nMaxDepth-nDepth)%2,m_nUserChessColor);
	if(nDepth==m_nMaxDepth)
	{
		//在根节点设定进度条
		m_pThinkProgress->SetRange(0,Count);
		m_pThinkProgress->SetStep(1);
	}

	//取所有走法的历史得分
	for(i=0;i<Count;i++) 

		m_pMG->m_MoveList[nDepth][i].Score=GetHistoryScore(&m_pMG->m_MoveList[nDepth][i]);

	MergeSort(m_pMG->m_MoveList[nDepth],Count,0);//对Count种走法按历史得分大小排序

	int bestmove=-1;//记录最佳走法的变量

	for(i=0;i<Count;i++) 
	{
		if(nDepth==m_nMaxDepth)
			m_pThinkProgress->StepIt();//走进度条

		type=MakeMove(&m_pMG->m_MoveList[nDepth][i]);
		score=-AlphaBeta(nDepth-1,-beta,-alpha);
		UnMakeMove(&m_pMG->m_MoveList[nDepth][i],type); 

		if(score>alpha)
		{
			alpha=score;
			if(nDepth==m_nMaxDepth)
				m_cmBestMove=m_pMG->m_MoveList[nDepth][i];
			bestmove=i;
		}
        if(alpha>=beta) 
		{
			bestmove=i;
			break;
		}			
	}
	if(bestmove!=-1)
		EnterHistoryScore(&m_pMG->m_MoveList[nDepth][bestmove],nDepth);//将最佳走法汇入历史记录表

	return alpha;
}
예제 #5
0
//change player, if player has no moves change again
void GamePP::SwitchTurn()
{
	if(IsGameOver())
		win=GetWinner();
	else
	{
		currentplayer=3-currentplayer;
		if(b->GetMoves(currentplayer).empty())
			SwitchTurn();
	}
}
예제 #6
0
void ICP::DcGS(void) const
{
  // Go search

  NoParameters();
  if (IsGameOver()) ReportGameOver();
  else
  {
    Move move;

    FindMove(move);
    PrintFSL(fsLbMove); move.Print(stateptr->FetchSearchFEnv()); PrintNL();
  };
}
예제 #7
0
	void Player::ResetLifeValues()
	{
		m_lifeTimeMs = 0.0f;

		if (IsGameOver())
		{
			m_speed = 0.0f;
		}
		else
		{
			m_health = 1.0f;
			m_fuel = 1.0f;
			m_speed = DefaultSpeed;
		}

		m_speedItemTimeout = 0.0f;
		m_numberOfBombItems = 0;
		m_itemMessageTimeoutMs = 0;
		m_showHealthWarningTimeoutMs = 0;
	}
예제 #8
0
void IGameController::TogglePause()
{
	if(IsGameOver())
		return;

	if(GameServer()->m_World.m_Paused)
	{
		// unpause
		if(g_Config.m_SvUnpauseTimer > 0)
			m_UnpauseTimer = g_Config.m_SvUnpauseTimer*Server()->TickSpeed();
		else
		{
			GameServer()->m_World.m_Paused = false;
			m_UnpauseTimer = 0;
		}
	}
	else
	{
		// pause
		GameServer()->m_World.m_Paused = true;
		m_UnpauseTimer = 0;
	}
}
예제 #9
0
파일: Engine.cpp 프로젝트: npburg/domlib
void Engine::Play( void )
{
    m_pCurrentPlayer = GetFirstPlayer();

    try
    {
        while( !IsGameOver() )
        {
            m_pCurrentPlayer->PlayTurn();
            if( m_OutpostFlag )
            {
                // do not increment the pPlayer pointer;
            }
            else
            {
                m_pCurrentPlayer = GetNextPlayer( m_pCurrentPlayer );
            }
        }
    }
    catch( std::wstring* errorString )
    {
        std::wcout << L"Exception raised: " << errorString << L"\n";
    }
}
예제 #10
0
////////////////////////////////////////////////////////////////
// Main battle method, emulation of tanks battle, finding who winner
void CBattleField::Battle(std::istream& _is)
{
	Time_t time;;
	_is >> time;
		
	while (!IsGameOver())
	{
		if (!time && _commandsCount != 0)
		{
			_is >> time;	
		}
		
		////////////////////////////////////////////
		// Loop getting command at this time momment
		// Like: 
		// 25 A SHOOT
		// 25 A MOVE
		// 25 A STOP
		while (time == _time && _commandsCount != 0)
		{
			_commandsCount--;
			time = 0;
			PointName_t name;
			CommandName_t cmd;
			Angle_t angle;
			
			//Read tank name
			_is >> name;
			
			_is >> cmd;

			if (cmd == g_commandTurn)
			{
				//if command "turn" need read angle, for correct input
				_is >> angle;
			}

			Point_t tank = GetTankByName(name);

			// If tank exist recive command, else if not exist ignore command 
			if (tank != 0)
			{
				if (cmd == g_commandTurn)
				{
					//Tank recive command "TURN"
					tank->SetNewAngle(angle);
				}
				else if (cmd == g_commandStop)
				{
					//Tank recive command "STOP"
					tank->Stop();
				}
				else if (cmd == g_commandShoot)
				{
					//Tank recive command "SHOOT"
					//BOOOOOOOOOOM! :-)
					MakeShot(tank->GetX(), tank->GetY(), tank->GetAngle());
				}
				else if (cmd == g_commandMove)
				{
					//Tank recive command "MOVE"
					tank->Move();
				}
				else
				{
					//Wrong command name
					throw CError(ERR_WRONG_COMMAND);
				}
			}

			if (_commandsCount)
			{
				_is >> time;
			}
		}
예제 #11
0
int CAlphaBeta_TTEngine::AlphaBeta(int nDepth, int alpha, int beta)
{
    int score;
    int Count,i;
    BYTE type;
    int side;

    i=IsGameOver(CurPosition,nDepth);
    if(i!=0)
        return i;
    
    //察看当前节点是否在置换表中有有效数据
    side=(m_nMaxDepth-nDepth)%2;
    score=LookUpHashTable(alpha,beta,nDepth,side); 
    if(score!=66666) 
        return score;//命中,直接返回表中的值

    //叶子节点取估值
    if(nDepth<=0)
    {
        score=m_pEval->Eveluate(CurPosition,side,m_nUserChessColor);
        EnterHashTable(exact,score,nDepth,side);//将求得的估值放进置换表
        return score;
    }

    Count=m_pMG->CreatePossibleMove(CurPosition,nDepth,side,m_nUserChessColor);
    if(nDepth==m_nMaxDepth)
    {
        //在根节点设定进度条        
        progress->setTotalSteps(Count);
        progress->setProgress(1);
    }

    int eval_is_exact=0;//数据类型标志

    for(i=0;i<Count;i++)//对当前节点的下一步每一可能的走法
    {
        if(nDepth==m_nMaxDepth)
            progress->nextStep();

        Hash_MakeMove(&m_pMG->m_MoveList[nDepth][i],CurPosition);//产生该走法所对应子节点的哈希值
        type=MakeMove(&m_pMG->m_MoveList[nDepth][i]);            //产生子节点
        
        score=-AlphaBeta(nDepth-1,-beta,-alpha);//递归搜索子节点

        Hash_UnMakeMove(&m_pMG->m_MoveList[nDepth][i],type,CurPosition);//恢复当前节点的哈希值 
        UnMakeMove(&m_pMG->m_MoveList[nDepth][i],type);                //撤销子节点
        if(score>=beta)//beta剪枝
        {
            EnterHashTable(lower_bound,score,nDepth,side);//将节点下边界存入置换表
            return score;//返回下边界
        }

        if(score>alpha)
        {
            alpha=score;    //取最大值
            eval_is_exact=1;//设定确切值标志
            if(nDepth==m_nMaxDepth)
                m_cmBestMove=m_pMG->m_MoveList[nDepth][i];
        }
    }

    //将搜索结果放进置换表
    if(eval_is_exact) 
        EnterHashTable(exact,alpha,nDepth,side);      //确切值
    else 
        EnterHashTable(upper_bound,alpha,nDepth,side);//上边界

    return alpha;//返回最佳值/上界
}
예제 #12
0
int CNegaScout::NegaScout(int depth, int alpha, int beta)
{
	int Count,i;
	BYTE type;
	int a,b,t;
	int side;
	int score;
	
	i = IsGameOver(CurPosition, depth);
	if (i != 0)
		return i;
	
	side = (m_nMaxDepth-depth)%2;
	
	score = LookUpHashTable(alpha, beta, depth, side); 
	if (score != 66666) 
		return score;
	
	if (depth <= 0)	//叶子节点取估值
	{
		score = m_pEval->Eveluate(CurPosition, side );
		EnterHashTable(exact, score, depth, side );
		return score;
	}
	
	Count = m_pMG->CreatePossibleMove(CurPosition, depth, side);
	
	for (i=0;i<Count;i++) 
	{
		m_pMG->m_MoveList[depth][i].Score = 
			GetHistoryScore(&m_pMG->m_MoveList[depth][i]);
	}
	MergeSort(m_pMG->m_MoveList[depth], Count, 0);
	
	int bestmove=0;
	
    a = alpha;
    b = beta;
    int eval_is_exact = 0;
    for ( i = 0; i < Count; i++ ) 
	{
		Hash_MakeMove(&m_pMG->m_MoveList[depth][i], CurPosition);
		type = MakeMove(&m_pMG->m_MoveList[depth][i]);
		
		t = -NegaScout(depth-1 , -b, -a );
		
		if (t > a && t < beta && i > 0) 
		{
			a = -NegaScout (depth-1, -beta, -t );     /* re-search */
			eval_is_exact = 1;
			if(depth == m_nMaxDepth)
				m_cmBestMove = m_pMG->m_MoveList[depth][i];
			bestmove = i;
		}
		Hash_UnMakeMove(&m_pMG->m_MoveList[depth][i],type, CurPosition); 
		UnMakeMove(&m_pMG->m_MoveList[depth][i],type); 
		if (a < t)
		{
			eval_is_exact = 1;
			a=t;
			if(depth == m_nMaxDepth)
				m_cmBestMove = m_pMG->m_MoveList[depth][i];
		}
		if ( a >= beta ) 
		{
			EnterHashTable(lower_bound, a, depth,side);
			EnterHistoryScore(&m_pMG->m_MoveList[depth][i], depth);
			return a;
		}
		b = a + 1;                      /* set new null window */
	}
	
	EnterHistoryScore(&m_pMG->m_MoveList[depth][bestmove], depth);
	if (eval_is_exact) 
		EnterHashTable(exact, a, depth,side);
	else 
		EnterHashTable(upper_bound, a, depth,side);
	return a;
}
예제 #13
0
	void Player::HandleGameLogic()
	{
		assert(m_asteroidManager);

		if (m_gameTimeMs == 0)
		{
			m_game.GetSound().PlayRocketMotorSound(0.86f);
		}

		if (m_explosionTimeoutMs >= 0)
		{
			m_explosionTimeoutMs -= m_game.GetElapsedTimeThisFrameInMs();
			if (m_explosionTimeoutMs < 0)
				m_explosionTimeoutMs = 0;
		}
		else if (IsGameOver() == false)
		{
			m_gameTimeMs += m_game.GetElapsedTimeThisFrameInMs();
			m_lifeTimeMs += m_game.GetElapsedTimeThisFrameInMs();
		}

		if (m_explosionTimeoutMs2 >= 0)
		{
			m_explosionTimeoutMs2 -= m_game.GetElapsedTimeThisFrameInMs();
			if (m_explosionTimeoutMs2 < 0)
				m_explosionTimeoutMs2 = 0;
		}

		if (m_explosionTimeoutMs3 >= 0)
		{
			m_explosionTimeoutMs3 -= m_game.GetElapsedTimeThisFrameInMs();
			if (m_explosionTimeoutMs3 < 0)
				m_explosionTimeoutMs3 = 0;
		}

		if (m_cameraWobbelTimeoutMs > 0)
		{
			m_cameraWobbelTimeoutMs -= m_game.GetElapsedTimeThisFrameInMs();
			if (m_cameraWobbelTimeoutMs < 0)
				m_cameraWobbelTimeoutMs = 0;
		}

		if (IsGameOver())
			return;

		const float oldHealth = m_health;

		m_game.GetSound().ChangeRocketMotorPitchEffect(-0.24f + m_speed * 0.6f);

		// Check if too near to an asteroid. Check 3x3 sector in middle.
		if (CanControlRocket())
		{
			const float playerCollision = m_asteroidManager->PlayerAsteroidCollision(*this);
			if (playerCollision > 0.0f)
			{
				m_health -= 0.1f + playerCollision * 4.25f;
				if (oldHealth == 1.0f && m_health <= 0.0f)
				{
					m_health = 0.1f;
				}
			}
		}

		// Fuel
		if (m_fuel < 0.0f)
		{
			m_fuel = 0.0f;
			m_health -= m_game.GetMoveFactorPerSecond() / HurtFactorIfFuelIsEmpty;
		}

		// Show health low warning if health is getting very low
		if ((oldHealth >= 0.25f && m_health < 0.25f) ||
			(oldHealth >= 0.1f && m_health < 0.1f))
			m_showHealthWarningTimeoutMs = 8 * 1000;
		if (m_showHealthWarningTimeoutMs > 0)
		{
			m_showHealthWarningTimeoutMs -= m_game.GetElapsedTimeThisFrameInMs();
			m_showHealthWarningTimeoutMs = std::max(0.0f, m_showHealthWarningTimeoutMs);
		}

		// Die if health is 0 or lower
		if (m_health <= 0.0f)
		{
			m_health = 0.0f;

			m_explosionTimeoutMs = MaxExplosionTimeoutMs;

			// Reset everything for the player, all items and stuff
			ResetLifeValues();

			if (m_lifes > 0)
			{
				m_game.GetSound().PlayExplosionSound();
				m_lifes--;
			}
			else
			{
				m_victory = false;
				m_explosionTimeoutMs2 = MaxExplosionTimeoutMs * 1.6f;
				m_explosionTimeoutMs3 = MaxExplosionTimeoutMs * 2.1f;
				SetGameOverAndUploadHighscore();
				m_game.GetSound().StopRocketMotorSound();
				m_game.GetSound().PlayDefeatSound();
			}

			m_speed = MinSpeedWithoutItem;

			m_asteroidManager->KillAllInnerSectorAsteroids();
		}

		// Reached target?
		if (m_game.GetCamera().getPosition().z >= 
			m_asteroidManager->GetLevel().GetLength() * GameAsteroidManager::SectorDepth)
		{
			m_victory = true;

			// Life bonus
			m_score += m_lifes * 10000;

			// Time bonus
			const int maxGameTime = (m_asteroidManager->GetLevel().GetLength() / 2) * 1000;
			if (m_gameTimeMs < maxGameTime)
			{
				m_score += (int)(maxGameTime - m_gameTimeMs) / 10;
			}

			// Health & fuel bonus
			m_score += (int)(m_health * 3000);
			m_score += (int)(m_fuel * 4000);

			SetGameOverAndUploadHighscore();
			m_game.GetSound().StopRocketMotorSound();
			m_game.GetSound().PlayVictorySound();
		}
	}
예제 #14
0
int CNegaScout_TT_HH::NegaScout(int depth, int alpha, int beta)
{
	bool bIsSure = false;
	int Count,i;
	int a,b,t;
	int side;
	int score;
	int mtype = (m_nMaxDepth%2 == depth%2) ? (-1) : (1);
	CPublicToMakeMove ptmm;
	i = IsGameOver(CurPosition, depth,mtype);	
	if (i != 0)
		return i;
	
	side = (m_nMaxDepth-depth)%2;
	
	score = LookUpHashTable(alpha, beta, depth, side); 
	if (score != 6666666) 
	{
		G_nCountTTHH++;
		return score;
	}
	
	if (depth <= 0)	//叶子节点取估值
	{
		int Now1 = GetTickCount();
		score = m_pEval->Eveluate(CurPosition,mtype,(m_nMaxDepth-depth)%2);
		ETime += GetTickCount() - Now1;
		EnterHashTable(exact, score, depth, side );
		return score;
	}
	int Now2 = GetTickCount();
	Count = m_pMG->CreatePossibleMove(CurPosition, depth, mtype);
	GTime += GetTickCount() - Now2;
	if(1 == Count && depth == m_nMaxDepth)
	{
		m_cmBestMove = m_pMG->m_nMoveList[depth][0];
		return 0;
	}
	for (i=0;i<Count;i++) 
	{
		m_pMG->m_nMoveList[depth][i].Score = 
			GetHistoryScore(&m_pMG->m_nMoveList[depth][i]);
	}
	MergeSort(m_pMG->m_nMoveList[depth], Count, 0);
	
	int bestmove=-1;
	
    a = alpha;
    b = beta;
    int eval_is_exact = 0;
    for ( i = 0; i < Count; i++ ) 
	{
		Hash_MakeMove(&m_pMG->m_nMoveList[depth][i], CurPosition);
		MakeMove(&m_pMG->m_nMoveList[depth][i],ptmm);
		
		t = -NegaScout(depth-1 , -b, -a);
		
		if (t > a && t < beta && i > 0) 
		{
			a = -NegaScout (depth-1, -beta, -t);     /* re-search */
			eval_is_exact = 1;
			if(depth == m_nMaxDepth)
			{
				bIsSure = true;
				Hash_UnMakeMove(&m_pMG->m_nMoveList[depth][i],CurPosition); 
				UnMakeMove(&m_pMG->m_nMoveList[depth][i],ptmm); 
				m_cmBestMove = m_pMG->m_nMoveList[depth][i];
			}
			bestmove = i;
		}
		if(bIsSure == false)
		{
			Hash_UnMakeMove(&m_pMG->m_nMoveList[depth][i],CurPosition); 
			UnMakeMove(&m_pMG->m_nMoveList[depth][i],ptmm); 
		}
		else
		{
			bIsSure = false;
		}
		if (a < t)
		{
			eval_is_exact = 1;
			a=t;
			if(depth == m_nMaxDepth)
				m_cmBestMove = m_pMG->m_nMoveList[depth][i];
		}
		if ( a >= beta ) 
		{
			EnterHashTable(lower_bound, a, depth,side);
			EnterHistoryScore(&m_pMG->m_nMoveList[depth][i], depth);
			return a;
		}
		b = a + 1;                      /* set new null window */
	}
	if (bestmove != -1)
	EnterHistoryScore(&m_pMG->m_nMoveList[depth][bestmove], depth);
	if (eval_is_exact) 
		EnterHashTable(exact, a, depth,side);
	else 
		EnterHashTable(upper_bound, a, depth,side);
	return a;
}
예제 #15
0
int CNegaScout_TT_HH::NegaScout(int depth, int alpha, int beta){
	int count,i;
	int type;
	int a,b,t;
	int side;
	int score;
	
	i = IsGameOver(m_cur_position, depth);
	if (i != 0)
		return i;
	
	side = 1-(m_max_depth-depth)%2;
	
	score = m_tt->LookupHashTable(alpha, beta, depth, side);
	if (score != INVALID_SCORE && depth != m_max_depth){
		/*if (depth == m_max_depth){
			ChessMove move = new ChessMove();
			move.Move = m_tt.LookupBestMove(side);
			m_best_move = move;
		}*/
		return score;
	}
	
	if (depth <= 0)	
	{
		score = m_evaluator->Evaluate(m_cur_position, side == 0, depth);
		m_tt->EnterHashTable(EXACT, score, depth, side);
		return score;
	}
	
	//m_nMovecount = 0;
	count = m_move_generator->CreatePossibleMove(m_cur_position, m_moves, depth, side);
	AddMoves(count, depth);
	
	for (i = 0; i < count; ++i) 
	{
		m_move_list[depth][i].m_score = m_hh->GetHistoryScore(m_move_list[depth][i]);
	}
	m_hh->MergeSort(m_move_list[depth], count, false);
	
	int bestmove = -1;
	
    a = alpha;
    b = beta;
    int eval_is_exact = 0;
    for (i = 0; i < count; ++i){
		m_tt->HashMakeMove(m_move_list[depth][i], m_cur_position);
		type = MakeMove(m_move_list[depth][i]);

		t = -NegaScout(depth-1 , -b, -a);

		if (t > a && t < beta && i > 0){
			a = -NegaScout (depth-1, -beta, -t);     /* re-search */
			eval_is_exact = 1; 
			if(depth == m_max_depth){
				m_best_move = m_move_list[depth][i];
				//m_tt.EnterHashBestMove(m_best_move.Move, side);
			}
			bestmove = i; 
		}
		
		m_tt->HashUnmakeMove(m_move_list[depth][i], type, m_cur_position); 
		UnmakeMove(m_move_list[depth][i],type); 
		if (a < t){
			eval_is_exact = 1;
			a = t;
			if(depth == m_max_depth) {
				m_best_move = m_move_list[depth][i];
				//m_tt.EnterHashBestMove(m_best_move.Move, side);
			}
		}
		if (a >= beta) 
		{
			m_tt->EnterHashTable(LOWER_BOUND, a, depth, side);
			m_hh->EnterHistoryScore(m_move_list[depth][i], depth);
			return a;
		}
		b = a + 1;                      /* set new null window */
	}
	if (bestmove != -1)
		m_hh->EnterHistoryScore(m_move_list[depth][bestmove], depth);
	if (eval_is_exact != 0) 
		m_tt->EnterHashTable(EXACT, a, depth, side);
	else 
		m_tt->EnterHashTable(UPPER_BOUND, a, depth, side);
	return a;
}
예제 #16
0
	bool Player::CanControlRocket() const
	{
		return (m_lifeTimeMs > 3000) && 
			(m_explosionTimeoutMs < 0) && 
			(IsGameOver() == false);
	}
예제 #17
0
void ICP::DcGP(void) const
{
  // Go and play

  NoParameters(); if (!IsGameOver()) ProgMove(); else ReportGameOver();
}
예제 #18
0
int CPVS_Engine::PrincipalVariation(int nDepth, int alpha, int beta)
{
	int score;
	int Count,i;
	BYTE type;
	int best;

	i=IsGameOver(CurPosition, nDepth);
	if(i!=0)
		return i;

	//叶子节点取估值
	if(nDepth<=0)
		return m_pEval->Eveluate(CurPosition,(m_nMaxDepth-nDepth)%2,m_nUserChessColor);
	
	Count=m_pMG->CreatePossibleMove(CurPosition,nDepth,(m_nMaxDepth-nDepth)%2,m_nUserChessColor);
	if(nDepth==m_nMaxDepth)
	{
		//在根节点设定进度条
		m_pThinkProgress->SetRange(0,Count);
		m_pThinkProgress->SetStep(1);
	}
	
	type=MakeMove(&m_pMG->m_MoveList[nDepth][0]);   //产生第一个节点
	best=-PrincipalVariation(nDepth-1,-beta,-alpha);//使用全窗口搜索第一个节点
	UnMakeMove(&m_pMG->m_MoveList[nDepth][0],type); //撤销第一个节点 
	
	//靠近根节点保存最佳走法
	if(nDepth==m_nMaxDepth)
		m_cmBestMove=m_pMG->m_MoveList[nDepth][0];
	
	//从第二个节点起,对每一节点
	for(i=1;i<Count;i++)
	{
		if(nDepth==m_nMaxDepth)
			m_pThinkProgress->StepIt();//走进度条

		if(best<beta)//如果不能Beta剪枝
		{
			if(best>alpha)
				alpha=best;

			type=MakeMove(&m_pMG->m_MoveList[nDepth][i]);       //产生子个节点
			score=-PrincipalVariation(nDepth-1,-alpha-1,-alpha);//使用极窄窗搜索

			if(score>alpha && score<beta) 
			{
				best=-PrincipalVariation(nDepth-1,-beta,-score);//failhigh,重新搜索
				
				//靠近根节点保存最佳走法
				if(nDepth==m_nMaxDepth)
					m_cmBestMove=m_pMG->m_MoveList[nDepth][i];
			}
			else
				if(score>best)
				{
					best=score;//窄窗搜索命中
					if(nDepth==m_nMaxDepth)
						m_cmBestMove=m_pMG->m_MoveList[nDepth][i];
				}

			UnMakeMove(&m_pMG->m_MoveList[nDepth][i],type);//撤销子节点
		}
	}

	return best;//返回最佳值
}
int CNegaScout_TT_HH::NegaScout(int iDepth, int iAlpha, int iBeta)
{
	int iCount,iGameOver;
	BYTE byChess;
	int a,b,t;
	int iSide;
	int iScore;
	int i;
	
	iGameOver=IsGameOver(byCurChessBoard, iDepth);
	if(iGameOver!=0)
		return iGameOver;
	
	iSide=(m_iMaxDepth-iDepth)%2;//计算当前节点的类型,极大0/极小1
	
	iScore=LookUpHashTable(iAlpha,iBeta,iDepth,iSide);
	if(iScore!=66666)
		return iScore;
	
	if(iDepth<=0)//叶子节点取估值
	{
		iScore=m_pEval->Eveluate(byCurChessBoard,iSide);
		EnterHashTable(Exact,iScore,iDepth,iSide);//将估值存入置换表
		return iScore;
	}
	
	iCount=m_pMG->CreatePossibleMove(byCurChessBoard,iDepth,iSide,m_nUserChessColor);
	if(iDepth==m_iMaxDepth)
	{
		//在根节点设定进度条
		m_pThinkProgress->SetRange(0,iCount);
		m_pThinkProgress->SetStep(1);
	}

	for(i=0;i<iCount;i++)
		m_pMG->m_MoveList[iDepth][i].iScore=GetHistoryScore(&m_pMG->m_MoveList[iDepth][i]);
	MergeSort(m_pMG->m_MoveList[iDepth],iCount,0);
	
	int bestmove=-1;
	
    a=iAlpha;
    b=iBeta;

    int eval_is_exact=0;

    for(i=0;i<iCount;i++) 
	{
		if(iDepth==m_iMaxDepth)
			m_pThinkProgress->StepIt();//走进度条

		Hash_MakeMove(&m_pMG->m_MoveList[iDepth][i],byCurChessBoard);
		byChess=MakeMove(&m_pMG->m_MoveList[iDepth][i]);
		
		t=-NegaScout(iDepth-1,-b,-a);
		
		if(t>a && t<iBeta && i>0) 
		{
			//对于第一个后的节点,如果上面的搜索failhigh
			a=-NegaScout(iDepth-1,-iBeta,-t);//递归搜索子节点
			eval_is_exact=1;//设数据类型为精确值
			if(iDepth==m_iMaxDepth)
				m_cmBestMove=m_pMG->m_MoveList[iDepth][i];
			bestmove=i;
		}
		Hash_UnMakeMove(&m_pMG->m_MoveList[iDepth][i],byChess,byCurChessBoard); 
		UnMakeMove(&m_pMG->m_MoveList[iDepth][i],byChess); 
		if(a<t)
		{
			eval_is_exact=1;
			a=t;
			if(iDepth==m_iMaxDepth)
				m_cmBestMove=m_pMG->m_MoveList[iDepth][i];
		}
		if(a>=iBeta)
		{
			EnterHashTable(LowerBound,a,iDepth,iSide);
			EnterHistoryScore(&m_pMG->m_MoveList[iDepth][i],iDepth);
			return a;
		}
		b=a+1;//set new null window
	}
	if(bestmove!=-1)
		EnterHistoryScore(&m_pMG->m_MoveList[iDepth][bestmove],iDepth);
	if(eval_is_exact)
		EnterHashTable(Exact,a,iDepth,iSide);
	else
		EnterHashTable(UpperBound,a,iDepth,iSide);

	return a;
}