std::vector<GameState> AStarAlgorithm::FindPath(const GameRules &gameRules, GameState &startState)
{
	GameState finalState = gameRules.GetFinalState();
 	std::unordered_set<UINT64> openStatesHashTable, closedStatesHashTable;
	startState.SetG(0);
	startState.SetH(gameRules.CalculateH(startState));
	openStatesHeap.push(&startState);
	openStatesHashTable.insert(startState.GetHash());

	while (!openStatesHeap.empty())
	{
		GameState* currentState = openStatesHeap.top();
		if (*currentState == finalState)
		{
			return GetPath(*currentState, finalState);
		}
		openStatesHeap.pop();
		closedStatesHashTable.insert(currentState->GetHash());
		std::vector<GameState*> neighborStates = gameRules.GetNeighborStates(currentState);
		for (std::vector<GameState*>::const_iterator currentNeighborIterator = neighborStates.begin(); 
			currentNeighborIterator != neighborStates.end(); ++currentNeighborIterator)
		{
			GameState *currentNeighbor = *currentNeighborIterator;
			currentNeighbor->SetH(gameRules.CalculateH(*currentNeighbor));
			if (closedStatesHashTable.find(currentNeighbor->GetHash()) != closedStatesHashTable.end())	
				continue;
			if (openStatesHashTable.find(currentNeighbor->GetHash()) == openStatesHashTable.end())
			{
				openStatesHeap.push(currentNeighbor);
				openStatesHashTable.insert(currentNeighbor->GetHash());
			}
			else
			{
				if (currentState->GetG() + 1 < currentNeighbor->GetG())
				{
					currentNeighbor->SetParent(currentState);
					currentNeighbor->SetG(currentState->GetG() + 1);
				}
			}
		}
	}
	return std::vector<GameState>();
}
int NegamaxAlphaBetaSearcher::NegaMax(GameState& state, int depth, int alpha, int beta, int max_player_id)
{
    int alphaOrig = alpha;
#if 0
    unsigned int state_hash = state.GetHash();

    //查询置换表
    TT_ENTRY ttEntry = { 0 };
    if(LookupTranspositionTable(state_hash, ttEntry) && (ttEntry.depth >= depth))
    {
        if(ttEntry.flag == TT_FLAG_EXACT)
            return ttEntry.value;
        else if(ttEntry.flag == TT_FLAG_LOWERBOUND)
            alpha = std::max(alpha, ttEntry.value);
        else// if(ttEntry.flag == TT_FLAG_UPPERBOUND)
            beta = std::min(beta, ttEntry.value);

        if(beta <= alpha)
            return ttEntry.value;
    }
#endif
    if(state.IsGameOver() || (depth == 0))
    {
#ifdef _DEBUG
        _searcherCounter++;
#endif
        return EvaluateNegaMax(state, max_player_id);
    }
    
    state.SwitchPlayer();
    int score = -INFINITY;
    int player_id = state.GetCurrentPlayer();

    std::vector<MOVES_LIST> moves;
    int mc = state.FindMoves(player_id, moves);
    SortMoves(moves);
    for(int i = 0; i < mc; i++)
    {
        state.DoPutChess(moves[i].cell, player_id);
        int value = -NegaMax(state, depth - 1, -beta, -alpha, max_player_id);
        state.UndoPutChess(moves[i].cell);
        score = std::max(score, value);
        alpha = std::max(alpha, value);
        if(beta <= alpha)
            break;
    }

    state.SwitchPlayer();
#if 0
    //写入置换表
    ttEntry.value = score;
    if(score <= alphaOrig)
        ttEntry.flag = TT_FLAG_UPPERBOUND;
    else if(score >= beta)
        ttEntry.flag = TT_FLAG_LOWERBOUND;
    else
        ttEntry.flag = TT_FLAG_EXACT;

    ttEntry.depth = depth;
    StoreTranspositionTable(state_hash, ttEntry);
#endif
    return score;
}