Beispiel #1
0
        public void Retreat(GameState state, int[,] EnemyDist, Ant ant)
        {
            var best = Ants.Aim.Keys.Select(dir => new { dir, loc = state.GetDestination(ant, dir) })
                       .Where(x => !state.OccupiedNextRound.At(x.loc))
                       .Where(x => state.GetIsPassable(x.loc))
                       .OrderBy(x => EnemyDist.At(x.loc))
                       .LastOrDefault();

            if (best == null)
            {
                return;
            }

            if (EnemyDist.At(best.loc) >= EnemyDist.At(ant))
            {
                Bot.IssueOrder(state, ant, best.dir, "Retreat" + battleId);
            }


            //foreach (Direction direction in Ants.Aim.Keys)
            //{
            //    Location newLoc = state.GetDestination(ant, direction);
            //   //Todo sort best result;
            //    if (state.GetIsPassable(newLoc) && !state.OccupiedNextRound.At(newLoc) && EnemyDist.At(newLoc) > EnemyDist.At(ant))
            //    {
            //        Bot.IssueOrder(state, ant, direction);
            //        break;
            //    }
            //}
        }
Beispiel #2
0
        public void Attack(GameState state, int[,] EnemyDist, Ant ant)
        {
            var best = Ants.Aim.Keys.Select(dir => new { dir, loc = state.GetDestination(ant, dir) })
                       .Where(x => !state.OccupiedNextRound.At(x.loc))
                       .Where(x => state.GetIsPassable(x.loc))
                       .OrderByDescending(x => EnemyDist.At(x.loc))
                       //.ThenBy(state.GetBestDirection(x.loc, loc) //Prioritize by direction, need to have a goal...
                       .LastOrDefault();

            if (best == null)
            {
                return;//TODO wals around obstacle here??
            }
            if (EnemyDist.At(best.loc) <= EnemyDist.At(ant))
            {
                Bot.IssueOrder(state, ant, best.dir, "Attack" + battleId);
            }


            //foreach (Direction direction in Ants.Aim.Keys)
            //{
            //    Location newLoc = state.GetDestination(ant, direction);
            //   //Todo sort best result;
            //    if (state.GetIsPassable(newLoc) && !state.OccupiedNextRound.At(newLoc) && EnemyDist.At(newLoc) > EnemyDist.At(ant))
            //    {
            //        Bot.IssueOrder(state, ant, direction);
            //        break;
            //    }
            //}
        }
Beispiel #3
0
        public static void IssueOrder(GameState state, Location loc, Direction direction, string action)
        {
            System.Console.Out.WriteLine("o {0} {1} {2}", loc.Row, loc.Col, direction.ToChar());

            Logger.Log.Trace("Ant Moved : {0} => {1} ({2}) ", loc, direction, action);

            if (state.OccupiedNextRound.At(loc) != true)
            {
                Logger.Log.Error("Source Location was not occupied (ant moved)...   ANT {0}  {1}", loc, new System.Diagnostics.StackTrace(1, true));
            }

            if (state.OccupiedNextRound.At(state.GetDestination(loc, direction)) == true)
            {
                Logger.Log.Error("Dest Location is occupied...   ANT {0}  {1}", loc, new System.Diagnostics.StackTrace(1, true));
            }

            state.OccupiedNextRound.Set(loc, false);
            state.OccupiedNextRound.Set(state.GetDestination(loc, direction), true);
        }
Beispiel #4
0
        public static TargetWithDir <T> FindClosest <T>(GameState state, Location startingPoint, Func <Location, T> test, int MaxDistance = 10) where T : class
        {
            Dictionary <Location, int> distance = new Dictionary <Location, int>();

            var queue = new Queue <Location>();

            distance[startingPoint] = 0;
            queue.Enqueue(startingPoint);


            while (queue.Count > 0)
            {
                var item = queue.Dequeue();

                foreach (Direction direction in Ants.Aim.Keys)
                {
                    Location newLoc = state.GetDestination(item, direction);
                    if (distance.ContainsKey(newLoc))
                    {
                        continue;//Already tested
                    }
                    if (!state.GetIsPassable(newLoc))
                    {
                        continue;//Cant go there
                    }
                    T result = test(newLoc);
                    if (result != null)
                    {
                        return(new TargetWithDir <T>(result, direction, distance[item] + 1, startingPoint));
                    }

                    if (distance[item] + 1 >= MaxDistance)
                    {
                        continue;
                    }

                    distance[newLoc] = distance[item] + 1;
                    queue.Enqueue(newLoc);
                }
            }

            return(null);
        }
Beispiel #5
0
        private bool goToFront(GameState state, int[,] visibility, Ant ant)
        {
            int       value = visibility.At(ant);
            Direction dir   = Direction.North;

            foreach (Direction direction in Ants.Aim.Keys)
            {
                Location newLoc = state.GetDestination(ant, direction);
                if (state.GetIsPassable(newLoc) && !state.OccupiedNextRound.At(newLoc) && value > visibility.At(newLoc))
                {
                    value = visibility.At(newLoc);
                    dir   = direction;
                }
            }
            if (value != visibility.At(ant))
            {
                IssueOrder(state, ant, dir, "Go To Front");
                return(true);
            }
            return(false);
        }
Beispiel #6
0
        private bool getFood(GameState state, int[,] FoodProximity, Ant ant)
        {
            if (FoodProximity.At(ant) < FoodRadius)
            {
                int       value = 999;
                Direction dir   = Direction.North;
                foreach (Direction direction in Ants.Aim.Keys)
                {
                    Location newLoc = state.GetDestination(ant, direction);
                    if (state.GetIsPassable(newLoc) && !state.OccupiedNextRound.At(newLoc) && value > FoodProximity.At(newLoc))
                    {
                        value = FoodProximity.At(newLoc);
                        dir   = direction;
                    }
                }

                IssueOrder(state, ant, dir, "GetFoodOld");
                return(true);
            }

            return(false);
        }
Beispiel #7
0
        private bool explore(GameState state, int[,] visibility, Ant ant)
        {
            ////find the nearest undiscovered spot and go in that direction
            // TODO if two direction are in the way of the "unknown", select the one with the most spread with the other ants
            {
                int value = visibility.At(ant);
                if (value < unknownExplorationDistance)
                {
                    Direction dir = Direction.North;
                    foreach (Direction direction in Ants.Aim.Keys)
                    {
                        Location newLoc = state.GetDestination(ant, direction);
                        if (state.GetIsPassable(newLoc) && !state.OccupiedNextRound.At(newLoc) && value > visibility.At(newLoc))
                        {
                            value = visibility.At(newLoc);
                            dir   = direction;
                        }
                    }
                    if (value != visibility.At(ant))
                    {
                        IssueOrder(state, ant, dir, "Explore");
                        return(true);
                    }
                }
            }


            //try distanciate other ants
            //var AllyProximity = calculateAllyProximity(state, ant);
            //if (AllyProximity.At(ant) < 20)
            //{
            //    int value = AllyProximity.At(ant);
            //    Direction dir = Direction.North;
            //    foreach (Direction direction in Ants.Aim.Keys)
            //    {
            //        Location newLoc = state.GetDestination(ant, direction);
            //        if (state.GetIsPassable(newLoc) && !state.OccupiedNextRound.At(newLoc) && value < AllyProximity.At(newLoc))
            //        {
            //            value = AllyProximity.At(newLoc);
            //            dir = direction;
            //        }

            //    }
            //    if (value != AllyProximity.At(ant))
            //    {
            //        IssueOrder(state, ant, dir);
            //        return true;
            //    }
            //}

            ////try all the directions
            //foreach (Direction direction in Ants.Aim.Keys)
            //{

            //    // GetDestination will wrap around the map properly
            //    // and give us a new location
            //    Location newLoc = state.GetDestination(ant, direction);

            //    // GetIsPassable returns true if the location is land
            //    if (state.GetIsPassable(newLoc))
            //    {
            //        IssueOrder(ant, direction);
            //        // stop now, don't give 1 and multiple orders
            //        return true;
            //    }
            //}

            return(false);
        }
Beispiel #8
0
        public override void DoTurn(GameState state)
        {
            try
            {
                Log.Debug("Starting Turn " + turn++);// state.TimeRemaining
                //FoodRadius = (int)Math.Sqrt(state.ViewRadius2);


                //Calculate proximity
                //var FoodProximity = calculateFoodProximity(state);
                var visibility = calculateVisibilityProximity(state);

                var enemyProximity = CalculateProximity(state, state.EnemyHills.Union <TeamLocation>(state.EnemyAnts).ToList(), 200);


                var antMoved         = new List <Ant>();
                var ennemyConsidered = new List <Ant>();


                //Attack/defend
                foreach (Ant enemy in state.EnemyAnts)
                {
                    if (ennemyConsidered.Contains(enemy))
                    {
                        continue;
                    }

                    if (Math.Sqrt(state.ViewRadius2) - visibility.At(enemy) < BattleRadius)
                    {
                        var battle = new Battle();
                        battle.StartBattle(state, state.MyAnts.Except(antMoved).OrderBy(a => state.GetDistance(enemy, a)).First(), enemy, enemyProximity);

                        ennemyConsidered.AddRange(battle.EnemyPlatoon);
                        antMoved.AddRange(battle.AllyPlatoon);
                    }
                }



                { //Food.getAnt
                    var antLookingForFood = state.MyAnts.Except(antMoved).ToList();
                    var antGatheringFood  = new Dictionary <Ant, TargetWithDir <Ant> >();
                    var foodqueue         = new Queue <Location>(state.FoodTiles.Union(state.EnemyHills));

                    while (foodqueue.Count > 0)
                    {
                        var food   = foodqueue.Dequeue();
                        var result = FindClosest(state, food, x => antLookingForFood.Select(ant => (x.Row == ant.Row && x.Col == ant.Col) ? ant : null).Where(y => y != null).FirstOrDefault());
                        Log.Trace("Food.GetAnt : Food{0} => Ant {1}", food, result?.Target);
                        if (result != null)
                        {
                            if (antGatheringFood.ContainsKey(result.Target))
                            {
                                Log.Trace("Food.GetAnt : ANT already selected  at Food{0} => Ant {1}", antGatheringFood[result.Target].Source, result.Target);
                                if (antGatheringFood[result.Target].Dist > result.Dist)
                                {
                                    foodqueue.Enqueue(antGatheringFood[result.Target].Source);
                                }
                                else
                                {
                                    continue;
                                }
                            }

                            var      dir    = result.Dir.Opposite();
                            Location newLoc = state.GetDestination(result.Target, dir);


                            antGatheringFood.Add(result.Target, result);

                            antLookingForFood.Remove(result.Target);
                        }
                    }


                    foreach (var item in antGatheringFood)
                    {
                        var      result = item.Value;
                        var      dir    = result.Dir.Opposite();
                        Location newLoc = state.GetDestination(result.Target, dir);

                        if (!state.OccupiedNextRound.At(newLoc))
                        {
                            IssueOrder(state, result.Target, dir, "GetFood");
                        }
                    }

                    antMoved.AddRange(antGatheringFood.Keys);
                }

                var antToMove = state.MyAnts.Except(antMoved).ToList();
                foreach (Ant ant in antToMove)
                {
                    // check if we have time left to calculate more orders
                    if (state.TimeRemaining < 10)
                    {
                        break;
                    }



                    // General game signals
                    // Defend hill -> converge + sacrifice self
                    //continue if move done


                    //if (getFood(state, FoodProximity, ant)) //Replace par food.getAnt() above
                    //    continue;


                    if (explore(state, visibility, ant))
                    {
                        continue;
                    }

                    goToFront(state, enemyProximity, ant);
                }
            }
            catch (Exception e)
            {
                Log.Debug(e.ToString());
            }

            //For debugging
            //while (state.TimeRemaining > 10) continue;
        }
        // DoTurn is run once per turn
        public override void DoTurn(GameState state)
        {
            state.expectedLocation.Clear();
            //attack until our number of ants falls below 250 from 300
            if (!attackMode && state.MyAnts.Count > 300) attackMode = true;
            if (attackMode && state.MyAnts.Count < 250) attackMode = false;

            this.diffuseOne(state);
            this.diffuseTwo(state);
            // loop through all my ants and try to give them orders
            foreach (Ant ant in state.MyAnts)
            {
                Location up = state.GetDestination(ant, Direction.North);
                Location right = state.GetDestination(ant, Direction.East);
                Location left = state.GetDestination(ant, Direction.West);
                Location down = state.GetDestination(ant, Direction.South);

                List<Tup4> adjacentTiles = new List<Tup4>();

                //use diffusion layer 1 this layer prefers to harvest food and grow the ant colony
                if (!attackMode)
                {
                    Tup4 n1 = new Tup4(state.diffusionOne[up.Row, up.Col], Direction.North, up.Row, up.Col);
                    Tup4 e1 = new Tup4(state.diffusionOne[right.Row, right.Col], Direction.East, right.Row, right.Col);
                    Tup4 w1 = new Tup4(state.diffusionOne[left.Row, left.Col], Direction.West, left.Row, left.Col);
                    Tup4 s1 = new Tup4(state.diffusionOne[down.Row, down.Col], Direction.South, down.Row, down.Col);
                    adjacentTiles.Add(n1);
                    adjacentTiles.Add(e1);
                    adjacentTiles.Add(s1);
                    adjacentTiles.Add(w1);
                }
                else
                {
                    Tup4 n2 = new Tup4(state.diffusionTwo[up.Row, up.Col], Direction.North, up.Row, up.Col);
                    Tup4 e2 = new Tup4(state.diffusionTwo[right.Row, right.Col], Direction.East, right.Row, right.Col);
                    Tup4 w2 = new Tup4(state.diffusionTwo[left.Row, left.Col], Direction.West, left.Row, left.Col);
                    Tup4 s2 = new Tup4(state.diffusionTwo[down.Row, down.Col], Direction.South, down.Row, down.Col);
                    //use diffusion layer 2, this layer prefers to be aggressive
                    adjacentTiles.Add(n2);
                    adjacentTiles.Add(s2);
                    adjacentTiles.Add(e2);
                    adjacentTiles.Add(w2);
                }

                double maxDiffusion = 0; //assume the ant can't move
                Direction direction = Direction.East;
                int ct = 0;
                int row = 0;
                int col = 0;
                //check the four adjacent tiles to move
                while (ct < 4)
                {
                   //check if this tile has a higher diffusion score and that it is not occupied already by a friendly ant
                    if (adjacentTiles[ct].Item1 > maxDiffusion && state.diffusionOne[adjacentTiles[ct].Item3, adjacentTiles[ct].Item4] > 0 && state.GetIsUnoccupied(new Location(adjacentTiles[ct].Item3, adjacentTiles[ct].Item4)))
                    {
                        maxDiffusion = adjacentTiles[ct].Item1;
                        direction = adjacentTiles[ct].Item2;
                        row = adjacentTiles[ct].Item3;
                        col = adjacentTiles[ct].Item4;
                    }
                    ct += 1;
                }

                //ants will only move onto tiles with a diffusion score > 0
                if (maxDiffusion > 0)
                {
                    IssueOrder(ant, direction);
                    state.diffusionOne[row, col] = 0;
                    state.expectedLocation[state.GetDestination(ant, direction)] = ant;
                }
                else
                {
                    //ant could not move expected location is the same
                    state.expectedLocation[new Location(ant.Row, ant.Col)] = ant;
                }
                // check if we have time left to calculate more orders
                if (state.TimeRemaining < 10)
                {
                    //exit the loop immediately to prevent the bot from timing out
                   break;
                }
            }
        }
Beispiel #10
0
        /// <summary>
        /// Calculate the current diffusion scores for layer 2.
        /// </summary>
        /// <param name="state">The state.</param>
        public void diffuseTwo(GameState state)
        {
            for (int row = 0; row < state.Height; row++)
            {
                for (int col = 0; col < state.Width; col++)
                {
                    if (state.map[row, col] == Tile.Water) state.diffusionTwo[row, col] = WATER_SCORE;

                    else if (state.map[row, col] == Tile.Ant
                        && state.ants.ContainsKey(new Location(row, col))
                        && state.ants[new Location(row, col)].Team != 0)
                    {
                        state.diffusionTwo[row, col] = ENEMY_ANT_SCORE_D2;
                    }
                    else if (state.map[row, col] == Tile.Unseen)
                    {
                        state.diffusionTwo[row, col] = UNSEEN_SCORE_D2;
                    }
                    else if (state.isEnemyHill(row, col))
                    {
                        state.diffusionTwo[row, col] = ENEMYHILL_SCORE_D2;
                    }
                    else if (state.isMyHill(row, col))
                    {
                        state.diffusionTwo[row, col] = MYHILL_SCORE;
                    }
                    else
                    {
                        double u = state.diffusionTwo[row, col];
                        Location location = new Location(row, col);
                        Location up = state.GetDestination(location, Direction.North);
                        Location right = state.GetDestination(location, Direction.East);
                        Location left = state.GetDestination(location, Direction.West);
                        Location down = state.GetDestination(location, Direction.South);
                        state.diffusionTwo[row, col] = u + D2_COEFFICIENT * (1
                                                     + state.diffusionTwo[up.Row, up.Col]
                                                     + state.diffusionTwo[down.Row, down.Col]
                                                     + state.diffusionTwo[left.Row, left.Col]
                                                     + state.diffusionTwo[right.Row, right.Col]
                                                     - u * 4);
                    }
                }
            }
        }
Beispiel #11
0
        /// <summary>
        /// Calculate the current diffusion scores for layer 1.
        /// </summary>
        /// <param name="state">The state.</param>
        public void diffuseOne(GameState state)
        {
            for (int row = 0; row < state.Height; row++)
            {
                for (int col = 0; col < state.Width; col++)
                {
                    if (state.map[row, col] == Tile.Water)
                    {
                        state.diffusionOne[row, col] = WATER_SCORE;
                    }

                    else if (state.map[row, col] == Tile.Ant)
                    {
                        state.diffusionOne[row, col] = MY_ANT_SCORE_D1;

                        Location location = new Location(row, col);
                        if (state.ants.ContainsKey(location))
                        {
                            Ant ant = state.ants[location];

                            if (ant.Team != 0)
                            {
                                List<AntHill> myHills = state.MyHills;
                                foreach (AntHill myHill in myHills)
                                {
                                    if (state.GetDistance(myHill, ant) <= 12)
                                    {
                                        state.diffusionOne[row, col] = HILL_IN_DANGER;

                                        break;
                                    }
                                }
                            }
                        }
                    }
                    else if (state.map[row, col] == Tile.Food)
                    {
                        state.diffusionOne[row, col] = FOOD_SCORE_D1;
                    }
                    else if (state.map[row, col] == Tile.Unseen)
                    {
                        state.diffusionOne[row, col] = UNSEEN_SCORE_D1;
                    }
                    else if (state.isEnemyHill(row, col))
                    {
                        state.diffusionOne[row, col] = ENEMYHILL_SCORE_D1;
                    }
                    else if (state.isMyHill(row, col))
                    {
                        state.diffusionOne[row, col] = MYHILL_SCORE;
                    }
                    else
                    {
                        double u = state.diffusionOne[row, col];
                        Location L = new Location(row, col);
                        Location up = state.GetDestination(L, Direction.North);
                        Location right = state.GetDestination(L, Direction.East);
                        Location left = state.GetDestination(L, Direction.West);
                        Location down = state.GetDestination(L, Direction.South);
                        state.diffusionOne[row, col] = u + D1_COEFFICIENT * (1
                                                     + state.diffusionOne[up.Row, up.Col]
                                                     + state.diffusionOne[down.Row, down.Col]
                                                     + state.diffusionOne[left.Row, left.Col]
                                                     + state.diffusionOne[right.Row, right.Col]
                                                     - u * 4);
                    }
                }
            }
        }