public override IWorkshopTree Get(ActionSet actionSet, IWorkshopTree[] parameterValues, object[] additionalParameterData) { Element effectArray = (Element)parameterValues[0]; double destroyPerLoop = (double)additionalParameterData[1]; ForeachBuilder foreachBuilder = new ForeachBuilder(actionSet, effectArray); for (int i = 0; i < destroyPerLoop; i++) { if (i == 0) { actionSet.AddAction( Element.Part <A_DestroyEffect>(foreachBuilder.IndexValue) ); } else { actionSet.AddAction( Element.Part <A_DestroyEffect>(Element.Part <V_ValueInArray>(effectArray, foreachBuilder.Index + i)) ); } } foreachBuilder.Finish(); return(null); }
protected override void Assign() { potentialDestinations = actionSet.VarCollection.Assign("Dijkstra: Potential Destinations", actionSet.IsGlobal, false); actionSet.AddAction(potentialDestinations.SetVariable(new V_EmptyArray())); chosenDestination = actionSet.VarCollection.Assign("Dijkstra: Chosen Destination", actionSet.IsGlobal, assignExtended); ForeachBuilder getClosestNodes = new ForeachBuilder(actionSet, destinations); actionSet.AddAction(potentialDestinations.ModifyVariable(Operation.AppendToArray, GetClosestNode(actionSet, Nodes, getClosestNodes.IndexValue))); getClosestNodes.Finish(); }
override protected void Assign() { closestNodesToPlayers = actionSet.VarCollection.Assign("Dijkstra: Closest nodes", actionSet.IsGlobal, false); actionSet.AddAction(closestNodesToPlayers.SetVariable(Element.Part <V_EmptyArray>())); ForeachBuilder getClosestNodes = new ForeachBuilder(actionSet, players); actionSet.AddAction(closestNodesToPlayers.ModifyVariable(Operation.AppendToArray, GetClosestNode(actionSet, Nodes, getClosestNodes.IndexValue))); getClosestNodes.Finish(); }
protected override void Init() { // Assign an array that will be used to store the closest node to each player. _closestNodesToPlayers = ActionSet.VarCollection.Assign("Dijkstra: Closest nodes", ActionSet.IsGlobal, false); ActionSet.AddAction(_closestNodesToPlayers.SetVariable(EmptyArray())); // Loop through each player and get the closest node. ForeachBuilder getClosestNodes = new ForeachBuilder(ActionSet, _players); ActionSet.AddAction(_closestNodesToPlayers.ModifyVariable(Operation.AppendToArray, NodeFromPosition(getClosestNodes.IndexValue))); getClosestNodes.Finish(); }
override protected void GetResult() { ForeachBuilder assignPlayerPaths = new ForeachBuilder(actionSet, players); assignPlayerPaths.Setup(); IndexReference finalPath = actionSet.VarCollection.Assign("Dijkstra: Final Path", actionSet.IsGlobal, false); Backtrack( Element.Part <V_ValueInArray>( closestNodesToPlayers.GetVariable(), assignPlayerPaths.Index ), finalPath ); Pathfind(actionSet, pathfinderInfo, (Element)finalPath.GetVariable(), assignPlayerPaths.IndexValue, position); assignPlayerPaths.Finish(); }
public override IWorkshopTree Get(ActionSet actionSet, IWorkshopTree[] parameterValues) { if (parameterValues[0] is V_Array ar) { if (ar.ParameterValues.All(element => element is V_Number)) { return(new V_Number(ar.ParameterValues.Average(element => ((V_Number)element).Value))); } else if (ar.ParameterValues.All(element => ((Element)element).ConstantSupported <Vertex>())) { Vertex sum_ = new Vertex(); foreach (IWorkshopTree vert in ar.ParameterValues) { sum_ += (Vertex)((Element)vert).GetConstant(); } return((sum_ / ar.ParameterValues.Length).ToVector()); } else { Element sum_ = (Element)ar.ParameterValues[0]; for (int i = 1; i < ar.ParameterValues.Length; i++) { sum_ += (Element)ar.ParameterValues[i]; } return(sum_ / ar.ParameterValues.Length); } } else if (parameterValues[0] is V_EmptyArray) { return(new V_Number(0)); } else { IndexReference array = actionSet.VarCollection.Assign("_arrayToAverage", actionSet.IsGlobal, true); IndexReference sum = actionSet.VarCollection.Assign("_sumOfAverageArray", actionSet.IsGlobal, true); actionSet.AddAction(array.SetVariable((Element)parameterValues[0])); actionSet.AddAction(sum.SetVariable(0)); ForeachBuilder builder = new ForeachBuilder(actionSet, array.GetVariable()); actionSet.AddAction(sum.ModifyVariable(Operation.Add, builder.IndexValue)); builder.Finish(); return((Element)sum.GetVariable() / Element.Part <V_CountOf>(array.GetVariable())); } }
public void Get() { var firstNode = GetClosestNode(actionSet, Nodes, Source); Assign(); current = actionSet.VarCollection.Assign("Dijkstra: Current", actionSet.IsGlobal, assignExtended); distances = actionSet.VarCollection.Assign("Dijkstra: Distances", actionSet.IsGlobal, false); unvisited = actionSet.VarCollection.Assign("Dijkstra: Unvisited", actionSet.IsGlobal, false); IndexReference connectedSegments = actionSet.VarCollection.Assign("Dijkstra: Connected Segments", actionSet.IsGlobal, assignExtended); IndexReference neighborIndex = actionSet.VarCollection.Assign("Dijkstra: Neighbor Index", actionSet.IsGlobal, assignExtended); IndexReference neighborDistance = actionSet.VarCollection.Assign("Dijkstra: Distance", actionSet.IsGlobal, assignExtended); parentArray = GetParentArray(); if (useAttributes) { parentAttributeInfo = GetParentAttributeArray(); } // Set the current variable as the first node. actionSet.AddAction(current.SetVariable(firstNode)); SetInitialDistances(actionSet, distances, (Element)current.GetVariable()); SetInitialUnvisited(); actionSet.AddAction(Element.Part <A_While>(LoopCondition())); // Invoke LoopStart OnLoop.Invoke(actionSet); // Get neighboring indexes actionSet.AddAction(connectedSegments.SetVariable(GetConnectedSegments( (Element)current.GetVariable() ))); // Loop through neighboring indexes ForeachBuilder forBuilder = new ForeachBuilder(actionSet, connectedSegments.GetVariable()); // Invoke OnConnectLoop OnConnectLoop.Invoke(actionSet); actionSet.AddAction(ArrayBuilder <Element> .Build( // Get the index from the segment data neighborIndex.SetVariable( Element.Part <V_FirstOf>(Element.Part <V_FilteredArray>( BothNodes(forBuilder.IndexValue), new V_Compare( new V_ArrayElement(), Operators.NotEqual, current.GetVariable() ) )) ), // Get the distance between the current and the neighbor index. neighborDistance.SetVariable( Element.Part <V_DistanceBetween>( Nodes[(Element)neighborIndex.GetVariable()], Nodes[(Element)current.GetVariable()] ) + ((Element)distances.GetVariable())[(Element)current.GetVariable()] ) )); // Set the current neighbor's distance if the new distance is less than what it is now. actionSet.AddAction(Element.Part <A_If>(Element.Part <V_Or>( new V_Compare( ((Element)distances.GetVariable())[(Element)neighborIndex.GetVariable()], Operators.Equal, new V_Number(0) ), (Element)neighborDistance.GetVariable() < ((Element)distances.GetVariable())[(Element)neighborIndex.GetVariable()] ))); actionSet.AddAction(distances.SetVariable((Element)neighborDistance.GetVariable(), null, (Element)neighborIndex.GetVariable())); actionSet.AddAction(parentArray.SetVariable((Element)current.GetVariable() + 1, null, (Element)neighborIndex.GetVariable())); if (useAttributes) { if (!reverseAttributes) { actionSet.AddAction(parentAttributeInfo.SetVariable( value: Element.TernaryConditional( new V_Compare( current.GetVariable(), Operators.Equal, Node1(forBuilder.IndexValue) ), Node2Attribute(forBuilder.IndexValue), Node1Attribute(forBuilder.IndexValue) ), index: neighborIndex.Get() )); } else { actionSet.AddAction(parentAttributeInfo.SetVariable( value: Element.TernaryConditional( new V_Compare( current.GetVariable(), Operators.Equal, Node1(forBuilder.IndexValue) ), Node1Attribute(forBuilder.IndexValue), Node2Attribute(forBuilder.IndexValue) ), index: neighborIndex.Get() )); } } // End the if. actionSet.AddAction(new A_End()); // End the for. forBuilder.Finish(); // Remove the current node from the unvisited array. actionSet.AddAction(unvisited.ModifyVariable(Operation.RemoveFromArrayByValue, (Element)current.GetVariable())); EndLoop(); actionSet.AddAction(current.SetVariable(LowestUnvisited(Nodes, (Element)distances.GetVariable(), (Element)unvisited.GetVariable()))); actionSet.AddAction(new A_End()); GetResult(); actionSet.AddAction(ArrayBuilder <Element> .Build( current.SetVariable(0), distances.SetVariable(0), connectedSegments.SetVariable(0), neighborIndex.SetVariable(0), neighborDistance.SetVariable(0), parentArray.SetVariable(0), parentAttributeInfo.SetVariable(0) )); }
public void Get() { var firstNode = ClosestNodeToPosition(Nodes, position); Assign(); current = actionSet.VarCollection.Assign("Dijkstra: Current", actionSet.IsGlobal, true); IndexReference distances = actionSet.VarCollection.Assign("Dijkstra: Distances", actionSet.IsGlobal, false); unvisited = actionSet.VarCollection.Assign("Dijkstra: Unvisited", actionSet.IsGlobal, false); IndexReference connectedSegments = actionSet.VarCollection.Assign("Dijkstra: Connected Segments", actionSet.IsGlobal, true); IndexReference neighborIndex = actionSet.VarCollection.Assign("Dijkstra: Neighbor Index", actionSet.IsGlobal, true); IndexReference neighborDistance = actionSet.VarCollection.Assign("Dijkstra: Distance", actionSet.IsGlobal, true); parentArray = actionSet.VarCollection.Assign("Dijkstra: Parent Array", actionSet.IsGlobal, false); // Set the current variable as the first node. actionSet.AddAction(current.SetVariable(firstNode)); SetInitialDistances(actionSet, distances, (Element)current.GetVariable()); SetInitialUnvisited(actionSet, Nodes, unvisited); WhileBuilder whileBuilder = new WhileBuilder(actionSet, LoopCondition()); whileBuilder.Setup(); // Get neighboring indexes actionSet.AddAction(connectedSegments.SetVariable(GetConnectedSegments( Nodes, Segments, (Element)current.GetVariable(), reversed ))); // Loop through neighboring indexes ForeachBuilder forBuilder = new ForeachBuilder(actionSet, connectedSegments.GetVariable()); forBuilder.Setup(); actionSet.AddAction(ArrayBuilder <Element> .Build( // Get the index from the segment data neighborIndex.SetVariable( Element.TernaryConditional( new V_Compare( current.GetVariable(), Operators.NotEqual, Node1(forBuilder.IndexValue) ), Node1(forBuilder.IndexValue), Node2(forBuilder.IndexValue) ) ), // Get the distance between the current and the neighbor index. neighborDistance.SetVariable( Element.Part <V_DistanceBetween>( Nodes[(Element)neighborIndex.GetVariable()], Nodes[(Element)current.GetVariable()] ) + ((Element)distances.GetVariable())[(Element)current.GetVariable()] ) )); // Set the current neighbor's distance if the new distance is less than what it is now. IfBuilder ifBuilder = new IfBuilder(actionSet, (Element)neighborDistance.GetVariable() < WorkingDistance((Element)distances.GetVariable(), (Element)neighborIndex.GetVariable()) ); ifBuilder.Setup(); actionSet.AddAction(distances.SetVariable((Element)neighborDistance.GetVariable(), null, (Element)neighborIndex.GetVariable())); actionSet.AddAction(parentArray.SetVariable((Element)current.GetVariable() + 1, null, (Element)neighborIndex.GetVariable())); ifBuilder.Finish(); forBuilder.Finish(); actionSet.AddAction(ArrayBuilder <Element> .Build( // Add the current to the visited array. unvisited.SetVariable(Element.Part <V_RemoveFromArray>(unvisited.GetVariable(), current.GetVariable())), // Set the current node as the smallest unvisited. current.SetVariable(LowestUnvisited(Nodes, (Element)distances.GetVariable(), (Element)unvisited.GetVariable())) )); whileBuilder.Finish(); GetResult(); actionSet.AddAction(ArrayBuilder <Element> .Build( current.SetVariable(-1), distances.SetVariable(-1), connectedSegments.SetVariable(-1), neighborIndex.SetVariable(-1), neighborDistance.SetVariable(-1), parentArray.SetVariable(-1) )); Reset(); }
public void Get() { IndexReference neighborIndex = actionSet.VarCollection.Assign("Dijkstra: Neighbor Index", actionSet.IsGlobal, AssignExtended); IndexReference neighborDistance = actionSet.VarCollection.Assign("Dijkstra: Distance", actionSet.IsGlobal, AssignExtended); IndexReference neighborSegmentAttributes = actionSet.VarCollection.Assign("Dijkstra: Neighbor Attributes", actionSet.IsGlobal, AssignExtended); InitializeVariables(); actionSet.AddAction(While(Info.LoopCondition)); // Invoke LoopStart Info.OnLoop(); // Get neighboring indexes var connectedSegments = actionSet.VarCollection.Assign("Dijkstra: Connected Segments", actionSet.IsGlobal, AssignExtended); connectedSegments.Set(actionSet, GetConnectedSegments()); // Loop through neighboring indexes ForeachBuilder forBuilder = new ForeachBuilder(actionSet, connectedSegments.GetVariable()); // Invoke OnConnectLoop Info.OnConnectLoop(); actionSet.AddAction(ArrayBuilder <Element> .Build( // Get the index from the segment data neighborIndex.SetVariable( FirstOf(Filter( BothNodes(forBuilder.IndexValue), Compare(ArrayElement(), Operator.NotEqual, Current.GetVariable()) )) ), // Get the distance between the current and the neighbor index. neighborDistance.SetVariable( DistanceBetween( nodes[neighborIndex.Get()], nodes[Current.Get()] ) + Distances.Get()[Current.Get()] ) )); // Get the attributes from the current node to the neighbor node. actionSet.AddAction(neighborSegmentAttributes.SetVariable(Filter(attributes, And( Compare(YOf(ArrayElement()), Operator.Equal, Current.Get()), Compare(XOf(ArrayElement()), Operator.Equal, neighborIndex.Get()) ) ))); string ifComment = @"If the distance between this node and the neighbor node is lower than the node's current parent, then the current node is closer and should be set as the neighbor's parent. Alternatively, if the neighbor's distance is 0, that means it was not set so this should be set as the parent regardless. Additionally, make sure that any of the neighbor's attributes is in the attribute array."; // Set the current neighbor's distance if the new distance is less than what it is now. actionSet.AddAction(ifComment, If(And( Or( Not(Distances.Get()[neighborIndex.Get()]), neighborDistance.Get() < Distances.Get()[neighborIndex.Get()] ), Or( // There are no attributes. Not(CountOf(neighborSegmentAttributes.Get())), // There are attributes and the attribute array contains one of the attributes. Any( neighborSegmentAttributes.Get(), Contains(Info.EnabledAttributes, ZOf(ArrayElement())) ) ) ))); actionSet.AddAction( "Set the neighbor's distance to be the distance between the current node and neighbor node.", Distances.SetVariable(neighborDistance.Get(), index: neighborIndex.Get()) ); actionSet.AddAction( @"Set the neighbor's parent ('parentArray[neighborIndex]') to be current. 1 is added to current because 0 means no parent was set yet (the first node will have current equal 0). This value will be subtracted back by 1 when used.", ParentArray.SetVariable(Current.Get() + 1, index: neighborIndex.Get()) ); actionSet.AddAction(End()); // End the if. forBuilder.Finish(); // End the for. actionSet.AddAction(Unvisited.ModifyVariable(Operation.RemoveFromArrayByValue, Current.Get())); // Remove the current node from the unvisited array. Info.OnLoopEnd(); // External end loop logic. Current.Set(actionSet, LowestUnvisited()); // Set current to the unvisited node with the lowest distance. actionSet.AddAction(End()); // End the while loop. Info.Finished(); // Done. // Reset variables. actionSet.AddAction(ArrayBuilder <Element> .Build( // Current.SetVariable(0), // Distances.SetVariable(0), // neighborIndex.SetVariable(0), // neighborDistance.SetVariable(0), // ParentArray.SetVariable(0) Current.SetVariable(0), Distances.SetVariable(0), connectedSegments.SetVariable(0), neighborIndex.SetVariable(0), neighborDistance.SetVariable(0), ParentArray.SetVariable(0) )); }