예제 #1
0
 public void AddAnt(int col, int row, int team)
 {
     if (team == 0)
     {
         var ant = new MyAnt {
             X = col, Y = row
         };
         var index = MyAnts.BinarySearch(ant);
         if (index < 0)
         {
             MyAnts.Insert(~index, ant);
             NewAnt(ant);
             ant.Live = true;
             ant.Home = Hills.Where(x => x.DirectDistanceTo(ant) == Hills.Min(h => h.DirectDistanceTo(ant))).First();
         }
         else
         {
             ApplyAntVision(ant);
             MyAnts[index].Live = true;
         }
     }
     else
     {
         var ant = new Ant {
             X = col, Y = row, Team = team
         };
         EnemyAnts.Add(ant);
     }
     Map[col, row] = Tile.Ant;
 }
예제 #2
0
        List <MoveData> MoveToExploreNV(MyAnt ant, GameState state)
        {
            var result     = new List <MoveData>();
            int maxExplore = 0;

            for (int i = 0; i < 4; i++)
            {
                if (ant.RightDirections[i])
                {
                    var newLoc = ant + PathFinding.Directions[i];
                    if (ant.Exploration[i].VisibleCellCount > maxExplore && !state.NextTurnPreview[newLoc.X, newLoc.Y])
                    {
                        maxExplore = ant.Exploration[i].VisibleCellCount;
                    }
                }
            }
            if (maxExplore > 0)
            {
                for (int i = 0; i < 4; i++)
                {
                    if (ant.RightDirections[i])
                    {
                        var newLoc = ant + PathFinding.Directions[i];
                        if (ant.Exploration[i].VisibleCellCount == maxExplore && !state.NextTurnPreview[newLoc.X, newLoc.Y])
                        {
                            result.Add(new MoveData(newLoc, (Direction)i));
                        }
                    }
                }
            }
            return(result);
        }
예제 #3
0
 void ApplyAntVision(MyAnt ant)
 {
     FillVisionMap(ant);
     foreach (var loc in MoveVision)
     {
         var point = loc + ant;
         var tile  = GetTile(point);
         if (tile == Tile.Unseen)
         {
             SetTile(point, Tile.Land);
         }
     }
 }
예제 #4
0
 void NewAnt(MyAnt ant)
 {
     FillVisionMap(ant);
     foreach (var loc in FullVision)
     {
         var point = loc + ant;
         var tile  = GetTile(point);
         if (tile == Tile.Unseen)
         {
             SetTile(point, Tile.Land);
         }
     }
 }
예제 #5
0
        List <MoveData> MoveToFood(MyAnt ant, GameState state)
        {
            var result = new List <MoveData>();

            for (int i = 0; i < 4; i++)
            {
                if (ant.RightDirections[i])
                {
                    var newLoc = ant + PathFinding.Directions[i];
                    if (ant.Food.DistanceMap[newLoc.X, newLoc.Y] == ant.FoodDistance - 1 && !state.NextTurnPreview[newLoc.X, newLoc.Y])
                    {
                        result.Add(new MoveData(newLoc, (Direction)i));
                    }
                }
            }
            return(result);
        }
예제 #6
0
        List <MoveData> MoveFromHill(MyAnt ant, GameState state)
        {
            var result = new List <MoveData>();

            if (ant.Home == null)
            {
                return(result);
            }
            if (ant.PointFromHill != null)
            {
                return(result);
            }

            var fromHillDirections = new int[4];
            var stochastics        = new int[4];
            var locs  = new Location[4];
            var count = 0;

            for (int i = 0; i < 4; i++)
            {
                if (ant.RightDirections[i])
                {
                    var newLoc = ant + PathFinding.Directions[i];
                    if (state.NextTurnPreview[newLoc.X, newLoc.Y])
                    {
                        continue;
                    }
                    if (ant.Home.DistanceMap[ant.X, ant.Y] < ant.Home.DistanceMap[newLoc.X, newLoc.Y] && ant.Home.DistanceMap[ant.X, ant.Y] != -1)
                    {
                        if (ant.Home.StochasticMap[newLoc.X, newLoc.Y] == 0)
                        {
                            ant.Home.StochasticMap[newLoc.X, newLoc.Y] = PathFinding.GetTotalLeafCount(newLoc, ant.Home);
                        }
                        fromHillDirections[count] = i;
                        stochastics[count]        = ant.Home.StochasticMap[newLoc.X, newLoc.Y];
                        locs[count] = newLoc;
                        count++;
                    }
                }
            }

            if (count == 0 || stochastics.Sum() < 20)
            {
                return(result);
            }
            else
            {
                int r   = rnd.Next(stochastics.Sum());
                int sum = 0;
                for (int i = 0; i < count; i++)
                {
                    if (r >= sum && r < sum + stochastics[i])
                    {
                        return new List <MoveData> {
                                   new MoveData(locs[i], (Direction)fromHillDirections[i])
                        }
                    }
                    ;
                    sum += stochastics[i];
                }
                return(result);
            }
        }

        List <MoveData> MoveFromHillFast(MyAnt ant, GameState state)
        {
            var result = new List <MoveData>();

            if (ant.PointFromHill != null)
            {
                return(result);
            }

            var fromHillDirections = new bool[4];

            for (int i = 0; i < 4; i++)
            {
                if (ant.RightDirections[i])
                {
                    var newLoc = ant + PathFinding.Directions[i];
                    if (state.NextTurnPreview[newLoc.X, newLoc.Y])
                    {
                        continue;
                    }
                    if (ant.Home.DistanceMap[ant.X, ant.Y] <= ant.Home.DistanceMap[newLoc.X, newLoc.Y] && ant.Home.DistanceMap[ant.X, ant.Y] != -1)
                    {
                        result.Add(new MoveData(newLoc, (Direction)i));
                    }
                }
            }
            return(result);
        }

        List <MoveData> SpecificMoveFromHill(MyAnt ant, GameState state)
        {
            if (ant.Home == null)
            {
                return(new List <MoveData>());
            }

            if (ant.PointFromHill != null)
            {
                var result = new List <MoveData>();
                for (int i = 0; i < 4; i++)
                {
                    if (ant.RightDirections[i])
                    {
                        var newLoc = ant + PathFinding.Directions[i];
                        if (!state.NextTurnPreview[newLoc.X, newLoc.Y])
                        {
                            if (ant.SpecificPath[newLoc.X, newLoc.Y] != -1 && ant.SpecificPath[newLoc.X, newLoc.Y] < ant.SpecificPath[ant.X, ant.Y])
                            {
                                result.Add(new MoveData(newLoc, (Direction)i));
                            }
                        }
                    }
                }
                return(result);
            }

            int radius = Math.Min(30, Math.Min(state.Width - 1, state.Height - 1));

            do
            {
                var d = new Location();
                for (int dCoo = 0; dCoo < radius; dCoo++)
                {
                    for (int k = 0; k < 4; k++)
                    {
                        d.X = dCoo * (k / 2 == 0 ? -1 : 1);
                        d.Y = (radius - dCoo) * (k % 2 == 0 ? -1 : 1);
                        var loc = ant + d;
                        if (!state.NextTurnPreview[loc.X, loc.Y])
                        {
                            if (ant.Home.DistanceMap[loc.X, loc.Y] > ant.Home.DistanceMap[ant.X, ant.Y])
                            {
                                if (ant.Home.StochasticMap[loc.X, loc.Y] == 0)
                                {
                                    ant.Home.StochasticMap[loc.X, loc.Y] = PathFinding.GetTotalLeafCount(loc, ant.Home);
                                }
                                if (ant.Home.StochasticMap[loc.X, loc.Y] < 20)
                                {
                                    continue;
                                }

                                ant.PointFromHill = loc;
                                if (ant.SpecificPath == null)
                                {
                                    ant.SpecificPath = new int[state.Width, state.Height];
                                }
                                PathFinding.FillArray(loc, ant.SpecificPath, ant);

                                var result = new List <MoveData>();
                                for (int i = 0; i < 4; i++)
                                {
                                    if (ant.RightDirections[i])
                                    {
                                        var newLoc = ant + PathFinding.Directions[i];
                                        if (!state.NextTurnPreview[newLoc.X, newLoc.Y])
                                        {
                                            if (ant.SpecificPath[newLoc.X, newLoc.Y] != -1 && ant.SpecificPath[newLoc.X, newLoc.Y] < ant.SpecificPath[ant.X, ant.Y])
                                            {
                                                result.Add(new MoveData(newLoc, (Direction)i));
                                            }
                                        }
                                    }
                                }
                                return(result);
                            }
                        }
                    }
                }
                radius++;
            }while (radius < state.Width && radius < state.Height);
            return(new List <MoveData>());
        }

        List <MoveData> MoveRandom(MyAnt ant, GameState state)
        {
            var result = new List <MoveData>();

            for (int i = 0; i < 4; i++)
            {
                if (ant.RightDirections[i])
                {
                    var newLoc = ant + PathFinding.Directions[i];
                    if (!state.NextTurnPreview[newLoc.X, newLoc.Y])
                    {
                        result.Add(new MoveData(newLoc, (Direction)i));
                    }
                }
            }
            return(result);
        }
예제 #7
0
        List <MoveData> TryMove(MyAnt ant, GameState state)
        {
            List <MoveData> result;

            if (ant.Defend != null)
            {
                result = DefendHill(ant, state);
                for (int i = 0; i < result.Count; i++)
                {
                    result[i].Critical = true;
                }
                if (result.Count == 0)
                {
                    return(MoveRandom(ant, state));
                }
                else
                {
                    return(result);
                }
            }

            if (ant.EnemyHill != null && ant.EnemyHillDistance < 10)
            {
                result = MoveToEnemyHill(ant, state);
                if (result.Count > 0)
                {
                    return(result);
                }
            }

            if (state.Hills.Count > 0)
            {
                if (ant.Food != null)
                {
                    result = MoveToFood(ant, state);
                    if (ant.FoodDistance < 10)
                    {
                        for (int i = 0; i < result.Count; i++)
                        {
                            result[i].DeathForFood = true;
                        }
                    }
                    if (result.Count > 0)
                    {
                        return(result);
                    }
                }
            }

            if (!iSeeEnemy)
            {
                if (state.RemainMs > 150)
                {
                    result = MoveFromHill(ant, state);
                }
                else
                {
                    result = MoveFromHillFast(ant, state);
                }
                if (result.Count > 0)
                {
                    return(result);
                }
            }

            result = MoveToExploreNew(ant, state);
            if (result.Count > 0)
            {
                return(result);
            }

            if (!ant.GoToEnemyHill)
            {
                if (state.RemainMs > 150)
                {
                    result = MoveFromHill(ant, state);
                }
                else
                {
                    result = MoveFromHillFast(ant, state);
                }
                if (result.Count > 0)
                {
                    return(result);
                }
            }

            if (ant.EnemyHill != null)
            {
                result = MoveToEnemyHill(ant, state);
                if (result.Count > 0)
                {
                    return(result);
                }
            }

            result = SpecificMoveFromHill(ant, state);
            if (result.Count > 0)
            {
                return(result);
            }

            result = MoveToExploreNV(ant, state);
            if (result.Count > 0)
            {
                return(result);
            }

            result = MoveRandom(ant, state);

            return(result);
        }
예제 #8
0
        bool ProcessAnt(MyAnt ant, GameState state, int depth, List <MyAnt> usedAnts, List <Location> usedLocs)
        {
            if (!ant.RightDirections[0] &&
                !ant.RightDirections[1] &&
                !ant.RightDirections[2] &&
                !ant.RightDirections[3])
            {
                int minAttack = int.MaxValue;
                int goodDir   = -1;
                for (int dir = 0; dir < 4; dir++)
                {
                    var newLoc = ant + PathFinding.Directions[dir];
                    if (state.Map[newLoc.X, newLoc.Y] != Tile.Food && state.Map[newLoc.X, newLoc.Y] != Tile.Water)
                    {
                        int index = state.MyAnts.BinarySearch(new MyAnt(newLoc));
                        if (index >= 0 && state.MyAnts[index].Processed)
                        {
                            continue;
                        }
                        if (!state.NextTurnPreview[newLoc.X, newLoc.Y])
                        {
                            int att = state.GetAttackLoc(newLoc);
                            if (att < minAttack)
                            {
                                goodDir   = dir;
                                minAttack = att;
                            }
                        }
                    }
                }
                if (minAttack != int.MaxValue)
                {
                    ant.Move      = true;
                    ant.Direction = (Direction)goodDir;
                    ant.Processed = true;
                    var newLoc = ant + PathFinding.Directions[goodDir];
                    state.NextTurnPreview[newLoc.X, newLoc.Y] = true;
                    return(true);
                }
                ant.Move      = false;
                ant.Processed = true;
                state.NextTurnPreview[ant.X, ant.Y] = true;
                return(false);
            }

            var possibleMoves = TryMove(ant, state);

            if (possibleMoves.Count == 0)
            {
                return(false);
            }

            foreach (var md in possibleMoves)
            {
                md.Order = rnd.Next(0, 1000);
            }

            foreach (var md in possibleMoves.OrderBy(m => m.Order))
            {
                List <MyAnt>    rUsedAnts = null;
                List <Location> rUsedLocs = null;
                bool            result    = true;
                ant.Processed = true;
                state.NextTurnPreview[md.X, md.Y] = true;
                var index = state.MyAnts.BinarySearch(new MyAnt(md));
                if (index >= 0)
                {
                    if (!state.MyAnts[index].Processed)
                    {
                        rUsedAnts = new List <MyAnt>();
                        rUsedLocs = new List <Location>();
                        result    = ProcessAnt(state.MyAnts[index], state, depth + 1, rUsedAnts, rUsedLocs);
                    }
                }
                if (result)
                {
                    if (!md.Critical || ant.FightDirections[(int)md.Direction] > 1)
                    {
                        if (!md.DeathForFood || (ant.FightDirections[(int)md.Direction] > 1 && state.Players == 2))
                        {
                            if (ant.FightDirections[(int)md.Direction] > 0)
                            {
                                result = CheckForFight(md, state, null, null);
                                if (!result && rUsedAnts != null && rUsedLocs != null)
                                {
                                    for (int i = 0; i < rUsedAnts.Count; i++)
                                    {
                                        rUsedAnts[i].Processed = false;
                                    }
                                    for (int i = 0; i < rUsedLocs.Count; i++)
                                    {
                                        state.NextTurnPreview[rUsedLocs[i].X, rUsedLocs[i].Y] = false;
                                    }
                                }
                            }
                        }
                    }
                }
                if (!result)
                {
                    if (depth == 0)
                    {
                        ant.RightDirections[(int)md.Direction] = false;
                    }
                    ant.Processed = false;
                    ant.Move      = false;
                    state.NextTurnPreview[md.X, md.Y] = false;
                }
                if (result)
                {
                    ant.Processed       = true;
                    ant.Direction       = md.Direction;
                    ant.Move            = true;
                    ant.AttackEnemyHill = md.AttackEnemyHill;
                    if (usedAnts != null && usedLocs != null)
                    {
                        usedAnts.Add(ant);
                        usedLocs.Add(md);
                        if (rUsedAnts != null && rUsedLocs != null)
                        {
                            usedAnts.AddRange(rUsedAnts);
                            usedLocs.AddRange(rUsedLocs);
                        }
                    }
                    return(true);
                }
            }

            if (depth == 0)
            {
                return(ProcessAnt(ant, state, depth, null, null));
            }
            else
            {
                return(false);
            }
        }