int NegamaxAlphaBetaSearcher::SearchBestPlay(const GameState& state, int depth) { std::vector<int> bestCell; int bestValue = -INFINITY; int bestPos = 0; #ifdef _DEBUG _searcherCounter = 0; #endif ResetTranspositionTable(); GameState tryState = state; int player_id = state.GetCurrentPlayer(); std::vector<MOVES_LIST> moves; int mc = tryState.FindMoves(player_id, moves); if(mc == 0) //遇到无路可走的情况,比如被对方逼着走禁手,可放弃一步 { return -1; } SortMoves(moves); for(int i = 0; i < mc; i++) { tryState.DoPutChess(moves[i].cell, player_id); int value = NegaMax(tryState, depth - 1, -INFINITY, INFINITY, player_id); tryState.UndoPutChess(moves[i].cell); if(value > bestValue) { bestValue = value; bestCell.clear(); bestCell.push_back(moves[i].cell); } else if(value == bestValue) { bestCell.push_back(moves[i].cell); } } if(bestCell.size() > 0) bestPos = rand() % bestCell.size(); #ifdef _DEBUG std::cout << "NegamaxSearcher " << _searcherCounter << " (with Alpha-Beta)" << std::endl; #endif return bestCell[bestPos]; }
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; }