bool AlphaBetaSearch::getNextMoveVec(IDType playerToMove, MoveArray & moves, const size_t & moveNumber, const TTLookupValue & TTval, const size_t & depth, std::vector<Action> & moveVec) const
{
    if (_params.maxChildren() && (moveNumber >= _params.maxChildren()))
    {
        return false;
    }

    // if this move is beyond the first, check to see if we are only using a single move
    if (moveNumber == 1)
    {
        // if we are player modeling, we should have only generated the first move
        if (_params.playerModel(playerToMove) != PlayerModels::None)
	    {
            // so return false
		    return false;
	    }

	    // if there is a transposition table entry for this state
	    if (TTval.found())
	    {
		    // if there was a valid move found with higher depth, just do that one
		    const AlphaBetaMove & abMove = getAlphaBetaMove(TTval, playerToMove);
		    if ((TTval.entry()->getDepth() >= depth) && abMove.isValid())
		    {
                // so return false
			    return false;
		    }
	    }
    }

	const Array<std::vector<Action>, Constants::Max_Ordered_Moves> & orderedMoves(_orderedMoves[depth]);
    moveVec.clear();
   
	// if this move should be from the ordered list, return it from the list
	if (moveNumber < orderedMoves.size())
	{
        moveVec.assign(orderedMoves[moveNumber].begin(), orderedMoves[moveNumber].end());
        return true;
	}
	// otherwise return the next move vector starting from the beginning
	else
	{
        if (moves.hasMoreMoves())
        {
            moves.getNextMoveVec(moveVec);
            return true;
        }
        else
        {
            return false;
        }
	}
}
Пример #2
0
const MoveTuple AlphaBeta::getNumMoveTuples(MoveArray & moves, const TTLookupValue & TTval, const IDType & playerToMove, const size_t & depth) const
{
	// if we are doing opponent modeling, there is just one move to do
	if (_params.usePlayerModel(playerToMove))
	{
		return 1;
	}

	// if there is a transposition table entry for this state
	if (TTval.found())
	{
		// if there was a valid move found with higher depth, just do that one
		const AlphaBetaMove & abMove = getAlphaBetaMove(TTval, playerToMove);
		if ((TTval.entry()->getDepth() >= depth) && abMove.isValid() && (abMove.moveTuple() < moves.numMoveTuples()))
		{
			return 1;
		}
	}

	// otherwise, it's the number of possible moves + number of ordered moves
	return moves.numMoveTuples();
}
Пример #3
0
void AlphaBeta::generateOrderedMoves(GameState & state, MoveArray & moves, const TTLookupValue & TTval, const IDType & playerToMove, const size_t & depth)
{
	// get the array where we will store the moves and clear it
	Array<MoveTuple, Search::Constants::Max_Ordered_Moves> & orderedMoves(_orderedMoves[depth]);
	orderedMoves.clear();

	// if we are using opponent modeling, get the move and then return, we don't want to put any more moves in
	if (_params.usePlayerModel(playerToMove))
	{
		MoveTuple playerModelMove = _params.getPlayer(playerToMove)->getMoveTuple(state, moves);
		orderedMoves.add(playerModelMove);
		return;
	}

	// if there is a transposition table entry for this state
	if (TTval.found())
	{
		// get the abMove we stored for this player
		const AlphaBetaMove & abMove = getAlphaBetaMove(TTval, playerToMove);

		// here we get an incorrect move from the transposition table
		if (abMove.moveTuple() >= moves.numMoveTuples())
		{
			HashType h0 = state.calculateHash(0);
			HashType h1 = state.calculateHash(1);

			MoveArray moves2;
			state.generateMoves(moves2, playerToMove);
			// figure out why
			//fprintf(stderr, "Something very wrong, this tuple (%d) doesn't exist, only (%d) moves\n", (int)abMove.moveTuple(), (int)moves.numMoveTuples());
		}

		_results.ttFoundCheck++;

		// Two checks:
		// 1) Is the move 'valid' ie: was it actually set inside the TT
		// 2) Is it a valid tuple number for this move set? This guards against double
		//    hash collision errors. Even if it is a collision, this is just a move
		//    ordering, so no errors should occur.
		if (abMove.isValid() && (abMove.moveTuple() < moves.numMoveTuples()))
		{
			orderedMoves.add(abMove.moveTuple());
			_results.ttMoveOrders++;
			return;
		}
		else
		{
			_results.ttFoundButNoMove++;
		}
	}

	// if we are using script modeling, insert the script moves we want
	if (_params.useScriptMoveFirst())
	{
		for (size_t s(0); s<_allScripts.size(); s++)
		{
			MoveTuple scriptMove = _allScripts[s]->getMoveTuple(state, moves);

			orderedMoves.addUnique(scriptMove);
		}
	}
}