Esempio n. 1
0
 public Cell Copy()
 {
     Cell copy = new Cell ();
     copy.blocked = this.blocked;
     copy.seen = this.seen;
     copy.safe = this.safe;
     copy.noisy = this.noisy;
     copy.waypoint = this.waypoint;
     copy.goal = this.goal;
     copy.cluster = this.cluster;
     return copy;
 }
Esempio n. 2
0
        public void ComputeSeenCells(Cell[][][] fullmap)
        {
            seenCells = new Cell[fullmap.Length][][];

            for (int t = 0; t < fullmap.Length; t++) {
                seenCells[t] = new Cell[fullmap[0].Length][];

                for (int x = 0; x < fullmap[0][0].Length; x++) {
                    seenCells[t][x] = new Cell[fullmap[0][0].Length];
                }
            }

            for (int t = 0; t < this.cells.Length; t++) {
                foreach (Vector2 p in this.cells[t]) {
                    seenCells[t][(int)p.x][(int)p.y] = fullmap[t][(int)p.x][(int)p.y];
                }
            }
        }
Esempio n. 3
0
        public List<Node> Compute(int startX, int startY, int endX, int endY, int attemps, float stepSize, float playerMaxHp, float playerSpeed, float playerDps, Cell[][][] matrix, bool smooth = false)
        {
            // Initialization
            tree = new KDTree (3);
            deathPaths = new List<List<Node>> ();
            nodeMatrix = matrix;

            //Start and ending node
            Node start = GetNode (0, startX, startY);
            start.visited = true;
            start.parent = null;
            start.playerhp = playerMaxHp;
            foreach (Enemy e in enemies) {
                start.enemyhp.Add (e, e.maxHealth);
            }

            // Prepare start and end node
            Node end = GetNode (0, endX, endY);
            tree.insert (start.GetArray (), start);

            // Prepare the variables
            Node nodeVisiting = null;
            Node nodeTheClosestTo = null;

            float tan = playerSpeed / 1;
            angle = 90f - Mathf.Atan (tan) * Mathf.Rad2Deg;

            /*Distribution algorithm
             * List<Distribution.Pair> pairs = new List<Distribution.Pair> ();

            for (int x = 0; x < matrix[0].Length; x++)
                for (int y = 0; y < matrix[0].Length; y++)
                    if (((Cell)matrix [0] [x] [y]).waypoint)
                        pairs.Add (new Distribution.Pair (x, y));

            pairs.Add (new Distribution.Pair (end.x, end.y));

            Distribution rd = new Distribution(matrix[0].Length, pairs.ToArray());*/

            DDA dda = new DDA (tileSizeX, tileSizeZ, nodeMatrix [0].Length, nodeMatrix [0] [0].Length);
            //RRT algo
            for (int i = 0; i <= attemps; i++) {

                //Get random point
                int rt = Random.Range (1, nodeMatrix.Length);
                int rx = Random.Range (0, nodeMatrix [rt].Length);
                int ry = Random.Range (0, nodeMatrix [rt] [rx].Length);
                //Distribution.Pair p = rd.NextRandom();
                //int rx = p.x, ry = p.y;
                nodeVisiting = GetNode (rt, rx, ry);
                if (nodeVisiting.visited || nodeVisiting.cell.blocked) {
                    i--;
                    continue;
                }

                nodeTheClosestTo = (Node)tree.nearest (new double[] {rx, rt, ry});

                // Skip downwards movement
                if (nodeTheClosestTo.t > nodeVisiting.t)
                    continue;

                // Skip if player is dead
                if (nodeTheClosestTo.playerhp <= 0)
                    continue;

                // Only add if we are going in ANGLE degrees or higher
                Vector3 p1 = nodeVisiting.GetVector3 ();
                Vector3 p2 = nodeTheClosestTo.GetVector3 ();
                Vector3 pd = p1 - p2;
                if (Vector3.Angle (pd, new Vector3 (pd.x, 0f, pd.z)) < angle) {
                    continue;
                }

                // And we have line of sight
                if (nodeVisiting.cell.blocked) {
                    continue;
                }

                // Check for all alive enemies
                List<Cell[][][]> seenList = new List<Cell[][][]> ();
                foreach (Enemy e in enemies) {
                    if (nodeTheClosestTo.enemyhp [e] > 0)
                        seenList.Add (e.seenCells);
                }

                Node hit = dda.Los3D (nodeMatrix, nodeTheClosestTo, nodeVisiting, seenList.ToArray ());

                if (hit != null) {
                    if (hit.cell.blocked || (!simulateCombat && hit.cell.seen && !hit.cell.safe)) // Collision with obstacle, ignore. If we don't simulate combat, ignore collision with enemy
                        continue;
                    else {
                        // Which enemy has seen me?
                        Enemy toFight = null;
                        foreach (Enemy e in enemies) {
                            if (e.seenCells [hit.t] [hit.x] [hit.y] != null && nodeTheClosestTo.enemyhp [e] > 0)
                                toFight = e;
                        }

                        // Solve the time
                        float timef = nodeTheClosestTo.enemyhp [toFight] / (playerDps * stepSize);
                        int timeT = Mathf.CeilToInt (timef);

                        // Search for more enemies
                        List<object> more = new List<object> ();
                        foreach (Enemy e2 in enemies) {
                            if (toFight != e2)
                                for (int t = hit.t; t < hit.t + timeT; t++)
                                    if (e2.seenCells [t] [hit.x] [hit.y] != null && nodeTheClosestTo.enemyhp [e2] > 0) {
                                        Tuple<Enemy, int> whenSeen = new Tuple<Enemy, int> (e2, t);
                                        more.Add (whenSeen);
                                        break; // Skip this enemy
                                    }
                        }

                        // Did another enemy saw the player while he was fighting?
                        if (more.Count > 0) {

                            // Who dies when
                            List<object> dyingAt = new List<object> ();

                            // First, save when the first fight starts
                            Node firstFight = NewNode (hit.t, hit.x, hit.y);
                            firstFight.parent = nodeTheClosestTo;

                            // Then when the first guy dies
                            Tuple<Enemy, int> death = new Tuple<Enemy, int> (toFight, firstFight.t + timeT);
                            dyingAt.Add (death);

                            // And proccess the other stuff
                            copy (nodeTheClosestTo, firstFight);
                            firstFight.fighting.Add (toFight);

                            // Navigation node
                            Node lastNode = firstFight;

                            // Solve for all enemies joining the fight
                            foreach (object o in more) {
                                Tuple<Enemy, int> joined = (Tuple<Enemy, int>)o;

                                // Calculate dying time
                                timef = timef + lastNode.enemyhp [joined.First] / (playerDps * stepSize);
                                timeT = Mathf.CeilToInt (timef);
                                death = new Tuple<Enemy, int> (joined.First, timeT + hit.t);
                                dyingAt.Add (death);

                                // Create the node structure
                                Node startingFight = NewNode (joined.Second, hit.x, hit.y);

                                // Add to fighting list
                                copy (lastNode, startingFight);
                                startingFight.fighting.Add (joined.First);

                                // Correct parenting
                                startingFight.parent = lastNode;
                                lastNode = startingFight;
                            }

                            // Solve for all deaths
                            foreach (object o in dyingAt) {

                                Tuple<Enemy, int> dead = (Tuple<Enemy, int>)o;
                                Node travel = lastNode;
                                bool didDie = false;
                                while (!didDie && travel.parent != null) {

                                    // Does this guy dies between two nodes?
                                    if (dead.Second > travel.parent.t && dead.Second < travel.t) {

                                        // Add the node
                                        Node adding = NewNode (dead.Second + hit.t, hit.x, hit.y);
                                        adding.fighting = new List<Enemy> ();
                                        adding.fighting.AddRange (travel.parent.fighting);

                                        // And remove the dead people
                                        adding.fighting.Remove (dead.First);
                                        adding.died = dead.First;

                                        Node remove = lastNode;

                                        // Including from nodes deeper in the tree
                                        while (remove != travel.parent) {
                                            remove.fighting.Remove (dead.First);
                                            remove = remove.parent;
                                        }

                                        // Reparent the nodes
                                        adding.parent = travel.parent;
                                        travel.parent = adding;
                                        didDie = true;
                                    }

                                    travel = travel.parent;
                                }
                                if (!didDie) {
                                    // The guy didn't die between, that means he's farthest away than lastNode
                                    Node adding = NewNode (dead.Second, hit.x, hit.y);
                                    copy (lastNode, adding);
                                    adding.fighting.Remove (dead.First);
                                    adding.enemyhp [dead.First] = 0;
                                    adding.died = dead.First;
                                    adding.parent = lastNode;

                                    // This is the new lastNode
                                    lastNode = adding;
                                }
                            }

                            // Grab the first node with fighting
                            Node first = lastNode;
                            while (first.parent != nodeTheClosestTo)
                                first = first.parent;

                            while (first != lastNode) {

                                Node navigate = lastNode;
                                // And grab the node just after the first
                                while (navigate.parent != first)
                                    navigate = navigate.parent;

                                // Copy the damage already applied
                                navigate.playerhp = first.playerhp;

                                // And deal more damage
                                foreach (Enemy dmgDealer in first.fighting)
                                    navigate.playerhp -= (navigate.t - first.t) * dmgDealer.dps * stepSize;

                                // Goto next node
                                first = navigate;

                            }
                            // Make the tree structure
                            nodeVisiting = lastNode;
                        } else {
                            // Only one enemy has seen me
                            Node toAdd = NewNode (hit.t, hit.x, hit.y);
                            nodeVisiting = NewNode (hit.t + timeT, hit.x, hit.y);

                            nodeVisiting.parent = toAdd;
                            toAdd.parent = nodeTheClosestTo;

                            copy (nodeTheClosestTo, toAdd);
                            toAdd.fighting.Add (toFight);

                            copy (nodeTheClosestTo, nodeVisiting);
                            nodeVisiting.playerhp = toAdd.playerhp - timef * toFight.dps * stepSize;
                            nodeVisiting.enemyhp [toFight] = 0;
                            nodeVisiting.died = toFight;
                        }
                    }
                } else {
                    // Nobody has seen me
                    nodeVisiting.parent = nodeTheClosestTo;
                    copy (nodeTheClosestTo, nodeVisiting);
                }

                try {
                    tree.insert (nodeVisiting.GetArray (), nodeVisiting);
                } catch (KeyDuplicateException) {
                }

                nodeVisiting.visited = true;

                // Add the path to the death paths list
                if (nodeVisiting.playerhp <= 0) {
                    Node playerDeath = nodeVisiting;
                    while (playerDeath.parent.playerhp <= 0)
                        playerDeath = playerDeath.parent;

                    deathPaths.Add (ReturnPath (playerDeath, smooth));
                }

                // Attemp to connect to the end node
                if (nodeVisiting.playerhp > 0) {
                    // Compute minimum time to reach the end node
                    p1 = nodeVisiting.GetVector3 ();
                    p2 = end.GetVector3 ();
                    p2.y = p1.y;
                    float dist = Vector3.Distance (p1, p2);

                    float t = dist * Mathf.Tan (angle);
                    pd = p2;
                    pd.y += t;

                    if (pd.y <= nodeMatrix.GetLength (0)) {
                        Node endNode = GetNode ((int)pd.y, (int)pd.x, (int)pd.z);
                        // Try connecting

                        seenList = new List<Cell[][][]> ();
                        foreach (Enemy e in enemies) {
                            if (nodeTheClosestTo.enemyhp [e] > 0)
                                seenList.Add (e.seenCells);
                        }

                        hit = dda.Los3D (nodeMatrix, nodeVisiting, endNode, seenList.ToArray ());

                        // To simplify things, only connect if player isn't seen or collides with an obstacle
                        if (hit == null) {
                            endNode.parent = nodeVisiting;
                            copy (endNode.parent, endNode);
                            List<Node> done = ReturnPath (endNode, smooth);
                            //UpdateNodeMatrix (done);
                            return done;
                        }
                    }

                    if (nodeVisiting.playerhp < playerMaxHp)
                        // Health pack solving
                        foreach (HealthPack pack in packs) {
                            if (!nodeVisiting.picked.Contains(pack)) {
                                // Compute minimum time to reach the pack
                                p1 = nodeVisiting.GetVector3 ();
                                p2 = new Vector3(pack.posX, p1.y, pack.posZ);
                                dist = Vector3.Distance (p1, p2);

                                t = dist * Mathf.Tan (angle);
                                pd = p2;
                                pd.y += t;

                                if (pd.y <= nodeMatrix.GetLength (0)) {
                                    // TODO If the node is already on the Tree, things may break!
                                    // but we need to add it to the tree and retrieve from it to make it a possible path!
                                    Node packNode = GetNode ((int)pd.y, (int)pd.x, (int)pd.z);

                                    // Try connecting
                                    seenList = new List<Cell[][][]> ();
                                    foreach (Enemy e in enemies) {
                                        if (nodeVisiting.enemyhp [e] > 0)
                                            seenList.Add (e.seenCells);
                                    }

                                    hit = dda.Los3D (nodeMatrix, nodeVisiting, packNode, seenList.ToArray ());

                                    // To simplify things, only connect if player isn't seen or collides with an obstacle
                                    if (hit == null) {
                                        packNode.parent = nodeVisiting;
                                        copy (packNode.parent, packNode);
                                        packNode.picked.Add(pack);
                                        packNode.playerhp = playerMaxHp;
                                        try {
                                            tree.insert(packNode.GetArray(), packNode);
                                        } catch (KeyDuplicateException) {
                                        }
                                    }
                                }
                            }
                        }
                }

                //Might be adding the neighboor as a the goal
                if (nodeVisiting.x == end.x & nodeVisiting.y == end.y) {
                    //Debug.Log ("Done2");
                    List<Node> done = ReturnPath (nodeVisiting, smooth);
                    //UpdateNodeMatrix (done);
                    return done;

                }
            }

            return new List<Node> ();
        }
Esempio n. 4
0
        public List<Node> Compute(int startX, int startY, int endX, int endY, int attemps, float speed, Cell[][][] matrix, bool smooth = false)
        {
            // Initialization
            tree = new KDTree (3);
            explored = new List<Node> ();
            nodeMatrix = matrix;

            //Start and ending node
            Node start = GetNode (0, startX, startY);
            start.visited = true;
            start.parent = null;

            // Prepare start and end node
            Node end = GetNode (0, endX, endY);
            tree.insert (start.GetArray (), start);
            explored.Add (start);

            // Prepare the variables
            Node nodeVisiting = null;
            Node nodeTheClosestTo = null;

            float tan = speed / 1;
            angle = 90f - Mathf.Atan (tan) * Mathf.Rad2Deg;

            List<Distribution.Pair> pairs = new List<Distribution.Pair> ();

            for (int x = 0; x < matrix[0].Length; x++)
                for (int y = 0; y < matrix[0].Length; y++)
                    if (((Cell)matrix [0] [x] [y]).waypoint)
                        pairs.Add (new Distribution.Pair (x, y));

            pairs.Add (new Distribution.Pair (end.x, end.y));

            //Distribution rd = new Distribution(matrix[0].Length, pairs.ToArray());

            //RRT algo
            for (int i = 0; i <= attemps; i++) {

                //Get random point
                int rt = Random.Range (1, nodeMatrix.Length);
                //Distribution.Pair p = rd.NextRandom();
                int rx = Random.Range (0, nodeMatrix [rt].Length);
                int ry = Random.Range (0, nodeMatrix [rt] [rx].Length);
                //int rx = p.x, ry = p.y;
                nodeVisiting = GetNode (rt, rx, ry);
                if (nodeVisiting.visited || nodeVisiting.cell.blocked) {
                    i--;
                    continue;
                }

                explored.Add (nodeVisiting);

                nodeTheClosestTo = (Node)tree.nearest (new double[] {rx, rt, ry});

                // Skip downwards movement
                if (nodeTheClosestTo.t > nodeVisiting.t)
                    continue;

                // Only add if we are going in ANGLE degrees or higher
                Vector3 p1 = nodeVisiting.GetVector3 ();
                Vector3 p2 = nodeTheClosestTo.GetVector3 ();
                Vector3 pd = p1 - p2;
                if (Vector3.Angle (pd, new Vector3 (pd.x, 0f, pd.z)) < angle) {
                    continue;
                }

                // And we have line of sight
                if ((nodeVisiting.cell.seen && !nodeVisiting.cell.safe) || Extra.Collision.CheckCollision (nodeVisiting, nodeTheClosestTo, this, SpaceState.Editor, true))
                    continue;

                try {
                    tree.insert (nodeVisiting.GetArray (), nodeVisiting);
                } catch (KeyDuplicateException) {
                }

                nodeVisiting.parent = nodeTheClosestTo;
                nodeVisiting.visited = true;

                // Attemp to connect to the end node
                if (Random.Range (0, 1000) > 0) {
                    p1 = nodeVisiting.GetVector3 ();
                    p2 = end.GetVector3 ();
                    p2.y = p1.y;
                    float dist = Vector3.Distance (p1, p2);

                    float t = dist * Mathf.Tan (angle);
                    pd = p2;
                    pd.y += t;

                    if (pd.y <= nodeMatrix.GetLength (0)) {
                        Node endNode = GetNode ((int)pd.y, (int)pd.x, (int)pd.z);
                        if (!Extra.Collision.CheckCollision (nodeVisiting, endNode, this, SpaceState.Editor, true)) {
                            //Debug.Log ("Done3");
                            endNode.parent = nodeVisiting;
                            return ReturnPath (endNode, smooth);
                        }
                    }
                }

                //Might be adding the neighboor as a the goal
                if (nodeVisiting.x == end.x & nodeVisiting.y == end.y) {
                    //Debug.Log ("Done2");
                    return ReturnPath (nodeVisiting, smooth);

                }
            }

            return new List<Node> ();
        }
Esempio n. 5
0
        void OnGUI()
        {
            #region Pre-Init

            // Wait for the floor to be set and initialize the drawer and the mapper
            if (floor != null) {
                if (floor.collider == null) {
                    Debug.LogWarning ("Floor has no valid collider, game object ignored.");
                    floor = null;
                } else {
                    drawer = floor.gameObject.GetComponent<MapperEditorDrawer> ();
                    if (drawer == null) {
                        drawer = floor.gameObject.AddComponent<MapperEditorDrawer> ();
                        drawer.hideFlags = HideFlags.HideInInspector;
                    }
                }
                if (mapper == null) {
                    mapper = floor.GetComponent<Mapper> ();

                    if (mapper == null)
                        mapper = floor.AddComponent<Mapper> ();

                    mapper.hideFlags = HideFlags.None;
                }
            }

            #endregion

            // ----------------------------------

            scrollPos = EditorGUILayout.BeginScrollView (scrollPos);

            #region 1. Map

            EditorGUILayout.LabelField ("1. Map");
            playerPrefab = (GameObject)EditorGUILayout.ObjectField ("Player Prefab", playerPrefab, typeof(GameObject), false);

            floor = (GameObject)EditorGUILayout.ObjectField ("Floor", floor, typeof(GameObject), true);
            gridSize = EditorGUILayout.IntSlider ("Grid size", gridSize, 10, 300);

            if (GUILayout.Button ((MapperEditor.editGrid ? "Finish Editing" : "Edit Grid"))) {
                if (floor != null) {
                    MapperEditor.editGrid = !MapperEditor.editGrid;
                    Selection.activeGameObject = mapper.gameObject;
                }
            }

            EditorGUILayout.LabelField ("");

            #endregion

            // ----------------------------------

            #region 2. Units

            EditorGUILayout.LabelField ("2. Units");

            playerDPS = EditorGUILayout.Slider("Player DPS", playerDPS, 0.1f, 100f);
            if (GUILayout.Button ("Store Positions")) {
                StorePositions ();
            }
            EditorGUILayout.LabelField ("");

            #endregion

            // ----------------------------------

            #region 3. Map Computation

            EditorGUILayout.LabelField ("3. Map Computation");
            timeSamples = EditorGUILayout.IntSlider ("Time samples", timeSamples, 1, 10000);
            stepSize = EditorGUILayout.Slider ("Step size", stepSize, 0.01f, 1f);
            stepInTicks = ((long)(stepSize * 10000000L));
            ticksBehind = EditorGUILayout.IntSlider (new GUIContent ("Ticks behind", "Number of ticks that the FoV will remain seen after the enemy has no visibility on that cell (prevents noise/jitter like behaviours)"), ticksBehind, 0, 100);

            if (GUILayout.Button ("Precompute Maps")) {

                //Find this is the view
                if (playerPrefab == null) {
                    playerPrefab = GameObject.Find ("Player");
                }

                if (floor == null) {
                    floor = (GameObject)GameObject.Find ("Floor");

                    if (mapper == null) {
                        mapper = floor.GetComponent<Mapper> ();

                        if (mapper == null)
                            mapper = floor.AddComponent<Mapper> ();

                        mapper.hideFlags = HideFlags.None;

                    }
                    drawer = floor.gameObject.GetComponent<MapperEditorDrawer> ();
                    if (drawer == null) {
                        drawer = floor.gameObject.AddComponent<MapperEditorDrawer> ();
                        drawer.hideFlags = HideFlags.HideInInspector;
                    }
                }

                if (!simulated) {
                    StorePositions ();
                    simulated = true;
                }

                Cell[][] baseMap = null;
                if (MapperEditor.grid != null) {
                    Cell[][] obstacles = mapper.ComputeObstacles ();
                    baseMap = new Cell[gridSize][];
                    for (int x = 0; x < gridSize; x++) {
                        baseMap [x] = new Cell[gridSize];
                        for (int y = 0; y < gridSize; y++) {
                            baseMap [x] [y] = MapperEditor.grid [x] [y] == null ? obstacles [x] [y] : MapperEditor.grid [x] [y];
                        }
                    }
                }

                original = mapper.PrecomputeMaps (SpaceState.Editor, floor.collider.bounds.min, floor.collider.bounds.max, gridSize, gridSize, timeSamples, stepSize, ticksBehind, baseMap);

                drawer.fullMap = original;
                float maxSeenGrid;
                drawer.seenNeverSeen = Analyzer.ComputeSeenValuesGrid (original, out maxSeenGrid);
                drawer.seenNeverSeenMax = maxSeenGrid;
                drawer.tileSize = SpaceState.Editor.tileSize;
                drawer.zero.Set (floor.collider.bounds.min.x, floor.collider.bounds.min.z);

                ResetAI ();
                previous = DateTime.Now;
            }
            EditorGUILayout.LabelField ("");

            #endregion

            // ----------------------------------

            #region 4. Path

            EditorGUILayout.LabelField ("4. Path");

            start = (GameObject)EditorGUILayout.ObjectField ("Start", start, typeof(GameObject), true);
            end = (GameObject)EditorGUILayout.ObjectField ("End", end, typeof(GameObject), true);
            attemps = EditorGUILayout.IntSlider ("Attempts", attemps, 1000, 100000);
            iterations = EditorGUILayout.IntSlider ("Iterations", iterations, 1, 1500);
            randomSeed = EditorGUILayout.IntSlider("Random Seed", randomSeed, -1, 10000);
            smoothPath = EditorGUILayout.Toggle ("Smooth path", smoothPath);
            simulateCombat = EditorGUILayout.Toggle ("Simulate combat", simulateCombat);

            if (GUILayout.Button ("(WIP) Compute 3D A* Path")) {
                float playerSpeed = GameObject.FindGameObjectWithTag ("AI").GetComponent<Player> ().speed;

                //Check the start and the end and get them from the editor.
                if (start == null) {
                    start = GameObject.Find ("Start");
                }
                if (end == null) {
                    end = GameObject.Find ("End");
                }

                startX = (int)((start.transform.position.x - floor.collider.bounds.min.x) / SpaceState.Editor.tileSize.x);
                startY = (int)((start.transform.position.z - floor.collider.bounds.min.z) / SpaceState.Editor.tileSize.y);
                endX = (int)((end.transform.position.x - floor.collider.bounds.min.x) / SpaceState.Editor.tileSize.x);
                endY = (int)((end.transform.position.z - floor.collider.bounds.min.z) / SpaceState.Editor.tileSize.y);

                paths.Clear ();
                deaths.Clear ();
                ClearPathsRepresentation ();
                arrangedByCrazy = arrangedByDanger = arrangedByDanger3 = arrangedByDanger3Norm = arrangedByLength = arrangedByLoS = arrangedByLoS3 = arrangedByLoS3Norm = arrangedByTime = arrangedByVelocity = null;

                Exploration.DavAStar3d astar3d = new DavAStar3d();
                List<Node> nodes = astar3d.Compute(startX, startY, endX, endY, original, playerSpeed);

                if (nodes.Count > 0) {
                    paths.Add (new Path (nodes));
                    toggleStatus.Add (paths.Last (), true);
                    paths.Last ().color = new Color (UnityEngine.Random.Range (0.0f, 1.0f), UnityEngine.Random.Range (0.0f, 1.0f), UnityEngine.Random.Range (0.0f, 1.0f));
                }
            }

            if (GUILayout.Button ("Compute Path")) {
                float playerSpeed = GameObject.FindGameObjectWithTag ("AI").GetComponent<Player> ().speed;
                float playerMaxHp = GameObject.FindGameObjectWithTag ("AI").GetComponent<Player> ().maxHp;

                //Check the start and the end and get them from the editor.
                if (start == null) {
                    start = GameObject.Find ("Start");
                }
                if (end == null) {
                    end = GameObject.Find ("End");
                }

                paths.Clear ();
                deaths.Clear ();
                ClearPathsRepresentation ();
                arrangedByCrazy = arrangedByDanger = arrangedByDanger3 = arrangedByDanger3Norm = arrangedByLength = arrangedByLoS = arrangedByLoS3 = arrangedByLoS3Norm = arrangedByTime = arrangedByVelocity = null;

                // Prepare start and end position
                startX = (int)((start.transform.position.x - floor.collider.bounds.min.x) / SpaceState.Editor.tileSize.x);
                startY = (int)((start.transform.position.z - floor.collider.bounds.min.z) / SpaceState.Editor.tileSize.y);
                endX = (int)((end.transform.position.x - floor.collider.bounds.min.x) / SpaceState.Editor.tileSize.x);
                endY = (int)((end.transform.position.z - floor.collider.bounds.min.z) / SpaceState.Editor.tileSize.y);

                GameObject[] hps = GameObject.FindGameObjectsWithTag("HealthPack");
                HealthPack[] packs = new HealthPack[hps.Length];
                for (int i = 0; i < hps.Length; i++) {
                    packs[i] = hps[i].GetComponent<HealthPack>();
                    packs[i].posX = (int)((packs[i].transform.position.x - floor.collider.bounds.min.x) / SpaceState.Editor.tileSize.x);
                    packs[i].posZ = (int)((packs[i].transform.position.z - floor.collider.bounds.min.z) / SpaceState.Editor.tileSize.y);
                }

                // Update the parameters on the RRT class
                rrt.min = floor.collider.bounds.min;
                rrt.tileSizeX = SpaceState.Editor.tileSize.x;
                rrt.tileSizeZ = SpaceState.Editor.tileSize.y;
                rrt.enemies = SpaceState.Editor.enemies;
                rrt.packs = packs;
                rrt.simulateCombat = simulateCombat;

                int seed = randomSeed;
                if (randomSeed != -1)
                    UnityEngine.Random.seed = randomSeed;
                else {
                    DateTime now = DateTime.Now;
                    seed = now.Millisecond + now.Second + now.Minute + now.Hour + now.Day + now.Month+ now.Year;
                    UnityEngine.Random.seed = seed;
                }

                List<Node> nodes = null;
                for (int it = 0; it < iterations; it++) {

                    // Make a copy of the original map
                    fullMap = new Cell[original.Length][][];
                    for (int t = 0; t < original.Length; t++) {
                        fullMap[t] = new Cell[original[0].Length][];
                        for (int x = 0; x < original[0].Length; x++) {
                            fullMap[t][x] = new Cell[original[0][0].Length];
                            for (int y = 0; y < original[0][0].Length; y++)
                                fullMap[t][x][y] = original[t][x][y].Copy();
                        }
                    }

                    // Use the copied map so the RRT can modify it
                    foreach (Enemy e in SpaceState.Editor.enemies) {
                        for (int t = 0; t < original.Length; t++)
                            for (int x = 0; x < original[0].Length; x++)
                                for (int y = 0; y < original[0][0].Length; y++)
                                    if (e.seenCells[t][x][y] != null)
                                        e.seenCells[t][x][y] = fullMap[t][x][y];

                        // TODO: Need to make a backup of the enemies positions, rotations and forwards

                    }
                    // We have this try/catch block here to account for the issue that we don't solve when we find a path when t is near the limit
                    try {
                        nodes = rrt.Compute (startX, startY, endX, endY, attemps, stepSize, playerMaxHp, playerSpeed, playerDPS, fullMap, smoothPath);
                        // Did we found a path?
                        if (nodes.Count > 0) {
                            paths.Add (new Path (nodes));
                            toggleStatus.Add (paths.Last (), true);
                            paths.Last ().color = new Color (UnityEngine.Random.Range (0.0f, 1.0f), UnityEngine.Random.Range (0.0f, 1.0f), UnityEngine.Random.Range (0.0f, 1.0f));
                        }
                        // Grab the death list
                        foreach (List<Node> deathNodes in rrt.deathPaths) {
                            deaths.Add(new Path(deathNodes));
                        }
                    } catch (Exception e) {
                        Debug.LogWarning("Skip errored calculated path");
                        Debug.LogException(e);
                        // This can happen in two different cases:
                        // In line 376 by having a duplicate node being picked (coincidence picking the EndNode as visiting but the check is later on)
                        // We also cant just bring the check earlier since there's data to be copied (really really rare cases)
                        // The other case is yet unkown, but it's a conicidence by trying to insert a node in the tree that already exists (really rare cases)
                    }
                }
                // Set the map to be drawn
                drawer.fullMap = fullMap;
                ComputeHeatMap (paths, deaths);

                // Compute the summary about the paths and print it
                String summary = "Summary:\n";
                summary += "Seed used:" + seed;
                summary += "\nSuccessful paths found: " + paths.Count;
                summary += "\nDead paths: " + deaths.Count;

                // How many paths killed how many enemies
                Dictionary<int, int> map = new Dictionary<int, int>();
                for (int i = 0; i <= SpaceState.Editor.enemies.Length; i++)
                    map.Add(i, 0);
                foreach (Path p in paths) {
                    int killed = 0;
                    foreach (Node n in p.points)
                        if (n.died != null)
                            killed++;

                    if (map.ContainsKey(killed))
                        map[killed]++;
                    else
                        map.Add(killed, 1);
                }

                foreach (int k in map.Keys) {
                    summary += "\n" + map[k] + " paths killed " + k + " enemies";
                }

                // Debug.Log(summary);
            }

            if (GUILayout.Button ("(DEBUG) Export Paths")) {
                List<Path> all = new List<Path>();
                all.AddRange(paths);
                all.AddRange(deaths);
                PathBulk.SavePathsToFile ("pathtest.xml", all);
            }

            if (GUILayout.Button ("(DEBUG) Import Paths")) {
                paths.Clear ();
                ClearPathsRepresentation ();
                List<Path> pathsImported = PathBulk.LoadPathsFromFile ("pathtest.xml");
                foreach (Path p in pathsImported) {
                    if (p.points.Last().playerhp <= 0) {
                        deaths.Add(p);
                    } else {
                        p.name = "Imported " + (++imported);
                        p.color = new Color (UnityEngine.Random.Range (0.0f, 1.0f), UnityEngine.Random.Range (0.0f, 1.0f), UnityEngine.Random.Range (0.0f, 1.0f));
                        toggleStatus.Add (p, true);
                    }
                }
                ComputeHeatMap (paths, deaths);
                SetupArrangedPaths (paths);
            }

            EditorGUILayout.LabelField ("");

            #endregion

            // ----------------------------------

            #region 5. Visualization

            EditorGUILayout.LabelField ("5. Visualization");

            timeSlice = EditorGUILayout.IntSlider ("Time", timeSlice, 0, timeSamples - 1);
            drawMap = EditorGUILayout.Toggle ("Draw map", drawMap);
            drawNeverSeen = EditorGUILayout.Toggle ("- Draw safe places", drawNeverSeen);
            drawFoVOnly = EditorGUILayout.Toggle ("- Draw only fields of view", drawFoVOnly);
            drawHeatMap = EditorGUILayout.Toggle ("- Draw heat map", drawHeatMap);
            drawCombatHeatMap = EditorGUILayout.Toggle ("-> Draw combat heat map", drawCombatHeatMap);
            drawHeatMap3d = EditorGUILayout.Toggle ("-> Draw heat map 3d", drawHeatMap3d);
            drawDeathHeatMap = EditorGUILayout.Toggle ("-> Draw death heat map", drawDeathHeatMap);
            drawDeathHeatMap3d = EditorGUILayout.Toggle ("--> Draw 3d death heat map", drawDeathHeatMap3d);
            drawPath = EditorGUILayout.Toggle ("Draw path", drawPath);
            drawCombatLines = EditorGUILayout.Toggle ("Draw combat lines", drawCombatLines);

            if (drawer != null) {
                drawer.heatMap = null;
                drawer.heatMap3d = null;
                drawer.deathHeatMap = null;
                drawer.deathHeatMap3d = null;
                drawer.combatHeatMap = null;

                if (drawHeatMap) {
                    if (drawCombatHeatMap)
                        drawer.combatHeatMap = combatHeatMap;

                    else if (drawHeatMap3d)
                        drawer.heatMap3d = heatMap3d;

                    else if (drawDeathHeatMap) {
                        if (drawDeathHeatMap3d)
                            drawer.deathHeatMap3d = deathHeatMap3d;
                        else
                            drawer.deathHeatMap = deathHeatMap;
                    }

                    else
                        drawer.heatMap = heatMap;
                }
            }

            EditorGUILayout.LabelField ("");

            if (GUILayout.Button (playing ? "Stop" : "Play")) {
                playing = !playing;
            }

            EditorGUILayout.LabelField ("");

            /*if (GUILayout.Button ("Batch computation")) {
                BatchComputing ();
            }*/

            #endregion

            // ----------------------------------

            #region 6. Paths

            EditorGUILayout.LabelField ("6. Paths");

            EditorGUILayout.LabelField ("");

            crazySeconds = EditorGUILayout.Slider ("Crazy seconds window", crazySeconds, 0f, 10f);

            if (GUILayout.Button ("Analyze paths")) {
                ClearPathsRepresentation ();

                // Setup paths names
                int i = 1;
                foreach (Path path in paths) {
                    path.name = "Path " + (i++);
                    path.color = new Color (UnityEngine.Random.Range (0.0f, 1.0f), UnityEngine.Random.Range (0.0f, 1.0f), UnityEngine.Random.Range (0.0f, 1.0f));
                    toggleStatus.Add (path, true);
                    path.ZeroValues ();
                }

                // Analyze paths
                Analyzer.PreparePaths (paths);
                //Analyzer.ComputePathsTimeValues (paths);
                //Analyzer.ComputePathsLengthValues (paths);
                //Analyzer.ComputePathsVelocityValues (paths);
                //Analyzer.ComputePathsLoSValues (paths, SpaceState.Editor.enemies, floor.collider.bounds.min, SpaceState.Editor.tileSize.x, SpaceState.Editor.tileSize.y, original, drawer.seenNeverSeen, drawer.seenNeverSeenMax);
                Analyzer.ComputePathsDangerValues (paths, SpaceState.Editor.enemies, floor.collider.bounds.min, SpaceState.Editor.tileSize.x, SpaceState.Editor.tileSize.y, original, drawer.seenNeverSeen, drawer.seenNeverSeenMax);
                //Analyzer.ComputeCrazyness (paths, original, Mathf.FloorToInt (crazySeconds / stepSize));
                //Analyzer.ComputePathsVelocityValues (paths);

                SetupArrangedPaths (paths);
            }

            if (GUILayout.Button ("(DEBUG) Export Analysis")) {
                XmlSerializer ser = new XmlSerializer (typeof(MetricsRoot), new Type[] {
                    typeof(PathResults),
                    typeof(PathValue),
                    typeof(Value)
                });

                MetricsRoot root = new MetricsRoot ();

                foreach (Path path in paths) {
                    root.everything.Add (new PathResults (path, Analyzer.pathMap [path]));
                }
                using (FileStream stream = new FileStream ("pathresults.xml", FileMode.Create)) {
                    ser.Serialize (stream, root);
                    stream.Flush ();
                    stream.Close ();
                }
            }

            if (GUILayout.Button ("(DEBUG) Compute clusters")) {
                ComputeClusters ();
            }

            #region Paths values display

            seeByTime = EditorGUILayout.Foldout (seeByTime, "Paths by Time");
            if (seeByTime && arrangedByTime != null) {
                for (int i = 0; i < arrangedByTime.Count; i++) {
                    EditorGUILayout.BeginHorizontal ();

                    EditorGUILayout.FloatField (arrangedByTime [i].name, arrangedByTime [i].time);
                    toggleStatus [arrangedByTime [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByTime [i]], GUILayout.MaxWidth (20f));
                    EditorGUILayout.ColorField (arrangedByTime [i].color, GUILayout.MaxWidth (40f));

                    EditorGUILayout.EndHorizontal ();
                }
            }

            seeByLength = EditorGUILayout.Foldout (seeByLength, "Paths by Length");
            if (seeByLength && arrangedByLength != null) {
                for (int i = 0; i < arrangedByLength.Count; i++) {
                    EditorGUILayout.BeginHorizontal ();

                    EditorGUILayout.FloatField (arrangedByLength [i].name, arrangedByLength [i].length2d);
                    toggleStatus [arrangedByLength [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByLength [i]], GUILayout.MaxWidth (20f));
                    EditorGUILayout.ColorField (arrangedByLength [i].color, GUILayout.MaxWidth (40f));

                    EditorGUILayout.EndHorizontal ();
                }
            }

            seeByDanger = EditorGUILayout.Foldout (seeByDanger, "Paths by Danger (A*)");
            if (seeByDanger && arrangedByDanger != null) {
                for (int i = 0; i < arrangedByDanger.Count; i++) {
                    EditorGUILayout.BeginHorizontal ();

                    EditorGUILayout.FloatField (arrangedByDanger [i].name, arrangedByDanger [i].danger);
                    toggleStatus [arrangedByDanger [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByDanger [i]], GUILayout.MaxWidth (20f));
                    EditorGUILayout.ColorField (arrangedByDanger [i].color, GUILayout.MaxWidth (40f));

                    EditorGUILayout.EndHorizontal ();
                }
            }

            seeByDanger3 = EditorGUILayout.Foldout (seeByDanger3, "Paths by Danger 3 (A*)");
            if (seeByDanger3 && arrangedByDanger3 != null) {
                for (int i = 0; i < arrangedByDanger3.Count; i++) {
                    EditorGUILayout.BeginHorizontal ();

                    EditorGUILayout.FloatField (arrangedByDanger3 [i].name, arrangedByDanger3 [i].danger3);
                    toggleStatus [arrangedByDanger3 [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByDanger3 [i]], GUILayout.MaxWidth (20f));
                    EditorGUILayout.ColorField (arrangedByDanger3 [i].color, GUILayout.MaxWidth (40f));

                    EditorGUILayout.EndHorizontal ();
                }
            }

            seeByDanger3Norm = EditorGUILayout.Foldout (seeByDanger3Norm, "Paths by Danger 3 (A*) (normalized)");
            if (seeByDanger3Norm && arrangedByDanger3Norm != null) {
                for (int i = 0; i < arrangedByDanger3Norm.Count; i++) {
                    EditorGUILayout.BeginHorizontal ();

                    EditorGUILayout.FloatField (arrangedByDanger3Norm [i].name, arrangedByDanger3Norm [i].danger3Norm);
                    toggleStatus [arrangedByDanger3Norm [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByDanger3Norm [i]], GUILayout.MaxWidth (20f));
                    EditorGUILayout.ColorField (arrangedByDanger3Norm [i].color, GUILayout.MaxWidth (40f));

                    EditorGUILayout.EndHorizontal ();
                }
            }

            seeByLoS = EditorGUILayout.Foldout (seeByLoS, "Paths by Line of Sight (FoV)");
            if (seeByLoS && arrangedByLoS != null) {
                for (int i = 0; i < arrangedByLoS.Count; i++) {
                    EditorGUILayout.BeginHorizontal ();

                    EditorGUILayout.FloatField (arrangedByLoS [i].name, arrangedByLoS [i].los);
                    toggleStatus [arrangedByLoS [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByLoS [i]], GUILayout.MaxWidth (20f));
                    EditorGUILayout.ColorField (arrangedByLoS [i].color, GUILayout.MaxWidth (40f));

                    EditorGUILayout.EndHorizontal ();
                }
            }

            seeByLoS3 = EditorGUILayout.Foldout (seeByLoS3, "Paths by Line of Sight 3 (FoV)");
            if (seeByLoS3 && arrangedByLoS3 != null) {
                for (int i = 0; i < arrangedByLoS3.Count; i++) {
                    EditorGUILayout.BeginHorizontal ();

                    EditorGUILayout.FloatField (arrangedByLoS3 [i].name, arrangedByLoS3 [i].los3);
                    toggleStatus [arrangedByLoS3 [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByLoS3 [i]], GUILayout.MaxWidth (20f));
                    EditorGUILayout.ColorField (arrangedByLoS3 [i].color, GUILayout.MaxWidth (40f));

                    EditorGUILayout.EndHorizontal ();
                }
            }

            seeByLoS3Norm = EditorGUILayout.Foldout (seeByLoS3Norm, "Paths by Line of Sight 3 (FoV) (normalized)");
            if (seeByLoS3Norm && arrangedByLoS3Norm != null) {
                for (int i = 0; i < arrangedByLoS3Norm.Count; i++) {
                    EditorGUILayout.BeginHorizontal ();

                    EditorGUILayout.FloatField (arrangedByLoS3Norm [i].name, arrangedByLoS3Norm [i].los3Norm);
                    toggleStatus [arrangedByLoS3Norm [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByLoS3Norm [i]], GUILayout.MaxWidth (20f));
                    EditorGUILayout.ColorField (arrangedByLoS3Norm [i].color, GUILayout.MaxWidth (40f));

                    EditorGUILayout.EndHorizontal ();
                }
            }

            seeByCrazy = EditorGUILayout.Foldout (seeByCrazy, "Paths by Crazyness");
            if (seeByCrazy && arrangedByCrazy != null) {
                for (int i = 0; i < arrangedByCrazy.Count; i++) {
                    EditorGUILayout.BeginHorizontal ();

                    EditorGUILayout.FloatField (arrangedByCrazy [i].name, arrangedByCrazy [i].crazy);
                    toggleStatus [arrangedByCrazy [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByCrazy [i]], GUILayout.MaxWidth (20f));
                    EditorGUILayout.ColorField (arrangedByCrazy [i].color, GUILayout.MaxWidth (40f));

                    EditorGUILayout.EndHorizontal ();
                }
            }

            seeByVelocity = EditorGUILayout.Foldout (seeByVelocity, "Paths by Velocity Changes");
            if (seeByVelocity && arrangedByVelocity != null) {
                for (int i = 0; i < arrangedByVelocity.Count; i++) {
                    EditorGUILayout.BeginHorizontal ();

                    EditorGUILayout.FloatField (arrangedByVelocity [i].name, arrangedByVelocity [i].velocity);
                    toggleStatus [arrangedByVelocity [i]] = EditorGUILayout.Toggle ("", toggleStatus [arrangedByVelocity [i]], GUILayout.MaxWidth (20f));
                    EditorGUILayout.ColorField (arrangedByVelocity [i].color, GUILayout.MaxWidth (40f));

                    EditorGUILayout.EndHorizontal ();
                }
            }

            #endregion

            #endregion

            // ----------------------------------

            #region Temp Player setup

            if (playerNode == null) {
                playerNode = GameObject.Find ("TempPlayerNode");
                if (playerNode == null) {
                    playerNode = new GameObject ("TempPlayerNode");
                    playerNode.hideFlags = HideFlags.HideAndDontSave;
                }
            }
            if (playerPrefab != null) {
                foreach (KeyValuePair<Path, bool> p in toggleStatus) {
                    if (p.Value) {
                        if (!players.ContainsKey (p.Key)) {
                            GameObject player = GameObject.Instantiate (playerPrefab) as GameObject;
                            player.transform.position.Set (p.Key.points [0].x, 0f, p.Key.points [0].y);
                            player.transform.parent = playerNode.transform;
                            players.Add (p.Key, player);
                            Material m = new Material (player.renderer.sharedMaterial);
                            m.color = p.Key.color;
                            player.renderer.material = m;
                            player.hideFlags = HideFlags.HideAndDontSave;
                        } else {
                            players [p.Key].SetActive (true);
                        }
                    } else {
                        if (players.ContainsKey (p.Key)) {
                            players [p.Key].SetActive (false);
                        }
                    }
                }
            }

            #endregion

            EditorGUILayout.EndScrollView ();

            // ----------------------------------

            if (drawer != null) {
                drawer.timeSlice = timeSlice;
                drawer.drawHeatMap = drawHeatMap;
                drawer.drawMap = drawMap;
                drawer.drawFoVOnly = drawFoVOnly;
                drawer.drawNeverSeen = drawNeverSeen;
                drawer.drawPath = drawPath;
                drawer.drawCombatLines = drawCombatLines;
                drawer.paths = toggleStatus;
                drawer.textDraw = textDraw;

            }

            if (original != null && lastTime != timeSlice) {
                lastTime = timeSlice;
                UpdatePositions (timeSlice, mapper);
            }

            SceneView.RepaintAll ();
        }
Esempio n. 6
0
        public List<Node> Compute(int startX, int startY, int endX, int endY, Cell[][][] matrix, float playerSpeed)
        {
            this.speed = 1.0d / playerSpeed;
            try {
                Priority_Queue.IPriorityQueue<Node> heap2 = new Priority_Queue.HeapPriorityQueue<Node> (1000000);
                List<Node> closed = new List<Node> ();

                // Initialize our version of the matrix (can we skip this?)
                Node[][][] newMatrix = new Node[matrix.Length][][];
                for (int t=0; t<matrix.Length; t++) {
                    newMatrix [t] = new Node[matrix [t].Length][];
                    for (int x = 0; x < matrix [t].Length; x++) {
                        newMatrix [t] [x] = new Node[matrix [t] [x].Length];
                        for (int y = 0; y < matrix [t] [x].Length; y++) {
                            newMatrix [t] [x] [y] = new Node ();
                            newMatrix [t] [x] [y].parent = null;
                            newMatrix [t] [x] [y].cell = matrix [t] [x] [y];
                            newMatrix [t] [x] [y].x = x;
                            newMatrix [t] [x] [y].y = y;
                            newMatrix [t] [x] [y].t = t;
                        }
                    }
                }
                // Do the work for the first cell before firing the algorithm
                start = newMatrix [0] [startX] [startY];
                end = newMatrix [0] [endX] [endY];
                start.parent = null;
                start.visited = true;
                start.accSpeed = speed - Math.Floor(speed);
                foreach (Node n in getAdjacent(start, newMatrix)) {
                    n.parent = start;
                    float fVal = f (n);
                    n.Priority = fVal;
                    heap2.Enqueue (n, fVal);
                }
                while (heap2.Count != 0) {
                    Node first = heap2.Dequeue ();
                    if (first.x == end.x && first.y == end.y) {
                        end = newMatrix [first.t] [end.x] [end.y];
                        break;
                    }
                    first.visited = true;
                    foreach (Node m in getAdjacent(first, newMatrix)) {
                        float currentG = g (first) + h (m, first);
                        float gVal = g (m);
                        if (m.visited) {
                            if (gVal > currentG) {
                                m.parent = first;
                                acc(m);
                            }
                        } else {
                            if (!heap2.Contains (m)) {
                                m.parent = first;
                                m.Priority = f (m);
                                heap2.Enqueue (m, m.Priority);
                                acc(m);
                            } else {
                                if (gVal > currentG) {
                                    m.parent = first;
                                    m.Priority = f (m);
                                    heap2.UpdatePriority (m, m.Priority);
                                    acc(m);
                                }
                            }
                        }
                    }
                }
                // Creates the result list
                Node e = end;
                List<Node> points = new List<Node> ();
                while (e != null) {
                    points.Add (e);
                    e = e.parent;
                }
                points.Reverse ();

                // If we didn't find a path
                if (points.Count == 1)
                    points.Clear ();
                return points;
            } catch (System.Exception e) {
                Debug.Log (e.Message);
                Debug.Log (e.StackTrace);
                Debug.Log ("ERROR 2");
                return null;
            }
        }
Esempio n. 7
0
        private static bool SetOrUpdateCellValue(SheetData sheetData, uint rowNumber, uint columnNumber, Type datatype, object value, DefaultCellStyle defaultCellStyle, uint customStyle = 0)
        {
            if (sheetData != null && value != null && datatype != null)
            {
                //创建cell.
                //0.不存在row,建立row,插入cell.
                //0.row存在1.删除cell.2.是否有比这个cell更大的cell,有插入大cell之前.否则直接附加在row后面.
                string cellRefrence = GetCellReference(rowNumber, columnNumber);

                IEnumerable <Row> equalOrbiggerRows = sheetData.Elements <Row>().Where(x => x.RowIndex >= rowNumber);
                Row equalRow = null, biggerRow = null;
                if (equalOrbiggerRows != null && equalOrbiggerRows.Count() > 0 && equalOrbiggerRows.First().RowIndex == rowNumber)
                {
                    equalRow = equalOrbiggerRows.First();
                }
                else if (equalOrbiggerRows != null && equalOrbiggerRows.Count() > 0 && equalOrbiggerRows.First().RowIndex > rowNumber)
                {
                    biggerRow = equalOrbiggerRows.First();
                }

                if (equalRow != null)//存在row.  1.是否存在cell,存在跟新,不存在建立新cell.2.是否有比这个cell更大的cell,有插入大cell之前.否则直接附加在Row后面.
                {
                    IEnumerable <Cell> equalOrbiggerCells = equalRow.Elements <Cell>().Where(x => x.CellReference >= new StringValue(cellRefrence));

                    Cell equalCell  = null;
                    Cell biggerCell = null;
                    if (equalOrbiggerCells != null && equalOrbiggerCells.Count() > 0 && equalOrbiggerCells.First().CellReference == cellRefrence)
                    {
                        equalCell = equalOrbiggerCells.First();
                    }
                    else if (equalOrbiggerCells != null && equalOrbiggerCells.Count() > 0 && equalOrbiggerCells.First().CellReference > new StringValue(cellRefrence))
                    {
                        biggerCell = equalOrbiggerCells.First();
                    }

                    Cell newCell = createCell(cellRefrence, datatype, value, defaultCellStyle, customStyle);
                    if (equalCell != null)
                    {
                        equalOrbiggerRows.First().ReplaceChild(newCell, equalCell);
                    }
                    else
                    {
                        if (biggerCell != null)
                        {
                            equalOrbiggerRows.First().InsertBefore(newCell, biggerCell);
                        }
                        else
                        {
                            equalOrbiggerRows.First().Append(newCell);
                        }
                    }
                }
                else//不存在.新建row and cell.
                {
                    Row newrow = new Row();
                    newrow.RowIndex = rowNumber;

                    Cell theCell = IncOpenExcel.createCell(cellRefrence, datatype, value, defaultCellStyle, customStyle);
                    if (theCell != null)
                    {
                        newrow.Append(theCell);
                    }

                    if (biggerRow != null)
                    {
                        sheetData.InsertBefore(newrow, equalOrbiggerRows.First());//插入的行不是最大的,插到比它大的前面.
                    }
                    else
                    {
                        sheetData.Append(newrow);; //插入的行是最大的,直接附加到最后
                    }
                }
            }
            return(true);
        }
Esempio n. 8
0
        public void OnSceneGUI()
        {
            // Update drawer
            if (drawer != null)
                drawer.editGrid = editGrid;

            // Stop if needed
            if (!editGrid) {
                didUpdate = false;
                return;
            }

            // Create grid
            if (grid == null || grid.Length != MapperWindowEditor.gridSize) {
                grid = new Cell[MapperWindowEditor.gridSize][];
                for (int i = 0; i < MapperWindowEditor.gridSize; i++)
                    grid [i] = new Cell[MapperWindowEditor.gridSize];
            }

            // Prepare holders
            if (mapper == null) {
                mapper = (Mapper)target;
            }
            if (drawer == null) {
                drawer = mapper.gameObject.GetComponent<MapperEditorDrawer> ();
            }

            drawer.editingGrid = grid;

            // Update Scene
            if (!didUpdate) {
                mapper.ComputeTileSize (SpaceState.Editor, mapper.collider.bounds.min, mapper.collider.bounds.max, MapperWindowEditor.gridSize, MapperWindowEditor.gridSize);
                drawer.tileSize.Set (SpaceState.Editor.tileSize.x, SpaceState.Editor.tileSize.y);
                drawer.zero.Set (SpaceState.Editor.floorMin.x, SpaceState.Editor.floorMin.z);
                didUpdate = true;
            }

            // Raycast
            Event current = Event.current;
            if (current != null && EventType.KeyDown == current.type) {
                Ray ray = HandleUtility.GUIPointToWorldRay (current.mousePosition);
                RaycastHit hit;
                if (Physics.Raycast (ray, out hit, Mathf.Infinity, 1 << LayerMask.NameToLayer ("Floor"))) {
                    if (hit.transform.CompareTag ("Floor")) {
                        Vector2 pos = new Vector2 ((hit.point.x - hit.collider.bounds.min.x) / SpaceState.Editor.tileSize.x, (hit.point.z - hit.collider.bounds.min.x) / SpaceState.Editor.tileSize.y);
                        Cell c = grid [(int)pos.x] [(int)pos.y];
                        if (c == null) {
                            c = new Cell ();
                            grid [(int)pos.x] [(int)pos.y] = c;
                        }

                        switch (current.keyCode) {
                        case KeyCode.Alpha0:
                            grid [(int)pos.x] [(int)pos.y] = null;
                            break;

                        case KeyCode.Alpha1:
                            c.safe = true;
                            break;

                        case KeyCode.Alpha2:
                            c.blocked = true;
                            break;

                        case KeyCode.Alpha3:
                            c.noisy = true;
                            break;

                        case KeyCode.Alpha4:
                            c.waypoint = true;
                            break;

                        case KeyCode.U:
                            c.cluster = 0;
                            break;

                        case KeyCode.Alpha6:
                            c.cluster |= 1;
                            break;

                        case KeyCode.Alpha7:
                            c.cluster |= 2;
                            break;

                        case KeyCode.Alpha8:
                            c.cluster |= 4;
                            break;

                        case KeyCode.Alpha9:
                            c.cluster |= 8;
                            break;

                        case KeyCode.Keypad4:
                            c.cluster |= 8;
                            break;

                        case KeyCode.Keypad5:
                            c.cluster |= 16;
                            break;

                        case KeyCode.Keypad6:
                            c.cluster |= 32;
                            break;

                        case KeyCode.Keypad7:
                            c.cluster |= 64;
                            break;

                        case KeyCode.Keypad8:
                            c.cluster |= 128;
                            break;

                        case KeyCode.Keypad9:
                            c.cluster |= 256;
                            break;
                        }

                        SceneView.RepaintAll ();
                    }
                }
            }
        }
Esempio n. 9
0
        public List<Node> Compute(int startX, int startY, int endX, int endY, Cell[][] matrix, bool improve)
        {
            List<Node> opened = new List<Node> ();
            Priority_Queue.IPriorityQueue<Node> heap2 = new Priority_Queue.HeapPriorityQueue<Node> (600);

            List<Node> closed = new List<Node> ();

            // Initialize our version of the matrix (can we skip this?)
            Node[][] newMatrix = new Node[matrix.Length][];
            for (int x = 0; x < matrix.Length; x++) {
                newMatrix [x] = new Node[matrix [x].Length];
                for (int y = 0; y < matrix[x].Length; y++) {
                    newMatrix [x] [y] = new Node ();
                    newMatrix [x] [y].parent = null;
                    newMatrix [x] [y].cell = matrix [x] [y];
                    newMatrix [x] [y].x = x;
                    newMatrix [x] [y].y = y;
                }
            }

            // Do the work for the first cell before firing the algorithm
            start = newMatrix [startX] [startY];
            end = newMatrix [endX] [endY];

            closed.Add (start);

            foreach (Node c in getAdjacent(start, newMatrix)) {
                c.parent = start;
                if (improve)
                    heap2.Enqueue (c, f (c));
                else
                    opened.Add (c);
            }

            while ((improve && heap2.Count > 0) || (!improve && opened.Count > 0)) {

                // Pick the closest to the goal
                Node minF = null;
                if (improve) {
                    minF = heap2.Dequeue ();
                } else {
                    for (int i = 0; i < opened.Count; i++) {
                        if (minF == null || f (minF) > f (opened [i]))
                            minF = opened [i];
                    }
                    opened.Remove (minF);
                }

                closed.Add (minF);

                // Found it
                if (minF == end)
                    break;

                foreach (Node adj in getAdjacent(minF, newMatrix)) {

                    float soFar = g (minF) + h (adj, minF);

                    // Create the links between cells (picks the best path)
                    if (closed.Contains (adj)) {
                        if (g (adj) > soFar) {
                            adj.parent = minF;
                        }
                    } else {
                        if ((improve && heap2.Contains (adj)) || (!improve && opened.Contains (adj))) {
                            if (g (adj) > soFar) {
                                adj.parent = minF;
                            }
                        } else {
                            adj.parent = minF;
                            if (improve)
                                heap2.Enqueue (adj, f (adj));
                            else
                                opened.Add (adj);
                        }
                    }
                }
            }

            // Creates the result list
            Node n = end;
            List<Node> points = new List<Node> ();
            while (n != null) {
                points.Add (n);
                n = n.parent;
            }
            points.Reverse ();

            // If we didn't find a path
            if (points.Count == 1)
                points.Clear ();
            return points;
        }
Esempio n. 10
0
        public List<Node> Compute(int startX, int startY, int endX, int endY, Cell[][][] matrix, int time, bool prob)
        {
            try{
            Priority_Queue.IPriorityQueue<Node> heap2 = new Priority_Queue.HeapPriorityQueue<Node>(600);

            // Initialize our version of the matrix (can we skip this?)
            Node[][] newMatrix = new Node[matrix[0].Length][];
            for (int x = 0; x < matrix [0].Length; x++) {
                newMatrix [x] = new Node[matrix [0] [x].Length];
                for (int y = 0; y < matrix [0] [x].Length; y++) {
                    newMatrix [x] [y] = new Node ();
                    newMatrix [x] [y].parent = null;
                    newMatrix [x] [y].cell = matrix [0] [x] [y];
                    newMatrix [x] [y].x = x;
                    newMatrix [x] [y].y = y;
                }
            }
            enemyPathProb(newMatrix);
            // Do the work for the first cell before firing the algorithm
            start = newMatrix [startX] [startY];
            end = newMatrix [endX] [endY];
            start.parent=null;
            start.visited=true;

            foreach (Node n in getAdjacent(start, newMatrix)) {
                n.t=time;
                n.parent = start;
                float fVal = f (n);
                n.Priority = fVal;
                heap2.Enqueue(n,fVal);
            }
            while(heap2.Count != 0){

                Node first = heap2.Dequeue();
                if(first == end)
                    break;
                first.visited=true;
                double temprt = 1;
                List<Node> adjs = getAdjacent(first,newMatrix);

                foreach(Node m in adjs){
                    float currentG = (float)(g (first) + h (first,m, ref temprt));
                    if(m.visited){
                            if(g (m)>currentG){
                                m.parent=first;
                                m.t = first.t+time;
                            }
                        }
                    else{
                        if( !heap2.Contains(m)){
                            m.parent = first;
                            m.t= first.t +time;
                            m.Priority = (float)temprt*f(m);
                            heap2.Enqueue(m, m.Priority);
                        }
                        else
                        {
                            float gVal = g (m);
                            if(gVal>currentG){
                                m.parent= first;
                                m.t = first.t+time;
                                m.Priority= (float)temprt *f (m);
                                heap2.UpdatePriority(m, m.Priority);
                            }
                        }
                    }
                }
            }
                // Creates the result list
                Node l = end;
                List<Node> points = new List<Node> ();
                while (l != null) {
                    points.Add (l);
                    l = l.parent;
                }
                points.Reverse ();

                // If we didn't find a path
                if (points.Count == 1)
                points.Clear ();
                return points;
            }catch(System.Exception e){
                                Debug.Log (e.Message);
                                Debug.Log (e.StackTrace);
                                Debug.Log ("ERROR 2");
                                return null;
                        }
        }
Esempio n. 11
0
        public bool HasLOS(Cell[][] im, Vector2 p1, Vector2 p2, Vector2 res, int x, int y)
        {
            // Perform the DDA line algorithm
            // Based on http://lodev.org/cgtutor/raycasting.html

            //which box of the map we're in
            int mapX = Mathf.FloorToInt (p2.x);
            int mapY = Mathf.FloorToInt (p2.y);

            //length of ray from current position to next x or y-side
            float sideDistX;
            float sideDistY;

            //length of ray from one x or y-side to next x or y-side
            float deltaDistX = Mathf.Sqrt (1 + (res.y * res.y) / (res.x * res.x));
            float deltaDistY = Mathf.Sqrt (1 + (res.x * res.x) / (res.y * res.y));

            //what direction to step in x or y-direction (either +1 or -1)
            int stepX;
            int stepY;

            //calculate step and initial sideDist
            if (res.x < 0) {
                stepX = -1;
                sideDistX = (p2.x - mapX) * deltaDistX;
            } else {
                stepX = 1;
                sideDistX = (mapX + tileSizeX - p2.x) * deltaDistX;
            }
            if (res.y < 0) {
                stepY = -1;
                sideDistY = (p2.y - mapY) * deltaDistY;
            } else {
                stepY = 1;
                sideDistY = (mapY + tileSizeZ - p2.y) * deltaDistY;
            }

            // Don't skip seen cells
            bool done = im [x] [y].blocked;
            bool seen = false;
            //perform DDA
            while (!done) {
                //jump to next map square, OR in x-direction, OR in y-direction
                if (sideDistX < sideDistY) {
                    sideDistX += deltaDistX;
                    mapX += stepX;
                } else {
                    sideDistY += deltaDistY;
                    mapY += stepY;
                }

                if (Vector2.Distance (p2, new Vector2 (mapX, mapY)) > Vector2.Distance (p1, p2)) {
                    seen = true;
                    done = true;
                }
                // Check map boundaries
                if (mapX < 0 || mapY < 0 || mapX >= cellsX || mapY >= cellsZ) {
                    seen = true;
                    done = true;
                } else {
                    //Check if ray has hit a wall
                    if (im [mapX] [mapY].blocked) {
                        done = true;
                    }
                    // End the algorithm
                    if (x == mapX && y == mapY) {
                        seen = true;
                        done = true;
                    }
                }
            }

            return seen;
        }
Esempio n. 12
0
 public bool HasLOS(Cell[][] im, Vector2 p1, Vector2 p2, Vector2 res)
 {
     return HasLOS (im, p1, p2, res, Mathf.FloorToInt (p1.x), Mathf.FloorToInt (p1.y));
 }
Esempio n. 13
0
 public bool HasLOS(Cell[][] im, Vector2 p1, Vector2 p2)
 {
     return HasLOS (im, p1, p2, (p2 - p1).normalized);
 }
Esempio n. 14
0
        public Node Los3D(Cell[][][] im, Node start, Node end, Cell[][][][] seenList = null)
        {
            Vector3 pos = new Vector3 (start.x, start.y, start.t);
            Vector3 p = new Vector3 (end.x, end.y, end.t);
            Vector3 res = (p - pos).normalized;
            if (seenList == null)
                seenList = new Cell[0][][][];

            //which box of the map we're in
            int mapX = start.x;
            int mapY = start.y;
            int mapT = start.t;

            //length of ray from current position to next x or y-side
            float sideDistX;
            float sideDistY;
            float sideDistT;

            //length of ray from one x or y-side to next x or y-side
            float deltaDistX = 1 / Mathf.Abs (res.x);
            float deltaDistY = 1 / Mathf.Abs (res.y);
            float deltaDistT = 1 / Mathf.Abs (res.z);

            //what direction to step in x or y-direction (either +1 or -1)
            int stepX;
            int stepY;
            int stepT;

            //calculate step and initial sideDist
            if (res.x < 0) {
                stepX = -1;
                sideDistX = (pos.x - mapX) * deltaDistX;
            } else {
                stepX = 1;
                sideDistX = (mapX + 1 - pos.x) * deltaDistX;
            }
            if (res.y < 0) {
                stepY = -1;
                sideDistY = (pos.y - mapY) * deltaDistY;
            } else {
                stepY = 1;
                sideDistY = (mapY + 1 - pos.y) * deltaDistY;
            }
            if (res.z < 0) {
                stepT = -1;
                sideDistT = (pos.z - mapT) * deltaDistT;
            } else {
                stepT = 1;
                sideDistT = (mapT + 1 - pos.z) * deltaDistT;
            }

            bool done = false;
            Node result = null;
            //perform DDA
            while (!done) {

                //jump to next map square, OR in x-direction, OR in y-direction
                if (sideDistX <= sideDistY && sideDistX <= sideDistT) {
                    sideDistX += deltaDistX;
                    mapX += stepX;
                } else if (sideDistY <= sideDistT) {
                    sideDistY += deltaDistY;
                    mapY += stepY;
                } else {
                    sideDistT += deltaDistT;
                    mapT += stepT;
                }

                // Check map boundaries
                if (stepX == 1) {
                    if (mapX > end.x)
                        done = true;
                } else if (mapX < end.x)
                    done = true;

                if (stepY == 1) {
                    if (mapY > end.y)
                        done = true;
                } else if (mapY < end.y)
                    done = true;

                if (stepT == 1) {
                    if (mapT > end.t)
                        done = true;
                } else if (mapT < end.t)
                    done = true;

                if (Vector3.Distance (p, new Vector3 (mapX, mapY, mapT)) > Vector3.Distance (p, pos)) {
                    // Check for maximum distance
                    done = true;
                }

                if (end.x == mapX && end.y == mapY) {
                    // End the algorithm on reach
                    done = true;
                }

                if (!done && !im[mapT][mapX][mapY].safe) {
                    // Check for ending conditions: safespot, blocked or seen by enemy
                    bool ignored = true;
                    if (im[mapT][mapX][mapY].blocked)
                        ignored = false;
                    else
                        foreach (Cell[][][] map in seenList)
                            if (map[mapT][mapX][mapY] != null)
                                ignored = false;

                    if (!ignored) {
                        result = new Node();
                        result.t = mapT;
                        result.x = mapX;
                        result.y = mapY;
                        result.cell = im[mapT][mapX][mapY];
                        done = true;
                    }
                }
            }

            return result;
        }