private Node CheckAddArc() { return(new Sequence( new LeafAssert(() => (StoryArc)userInput == StoryArc.ADD), new LeafInvoke(() => currArc = StoryArc.ADD) )); }
private Node CheckFreeformArc() { return(new Sequence( new LeafAssert(() => (StoryArc)userInput == StoryArc.FREEFORM), new LeafInvoke(() => currArc = StoryArc.FREEFORM) )); }
public void Verify_MapToEntity_WithExistingEntity_AssignsStoryArcProperties() { // Arrange var mapper = new StoryArcMapper(); var model = StoryArcsMockingSetup.DoMockingSetupForStoryArcModel(); // Act IStoryArc existingEntity = new StoryArc { Id = 1 }; mapper.MapToEntity(model.Object, ref existingEntity); // Assert // <None> // Related Objects Assert.Equal(model.Object.PrimaryImageFileId, existingEntity.PrimaryImageFileId); Assert.Equal(model.Object.FirstIssueAppearanceId, existingEntity.FirstIssueAppearanceId); Assert.Equal(model.Object.PublisherId, existingEntity.PublisherId); // Associated Objects model.VerifyGet(x => x.MovieStoryArcs, Times.Once); //Assert.Equal(model.Object.MovieStoryArcs?.Count, existingEntity.MovieStoryArcs?.Count); model.VerifyGet(x => x.StoryArcAliases, Times.Once); //Assert.Equal(model.Object.StoryArcAliases?.Count, existingEntity.StoryArcAliases?.Count); model.VerifyGet(x => x.StoryArcIssues, Times.Once); //Assert.Equal(model.Object.StoryArcIssues?.Count, existingEntity.StoryArcIssues?.Count); model.VerifyGet(x => x.StoryArcsWritten, Times.Once); //Assert.Equal(model.Object.StoryArcsWritten?.Count, existingEntity.StoryArcsWritten?.Count); }
public StoryArc(StoryArc other) { this.Beats = new StoryBeat[other.Beats.Length]; for (int i = 0; i < other.Beats.Length; i++) this.Beats[i] = new StoryBeat(other.Beats[i]); this.Participants = new uint[other.Participants.Length]; Array.Copy( other.Participants, this.Participants, other.Participants.Length); }
public void Verify_Add_Should_AddTheEntityToTheContext() { // Arrange Mock<IDbSet<StoryArc>> mockSetStoryArcs; var mockContext = StoryArcsMockingSetup.DoMockingSetupForContext(false, out mockSetStoryArcs); var repository = new StoryArcsRepository(mockContext.Object); var storyArcs = new StoryArc { Active = true, CustomKey = "SALVATORE-RAA", }; // Act repository.Add(storyArcs); // Assert mockSetStoryArcs.Verify(x => x.Add(storyArcs), Times.Once); }
protected override int[] SatisfiesWithUsage(IEnumerable<EventPopulation> populations, StoryArc arc, StoryEvent toFillIn) { int[] result = new int[populations.Count()]; int index = 0; foreach (EventPopulation population in populations) { for (int i = 0; i < population.Count; i++) { result[index] += GetUsage(population[i].Id); } index++; } return result; }
public void Verify_Add_Should_AddTheEntityToTheContext() { // Arrange Mock <IDbSet <StoryArc> > mockSetStoryArcs; var mockContext = StoryArcsMockingSetup.DoMockingSetupForContext(false, out mockSetStoryArcs); var repository = new StoryArcsRepository(mockContext.Object); var storyArcs = new StoryArc { Active = true, CustomKey = "SALVATORE-RAA", }; // Act repository.Add(storyArcs); // Assert mockSetStoryArcs.Verify(x => x.Add(storyArcs), Times.Once); }
/// <summary> /// Calculates the usage of all participants of an arc. /// </summary> private void CalculateUsage(StoryArc arc) { this.usage = new Dictionary<uint, int>(); this.maxUsage = 0; this.minUsage = int.MaxValue; for (int i = 0; i < arc.Beats.Length; i++) { for (int j = 0; j < arc.Beats[i].Events.Length; j++) { StoryEvent evnt = arc.Beats[i].Events[j]; for (int k = 0; k < evnt.Participants.Length; k++) { usage[evnt.Participants[k]] = GetUsage(evnt.Participants[k]) + 1; maxUsage = Mathf.Max(maxUsage, usage[evnt.Participants[k]]); minUsage = Mathf.Min(minUsage, usage[evnt.Participants[k]]); } } } }
// Update is called once per frame void Update () { if(Input.GetKeyDown(KeyCode.P)) { // foreach (EventSignature sig in EventLibrary.Instance.GetSignatures()) // Debug.Log(sig.ToString()); actor0.Set (StateName.RoleActor, StateName.IsStanding); actor1.Set (StateName.RoleActor, StateName.IsStanding); chair.Set (StateName.RoleChair); table.Set (StateName.RoleTable, StateName.HoldingBall); ePlanner = new EventPlanner(stateSpaceManager); //, AuthoredEventManager.instance); EventSignature sitDown = EventLibrary.Instance.GetSignaturesOfType(typeof(SitDown)).First(); EventSignature take = EventLibrary.Instance.GetSignaturesOfType(typeof(Take)).First(); EventSignature give = EventLibrary.Instance.GetSignaturesOfType(typeof(Give)).First(); // Transition startEvent = new Transition(sitDown, actor0.Id, chair.Id); // Transition endEvent = new Transition(sitDown, actor1.Id, chair.Id); StoryArc arc = new StoryArc( new StoryBeat(new StoryEvent(give, uint.MaxValue, uint.MaxValue)), new StoryBeat(new StoryEvent(take, uint.MaxValue, uint.MaxValue)) ); //arc = ePlanner.completeStoryArcUpTo(arc.Beats.Length, arc, null, PlanSpace.All); if(ePlanner.plan.Count>0) ePlanner.plan.Pop (); while(ePlanner.plan.Count>0) { Transition cur = (Transition)ePlanner.plan.Pop(); Debug.Log(cur.eventSig.ToString() + "with arguments " + + cur.eventIndexToID(0)+ " "+ cur.eventIndexToID(1)); } foreach(StoryBeat b in arc.Beats) { Debug.Log("new Beat:"); foreach(StoryEvent e in b.Events) Debug.Log(e.Signature.ToString() + " with arguments: " + e.Participants[0] + e.Participants[1]); } } }
/// <summary> /// Simulate the state of the StateSpaceManager up to a certain Beat (specified by level) /// </summary> public void SimulateUpTo(StateSpaceManager stateSpaceManager, int startLevel, StoryArc story) { stateSpaceManager.resetGlobalState (); for(int i=0; i< startLevel; i++) { foreach(StoryEvent ev in story.Beats[i].Events) { Rules.ClearCache(); Transition implicitPopulated = new Transition(ev); implicitPopulated.populate(stateSpaceManager.globalState.worldstate); stateSpaceManager.changeStateToPostconditionsOf(implicitPopulated); } } }
/// <summary> /// returns a story arc where all implicit parameters are not set. /// </summary> public StoryArc depopulateArc (StoryArc arc) { foreach (StoryBeat b in arc.Beats) { foreach(StoryEvent e in b.Events) { if(e.Signature.ExplicitParameterCount < e.Participants.Length) { for(int i = e.Signature.ExplicitParameterCount; i < e.Participants.Length; i++) e.Participants[i] = uint.MaxValue; } } } return arc; }
public Storylet(string storyletName, StoryArc storyArc) { this.storyArc = storyArc; this.storyletName = storyletName; }
public Storylet() { this.storyArc = StoryArc.ACTI; }
public Storylet(string storyletName, StoryArc storyArc, PreConditions preConditions) { this.storyArc = storyArc; this.preconditions = preConditions; this.storyletName = storyletName; }
/// <summary> /// Plans through a whole StoryArc. The returned StoryArc keeps all the previous Events in it and is globally consistent. If that's not possible, an Error is thrown. /// </summary> public StoryArc planGlobal(StoryArc arc, IEnumerable<SmartObject> reducedObjectSpace, PlanSpace option, ref bool success) { return planGlobalUpTo (arc.Beats.Count (), arc, reducedObjectSpace, option, ref success); }
/// <summary> /// Returns a list of the "x" best Beatpopulations for the storybeat in arc "arc" at position "curPlanningFrom". /// </summary> private List<BeatPopulation> getBestPopulations(int curPlanningFrom, StoryArc arc, int x) { SimulateUpTo(stateSpaceManager, curPlanningFrom, arc); DefaultState planningFrom = stateSpaceManager.globalState; List<BeatPopulation> pop = createBeatPopulationSet(arc.Beats[curPlanningFrom]); int i = 0; List<BeatPopulation> xBest = new List<BeatPopulation> (); foreach (BeatPopulation bp in pop) { StoryBeat distanceDummy = bp.ToStoryBeat(); int punishCost; //This is used to punish Populations which don't satisfy the current WorldState DefaultState planningTo = stateSpaceManager.getGlobalStateBeforeBeat(planningFrom, distanceDummy, out punishCost); bp.cost = punishCost + domains.First().costBetweenWorldStates(ref planningFrom, ref planningTo, 0); if(bp.cost==0) { xBest.Add(bp); i++; if(i>=x) return xBest; } } pop = pop.OrderBy(o=>o.cost).ToList(); return pop; }
/// <summary> /// Plan across the entire event space. /// </summary> private void PlanGlobal() { Rules.ClearCache (); StoryArc arc = manager.ToStoryArc(); undoArc = arc; EventPlanner ePlanner = new EventPlanner(stateSpaceManager); bool success = false; arc = ePlanner.planGlobal(arc, rectangleForObject.Keys, OPTION, ref success); arc = ePlanner.depopulateArc (arc); //removes the implicit Paramteres again manager.ClearAllEvents(); manager.ImportStoryArc(arc); HighlightPlannedEvents(ePlanner.IDs); }
protected abstract int[] SatisfiesWithUsage(IEnumerable<EventPopulation> populations, StoryArc arc, StoryEvent toFillIn);
public int[] Satisfies(IEnumerable<EventPopulation> populations, StoryArc arc, StoryEvent toFillIn) { CalculateUsage(arc); return SatisfiesWithUsage(populations, arc, toFillIn); }
/// <summary> /// Plans through a StoryArc up to level "planningUpTo". The returned StoryArc keeps all the previous Events in it and is globally consistent. If that's not possible, an Error is thrown. /// </summary> public StoryArc planGlobalUpTo(int planningUpTo, StoryArc arc, IEnumerable<SmartObject> reducedObjectSpace, PlanSpace option, ref bool success) { Debug.Log ("Start Planning Global"); StoryArc newArc = new StoryArc (arc); //Stacks are used to save: The arcs we planned, from where we started, Beatlevel we plan to. So we can go back if something went wrong Stack<StoryArc> arcStack = new Stack<StoryArc> (); Stack<int> fromStack = new Stack<int> (); Stack<int> ToStack = new Stack<int> (); Stack<List<EventID>> IdListStack = new Stack<List<EventID>>(); Stack<List<BeatPopulation>> BeatPopulationSetStack = new Stack<List<BeatPopulation>> (); Stack<int> xthTryStack = new Stack<int> (); List<StoryBeat> newBeats = new List<StoryBeat>(); List<Transition> upgoing = new List<Transition> (); Transition cur; int maxFails = (planningUpTo * (planningUpTo - 1)) / 2; int maxTrys = 1; int nrFails = 0; int curPlanningFrom = 0; int curPlanningUpTo = planningUpTo; int curTry = 0; arcStack.Push (newArc); fromStack.Push (curPlanningFrom); ToStack.Push (curPlanningUpTo); xthTryStack.Push (curTry); domains.Add (new EventDomain (stateSpaceManager)); EventDomain domain = (EventDomain)domains [0]; if(PlanSpace.Reduced == option) stateSpaceManager.setListReduced (reducedObjectSpace.ToArray ()); stateSpaceManager.option = option; BeatPopulationSetStack.Push (getBestPopulations(curPlanningFrom, arc, maxTrys)); List<Transition> bestChoice = new List<Transition>(); // while "from" isn't the last Beat yet we continue planning while(ToStack.Peek() != fromStack.Peek()) { arc = arcStack.Peek(); curPlanningFrom = fromStack.Peek(); curPlanningUpTo = ToStack.Peek (); //-------------------------------- //PLANNING WITH PARAMETERFILLING curTry = xthTryStack.Peek(); StoryBeat BeatWithNewPop = BeatPopulationSetStack.Peek().ElementAt(curTry).ToStoryBeat(); StoryBeat[] remainingBeats = arc.Beats; remainingBeats[curPlanningFrom] = BeatWithNewPop; arc = new StoryArc(remainingBeats); //-------------------------------- //Convert the EndEvents from Events to Transitions endEvents = arc.Beats[curPlanningFrom].Events; endTransitions = new Transition[endEvents.Length]; for (int i=0;i<endEvents.Length;i++) endTransitions[i] = new Transition(endEvents[i]); if(curTry==0) bestChoice = endTransitions.ToList(); //Adding the relevant states of the end-Transitions, so heuristic only depending on these states can be used to compute plan domain.relevanceMasks = stateSpaceManager.createRelevanceMasks(endTransitions); planner.init (ref domains, MAXNODES); stateSpaceManager.resetGlobalState (); SimulateUpTo (stateSpaceManager, curPlanningFrom, arc); //Set start state to the state after the Beat we are planning from DefaultState startState = new DefaultState (stateSpaceManager.globalState); //end state is set to the state after the startEvents and the necessary preconditions changed DefaultState endState = new DefaultState (startState); List<RelevanceMask> relev = domain.relevanceMasks.ToList(); //end state is changed according to the upgoing conditions for global consistency foreach(Transition t in upgoing) { endState = stateSpaceManager.getGlobalStateBeforeEvent(endState,t); foreach(RelevanceMask mask in stateSpaceManager.createRelevanceMasks(t)) relev.Add(mask); } domain.relevanceMasks = relev.ToArray(); //conditions from upgoing are overwritten if they conflict with preconditions for current beat foreach(Transition t in endTransitions) { endState = stateSpaceManager.getGlobalStateBeforeEvent(endState,t); } stateSpaceManager.endTransitions = endTransitions.ToList(); foreach(Transition t in upgoing) { stateSpaceManager.endTransitions.Add(t); } plan.Clear(); success = planner.computePlan (ref startState, ref endState, ref plan, TIMEOUT); //--------------------------------------------------------------- if (success) { plan.Pop (); //pop start event upgoing.Clear(); int oldNrBeats = arc.Beats.Count(); int newNrEvents = plan.Count; //add Beats up to the starting level of planning for(int i=0; i<curPlanningFrom; i++) { newBeats.Add(arc.Beats[i]); } //add planned beats List<EventID> IdList = new List<EventID>(); while(plan.Count>0) { cur = ((Transition)plan.Pop()); newBeats.Add(new StoryBeat(cur.ToStoryEvent())); IdList.Add(newBeats.Last().Events.First().ID); } //add Beats after the planning for(int i=curPlanningFrom; i<oldNrBeats; i++) { newBeats.Add(arc.Beats[i]); } newArc = new StoryArc(newBeats.ToArray()); IdListStack.Push(IdList); arcStack.Push(newArc); fromStack.Push(curPlanningFrom + 1 + newNrEvents); ToStack.Push (curPlanningUpTo + newNrEvents); if(fromStack.Peek() != ToStack.Peek()) BeatPopulationSetStack.Push (getBestPopulations(fromStack.Peek(), newArc, maxTrys)); xthTryStack.Push(0); newBeats.Clear(); upgoing.Clear(); } else { if(curTry + 1>=maxTrys || curTry >= BeatPopulationSetStack.Peek().Count-1) { nrFails++; //Propagate the Transitions we need to consider upwards if planning fails if (upgoing.Count == 0) foreach(Transition t in bestChoice) upgoing.Add (t); if(fromStack.Peek() > 0) { IdListStack.Pop (); fromStack.Pop (); arcStack.Pop(); ToStack.Pop (); BeatPopulationSetStack.Pop(); xthTryStack.Pop(); } if(fromStack.Peek()==0 || nrFails>maxFails) { return arc; } } else { int temp = xthTryStack.Peek(); temp++; xthTryStack.Pop(); xthTryStack.Push (temp); } } } List<EventID> IDsFromOneLevel; while(IdListStack.Count > 0) { IDsFromOneLevel = IdListStack.Pop (); foreach(EventID i in IDsFromOneLevel) IDs.Add(i); } return arcStack.Peek(); }
/// <summary> /// Imports the given story arc, converting the story events within to event stubs. /// </summary> public void ImportStoryArc(StoryArc arc) { for (int i = 0; i < arc.Beats.Length; i++) { ImportStoryBeat(arc.Beats[i], i); } }
/// <summary> /// Create a new StoryArcRunner with the given StoryArc, the given dependencies /// and the given CameraArgumentManager. /// </summary> /// <param name="arc">The given StoryArc.</param> /// <param name="dependencies">The termination dependencies.</param> /// <param name="cameraManager">The camera manager.</param> /// <returns>Returns a new StoryArcRunner initialized with the given values.</returns> public static StoryArcRunner GetRunner(StoryArc arc, Dictionary<EventID, List<EventID>> dependencies, CameraArgumentManager cameraManager) { //Create a new GameObject to hold the StoryArcRunner. We have it as a MonoBehavior to make the //camera work smoothly GameObject newGO = new GameObject("Runner"); StoryArcRunner runner = newGO.AddComponent<StoryArcRunner>(); runner.beats = new StoryBeatInstance[arc.Beats.Length]; for (int i = 0; i < arc.Beats.Length; i++) runner.beats[i] = new StoryBeatInstance(arc.Beats[i], dependencies); runner.arc = arc; runner.cameraManager = cameraManager; return runner; }