Example #1
0
    public static void MoveFarthestAndAttack(Droid attacker, BitArray targets)
    {
        if (attacker.AttacksLeft == 0)
        {
            return;
        }

        var liveTargets = targets.ToPoints().Where(p => Bb.DroidLookup[p].HealthLeft > 0);
        Func<Point, bool> patherPassable = p => IsPassable(p) || p.Equals(attacker.ToPoint());

        var movementSearch = new Pather.Search(new Point[] { attacker.ToPoint() }, patherPassable, p => false, (p1, p2) => 1, attacker.MovementLeft);
        var walkables = movementSearch.GScore.Keys.Where(p => movementSearch.GScore[p] <= attacker.MovementLeft);
        var walkablesWithTargets = walkables.Where(p => liveTargets.Any(t => p.IsInRange(attacker.Range, t)));

        Console.WriteLine("MoveFarthestAndAttack " + attacker.ToPoint());
        Console.WriteLine("Walkables: " + walkables.Count());
        Console.WriteLine("WalkablesWithTargets: " + walkablesWithTargets.Count());

        if (walkablesWithTargets.Any())
        {
            var walkTo = walkablesWithTargets.MaxBy(p => movementSearch.GScore[p]);
            var path = Pather.ConstructPath(movementSearch.CameFrom, walkTo);
            foreach (var step in path.Skip(1))
            {
                Console.WriteLine("Move {0} -> {1}", attacker.ToPoint(), step);
                attacker.move(step.x, step.y);
            }
            var target = liveTargets.First(t => attacker.IsInRange(t));
            attacker.operate(target.x, target.y);
        }
    }
Example #2
0
    public static void BeSmarter(IEnumerable<Point> attackers, IEnumerable<Point> targets, Func<Droid, IEnumerable<DroidTurn>, DroidTurn> choose)
    {
        Bb.ReadBoard();

        var validAttackers = attackers.Where(a => Bb.DroidLookup.ContainsKey(a) && Bb.DroidLookup[a].AttacksLeft > 0);
        if (!validAttackers.Any())
        {
            return;
        }

        var validTargets = targets.Where(t => t.IsAttackable());
        if (!validTargets.Any())
        {
            return;
        }

        var attackerBits = validAttackers.ToBitArray();
        var targetBits = validTargets.ToBitArray();

        var targetRangeSearch = new Pather.Search(
            targets,
            p => isPassable(p) || attackerBits.Get(p) || targetBits.Get(p),
            p => false);

        var reachingAttackers = targetRangeSearch.GScore.Keys.Where(p => attackerBits.Get(p));
        if (!reachingAttackers.Any())
        {
            return;
        }

        var attacker = reachingAttackers.MinBy((a1, a2) => CompareAttackers(a1, a2, targetRangeSearch.GScore));
        var droid = Bb.DroidLookup[attacker];

        var walkSearch = new Pather.Search(
            new[] { attacker },
            p => isPassable(p),
            p => false,
            (p1, p2) => 1,
            droid.MovementLeft);

        List<DroidTurn> turnChoices = new List<DroidTurn>();

        var walkable = walkSearch.GScore.Where(kvp => kvp.Value <= droid.MovementLeft).Select(kvp => kvp.Key);
        foreach (var destination in walkable)
        {
            var path = Pather.ConstructPath(walkSearch.CameFrom, destination).Skip(1);
            var targetsInRange = destination.GetPointsInRange(droid.Range).Where(p => targetBits.Get(p));
            var movementLeft = droid.MovementLeft - (path.Count());
            if (movementLeft > 0)
            {
                var nextWalkSearch = new Pather.Search(
                    new[] { destination },
                    p => isPassable(p) || p.Equals(attacker),
                    p => false,
                    (p1, p2) => 1,
                    movementLeft);
                var nextWalkable = nextWalkSearch.GScore.Where(kvp => kvp.Value <= movementLeft).Select(kvp => kvp.Key);
                foreach (var nextDestination in nextWalkable)
                {
                    var fullPath = path.Concat(Pather.ConstructPath(walkSearch.CameFrom, nextDestination).Skip(1));
                    var turn = new DroidTurn();
                    turn.Steps = fullPath;
                    turn.Targets = targetsInRange;
                    turnChoices.Add(turn);
                }
            }
            else
            {
                var turn = new DroidTurn();
                turn.Steps = path;
                turn.Targets = targetsInRange;
                turnChoices.Add(turn);
            }
        }

        Console.WriteLine("{0} {1}", (Unit)droid.Variant, droid.ToPoint());
        foreach (var turn in turnChoices)
        {
            foreach (var step in turn.Steps)
            {
                Console.Write(step + "->");
            }
            Console.WriteLine(" X" + turn.Targets.Count());
        }

        var choice = choose(droid, turnChoices);
        choice.Apply(droid);

        attackerBits.Set(droid.ToPoint(), false);

        BeSmarter(attackerBits.ToPoints(), targets, choose);
    }
Example #3
0
    public static void MoveCloseTo(Point mover, Point target)
    {
        Bb.ReadBoard();
        if (!Bb.DroidLookup.ContainsKey(mover))
        {
            return;
        }

        var droid = Bb.DroidLookup[mover];
        var search = new Pather.Search(
            new Point[] { mover },
            isPassable,
            p => false,
            (p1, p2) => 1,
            droid.MovementLeft);

        var walkable = search.GScore.Where(kvp => kvp.Value < droid.MovementLeft).Select(kvp => kvp.Key);
        if (!walkable.Any())
        {
            return;
        }

        var destination = walkable.MinBy(p => p.ManhattanDistance(target));
        var steps = Pather.ConstructPath(search.CameFrom, destination).Skip(1);

        foreach (var step in steps)
        {
            TryOperate(droid);
            droid.move(step.x, step.y);
        }
        TryOperate(droid);
    }
Example #4
0
 public static Point FindFastestSpawn(Func<Point, bool> isSpawnable, IEnumerable<Point> targets, int moveSpeed)
 {
     var search = new Pather.Search(targets, isPassable, p => false);
     var reachable = search.GScore.Keys.Where(s => isSpawnable(s));
     if (!reachable.Any())
     {
         return new Point(-1, -1);
     }
     return reachable.MinBy(s => search.GScore[s] + Bb.GetSpawnDelay(s) * moveSpeed);
 }