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; }