public float CombinedDistance(CombinedPlatformAStar cpas,
            GameState state, GameObject next1, GameObject next2)
        {
            var combinedPath = cpas.CombinedPlatformPath (state.P1, state.P2, state.Goal, state.Goal);

            return
                   Vector2.Distance (state.P1.SurfaceCenter, next1.Target) +
                   Vector2.Distance (state.P2.SurfaceCenter, next2.Target) +
                WaypointHeuristic.PlatformPathDistance(combinedPath.Select(x => x.Item1), next1) +
                WaypointHeuristic.PlatformPathDistance(combinedPath.Select(x => x.Item2), next2);
        }
        public List<Tuple<GameObject, GameObject>> CombinedPlatformPath(
            Player start1, Player start2, GameObject end1, GameObject end2)
        {
            var cacheKey = Tuple.Create (start1, start2, end1, end2);

            List<Tuple<GameObject, GameObject>> path;

            if (paths.ContainsKey(cacheKey)) {
                path = paths[cacheKey];
            } else {
            //                Debug.Print ("p2: {0}", start2);
            //                Debug.Print("platsBelow 1: {0}", PlatformUtil.PlatListStr(PlatformUtil.platsBelow (Platforms, start1)));
            //                Debug.Print("platsBelow 2: {0}", PlatformUtil.PlatListStr(PlatformUtil.platsBelow (Platforms, start2)));

                var platsBelow1 = PlatformUtil.platsBelow (Platforms, start1);
                var platsBelow2 = PlatformUtil.platsBelow (Platforms, start2);

                var plats1 = platsBelow1.Count () > 0 ? platsBelow1 : Platforms;
                var plats2 = platsBelow2.Count () > 0 ? platsBelow2 : Platforms;

                var startPlat1 = PlatformUtil.nearestReachablePlatform (start1, plats1);
                var startPlat2 = PlatformUtil.nearestReachablePlatform (start2, plats2);

            //                Debug.Print ("startPlat1: {0}", startPlat1);
            //                Debug.Print ("startPlat2: {0}", startPlat2);

            //                Debug.WriteLineIf (endReachablePlatforms1.Count == 0, "No platforms within reach of the 1st goal!");
            //                Debug.WriteLineIf (endReachablePlatforms2.Count == 0, "No platforms within reach of the 2nd goal!");

                path = runAStar (startPlat1, startPlat2, end1, end2).Select (p2g).ToList ();

                path.Add (Tuple.Create (end1, end2));

            //                Debug.Print ("ppls: {0}", PlatformUtil.PlatPairListStr (path));

                paths [cacheKey] = path;
            }

            return path;
        }
        public GameObject NextPlatform(Player player, GameObject end)
        {
            var path = PlatformPath (player, end);

            GameObject next;

            if (path.Count == 1) {
                next = path.First ();
            } else {
                var plat0 = path [0];
                var plat1 = path [1];

                var between0and1 = plat1.Distance(plat0) > plat1.Distance(player);
                var closeEnough = player.Distance(plat0) < (1 * Player.Size.X) && player.Y >= plat0.Y;
                var unreachable1 = PlatformUtil.unreachable (Platforms, player, plat1);
                var bothAbove = plat1.TopBoundary > player.BottomBoundary && plat0.TopBoundary > player.BottomBoundary;

                next = (!bothAbove && !unreachable1 && (between0and1 || closeEnough)) ? plat1 : plat0;
            }

            return next;
        }
        public List<GameObject> PlatformPath(Player start, GameObject end)
        {
            var tup = Tuple.Create (start, end);

            List<GameObject> path;

            if (paths.ContainsKey(tup)) {
                path = paths[tup];
            } else {
                var startPlat = PlatformUtil.nearestReachablePlatform (start, Platforms);

                var endReachablePlatforms = Platforms.FindAll (p => PlatformUtil.adjacent (Platforms, p, end));

                Debug.WriteLineIf (endReachablePlatforms.Count == 0, "No platforms within reach of the goal!");

                var endPlat = PlatformUtil.nearestPlatform (end.Center, endReachablePlatforms);

                path = runAStar (startPlat, endPlat).Concat(end).ToList<GameObject>();

                paths[tup] = path;
            }

            return path;
        }
        public Tuple<GameObject, GameObject> NextPlatform(Player player1, Player player2, GameObject end1, GameObject end2)
        {
            var path = CombinedPlatformPath (player1, player2, end1, end2);

            Tuple<GameObject, GameObject> next;

            if (path.Count == 1) {
                next = path.First ();
            } else {
                next = shouldGoNext(player1, path[0].Item1, path[1].Item1) ||
                       shouldGoNext(player2, path[0].Item2, path[1].Item2) ? path[1] : path[0];
            }

            return next;
        }
        private bool shouldGoNext(Player player, GameObject plat0, GameObject plat1)
        {
            var between0and1 = plat1.Distance(plat0) > plat1.Distance(player);
            var closeEnough = player.Distance(plat0) < (1 * Player.Size.X) && player.Y >= plat0.Y;
            var unreachable1 = PlatformUtil.unreachable (Platforms, player, plat1);
            var bothAbove = plat1.TopBoundary > player.BottomBoundary && plat0.TopBoundary > player.BottomBoundary;

            return !bothAbove && !unreachable1 && (between0and1 || closeEnough);
        }
        private List<Tuple<Platform, Platform>> runAStar(
            Platform start1, Platform start2, GameObject end1, GameObject end2)
        {
            int maxIters = 200;

            var paths = new SortedDictionary<double, StateNode>();

            var startPair = Tuple.Create (start1, start2);

            var root = new StateNode (null, startPair, startPair);
            paths.Add(combinedPlatformHeuristic(root, end1, end2), root);
            var best = root;

            for (int i = 0; i < maxIters &&
                !(PlatformUtil.adjacent(Platforms, best.Value.Item1, end1) &&
                  PlatformUtil.adjacent(Platforms, best.Value.Item2, end2)) &&
                paths.Count > 0; i++) {
                best.Children = PlatformGraph [best.Value].ToDictionary (x => x,
                    x => new StateNode(best, x, x));

                foreach (var c in best.Children) {
                    var h = combinedPlatformHeuristic (c.Value, end1, end2);
                    if (!paths.ContainsKey (h)) {
                        paths.Add (h, c.Value);
                    }
                }

                best = paths.First().Value;
                paths.Remove (paths.First().Key);
            }

            //            foreach (var p in paths.Take(5).Reverse()) {
            //                Debug.Print ("good path: {0}", PlatformUtil.PlatPairListStr (p.Value.ToPath().Select(tup => tup.Item2)));
            //            }

            return best.ToPath().Select(tup => tup.Item2).ToList();
        }
        double combinedPlatformHeuristic(StateNode node, GameObject end1, GameObject end2)
        {
            var endDist1 = Vector2.Distance (node.Value.Item1.SurfaceCenter, end1.SurfaceCenter);
            var endDist2 = Vector2.Distance (node.Value.Item2.SurfaceCenter, end2.SurfaceCenter);

            var platDist = Vector2.Distance (node.Value.Item1.Center, node.Value.Item2.Center);

            // Arbitrary values
            var healthWeight = 5;
            var depthWeight = 30;

            return endDist1 + endDist2 +
                healthWeight * Math.Abs (HealthControl.IdealDistance - platDist) +
                depthWeight * node.Depth();
        }
 private float PlatformPathDistance(GameState state, PlayerId pId, GameObject platform)
 {
     return PlatformPathDistance (pas.PlatformPath (state.Player (pId), state.Goal), platform);
 }
 public static float PlayerDistance(PlatformAStar pas, GameState state, PlayerId pId, GameObject target)
 {
     return Vector2.Distance (state.Player(pId).SurfaceCenter, target.Target) +
         PlatformPathDistance (pas.PlatformPath (state.Player (pId), state.Goal), target);
 }
        public static float PlatformPathDistance(IEnumerable<GameObject> path, GameObject platform)
        {
            var remainingPath = path.SkipWhile(x => x != platform).ToArray();

            float dist = 0f;
            for (int i = 0; i < remainingPath.Count () - 1; i++) {
                dist += remainingPath [i].Distance (remainingPath [i + 1]);
            }

            return dist;
        }
Beispiel #12
0
 void DrawPlatformTargets(GameObject plat1, GameObject plat2, Color c)
 {
 }
Beispiel #13
0
 public Point RasterizeDims(GameObject go)
 {
     return RasterizeDims(go.Size);
 }
Beispiel #14
0
 public Point RasterizeCoords(GameObject go)
 {
     return RasterizeCoords (go.Coords) + new Point (0, (int)Math.Round (-yScale () * go.H));
 }
Beispiel #15
0
 public void DrawGameObjectRect(GameObject go, Color c)
 {
     Point pt = RasterizeCoords (go);
     Point dim = RasterizeDims (go);
     spriteBatch.Draw (blankTexture, new Rectangle (pt.X, pt.Y, dim.X, dim.Y), c);
 }
 public float Distance(GameObject b)
 {
     return Vector2.Distance (SurfaceCenter, b.SurfaceCenter);
 }