public void PlaceObjective(ObjectiveRequirements objectiveRequirements, List<string> doorsToAvoidIds)
        {
            //Objectives are like clues in so much as they may be a 'clue' to lock a door

            var locksLockedByObjectiveIndices = GetLockIndicesByIds(objectiveRequirements.OpenLockId);
            if (locksLockedByObjectiveIndices.Count() != objectiveRequirements.OpenLockId.Count())
            {
                throw new ApplicationException("Lock for objective does not exist");
            }

            if (!GetValidRoomsToPlaceObjectiveOrClueForObjective(locksLockedByObjectiveIndices, doorsToAvoidIds).Contains(objectiveRequirements.Vertex))
                throw new ApplicationException("Can't place objective " + objectiveRequirements.Id + " at vertex " + objectiveRequirements.Vertex);

            var objective = BuildAndAddObjectiveToMap(objectiveRequirements);

            //An objective acts like
            //a) placing clues for the lock that depends on it
            //we include the objective itself for clarity (although this doesn't make a functional difference -
            //it's OK providing its parent doors are included)
            //IS THERE EVER A REASON TO INCLUDE THE OBJECTIVES IN THE DEPENDENCY TREE IF WE HAVE THEIR PARENTS?
            //WELL, IF WE SUBSEQUENTLY ADD CLUES THEN MAYBE YES
            var selfAndLockedItems = objective.OpenLockIndex.Union(new List<int> { objective.LockIndex });
            UpdateDependencyGraphWhenClueIsPlaced(objective.Vertex, selfAndLockedItems);
            //b) locking these clues with a virtual door that is the objective
            AddLockDependencyToExistingLocks(objective.LockIndex, objective.OpenLockIndex);
        }
        private Objective BuildAndAddObjectiveToMap(ObjectiveRequirements thisObj)
        {
            //Find the possible rooms that this objective could be placed in the real map
            var possibleRooms = mapNoCycles.roomMappingNoCycleToFullMap[thisObj.Vertex];

            int thisLockIndex = nextLockIndex;
            nextLockIndex++;

            var newObj = new Objective(thisObj.Vertex, thisObj.Id, thisLockIndex, GetLockIndicesByIds(thisObj.OpenLockId), thisObj.NumberOfCluesRequired, possibleRooms);

            //add to lock map
            objectiveMap.Add(thisLockIndex, newObj);
            lockDependencyGraph.AddVertex(thisLockIndex);

            //add to room map
            List<Objective> objListAtVertex;
            objectiveRoomMap.TryGetValue(thisObj.Vertex, out objListAtVertex);

            if (objListAtVertex == null)
            {
                objectiveRoomMap[thisObj.Vertex] = new List<Objective>();
            }

            objectiveRoomMap[thisObj.Vertex].Add(newObj);

            return newObj;
        }
 public void PlaceObjective(ObjectiveRequirements objectiveRequirements)
 {
     PlaceObjective(objectiveRequirements, new List<string>());
 }