Exemple #1
0
Direction MaxOfFewSearch::move(GameState& state, int ms
#ifdef DEBUG
							   , std::list<Direction>& moveSequence
#endif
  							  )
{
	Direction bestMove = DIR_END;
	double bestValue = -std::numeric_limits<double>::infinity();
	for(int i = 0; i < k_ || bestMove == DIR_END; ++i)
	{
		Direction direction = rand() % DIR_END;
		if(!state.canMove(direction))
			continue;
		
		state.move(direction);
		double value = heuristic_(state);
		state.undo(direction);
		
		if(value > bestValue || bestMove == DIR_END)
		{
			bestMove = direction;
			bestValue = value;
		}
	}
	
#ifdef DEBUG
	moveSequence.clear();
	moveSequence.push_front(bestMove);
#endif
	
	return bestMove;
}
/** This is the default implementation for extending and backing up a history sequence. */
SearchStatus BasicSearchStrategy::extendAndBackup(HistorySequence *sequence, long maximumDepth) {
    // We extend from the last entry in the sequence.    
    HistoryEntry *firstEntry = sequence->getLastEntry();
    long firstEntryId = firstEntry->getId();

    HistoryEntry *currentEntry = firstEntry;
    BeliefNode *currentNode = currentEntry->getAssociatedBeliefNode();

    SearchStatus status = SearchStatus::UNINITIALIZED;
    std::unique_ptr<StepGenerator> generator = factory_->createGenerator(status, currentEntry,
            currentEntry->getState(), currentNode->getHistoricalData());
    if (status == SearchStatus::UNINITIALIZED) {
        // Failure to initialize => return this status.
        return status;
    }

    // We check for some invalid possibilities in order to deal with them more cleanly.    
    Model *model = solver_->getModel();
    
    if (model->isTerminal(*currentEntry->getState())) {
        debug::show_message("WARNING: Attempted to continue sequence"
                " from a terminal state.");
        return SearchStatus::ERROR;
    } else if (currentEntry->getAction() != nullptr) {
        debug::show_message("ERROR: The last in the sequence already has an action!?");
        return SearchStatus::ERROR;
    } else if (currentEntry->immediateReward_ != 0) {
        debug::show_message("ERROR: The last in the sequence has a nonzero reward!?");
        return SearchStatus::ERROR;
    }

    while (true) {        
        if (currentNode->getDepth() >= maximumDepth) {
            // We've hit the depth limit, so we can't generate any more steps in the sequence.
            status = SearchStatus::OUT_OF_STEPS;            
            break;
        }
        // Step the search forward.
        Model::StepResult result = generator->getStep(currentEntry, currentEntry->getState(),
                currentNode->getHistoricalData());

        // Null action => stop the search.
        if (result.action == nullptr) {            
            break;
        }

        // Set the parameters of the current history entry using the ones we got from the result.
        currentEntry->immediateReward_ = result.reward;
        currentEntry->action_ = std::move(result.action);
        currentEntry->transitionParameters_ = std::move(result.transitionParameters);
        currentEntry->observation_ = std::move(result.observation);

        // Create the child belief node, and set the current node to be that node.
        BeliefNode *nextNode = currentNode->createOrGetChild(*currentEntry->action_,
                *currentEntry->observation_);
        currentNode = nextNode;

        // Now we create a new history entry and step the history forward.
        StateInfo *nextStateInfo = solver_->getStatePool()->createOrGetInfo(*result.nextState);
        currentEntry = sequence->addEntry();

        // Register the new history entry with its state, and with its associated belief node.
        currentEntry->registerState(nextStateInfo);
        currentEntry->registerNode(currentNode);

        if (result.isTerminal) {
            // Terminal state => search complete.            
            status = SearchStatus::FINISHED;
            break;
        }
    }   

    // OUT_OF_STEPS => must calculated a heuristic estimate.
    if (status == SearchStatus::OUT_OF_STEPS) {
        currentEntry->immediateReward_ = heuristic_(currentEntry, currentEntry->getState(),
                currentNode->getHistoricalData());
        status = SearchStatus::FINISHED;
    }

    if (status == SearchStatus::FINISHED) {
        // Now that we're finished, we back up the sequence.
        if (firstEntryId > 0 && currentEntry->getId() > firstEntryId) {
            // If we've extended a previously terminating sequence, we have to add a continuation.
            solver_->updateEstimate(firstEntry->getAssociatedBeliefNode(), 0, +1);
        }
        // We only do a partial backup along the newly generated part of the sequence.
        solver_->updateSequence(sequence, +1, firstEntryId);
    } else {
        // This shouldn't happen => print out an error message.
        if (status == SearchStatus::UNINITIALIZED) {
            debug::show_message("ERROR: Search algorithm could not initialize.");
        } else if (status == SearchStatus::INITIAL) {
            debug::show_message("ERROR: Search algorithm initialized but did not run!?");
        } else if (status == SearchStatus::ERROR) {
            debug::show_message("ERROR: Error in search algorithm!");
        } else {
            debug::show_message("ERROR: Invalid search status.");
        }
    }
    
    // Finally, we just return the status.
    return status;
}