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); } } } }