// 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);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Computes bounding rectangle around the face
        /// </summary>
        /// <param name="margin"></param>
        /// <returns></returns>
        public Rect BoundingBox(float margin = 0f)
        {
            if (IsOuter)
            {
                throw new GeomException("Bounding box is ill-defined for outer face");
            }

            return(BoundingBoxComputer.FromPoints(OuterVertices.Select(x => x.Pos), margin));
        }
        public void FromVector2Test()
        {
            var ret = BoundingBoxComputer.FromPoints(m_points);

            Assert.IsTrue(CmpRect(expRect, ret));
            ret = BoundingBoxComputer.FromPoints(m_points, 1f);
            Assert.IsTrue(CmpRect(expRectMargin, ret));

            Assert.AreEqual(BoundingBoxComputer.FromPoints(new List <Vector2>()), new Rect());
        }
Exemplo n.º 4
0
    private UnityEngine.Object LoadKingsTaxesLevel(XElement fileSelected, string name)
    {
        // create the output scriptable object
        var asset = ScriptableObject.CreateInstance <KingsTaxesLevel>();

        // retrieve page data from .ipe file
        var items = fileSelected.Descendants("page").First().Descendants("use");

        // get marker data into respective vector list
        asset.Villages.AddRange(GetMarkers(items, "disk"));
        asset.Castles.AddRange(GetMarkers(items, "square"));

        // normalize coordinates
        var total = new List <Vector2>();

        total.AddRange(asset.Villages);
        total.AddRange(asset.Castles);
        var rect = BoundingBoxComputer.FromPoints(total);

        asset.Villages = Normalize(rect, ktSIZE, asset.Villages);
        asset.Castles  = Normalize(rect, ktSIZE, asset.Castles);

        // give warning if no relevant data found
        if (asset.Villages.Count + asset.Castles.Count == 0)
        {
            EditorUtility.DisplayDialog("Warning", "File does not contain any villages/castles (disks and/or squares).", "OK");
        }

        // get level arguments
        var args = name.Split('_').ToList();

        if (args.Count > 2)
        {
            foreach (var item in args)
            {
                Debug.Log(item);
            }
            EditorUtility.DisplayDialog("Error", "Too many level arguments given in path name.", "OK");
            return(asset);
        }
        else if (args.Count == 2)
        {
            if (!float.TryParse(args[1], out asset.TSpannerRatio))
            {
                EditorUtility.DisplayDialog("Error", "Could not parse the t-spanner ratio.", "OK");
                return(asset);
            }
        }

        return(asset);
    }
        /// <summary>
        /// Creates a Unity mesh object from this triangulation
        /// Mapping between Unity mesh triangulation and this custom triangulation class.
        /// </summary>
        /// <returns></returns>
        public Mesh CreateMesh()
        {
            Mesh mesh = new Mesh();

            // make indexed map of vertices
            var vertices = new Dictionary <Vector2, int>();
            var index    = 0;

            foreach (var t in m_Triangles)
            {
                foreach (var v in t.Vertices)
                {
                    if (!vertices.ContainsKey(v))
                    {
                        vertices.Add(v, index++);
                    }
                }
            }

            var vertexList = vertices.Keys.ToList();

            // Calculate UV's
            var bbox  = BoundingBoxComputer.FromPoints(vertexList, 0.1f);
            var newUV = vertexList.Select <Vector2, Vector2>(p => Rect.PointToNormalized(bbox, p));

            // Calculate mesh triangles
            var tri = new List <int>();

            foreach (var t in m_Triangles)
            {
                tri.AddRange(new int[3] {
                    vertices[t.P0],
                    vertices[t.P1],
                    vertices[t.P2]
                });
            }

            // set mesh variables
            mesh.vertices  = vertexList.Select <Vector2, Vector3>(p => p).ToArray();
            mesh.uv        = newUV.ToArray();
            mesh.triangles = tri.ToArray();

            return(mesh);
        }
Exemplo n.º 6
0
    private UnityEngine.Object LoadShepherdLevel(XElement fileSelected, string name)
    {
        // create the output scriptable object
        var asset = ScriptableObject.CreateInstance <ShepherdLevel>();

        // retrieve page data from .ipe file
        var items = fileSelected.Descendants("page").First().Descendants("use");

        // get marker data into respective vector list
        List <string> markerTypes = new List <string> {
            "disk", "square", "cross", "circle"
        };

        for (int i = 0; i < markerTypes.Count; i++)
        {
            List <Vector2> sheepLocs = GetMarkers(items, markerTypes[i]);
            foreach (Vector2 l in sheepLocs)
            {
                asset.addSheep(l, i);
            }
        }

        // normalize coordinates

        var rect = BoundingBoxComputer.FromPoints(asset.SheepList);

        asset.SheepList = Normalize(rect, shSIZE, asset.SheepList);


        // give warning if no relevant data found
        if (asset.SheepList.Count == 0)
        {
            EditorUtility.DisplayDialog("Warning", "File does not contain any valid markers.", "OK");
        }

        asset.setBudget(int.Parse(name.Split('_').Last()));

        return(asset);
    }
Exemplo n.º 7
0
    /// <summary>
    /// Loads a convex hull level.
    /// </summary>
    /// <param name="fileSelected"></param>
    /// <param name="name"></param>
    /// <returns></returns>
    private UnityEngine.Object LoadHullLevel(XElement fileSelected, string name)
    {
        // create the output scriptable object
        var asset = ScriptableObject.CreateInstance<HullLevel>();

        // retrieve page data from .ipe file
        var items = fileSelected.Descendants("page").First().Descendants("use");

        // get marker data into respective vector list
        asset.Points.AddRange(GetMarkers(items, "disk"));

        // normalize coordinates
        var rect = BoundingBoxComputer.FromPoints(asset.Points);
        asset.Points = Normalize(rect, ktSIZE, asset.Points);

        // give warning if no relevant data found
        if (asset.Points.Count == 0)
        {
            EditorUtility.DisplayDialog("Warning", "File does not contain any villages/castles (disks and/or squares).", "OK");
        }

        return asset;
    }
Exemplo n.º 8
0
    public UnityEngine.Object LoadArtGalleryLevel(XElement fileSelected, string name)
    {
        // create the output scriptable object
        var asset = ScriptableObject.CreateInstance <ArtGalleryLevel>();

        // retrieve page data from .ipe file
        var items = fileSelected.Descendants("page").First().Descendants("path").ToList();

        // check that .ipe file contains one and only one polygon
        if (items.Count == 0)
        {
            EditorUtility.DisplayDialog("Error", "No paths (lines/polygons) found in ipe file.", "OK");
            return(asset);
        }

        var outerPoints = new List <Vector2>();
        var holes       = new List <List <Vector2> >();
        var checkPoints = new List <Vector2>();

        foreach (var poly in items)
        {
            List <float> transformation = null;
            if (poly.Attribute("matrix") != null)
            {
                transformation = poly.Attribute("matrix").Value
                                 .Split(' ')
                                 .Select(s => float.Parse(s))
                                 .ToList();
            }

            // retrieve coordinates from .ipe file
            var points = new List <Vector2>();
            foreach (var coordString in poly.Value.Split('\n'))
            {
                var coords = coordString.Split(' ').ToList();

                if (coords.Count < 2)
                {
                    continue;
                }

                var x = float.Parse(coords[0]);
                var y = float.Parse(coords[1]);

                if (!MathUtil.IsFinite(x) || !MathUtil.IsFinite(y))
                {
                    continue;
                }

                if (transformation != null)
                {
                    // apply transformation matrix (could be made into library function)
                    x = transformation[0] * x + transformation[2] * y + transformation[4];
                    y = transformation[1] * x + transformation[3] * y + transformation[5];
                }

                points.Add(new Vector2(x, y));
            }

            if (outerPoints.Count == 0 || new Polygon2D(outerPoints).Area < new Polygon2D(points).Area)
            {
                if (outerPoints.Count > 0)
                {
                    holes.Add(outerPoints);
                }
                outerPoints = points;
            }
            else
            {
                holes.Add(points);
            }

            // Add all defining vertices to checkPoints
        }


        // normalize coordinates
        var rect = BoundingBoxComputer.FromPoints(outerPoints);

        outerPoints = Normalize(rect, agSIZE, outerPoints);
        checkPoints.AddRange(outerPoints);
        for (var i = 0; i < holes.Count; i++)
        {
            holes[i] = Normalize(rect, agSIZE, holes[i]);
            checkPoints.AddRange(holes[i]);
        }



        // reverse if not clockwise
        if (!(new Polygon2D(outerPoints).IsClockwise()))
        {
            outerPoints.Reverse();
        }

        for (var i = 0; i < holes.Count; i++)
        {
            // reverse if not clockwise
            if (!(new Polygon2D(holes[i]).IsClockwise()))
            {
                holes[i].Reverse();
            }
        }

        var gridPoints = ComputeGridPoints(rect, outerPoints, holes, 50);

        checkPoints.AddRange(gridPoints);

        asset.Outer       = outerPoints;
        asset.Holes       = holes.Select(h => new Vector2Array(h.ToArray())).ToList();
        asset.CheckPoints = checkPoints;

        Debug.Log(asset.CheckPoints);

        // get level arguments
        var args = name.Split('_').ToList();

        if (args.Count > 2)
        {
            EditorUtility.DisplayDialog("Error", "Too many level arguments given in path name", "OK");
            return(asset);
        }
        else if (args.Count == 2)
        {
            asset.MaxNumberOfLighthouses = int.Parse(args[1]);
        }

        return(asset);
    }
Exemplo n.º 9
0
    public UnityEngine.Object LoadCastleCrushersLevel(XElement fileSelected, string name)
    {
        // create the output scriptable object
        var asset  = ScriptableObject.CreateInstance <LinesLevel>();
        var points = new List <Vector2>();

        // retrieve page data from .ipe file
        var items = fileSelected.Descendants("page").First().Descendants("path").ToList();

        foreach (var line in items)
        {
            List <float> transformation = null;
            if (line.Attribute("matrix") != null)
            {
                transformation = line.Attribute("matrix").Value
                                 .Split(' ')
                                 .Select(s => float.Parse(s))
                                 .ToList();
            }

            foreach (var coordString in line.Value.Split('\n'))
            {
                var coords = coordString.Split(' ').ToList();

                if (coords.Count < 2)
                {
                    continue;
                }

                var x = float.Parse(coords[0]);
                var y = float.Parse(coords[1]);

                if (!MathUtil.IsFinite(x) || !MathUtil.IsFinite(y))
                {
                    continue;
                }

                if (transformation != null)
                {
                    // apply transformation matrix (could be made into library function)
                    x = transformation[0] * x + transformation[2] * y + transformation[4];
                    y = transformation[1] * x + transformation[3] * y + transformation[5];
                }

                points.Add(new Vector2(x, y));
            }
        }


        // normalize coordinates
        var rect   = BoundingBoxComputer.FromPoints(points);
        var height = 7f;
        var width  = 11f;

        if (rect.width <= rect.height)
        {
            points = Normalize(rect, height, points);
        }
        else
        {
            points = Normalize(rect, width, points);
            rect   = BoundingBoxComputer.FromPoints(points);
            if (rect.height > height)
            {
                points = Normalize(rect, height * rect.width / rect.height, points);
            }
        }


        //for (int i = 0; i < points.Count; i++) {
        //    points[i] = new Vector2(((points[i].x - rect.xMin) / rect.width - 0.5f) * 15.84f,
        //                            ((points[i].y - rect.yMin) / rect.height - 0.5f) * 10 * 0.75f + 0.75f);
        //}

        var first  = new List <Vector2>();
        var second = new List <Vector2>();

        for (int i = 0; i < points.Count;)
        {
            first.Add(points[i++]);
            second.Add(points[i++]);
        }

        asset.startPoints = first;
        asset.endPoints   = second;

        // get level arguments
        var args = name.Split('_').ToList();

        if (args.Count > 2)
        {
            EditorUtility.DisplayDialog("Error", "Too many level arguments given in path name", "OK");
            return(asset);
        }
        else if (args.Count == 2)
        {
            asset.maxShots = int.Parse(args[1]);
        }

        Debug.Log(args[0] + ": " + asset.endPoints.Count + " walls and " + asset.maxShots + " shots");

        return(asset);
    }
Exemplo n.º 10
0
    private UnityEngine.Object LoadDivideLevel(XElement fileSelected, string name)
    {
        // create the output scriptable object
        var asset = ScriptableObject.CreateInstance <DivideLevel>();

        // retrieve page data from .ipe file
        var items = fileSelected.Descendants("page").First().Descendants("use");

        // get marker data into respective vector list
        asset.Spearmen.AddRange(GetMarkers(items, "disk"));
        asset.Archers.AddRange(GetMarkers(items, "square"));
        asset.Mages.AddRange(GetMarkers(items, "cross"));

        // normalize coordinates
        var total = new List <Vector2>();

        total.AddRange(asset.Spearmen);
        total.AddRange(asset.Archers);
        total.AddRange(asset.Mages);
        var rect = BoundingBoxComputer.FromPoints(total);

        asset.Spearmen = Normalize(rect, divSIZE, asset.Spearmen);
        asset.Archers  = Normalize(rect, divSIZE, asset.Archers);
        asset.Mages    = Normalize(rect, divSIZE, asset.Mages);

        // give warning if no relevant data found
        if (asset.Spearmen.Count + asset.Archers.Count + asset.Mages.Count == 0)
        {
            EditorUtility.DisplayDialog("Warning", "File does not contain any spearmen, archers, mages (disks, squares and/or crosses).", "OK");
        }

        // check for even number of points
        if (asset.Spearmen.Count % 2 != 0)
        {
            EditorUtility.DisplayDialog("Error", "File contains uneven number of spearmen (disks).", "OK");
            return(asset);
        }
        if (asset.Archers.Count % 2 != 0)
        {
            EditorUtility.DisplayDialog("Error", "File contains uneven number of archers (squares).", "OK");
            return(asset);
        }
        if (asset.Mages.Count % 2 != 0)
        {
            EditorUtility.DisplayDialog("Error", "File contains uneven number of mages (crosses).", "OK");
            return(asset);
        }

        // get level arguments
        var args = name.Split('_').ToList();

        if (args.Count > 2)
        {
            EditorUtility.DisplayDialog("Error", "Too many level arguments given in path name.", "OK");
            return(asset);
        }
        else if (args.Count == 2)
        {
            if (!int.TryParse(args[1], out asset.NumberOfSwaps))
            {
                EditorUtility.DisplayDialog("Error", "Could not parse level argument number of swaps.", "OK");
                return(asset);
            }
        }

        return(asset);
    }
 public Rect BoundingBox(float margin = 0f)
 {
     return(BoundingBoxComputer.FromPoints(Vertices, margin));
 }
Exemplo n.º 12
0
    public Object LoadArtGalleryLevel(XElement fileSelected, string name)
    {
        // create the output scriptable object
        var asset = ScriptableObject.CreateInstance <ArtGalleryLevel>();

        // retrieve page data from .ipe file
        var items = fileSelected.Descendants("page").First().Descendants("path").ToList();

        // check that .ipe file contains one and only one polygon
        if (items.Count == 0)
        {
            EditorUtility.DisplayDialog("Error", "No paths (lines/polygons) found in ipe file.", "OK");
            return(asset);
        }
        else if (items.Count > 1)
        {
            EditorUtility.DisplayDialog("Error", "File contains too many paths (lines/polygons).", "OK");
            return(asset);
        }

        // retrieve coordinates from .ipe file
        var points = new List <Vector2>();

        foreach (var item in items[0].Value.Split('\n'))
        {
            var coords = item.Split(' ').ToList();

            if (coords.Count < 2)
            {
                continue;
            }

            var x = float.Parse(coords[0]);
            var y = float.Parse(coords[1]);

            if (!MathUtil.IsFinite(x) || !MathUtil.IsFinite(y))
            {
                continue;
            }

            points.Add(new Vector2(x, y));
        }

        // normalize coordinates
        var rect = BoundingBoxComputer.FromPoints(points);

        Normalize(rect, agSIZE, ref points);

        asset.Outer = points;

        // reverse if not clockwise
        if (!asset.Polygon.IsClockwise())
        {
            points.Reverse();
            asset.Outer = points;
        }

        // get level arguments
        var args = name.Split('_').ToList();

        if (args.Count > 2)
        {
            EditorUtility.DisplayDialog("Error", "Too many level arguments given in path name", "OK");
            return(asset);
        }
        else if (args.Count == 2)
        {
            asset.MaxNumberOfLighthouses = int.Parse(args[1]);
        }

        return(asset);
    }