public void EngageBeaverAndFood(Beaver beaver, Spawner cattail, Point[] path) { Solver.MoveAlong(beaver, path); if (beaver.ToPoint().Equals(path.Last())) { Solver.Harvest(beaver, new[] { cattail }); } }
public void BuildLodge(Beaver beaver) { if (beaver.CanAct() && beaver.CanBuildLodge()) { Console.WriteLine(" Build Lodge: {0}, {1}+{2}/{3}", beaver.ToPoint(), beaver.Branches, beaver.Tile.Branches, this.Player.BranchesToBuildLodge); beaver.BuildLodge(); } }
public void MoveBeaverAndDrop(Beaver beaver, Tile lodge, Point[] path) { Solver.MoveAlong(beaver, path); if (beaver.ToPoint().Equals(path.Last())) { Solver.Drop(beaver, new[] { lodge }, "food"); } }
/// <summary>Gets off the lodge if it's on one</summary> private bool GetOffLodge(Beaver b) { if (b.Tile.LodgeOwner == null) { return(false); } Tile target = this.GetNeighborWhere(b.Tile, t => t.LodgeOwner == null && b.Moves < b.MoveCost(t)); return(target != null && b.Move(target)); }
/// <summary>Harvests resource</summary> private bool Harvest(Beaver b, string resource) { // Don't bother harvesting if it can't hold anymore stuff if (b.Branches + b.Food >= b.Job.CarryLimit) { return(false); } bool keepGoing = false; // Function for finding movement targets Func <Tile, bool> isTarget = t => t.Spawner != null && t.Spawner.Type == resource && !t.Spawner.HasBeenHarvested && t.Spawner.Health > 3; // Find nearest resource, skipping current node IEnumerable <Tile> basePath = this.FindPathCustom(b.Tile, (t, parent) => { double cost = this.GetCost(t, parent, b); if (cost < 0) { return(cost); } return(this.IsNextTo(t, isTarget) ? 0 : cost); }) .Skip(1); // Traverse path LinkedList <Tile> path = new LinkedList <Tile>(basePath); while (path.Any()) { // If can't move anymore if (b.Moves < b.MoveCost(path.First()) || !b.Move(path.First())) { break; } path.RemoveFirst(); keepGoing = true; } // Try to harvest if next to the target spawner Tile target = this.GetNeighborWhere(b.Tile, isTarget); if (target != null && b.Actions > 0) { if (AI.Verbose) { Console.WriteLine("Harvesting resource"); } b.Harvest(target.Spawner); keepGoing = true; } return(keepGoing); }
public static bool MoveOff(Beaver beaver) { if (!beaver.CanMove()) { return(false); } var target = beaver.Tile.GetNeighbors().FirstOrDefault(n => n.IsPathable() && beaver.Moves >= GetMoveCost(beaver.Tile, n)); return(target != null && beaver.Move(target)); }
public void BasicEngageBeaverAndTree(Beaver beaver, Spawner tree, Point[] path) { BuildLodge(beaver); Solver.Harvest(beaver, new[] { tree }); Solver.MoveAlong(beaver, path); if (beaver.ToPoint().Equals(path.Last())) { Solver.Drop(beaver, new[] { beaver.Tile }, "branches"); Solver.Harvest(beaver, new[] { tree }); } BuildLodge(beaver); }
public static void MoveAndAttack(Beaver attacker, IEnumerable <Beaver> targets) { if (attacker.CanMove()) { var targetPoints = targets .Where(t => t.Health > 0) .SelectMany(t => t.Tile.GetNeighbors().Select(n => n.ToPoint())); Move(attacker, targetPoints); } Attack(attacker, targets); }
public static void Drop(Beaver dropper, IEnumerable <Tile> targets, string resource) { if (!dropper.CanAct() || dropper.GetCount(resource) == 0) { return; } var target = targets.FirstOrDefault(t => t == dropper.Tile || dropper.Tile._HasNeighbor(t)); if (target != null) { dropper.Drop(target, resource, dropper.GetCount(resource)); } }
public static void Pickup(Beaver picker, IEnumerable <Tile> targets, string resource) { if (!picker.CanAct() || picker.OpenCarryCapacity() == 0) { return; } var targettables = targets.Where(t => t.GetCount(resource) > 0 && picker.Tile._HasNeighbor(t)); if (targettables.Any()) { var target = targettables.MaxByValue(t => t.GetCount(resource)); picker.Pickup(target, resource, Math.Min(target.GetCount(resource), picker.OpenCarryCapacity())); } }
public static void MoveAndDrop(Beaver dropper, IEnumerable <Tile> targets, string resource) { if (!dropper.CanAct() || dropper.GetCount(resource) == 0) { return; } if (dropper.CanMove()) { var movePoints = targets.Concat(targets.SelectMany(t => t.GetNeighbors())) .Select(n => n.ToPoint()); Move(dropper, movePoints); } Drop(dropper, targets, resource); }
public static void MoveAndHarvest(Beaver harvester, IEnumerable <Spawner> spawners) { if (harvester.OpenCarryCapacity() == 0) { return; } if (harvester.CanMove()) { var movePoints = spawners .SelectMany(s => s.Tile.GetNeighbors().Select(n => n.ToPoint())); Move(harvester, movePoints); } Harvest(harvester, spawners); }
public static void Attack(Beaver attacker, IEnumerable <Beaver> targets) { var targettables = targets.Where(t => t.CanBeAttacked()); var target = targettables.FirstOrDefault(t => attacker.Tile._HasNeighbor(t.Tile)); if (target != null) { while (attacker.CanAct() && target.CanBeAttacked()) { if (attacker.Owner == target.Owner) { Console.WriteLine("DIE SLACKER"); } attacker.Attack(target); } } }
public static void Move(Beaver mover, IEnumerable <Point> targets) { var targetPoints = targets.ToHashSet <Point>(); if (mover.CanMove()) { var search = new AStar <Point>( new[] { mover.ToPoint() }, p => targetPoints.Contains(p), (p1, p2) => GetMoveCost(p1.ToTile(), p2.ToTile()), p => 0, p => p.ToTile().GetReachableNeighbors(mover.Job.Moves).Select(t => t.ToPoint()) ); MoveAlong(mover, search.Path); } }
public static int CalcTurnsToMove(Beaver beaver, Point end, AStar <Point> search) { var path = search.CalcPathTo(end); var turns = 0; var moves = beaver.Moves; foreach (var p in path) { var cost = GetMoveCost(beaver.Tile, p.ToTile()); moves -= cost; if (moves < 0) { turns++; moves = beaver.Job.Moves - cost; } } return(turns); }
public static void MoveAndPickup(Beaver picker, IEnumerable <Tile> targets, string resource) { if (!picker.CanAct() || picker.OpenCarryCapacity() == 0) { return; } var targetPoints = targets.Where(t => t.GetCount(resource) > 0); if (picker.CanMove()) { var movePoints = targetPoints.Concat(targetPoints.SelectMany(t => t.GetNeighbors())) .Select(n => n.ToPoint()); Move(picker, movePoints); } Pickup(picker, targets, resource); }
public static void Harvest(Beaver harvester, IEnumerable <Spawner> targets) { if (!harvester.CanAct() || harvester.OpenCarryCapacity() == 0) { return; } var targettables = targets.Where(t => t.Health > 0); var target = targettables.FirstOrDefault(t => harvester.Tile._HasNeighbor(t.Tile)); if (target != null) { while (harvester.CanAct() && target.Health > 0) { harvester.Harvest(target); } } }
private double GetCost(Tile t, Tile parent, Beaver self = null) { // Don't move over friendly lodges or solids if (t.LodgeOwner != null) { return(-1); } if (t.Beaver != null && t.Beaver != self) { return(-1); } if (t.Spawner != null) { return(-1); } return(parent?.MoveCost(t) ?? 2); }
public static void MoveAlong(Beaver beaver, IEnumerable <Point> steps, bool dontStopInDanger = false) { if (!steps.Any()) { return; } IEnumerable <Point> dontStops = new Point[0]; if (dontStopInDanger) { var fears = AI._Player.Opponent.Beavers .Where(b => b.CanBeAttacked()) .Where(b => b.Job == AI.Basic || b.Job == AI.Fighter || b.Job == AI.Bulky || b.Job == AI.HotLady) .Where(b => !b.Tile.GetNeighbors().Any(n => n.Beaver != null && n.Beaver.Owner == AI._Player)); if (fears.Any()) { dontStops = AI._Game.Tiles.Where(t => fears.Select(b => b.ToPoint().ManhattanDistance(t.ToPoint())).Min() == 2) .ToPoints() .ToHashSet(); } } AI.GoalLocations[beaver.Id] = steps.Last(); if (!beaver.CanMove()) { return; } var queue = steps.SkipWhile(p => p.Equals(beaver.ToPoint())).ToQueue(); while (queue.Count > 0 && queue.Peek().ToTile().IsPathable() && GetMoveCost(beaver.Tile, queue.Peek().ToTile()) <= beaver.Moves && !dontStops.Contains(queue.Peek())) { beaver.Move(queue.Dequeue().ToTile()); } }
public static Point ToPoint(this Beaver beaver) { return(beaver.Tile.ToPoint()); }
public void EngageBeaverAndTree(Beaver beaver, Spawner tree, Point[] path) { var safeDistance = 5; var enemyDistance = 100; var opponentBeavers = this.Player.Opponent.Beavers.Where(b => b.Health > 0); if (opponentBeavers.Any()) { enemyDistance = opponentBeavers.Min(b => b.ToPoint().ManhattanDistance(tree.Tile.ToPoint())); } //if (tree.Tile.GetNeighbors().Where(n => ValidTreeNeighbor(n)).Count() > 1 || enemyDistance < safeDistance) if (enemyDistance < safeDistance) { BasicEngageBeaverAndTree(beaver, tree, path); } else { var landmark = this.Player.Beavers.MaxByValue(b => b.ToPoint().ManhattanDistance(tree.Tile.ToPoint())).Tile; var roadPath = new AStar <Point>( new[] { path.Last() }, p => p.Equals(landmark.ToPoint()), (p1, p2) => Solver.GetMoveCost(p1.ToTile(), p2.ToTile()), p => 0, p => p.ToTile().GetNeighbors().Where(n => n.Spawner == null && n.LodgeOwner == null).Select(t => t.ToPoint()) ).Path.ToHashSet(); var dropOffSearch = new AStar <Point>( new[] { beaver.ToPoint() }, p => false, (p1, p2) => Solver.GetMoveCost(p1.ToTile(), p2.ToTile()), p => 0, p => p.ToTile().GetReachableNeighbors(AI.Builder.Moves).Select(t => t.ToPoint()) ); var dropOffOrder = dropOffSearch.GScore .Where(g => !roadPath.Contains(g.Key) && g.Key.ToTile().FlowDirection == "" && !g.Key.Equals(beaver.ToPoint()) && tree.Tile.ToPoint().ManhattanDistance(g.Key) <= 3) .OrderByDescending(g => g.Key.ToTile().Branches) .ThenByDescending(g => g.Value); if (!dropOffOrder.Any()) { BasicEngageBeaverAndTree(beaver, tree, path); return; } if (dropOffOrder.First().Value > 3) { BasicEngageBeaverAndTree(beaver, tree, path); } var dropOff = dropOffOrder.First().Key; var dropOffPath = dropOffSearch.CalcPathTo(dropOff); if (beaver.ToPoint().Equals(dropOff)) { BuildLodge(beaver); } if (!beaver.FullLoad()) { Solver.Harvest(beaver, new[] { tree }); Solver.MoveAlong(beaver, path); Solver.Harvest(beaver, new[] { tree }); } else { if ((beaver.Branches + dropOff.ToTile().Branches) < this.Player.BranchesToBuildLodge) { Solver.Drop(beaver, new[] { dropOff.ToTile() }, "branches"); Solver.MoveAlong(beaver, path); } else if (beaver.ToPoint().Equals(dropOffPath.Last())) { Solver.Drop(beaver, new[] { dropOff.ToTile() }, "branches"); } else { Solver.MoveAlong(beaver, dropOffPath); BuildLodge(beaver); } } } }
public static int GetCount(this Beaver beaver, string resource) { return(resource[0] == 'f' ? beaver.Food : beaver.Branches); }
internal static int MoveCost(this Beaver b, Tile target) => b.Tile.MoveCost(target);
public static int OpenCarryCapacity(this Beaver beaver) { return(beaver.Job.CarryLimit - (beaver.Branches + beaver.Food)); }
public static bool FullLoad(this Beaver b) { return(b.Food + b.Branches == b.Job.CarryLimit); }
public static bool CanBeAttacked(this Beaver beaver) { return(beaver.Owner == AI._Player.Opponent && beaver.Health > 0 && beaver.Recruited == true); }
public static bool CanMove(this Beaver beaver) { return(beaver.Health > 0 && beaver.Moves > 0 && beaver.TurnsDistracted == 0 && beaver.Recruited == true); }
public static bool CanAct(this Beaver beaver) { return(beaver.Health > 0 && beaver.Actions > 0 && beaver.TurnsDistracted == 0 && beaver.Recruited == true); }
public static bool CanBuildLodge(this Beaver beaver) { return(beaver.Branches + beaver.Tile.Branches >= beaver.Owner.BranchesToBuildLodge && beaver.Tile.LodgeOwner == null); }
/// <summary>Attacks enemy beavers</summary> private bool Attack(Beaver b) { if (b.Actions <= 0) { return(false); } bool retValue = false; // Find suitable building spot Func <Tile, bool> isTarget = t => t.Beaver != null && t.Beaver.Owner != this.Player && t.Beaver.Recruited; IEnumerable <Tile> pfResult; if (this.NextLodge == null) { // Look for a spot two spaces away from an unclaimed food spot pfResult = this.FindPathCustom(b.Tile, (t, parent) => { double cost = this.GetCost(t, parent, b); if (cost < 0) { return(cost); } return(this.IsNextTo(t, isTarget) ? 0 : cost); }) .Skip(1); // Look for a spot two spaces away from any unclaimed resource if (!pfResult.Any()) { pfResult = this.FindPathCustom(b.Tile, (t, parent) => { double cost = this.GetCost(t, parent, b); if (cost < 0) { return(cost); } if (isTarget(t)) { return(0); } return(cost); }) .Skip(1); } // Set this as the next lodge spot if (pfResult.Any()) { this.NextLodge = pfResult.Last(); } } else { pfResult = this.FindPathCustom(b.Tile, this.NextLodge).Skip(1); } // Traverse path LinkedList <Tile> path = new LinkedList <Tile>(pfResult); while (path.Any()) { // If can't move if (b.Moves < b.MoveCost(path.First()) || !b.Move(path.First())) { break; } path.RemoveFirst(); retValue = true; } // Try to attack a beaver Tile target = this.GetNeighborWhere(b.Tile, isTarget); if (target != null) { while (b.Actions > 0 && b.Health > target.Beaver.Job.Damage) { b.Attack(target.Beaver); } } return(retValue); }