Exemplo n.º 1
0
    //I think this is working but idk how to correctly subtract time in the LCDController

    /**
     * This method takes the input on if the jumper wire was clicked on, if it was, then it subtracts 10 seconds from the timer if there is more than 10 seconds left on the timer
     * if there is less than 10 seconds left on the timer, it triggers the gameover function, due to there not being enough time left
     *
     * @param jumper - the jumper wire that is clicked on
     */
    public void Jumper(GameObject jumper)
    {
        if (uiManager.GetState() == UIStateManager.UIStates.GAME)
        {
            if (levelStartTime - timer > 10)
            {
                timer += 10;
                lcdController.SetTimer(levelStartTime - timer);
            }
            else
            {
                GameOver();
            }

            currentPosition.IsCurrent = false;
            currentPosition           = currentPosition.NextNode(jumper.GetComponent <JumperColor>().color);
            if (currentPosition == null)
            {
                GameOver();
            }
            else
            {
                currentPosition.IsCurrent = true;
                if (currentPosition == endNode)
                {
                    LevelWon();
                }
            }
        }
    }
Exemplo n.º 2
0
        private DFANode DFANodeClone_DFS(Dictionary <DFANode, DFANode> NodeMap, DFANode CurNode)
        {
            if (NodeMap.ContainsKey(CurNode))
            {
                return(NodeMap[CurNode]);
            }

            var newnode = new DFANode {
                ID = CurNode.ID, IsEndNode = CurNode.IsEndNode, Edge = new List <DFAEdge>()
            };

            NodeMap[CurNode] = newnode;

            foreach (var item in CurNode.Edge)
            {
                var newedge = new DFAEdge {
                    Condition = item.Condition, NextNode = null
                };

                if (item.NextNode != null)
                {
                    newedge.NextNode = DFANodeClone_DFS(NodeMap, item.NextNode);
                }

                newnode.Edge.Add(newedge);
            }

            return(newnode);
        }
Exemplo n.º 3
0
        // 2017-11-9 添加忽略字符过滤
        public bool contain(string inputMsg)
        {
            DFANode currentDFANode = dfaEntrance;
            DFANode _next          = null;

            for (int i = 0; i < inputMsg.Length; i++)
            {
                char _lc = this.toLowerCaseWithoutConfict(inputMsg[i]);
                if (!isIgnore(_lc))
                {
                    _next = currentDFANode.dfaTransition.get(_lc);
                    while (_next == null && currentDFANode != dfaEntrance)
                    {
                        currentDFANode = currentDFANode.failNode;
                        _next          = currentDFANode.dfaTransition.get(_lc);
                    }
                }
                if (_next != null)
                {
                    // 找到状态转移,可继续
                    currentDFANode = _next;
                }
                // 看看当前状态可退出否
                if (currentDFANode.isTerminal)
                {
                    // 可退出,记录,可以替换到这里
                    return(true);
                }
            }

            return(false);
        }
Exemplo n.º 4
0
        // 基于AC状态机查找匹配,并根据节点层数覆写应过滤掉的字符
        // 2017-11-9 屏蔽字替换包含忽略字符
        public string replace(string s)
        {
            // char[] input=s.ToCharArray();
            char[] result  = s.ToCharArray();
            bool   _filted = false;

            DFANode currentDFANode = dfaEntrance;
            DFANode _next          = null;
            int     replaceFrom    = 0;
            int     ignoreLength   = 0;
            bool    endIgnore      = false;

            for (int i = 0; i < s.Length; i++)
            {
                char _lc = this.toLowerCaseWithoutConfict(s[i]);
                _next = currentDFANode.dfaTransition.get(_lc);
                while (_next == null && !isIgnore(_lc) && currentDFANode != dfaEntrance)
                {
                    currentDFANode = currentDFANode.failNode;
                    _next          = currentDFANode.dfaTransition.get(_lc);
                }
                if (_next != null)
                {
                    // 找到状态转移,可继续
                    currentDFANode = _next;
                }
                if (!endIgnore && currentDFANode != dfaEntrance && isIgnore(_lc))
                {
                    ignoreLength++;
                }
                // 看看当前状态可退出否
                if (currentDFANode.isTerminal)
                {
                    endIgnore = true;
                    // 可退出,记录,可以替换到这里
                    int j = i - (currentDFANode.level - 1) - ignoreLength;
                    if (j < replaceFrom)
                    {
                        j = replaceFrom;
                    }
                    replaceFrom = i + 1;
                    for (; j <= i; j++)
                    {
                        result[j] = this.subChar;
                        _filted   = true;
                    }
                    currentDFANode = dfaEntrance;
                    ignoreLength   = 0;
                    endIgnore      = false;
                }
            }
            if (_filted)
            {
                return(new string(result));
            }
            else
            {
                return(s);
            }
        }
Exemplo n.º 5
0
        public IEnumerator NextNodeTest()
        {
            var gameObject = new GameObject();

            DFANode node1    = gameObject.AddComponent(typeof(DFANode)) as DFANode;
            var     nextNode = node1.NextNode("red");

            yield return(null);

            Assert.AreEqual(nextNode, null);
        }
Exemplo n.º 6
0
    /**
     * This method finds a minimal path from the start state to the ends state of the DFA
     *
     * @param
     */
    public List <DFAEdge> FindMinPath()
    {
        ResetVisited();

        var nodes = new Queue <Tuple <DFANode, DFANode> >();

        nodes.Enqueue(Tuple.Create <DFANode, DFANode>(startNode, null));

        while (nodes.Count > 0)
        {
            var current = nodes.Dequeue();

            current.Item1.Visited          = true;
            current.Item1.shortestPrevious = current.Item2;

            if (current.Item1 == endNode)
            {
                break;
            }
            else
            {
                foreach (DFANode n in current.Item1.GetChildNodes())
                {
                    if (!n.Visited)
                    {
                        nodes.Enqueue(Tuple.Create(n, current.Item1));
                    }
                }
            }
        }

        var shortestPath     = new List <DFANode>();
        var backtrackCurrent = endNode;

        while (backtrackCurrent != null)
        {
            shortestPath.Add(backtrackCurrent);
            backtrackCurrent = backtrackCurrent.shortestPrevious;
        }
        shortestPath.Reverse();

        var edgesForPath = new List <DFAEdge>();

        for (int i = 0; i < shortestPath.Count - 1; i++)
        {
            DFANode currNode = shortestPath[i];
            DFANode nextNode = shortestPath[i + 1];
            edgesForPath.Add(currNode.edges.Find(x => x.child == nextNode));
        }
        ResetVisited();

        return(edgesForPath);
    }
Exemplo n.º 7
0
        /**
         * @param ignore     要忽略的字符,即在检测时将被忽略的字符
         * @param substitute 过滤时要被替换的字符
         */
        public ACStringFilter(char[] ignore, char substitute)
        {
            dfaEntrance  = new DFANode();
            this.subChar = substitute;

            ignoreChars = new CharSet(ignore.Length);

            foreach (char c in ignore)
            {
                ignoreChars.add(c);
            }
        }
Exemplo n.º 8
0
        /**
         * 构造失效节点: 一个节点的失效节点所代表的字符串是该节点所表示它的字符串的最大 部分前缀
         */
        private void buildFailNode()
        {
            // 以下构造失效节点
            SQueue <DFANode> queues = new SQueue <DFANode>();

            dfaEntrance.failNode = dfaEntrance;          //

            foreach (DFANode v in dfaEntrance.dfaTransition)
            {
                v.level = 1;
                queues.offer(v);
                v.failNode = dfaEntrance;              // 失效节点指向状态机初始状态
            }
            ;

            DFANode curNode  = null;
            DFANode failNode = null;

            while (!queues.isEmpty())
            {
                curNode  = queues.poll();             // 该节点的失效节点已计算
                failNode = curNode.failNode;


                foreach (var kv in curNode.dfaTransition.entrySet())
                {
                    char    k = kv.key;
                    DFANode v = kv.value;

                    // 如果父节点的失效节点中有条相同的出边,那么失效节点就是父节点的失效节点
                    while (failNode != dfaEntrance && !failNode.dfaTransition.contains(k))
                    {
                        failNode = failNode.failNode;
                    }

                    v.failNode = failNode.dfaTransition.get(k);

                    if (v.failNode == null)
                    {
                        v.failNode = dfaEntrance;
                    }

                    v.level = curNode.level + 1;
                    queues.offer(v);                    // 计算下一层
                }
            }
        }
Exemplo n.º 9
0
 /**
  * This method progresses through the dfa state given a wire that got cut.
  *
  * @param wire - is the wire object that got cut
  */
 public void Traverse(GameObject wire)
 {
     currentPosition.IsCurrent = false;
     currentPosition           = currentPosition.NextNode(wire.GetComponent <DFAWire>().color);
     if (currentPosition == null)
     {
         GameOver();
     }
     else
     {
         currentPosition.IsCurrent = true;
         if (currentPosition == endNode)
         {
             LevelWon();
         }
     }
 }
Exemplo n.º 10
0
        public bool init(SList <string> keyWords)
        {
            clear();

            if (keyWords != null && !keyWords.isEmpty())
            {
                string[] values = keyWords.getValues();
                string   v;

                for (int i1 = 0, len = keyWords.size(); i1 < len; ++i1)
                {
                    v = values[i1];

                    if (v == null || (v = StringUtils.trim(v)).Length == 0)
                    {
                        continue;
                    }

                    DFANode currentDFANode = dfaEntrance;
                    for (int i = 0; i < v.Length; i++)
                    {
                        char _c = v[i];
                        // 逐点加入DFA
                        char    _lc   = toLowerCaseWithoutConfict(_c);
                        DFANode _next = currentDFANode.dfaTransition.get(_lc);
                        if (_next == null)
                        {
                            _next = new DFANode();
                            currentDFANode.dfaTransition.put(_lc, _next);
                        }
                        currentDFANode = _next;
                    }
                    if (currentDFANode != dfaEntrance)
                    {
                        currentDFANode.isTerminal = true;
                    }
                }
            }

            buildFailNode();
            return(true);
        }
Exemplo n.º 11
0
        private bool MatchDFA(string Code, int StartIndex, DFANode StartNode, out int Length)
        {
            var succlength = 0;
            var curnode    = StartNode;
            var curlength  = 0;

            while (true)
            {
                if (curnode.IsEndNode)
                {
                    succlength = curlength;
                }

                if ((StartIndex + curlength) >= Code.Length)
                {
                    break;
                }

                var matchedge = new DFAEdge();

                foreach (var edge in curnode.Edge)
                {
                    if (edge.Condition == Code[StartIndex + curlength])
                    {
                        matchedge = edge;
                        break;
                    }
                }

                if (matchedge.NextNode == null)
                {
                    Length = succlength;
                    break;
                }

                curnode = matchedge.NextNode;
                curlength++;
            }

            Length = succlength;
            return(succlength == 0 ? false : true);
        }
Exemplo n.º 12
0
    /**
     * This method destroys all the prior objects from the previous level such as nodes and edges of the dfa
     * it increases the timer by 1.5 seconds each level from the base of 30 seconds
     * it generates by calling the generate level function, which is given the level number and the amount of mutations per level
     * it sets the start node to the 0th node
     * it sets the end node to the 6th node
     * it sets the end node to color red to signify it is the end node
     * it calculates the edges based on a minimal path to traverse the DFA
     * and then it instantiates new wires to go along the new level
     * then it gives the lcd controller the new start time
     * @param  none
     */
    public void NextLevel()
    {
        uiManager.SwitchGame();
        currMaxVelocity = initMaxVelocity;

        levelNumber++;
        levelStartTime = Mathf.Min(99, 30 + 1.5f * (levelNumber - 1));
        timer          = 0;

        foreach (var node in allNodes)
        {
            Destroy(node.gameObject);
        }
        allNodes.Clear();

        foreach (var edge in allEdges)
        {
            Destroy(edge.gameObject);
        }
        allEdges.Clear();

        GenerateLevel(levelNumber, mutationsPerLevel);

        startNode           = allNodes[0];
        startNode.IsCurrent = true;
        currentPosition     = startNode;
        endNode             = allNodes[6];
        endNode.gameObject.GetComponent <Image>().color = Color.red;

        var edges = FindMinPath();

        edges = edges.OrderBy(x => UnityEngine.Random.Range(0, edges.Count - 1)).ToList();
        for (int i = 0; i < edges.Count; i++)
        {
            var newWire = Instantiate(possibleWires[i], bomb.transform);
            newWire.GetComponent <Renderer>().material.color = edges[i].GetColor();
            newWire.GetComponent <BombWire>().color          = edges[i].GetColorStr();
            wires.Add(newWire);
        }

        lcdController.SetTimer(levelStartTime);
    }
Exemplo n.º 13
0
 /**
  * This method progresses through the dfa state given a wire that got cut.
  *
  * @param wire - is the wire object that got cut
  */
 public void Traverse(GameObject wire)
 {
     if (uiManager.GetState() == UIStateManager.UIStates.GAME)
     {
         currentPosition.IsCurrent = false;
         currentPosition           = currentPosition.NextNode(wire.GetComponent <BombWire>().color);
         if (currentPosition == null)
         {
             GameOver();
         }
         else
         {
             currentPosition.IsCurrent = true;
             if (currentPosition == endNode)
             {
                 LevelWon();
             }
         }
     }
 }
Exemplo n.º 14
0
    protected void generateDFAGraph <T>(List <DFANode> DFANodes) where T : ProductionInLR0
    {
        for (int i = 0; i < DFANodes.Count; i++)
        {
            DFANode dFANode = DFANodes[i];

            List <string> nextTokens = getNextTokens(dFANode.productions);
            foreach (string token in nextTokens)
            {
                List <ProductionInLR0> newProductionsOfDFANode = goTo <T>(dFANode.productions, token);
                string dstID = getID(newProductionsOfDFANode);
                // 该项集从未出现
                if (dstID == null)
                {
                    dstID = Convert.ToString(DFANodes.Count);
                    DFANodes.Add(new DFANode(newProductionsOfDFANode, dstID));
                }

                // 更新边信息
                dFANode.degrees.Add(new Degree(dstID, token));
            }
        }
    }
Exemplo n.º 15
0
        private static void DFS(DFANode CurNode)
        {
            var curname = StateNameMap[CurNode];

            foreach (var item in CurNode.Edge)
            {
                if (!StateNameMap.ContainsKey(item.NextNode))
                {
                    var newname = (item.NextNode.IsEndNode ? "Z" : "Q") + (NewStateID++);
                    StateNameMap.Add(item.NextNode, newname);
                    VertexList.Add(newname);
                    EdgeList.Add(new string[3] {
                        curname, newname, item.Condition + ""
                    });
                    DFS(item.NextNode);
                }
                else
                {
                    EdgeList.Add(new string[3] {
                        curname, StateNameMap[item.NextNode], item.Condition + ""
                    });
                }
            }
        }
Exemplo n.º 16
0
    /**
     * This method spawns the edges corresponding to the DFA that was generated
     *
     * @param parent
     *
     * @param child
     *
     * @param color
     *
     * @param colorName
     */
    public DFAEdge SpawnEdge(DFANode parent, DFANode child, WireColor wireColor)
    {
        var newObj = Instantiate(this.dfaEdgePrefab, canvas.transform);
        var edge   = newObj.GetComponent <DFAEdge>();

        edge.parent = parent;
        edge.child  = child;
        edge.SetColor(wireColor);

        parent.edges.Add(edge);
        child.edges.Add(edge);

        var parentPos = parent.gameObject.transform.localPosition;
        var childPos  = child.gameObject.transform.localPosition;

        var edgeRectTrans = newObj.GetComponent <RectTransform>();

        edgeRectTrans.sizeDelta = new Vector2(Vector3.Distance(parentPos, childPos), 60);

        edge.transform.rotation      = Quaternion.Euler(90, 0, Vector3.SignedAngle(parentPos - childPos, parent.gameObject.transform.right, -parent.gameObject.transform.forward));
        edge.transform.localPosition = (parentPos + childPos) / 2;
        allEdges.Add(edge);
        return(edge);
    }
Exemplo n.º 17
0
        private string GetTargetSet(DFANode Node)
        {
            var r        = new StringBuilder();
            var nextnode = new Dictionary <char, DFANode>();

            foreach (var edge in Node.Edge)
            {
                nextnode[edge.Condition] = edge.NextNode;
            }

            foreach (var a in CurDFA.CharSet)
            {
                if (!nextnode.ContainsKey(a))
                {
                    r.Append("-1,");
                }
                else
                {
                    r.Append(DFANodeSetID[nextnode[a]] + ",");
                }
            }

            return(r.ToString());
        }
Exemplo n.º 18
0
    private List <WireColor> findMissingOutgoingColors(DFANode node)
    {
        var existingOutgoingColorLabels = new HashSet <string>(node.edges.Where(x => x.parent == node).Select(x => x.GetColorStr()));

        return(allWireColors.Where(x => !existingOutgoingColorLabels.Contains(x.label)).ToList());
    }
Exemplo n.º 19
0
 private DFANode DFANodeClone(DFANode CurNode)
 {
     return(DFANodeClone_DFS(new Dictionary <DFANode, DFANode>(), CurNode));
 }
Exemplo n.º 20
0
    /**
     * Called every physics update frame. Will update the physics based node topology and will update the edge transformations
     */
    void FixedUpdate()
    {
        float minX = canvas.GetComponent <RectTransform>().position.x + canvas.GetComponent <RectTransform>().rect.xMin;
        float maxX = canvas.GetComponent <RectTransform>().position.x + canvas.GetComponent <RectTransform>().rect.xMax;
        float minY = canvas.GetComponent <RectTransform>().position.y + canvas.GetComponent <RectTransform>().rect.yMin;
        float maxY = canvas.GetComponent <RectTransform>().position.y + canvas.GetComponent <RectTransform>().rect.yMax;

        Vector3[] canvasCorners = new Vector3[]
        {
            new Vector3(minX, minY),
            new Vector3(maxX, minY),
            new Vector3(maxX, maxY),
            new Vector3(minX, maxY),
        };

        for (int i = 0; i < canvasCorners.Length; i++)
        {
            canvasCorners[i] = canvas.transform.TransformPoint(canvasCorners[i]);
        }

        var velocities = new List <Vector3>();

        for (int n1 = 0; n1 < allNodes.Count; n1++)
        {
            Vector3 velocity = new Vector3();

            for (int n2 = 0; n2 < allNodes.Count; n2++)
            {
                if (n1 == n2)
                {
                    continue;
                }
                float   distance   = Vector3.Distance(allNodes[n1].gameObject.transform.localPosition, allNodes[n2].gameObject.transform.localPosition) + 0.000001f;
                Vector3 repulseDir = (allNodes[n1].gameObject.transform.localPosition - allNodes[n2].gameObject.transform.localPosition).normalized;
                Vector3 force      = repulseDir * (repulseCoeff / (distance * distance));
                velocity += force * Time.fixedDeltaTime;
            }

            velocities.Add(velocity);
        }

        for (int n1 = 0; n1 < allNodes.Count; n1++)
        {
            Vector3 velocity = new Vector3();

            for (int e = 0; e < allNodes[n1].edges.Count; e++)
            {
                DFANode connectedNode = allNodes[n1].edges[e].child;
                if (connectedNode == allNodes[n1])
                {
                    connectedNode = allNodes[n1].edges[e].parent;
                }


                Vector3 attractionDir = (connectedNode.gameObject.transform.localPosition - allNodes[n1].gameObject.transform.localPosition).normalized;
                Vector3 force         = attractionDir * attractionCoeff;
                velocity += force * Time.fixedDeltaTime;
            }

            for (int i = 0; i < 4; i++)
            {
                Vector3 corner1    = canvasCorners[i];
                int     nextCorner = i + 1;
                if (nextCorner >= 4)
                {
                    nextCorner -= 4;
                }
                Vector3 corner2 = canvasCorners[nextCorner];

                Vector3 edge      = corner2 - corner1;
                Vector3 cornerDir = allNodes[n1].transform.position - corner1;
                Vector3 edgePerp  = edge.normalized * Vector3.Dot(edge, cornerDir) / edge.magnitude;
                Vector3 forceDir  = (cornerDir - edgePerp).normalized;
                float   distance  = Vector3.Distance(cornerDir, edgePerp) + 0.00001f;

                Vector3 force = forceDir * (edgeRepulseCoeff / (distance * distance * distance));

                velocity += new Vector3(force.x, force.z, 0) * Time.fixedDeltaTime;
            }
            velocities[n1] += velocity;
        }

        for (int n1 = 0; n1 < allNodes.Count; n1++)
        {
            allNodes[n1].transform.localPosition += Mathf.Min(velocities[n1].magnitude, currMaxVelocity) * velocities[n1].normalized;
        }


        HashSet <DFANode> nodesTraversed = new HashSet <DFANode>();

        foreach (DFANode n in allNodes)
        {
            float delta = 0.0f;

            var edgesSortedByParentNodeRefHash = n.edges.OrderBy(x => {
                DFANode otherNode = x.parent;
                if (otherNode == n)
                {
                    otherNode = x.child;
                }
                return(otherNode.GetHashCode());
            }).ToList();

            DFANode currentNode = null;

            foreach (DFAEdge e in edgesSortedByParentNodeRefHash)
            {
                DFANode otherNode = e.parent;

                if (otherNode == n)
                {
                    otherNode = e.child;
                }

                if (currentNode != otherNode)
                {
                    delta       = 0;
                    currentNode = otherNode;
                }

                if (!nodesTraversed.Contains(otherNode))
                {
                    UpdateEdge(e, delta);
                    delta = -delta + (Mathf.Abs(delta) + 20);
                }
            }

            nodesTraversed.Add(n);
        }

        currMaxVelocity *= 0.9925f;
    }
Exemplo n.º 21
0
    public void mutateLevel(int level, int mutationsPerLevel)
    {
        Color blue   = allWireColors[0].color;
        Color red    = allWireColors[1].color;
        Color green  = allWireColors[2].color;
        Color purple = allWireColors[3].color;
        Color gray   = allWireColors[4].color;
        Color black  = allWireColors[5].color;
        Color color  = red;

        float z    = 0;
        float minX = canvas.GetComponent <RectTransform>().position.x + canvas.GetComponent <RectTransform>().rect.xMin;
        float maxX = canvas.GetComponent <RectTransform>().position.x + canvas.GetComponent <RectTransform>().rect.xMax;
        float minY = canvas.GetComponent <RectTransform>().position.y + canvas.GetComponent <RectTransform>().rect.yMin;
        float maxY = canvas.GetComponent <RectTransform>().position.y + canvas.GetComponent <RectTransform>().rect.yMax;

        int     nodeDiam = 1;
        int     padding  = 1;
        Vector3 origin   = new Vector3((minX + maxX) / 2, (minY + maxY) / 2, z);
        Vector3 xOffset  = new Vector3(nodeDiam + padding, 0, 0);
        Vector3 yOffset  = new Vector3(0, -nodeDiam - padding, 0);

        int columns = 3;
        int rows    = 2;
        int rowPos  = 2;
        int colPos  = 0;

        string[] colors     = { "red", "green", "blue", "black", "gray", "purple" };
        DFANode  parentNode = null;
        DFANode  childNode  = null;

        string edgeColor = "";

        for (int i = 0; i < level * mutationsPerLevel; i++)
        {
            int mutationType = UnityEngine.Random.Range(0, 3);
            if (mutationType == 0)
            //Create new edge
            {
                bool nodeHasColor = true;
                while (nodeHasColor)
                {
                    parentNode   = allNodes[UnityEngine.Random.Range(0, allNodes.Count - 1)];
                    edgeColor    = colors[UnityEngine.Random.Range(0, 6)];
                    nodeHasColor = parentNode.HasOutgoingEdge(edgeColor);
                }

                //Remove the do-while loop to enable recursive edges (edge going from a node to itself)
                do
                {
                    childNode = allNodes[UnityEngine.Random.Range(0, allNodes.Count)];
                } while(childNode == parentNode);

                switch (edgeColor)
                {
                case "red":
                    color = red;
                    break;

                case "green":
                    color = green;
                    break;

                case "blue":
                    color = blue;
                    break;

                case "black":
                    color = black;
                    break;

                case "gray":
                    color = gray;
                    break;

                case "purple":
                    color = purple;
                    break;
                }

                SpawnEdge(parentNode, childNode, color, edgeColor);
            }
            else if (mutationType == 1) //split a current edge
            {
                List <DFAEdge> outEdges;

                do
                {
                    parentNode = allNodes[UnityEngine.Random.Range(0, allNodes.Count)];
                    outEdges   = parentNode.edges.Where((other) => other.parent == parentNode).ToList();
                } while (outEdges.Count == 0);

                var index       = UnityEngine.Random.Range(0, outEdges.Count);
                var edgeToSplit = outEdges[index];

                childNode = edgeToSplit.child;
                color     = edgeToSplit.GetColor();
                edgeColor = edgeToSplit.GetColorStr();



                //vector stuff

                int x = 0;
                int y = 0;
                if (rows < columns)
                {
                    rowPos++;
                    x = rowPos;
                    y = rows + 1;
                    if (rowPos >= columns)
                    {
                        rows++;
                        colPos = 0;
                        rowPos = 0;
                    }
                }
                else
                {
                    colPos++;
                    x = columns + 1;
                    y = colPos;
                    if (colPos >= rows)
                    {
                        columns++;
                        colPos = 0;
                        rowPos = 0;
                    }
                }

                SpawnNode(origin + xOffset * x + yOffset * y);
                var newNode = allNodes[allNodes.Count - 1];

                //spawn an edge from parent to new
                SpawnEdge(parentNode, newNode, color, edgeColor);
                //spawn edge from new node to child
                edgeColor = colors[UnityEngine.Random.Range(0, 6)];
                switch (edgeColor)
                {
                case "red":
                    color = red;
                    break;

                case "green":
                    color = green;
                    break;

                case "blue":
                    color = blue;
                    break;

                case "black":
                    color = black;
                    break;

                case "gray":
                    color = gray;
                    break;

                case "purple":
                    color = purple;
                    break;
                }
                SpawnEdge(newNode, childNode, color, edgeColor);
                //remove the edge to split

                allEdges.Remove(edgeToSplit);
                parentNode.edges.Remove(edgeToSplit);
                childNode.edges.Remove(edgeToSplit);
                Destroy(edgeToSplit.gameObject);
            }
            else
            {
                var randNode      = allNodes[UnityEngine.Random.Range(0, allNodes.Count)];
                var randEdge      = randNode.edges[UnityEngine.Random.Range(0, randNode.edges.Count)];
                var allOutColors  = randNode.edges.Select(other => other.GetColorStr()).ToList();
                var missingColors = colors.Where(other => !allOutColors.Contains(other)).ToList();

                if (missingColors.Count > 0)
                {
                    var newColor = missingColors[UnityEngine.Random.Range(0, missingColors.Count)];
                    switch (newColor)
                    {
                    case "red":
                        randEdge.SetColor(red, newColor);
                        break;

                    case "green":
                        randEdge.SetColor(green, newColor);
                        break;

                    case "blue":
                        randEdge.SetColor(blue, newColor);
                        break;

                    case "black":
                        randEdge.SetColor(black, newColor);
                        break;

                    case "gray":
                        randEdge.SetColor(gray, newColor);
                        break;

                    case "purple":
                        randEdge.SetColor(purple, newColor);
                        break;
                    }
                }
                else
                {
                    i--;
                }
            }
        }
    }
Exemplo n.º 22
0
    void FixedUpdate()
    {
        float minX = canvas.GetComponent <RectTransform>().position.x + canvas.GetComponent <RectTransform>().rect.xMin;
        float maxX = canvas.GetComponent <RectTransform>().position.x + canvas.GetComponent <RectTransform>().rect.xMax;
        float minY = canvas.GetComponent <RectTransform>().position.y + canvas.GetComponent <RectTransform>().rect.yMin;
        float maxY = canvas.GetComponent <RectTransform>().position.y + canvas.GetComponent <RectTransform>().rect.yMax;

        Vector3[] canvasCorners = new Vector3[]
        {
            new Vector3(minX, minY),
            new Vector3(maxX, minY),
            new Vector3(maxX, maxY),
            new Vector3(minX, maxY),
        };

        for (int i = 0; i < canvasCorners.Length; i++)
        {
            canvasCorners[i] = canvas.transform.TransformPoint(canvasCorners[i]);
        }

        var velocities = new List <Vector3>();

        for (int n1 = 0; n1 < allNodes.Count; n1++)
        {
            Vector3 velocity = new Vector3();

            for (int n2 = 0; n2 < allNodes.Count; n2++)
            {
                if (n1 == n2)
                {
                    continue;
                }
                float   distance   = Vector3.Distance(allNodes[n1].gameObject.transform.localPosition, allNodes[n2].gameObject.transform.localPosition) + 0.000001f;
                Vector3 repulseDir = (allNodes[n1].gameObject.transform.localPosition - allNodes[n2].gameObject.transform.localPosition).normalized;
                Vector3 force      = repulseDir * (repulseCoeff / (distance * distance));
                velocity += force * Time.fixedDeltaTime;
            }

            velocities.Add(velocity);
        }

        for (int n1 = 0; n1 < allNodes.Count; n1++)
        {
            Vector3 velocity = new Vector3();

            for (int e = 0; e < allNodes[n1].edges.Count; e++)
            {
                DFANode connectedNode = allNodes[n1].edges[e].child;
                if (connectedNode == allNodes[n1])
                {
                    connectedNode = allNodes[n1].edges[e].parent;
                }


                Vector3 attractionDir = (connectedNode.gameObject.transform.localPosition - allNodes[n1].gameObject.transform.localPosition).normalized;
                Vector3 force         = attractionDir * attractionCoeff;
                velocity += force * Time.fixedDeltaTime;
            }

            for (int i = 0; i < 4; i++)
            {
                Vector3 corner1    = canvasCorners[i];
                int     nextCorner = i + 1;
                if (nextCorner >= 4)
                {
                    nextCorner -= 4;
                }
                Vector3 corner2 = canvasCorners[nextCorner];

                Vector3 edge      = corner2 - corner1;
                Vector3 cornerDir = allNodes[n1].transform.position - corner1;
                Vector3 edgePerp  = edge.normalized * Vector3.Dot(edge, cornerDir) / edge.magnitude;
                Vector3 forceDir  = (cornerDir - edgePerp).normalized;
                float   distance  = Vector3.Distance(cornerDir, edgePerp) + 0.00001f;

                Vector3 force = forceDir * (edgeRepulseCoeff / (distance * distance * distance));

                velocity += new Vector3(force.x, force.z, 0) * Time.fixedDeltaTime;
            }
            velocities[n1] += velocity;
        }

        for (int n1 = 0; n1 < allNodes.Count; n1++)
        {
            allNodes[n1].transform.localPosition += Mathf.Min(velocities[n1].magnitude, currMaxVelocity) * velocities[n1].normalized;
        }

        foreach (DFAEdge e in allEdges)
        {
            if (e != null)
            {
                RerenderEdge(e);
            }
        }

        currMaxVelocity *= 0.9925f;
    }