Esempio n. 1
0
	int NegaMax  (const uint64_t P, const uint64_t O, uint64_t& NodeCounter)
	{
		const uint64_t empties = Empties(P, O);
		if (empties == 4)
			return NegaMax_4(P, O, NodeCounter);

		uint64_t flipped;
		uint64_t BitBoardPossible = PossibleMoves(P, O);
		unsigned long Move;
		int Score = -64;
		NodeCounter++;

		if (!BitBoardPossible){
			if (HasMoves(O, P))
				return -NegaMax(O, P, NodeCounter);
			else //Game is over
				return EvalGameOver(P, empties);
		}

		while (BitBoardPossible)
		{
			Move = BitScanLSB(BitBoardPossible);
			RemoveLSB(BitBoardPossible);
			flipped = flip(P, O, Move);
			Score = MAX(Score, -NegaMax(O ^ flipped, P ^ (1ULL << Move) ^ flipped, NodeCounter));
		}

		return Score;
	}
Esempio n. 2
0
/*
因为没有传入side参数,因此只适合计算黑子的策略
*/
int NegaMaxEngine::NegaMax(int depth)
{
	int bestScore = -INFINITY;
	int side = (m_nSearchDepth - depth)%2;
	int childNodeCount, score;

	if(depth <= 0)
	{
		return m_pEval->Evaluate(CurPosition, side);
	}
	childNodeCount = m_pMG->CreatePossibleMove(CurPosition, depth , side);
	if(childNodeCount <= 0) return NOMORE_MOVE;
	for(int i=0; i<childNodeCount; ++i)
	{
		MakeMove(&m_pMG->m_MoveList[depth][i], side);
		score = -NegaMax(depth  -1);
		UnMakeMove(&m_pMG->m_MoveList[depth][i]);
		if(score > bestScore)
		{
			bestScore = score;
			if(depth == m_nSearchDepth)
			{
				m_cmBestMove = m_pMG->m_MoveList[depth][i];
			}
		}
	}
	return bestScore;
}
Esempio n. 3
0
void NegaMaxEngine::SearchAGoodMove(BYTE position[][GRID_NUM], int Type, int &x, int &y)
{
	memcpy(CurPosition, position, GRID_COUNT);
	NegaMax(m_nSearchDepth);
	x = m_cmBestMove.StonePos.x;
	y = m_cmBestMove.StonePos.y;
	return;
}
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;
}