// Random endless level generation
        // Determines the amount of shepherds placed based on the current level number
        private ShepherdLevel CreateEndlessLevel(int level)
        {
            // create the output scriptable object
            var asset = ScriptableObject.CreateInstance <ShepherdLevel>();

            // place the shepherds and sheep randomly
            List <Vector2> shepherds = RandomPos(level + 4);
            List <Vector2> sheep     = RandomPos(2 * (level + 4));

            // Print locations
            string sls = "Shepherd locations: \n";

            foreach (Vector2 v in shepherds)
            {
                sls += "(" + v.x + ", " + v.y + "), ";
            }
            Debug.Log(sls);
            string shls = "Sheep locations: \n";

            foreach (Vector2 v in sheep)
            {
                shls += "(" + v.x + ", " + v.y + "), ";
            }
            Debug.Log(shls);

            // Construct the voronoi diagram corresponding to the shepherd locations
            StartVoronoi();
            foreach (Vector2 me in shepherds)
            {
                // Add vertex to the triangulation and update the voronoi
                Delaunay.AddVertex(m_delaunay, me);
                m_delaunay.SetOwner(me, Random.Range(0, 4));
                m_dcel = Voronoi.Create(m_delaunay);
            }

            // Create vertical decomposition
            VerticalDecomposition vd = VertDecomp(m_dcel);

            // Use the vertical decomposition to determine the ownership of each sheep
            // and add the sheep to the level
            foreach (Vector2 s in sheep)
            {
                Trapezoid trap = vd.Search(s);
                Face      area = trap.bottom.face;
                int       i    = area.owner;
                asset.addSheep(s, i);
            }

            // Normalize coordinates
            var rect = BoundingBoxComputer.FromPoints(asset.SheepList);

            asset.SheepList = Normalize(rect, 6f, asset.SheepList);

            // Set shepherd budget
            asset.setBudget(shepherds.Count);

            return(asset);
        }
        public void DelaunayAddVertexTest()
        {
            var m_delaunay = Delaunay.Create();

            Delaunay.AddVertex(m_delaunay, m_topVertex);
            Delaunay.AddVertex(m_delaunay, m_botVertex);
            Delaunay.AddVertex(m_delaunay, m_leftVertex);
            Delaunay.AddVertex(m_delaunay, m_farRightVertex);
            Delaunay.AddVertex(m_delaunay, m_rightVertex);
            m_delaunay.RemoveInitialTriangle();
            Assert.IsTrue(Delaunay.IsValid(m_delaunay));

            // check for triangles
            var triangles = (System.Collections.ICollection)m_delaunay.Triangles;

            Assert.Contains(new Triangle(m_topVertex, m_rightVertex, m_leftVertex), triangles);
            Assert.Contains(new Triangle(m_leftVertex, m_rightVertex, m_botVertex), triangles);
            Assert.Contains(new Triangle(m_topVertex, m_farRightVertex, m_rightVertex), triangles);
            Assert.Contains(new Triangle(m_rightVertex, m_farRightVertex, m_botVertex), triangles);
        }
        // Handle inputs each frame
        void Update()
        {
            if (Input.GetKeyDown("c"))
            {
                VoronoiDrawer.CircleOn = !VoronoiDrawer.CircleOn;
            }

            if (Input.GetKeyDown("e"))
            {
                VoronoiDrawer.EdgesOn = !VoronoiDrawer.EdgesOn;
            }

            if (Input.GetKeyDown("v"))
            {
                VoronoiDrawer.VoronoiOn = !VoronoiDrawer.VoronoiOn;
            }

            // Handle mouse clicks
            if (Input.GetMouseButtonUp(0)) // LMB was clicked this frame
            {
                // Cast a ray, get everything it hits
                RaycastHit2D[] hit = Physics2D.RaycastAll(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero, Mathf.Infinity);

                if (hit.Length > 0) // If we hit something
                {
                    // Grab the top hit GameObject
                    GameObject lastHitObject = hit[hit.Length - 1].collider.gameObject;

                    // If a shepherd was clicked, remove it
                    if (lastHitObject.name == "shepherd(Clone)")
                    {
                        m_shepherds.Remove(lastHitObject);                     // remove from shepherd clone list
                        shepherdLocs.Remove(lastHitObject.transform.position); // remove location from list
                        Destroy(lastHitObject);
                        // Create new Delaunay triangulation
                        m_delaunay = Delaunay.Create();
                        foreach (KeyValuePair <Vector2, int> o in shepherdLocs)
                        {
                            Delaunay.AddVertex(m_delaunay, o.Key);
                            m_delaunay.SetOwner(o.Key, o.Value);
                        }

                        // Create new Voronoi diagram
                        m_dcel = Voronoi.Create(m_delaunay);
                        VoronoiDrawer.setDCEL(m_dcel);

                        // Create vertical decomposition and check solution
                        if (shepherdLocs.Count > 0)
                        {
                            VerticalDecomposition vd = VertDecomp(m_dcel);
                            Debug.LogAssertion("The current solution is " + (CheckSolution(vd) == 0 ? "correct!" : "wrong!"));

                            VoronoiDrawer.SetVD(vd);
                        }
                        else
                        {
                            // If we do not have any shepherds, do not create vertical decomposition
                            // Solution without shepherds is always wrong
                            Debug.LogAssertion("The current solution is wrong!");
                            continueButton.SetActive(false);
                            UpdateText(m_sheep.Count);
                        }

                        // Update Voronoi drawing
                        UpdateMesh();
                    }
                }
                else // LMB was clicked on empty space
                {
                    // Add shepherd at mouse location
                    var mousePos = Input.mousePosition;

                    if (!EventSystem.current.IsPointerOverGameObject() && shepherdLocs.Count < budget)
                    {
                        mousePos.z = 2.0f;
                        var            objectPos = Camera.main.ScreenToWorldPoint(mousePos);
                        var            obj       = Instantiate(m_shepherdPrefab, objectPos, Quaternion.identity);
                        SpriteRenderer sr        = obj.GetComponent <SpriteRenderer>();
                        sr.color = Colors[m_activeShepherd];

                        // The new vertex
                        var me = new Vector2(objectPos.x, objectPos.y);

                        // store owner of vertex
                        shepherdLocs.Add(me, m_activeShepherd);
                        m_shepherds.Add(obj);

                        // Add vertex to the triangulation
                        Delaunay.AddVertex(m_delaunay, me);
                        m_delaunay.SetOwner(me, m_activeShepherd);

                        // Update Voronoi
                        m_dcel = Voronoi.Create(m_delaunay);
                        VoronoiDrawer.setDCEL(m_dcel);

                        // Create vertical decomposition and check solution
                        VerticalDecomposition vd = VertDecomp(m_dcel);
                        CheckSolution(vd);

                        // Update VD in drawer
                        VoronoiDrawer.SetVD(vd);

                        // Update Voronoi drawing
                        UpdateMesh();
                    }
                }
            }
        }