Beispiel #1
0
        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);
        }
Beispiel #2
0
        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();
        }
Beispiel #3
0
        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();
        }
Beispiel #6
0
        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()));
            }
        }
Beispiel #7
0
        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)
                                    ));
        }