bool circle_formed()
    {
        FakeRope         fp             = start_rope;
        List <FakeRope>  previous       = new List <FakeRope>();
        Stack <FakeRope> node_to_search = new Stack <FakeRope>();

        node_to_search.Push(fp);
        while (node_to_search.Count > 0)
        {
            fp = node_to_search.Pop();
            if (!previous.Contains(fp))
            {
                previous.Add(fp);
                if (fp.next_rope() == null)
                {
                    return(false);
                }
                node_to_search.Push(fp.next_rope());
            }
            else
            {
                // there is a circle in the list
                return(true);
            }
        }
        return(false);
    }
    public void rope_reconstruction()
    {
        FakeRope fp = start_rope;

        while (fp.next_rope() != null)
        {
            fp = fp.next_rope();
        }
        end_rope = fp;
        line_end = fp.start;
    }
    int still_connect()
    {
        FakeRope fp  = start_rope;
        int      cnt = 0;

        current_string = "";
        while (fp != end_rope)
        {
            current_string += fp.ch.ToString();
            fp              = fp.next_rope();
            cnt++;
            if (fp == null)
            {
                return(-1);
            }
        }
        current_string += fp.ch.ToString();
        result_ui.GetComponent <Text>().text = "Current string :" + current_string;
        Debug.Log(level_controller.GetComponent <LevelController>().current_target());
        if (current_string == level_controller.GetComponent <LevelController>().current_target())
        {
            level_controller.GetComponent <LevelController>().level_up();
            transform.FindChild("cheers").gameObject.SetActive(true);
            Invoke("close_cheers", 3f);
        }
        return(cnt);
    }
    public bool attach_ropes(Transform hand, Transform src, Transform dest = null)
    {
        grabbing_end = false;
        if (hand.FindChild("start") == null && src.FindChild("start") == null)
        {
            Debug.LogError("The operating node is missing.");
        }
        hand.FindChild("start").SetParent(src);
        if (src.GetComponent <FakeRope>() == null)
        {
            Debug.Log("Nothing to be operated.");
            return(false);
        }


        if (dest == null)
        {
            connection_count = still_connect();
            if (connection_count == -1)
            {
                StartCoroutine("on_disconnected");
            }
            return(true);
        }
        FakeRope src_fr = src.GetComponent <FakeRope>();

        if (dest == start_rope.transform && src_fr == end_rope)
        {
            //invalid operation
            connection_count = still_connect();
            if (connection_count == -1)
            {
                StartCoroutine("on_disconnected");
            }
            return(false);
        }
        //if there is no error, could get rid of this
        if (dest.GetComponent <FakeRope>() == src_fr.first_child())
        {
            //invalid operation
            connection_count = still_connect();
            if (connection_count == -1)
            {
                StartCoroutine("on_disconnected");
            }
            return(false);
        }
        src_fr.attach(dest);

        if (dest == start_rope.transform)
        {
            if (!circle_formed())
            {
                FakeRope tmp = src_fr;
                while (tmp.first_child() != null)
                {
                    tmp = tmp.first_child();
                }
                start_rope          = tmp;
                line_start          = tmp.end;
                line_start.position = origin_pos_start;
                Debug.LogWarning("Attaching to the startnode.");
            }
            //change here: start node should be the child of scr_fr until there is none
        }

        if (src_fr == end_rope)
        {
            if (dest.GetComponent <FakeRope>() != null)
            {
                FakeRope tmp = dest.GetComponent <FakeRope>();
                //It is here that crushed!
                if (!circle_formed())
                {
                    while (tmp.next_rope() != null)
                    {
                        tmp = tmp.next_rope();
                    }
                    end_rope = tmp.GetComponent <FakeRope>();
                    line_end = end_rope.start;
                }
            }
        }
        //detect connections
        //detect circles from start, if so, reject connection
        if (circle_formed())
        {
            src_fr.dettach();
        }
        //fixing crush
        if (Mathf.Abs(GameObject.Find("hand_left").GetComponent <RotateHand>().get_offset_angle()) < 1e-5)
        {
            line_start.position = origin_pos_start;
        }
        connection_count = still_connect();
        if (connection_count == -1)
        {
            StartCoroutine("on_disconnected");
        }
        return(true);
    }