Example #1
0
    static SiteEx GetNeighbor(Map map, SiteEx from, Direction direction)
    {
        var leftCoord  = (ushort)(from.X == 0 ? (map.Width - 1) : from.X - 1);
        var rightCoord = (ushort)(from.X == (map.Width - 1) ? 0 : from.X + 1);
        var upCoord    = (ushort)(from.Y == 0 ? (map.Height - 1) : from.Y - 1);
        var downCoord  = (ushort)(from.Y == (map.Height - 1) ? 0 : from.Y + 1);

        switch (direction)
        {
        case Direction.West:
            return(new SiteEx(map, leftCoord, from.Y));

        case Direction.East:
            return(new SiteEx(map, rightCoord, from.Y));

        case Direction.North:
            return(new SiteEx(map, from.X, upCoord));

        case Direction.South:
            return(new SiteEx(map, from.X, downCoord));

        case Direction.Still:
        default:
            return(from);
        }
    }
Example #2
0
    private static Direction GetNearestNonPlayerDirection(Map map, SiteEx activeSite, ushort myID)
    {
        var lastTriedByDirection = new Dictionary <Direction, SiteEx>();

        lastTriedByDirection.Add(Direction.West, activeSite);
        lastTriedByDirection.Add(Direction.East, activeSite);
        lastTriedByDirection.Add(Direction.North, activeSite);
        lastTriedByDirection.Add(Direction.South, activeSite);

        for (int tries = 0; tries < map.Width / 2; tries++)
        {
            foreach (var kvp in lastTriedByDirection.ToArray())
            {
                if (NeighborInDirectionIsNonPlayer(map, kvp.Value, kvp.Key, myID))
                {
                    return(kvp.Key);
                }
                else
                {
                    lastTriedByDirection[kvp.Key] = GetNeighbor(map, lastTriedByDirection[kvp.Key], kvp.Key);
                }
            }
        }

        return(Direction.Still);
    }
Example #3
0
    static SiteEx GetNeighbor(Map map, SiteEx from, Direction direction)
    {
        var leftCoord  = (ushort)(from.X == 0 ? (map.Width - 1) : from.X - 1);
        var rightCoord = (ushort)(from.X == (map.Width - 1) ? 0 : from.X + 1);
        var upCoord    = (ushort)(from.Y == 0 ? (map.Height - 1) : from.Y - 1);
        var downCoord  = (ushort)(from.Y == (map.Height - 1) ? 0 : from.Y + 1);

        switch (direction)
        {
        case Direction.West:
            return(AllSites.First(s => s.X == leftCoord && s.Y == from.Y));

        case Direction.East:
            return(AllSites.First(s => s.X == rightCoord && s.Y == from.Y));

        case Direction.North:
            return(AllSites.First(s => s.X == from.X && s.Y == upCoord));

        case Direction.South:
            return(AllSites.First(s => s.X == from.X && s.Y == downCoord));

        case Direction.Still:
        default:
            return(from);
        }
    }
Example #4
0
    static List <SiteEx> GetAllNeighbors(Map map, SiteEx from)
    {
        var neighbors = new List <SiteEx>
        {
            GetNeighbor(map, @from, Direction.West),
            GetNeighbor(map, @from, Direction.East),
            GetNeighbor(map, @from, Direction.South),
            GetNeighbor(map, @from, Direction.North)
        };

        return(neighbors);
    }
Example #5
0
    private static Direction GetMoveDirection(Map map, SiteEx startSite, SiteEx destinationSite)
    {
        if (destinationSite.X == map.Width - 1 && startSite.X == 0)
        {
            return(Direction.West);
        }
        if (destinationSite.X == 0 && startSite.X == map.Width - 1)
        {
            return(Direction.East);
        }
        if (destinationSite.X < startSite.X)
        {
            return(Direction.West);
        }
        if (destinationSite.X > startSite.X)
        {
            return(Direction.East);
        }

        if (destinationSite.Y == map.Height - 1 && startSite.Y == 0)
        {
            return(Direction.North);
        }
        if (destinationSite.Y == 0 && startSite.Y == map.Height - 1)
        {
            return(Direction.South);
        }
        if (destinationSite.Y < startSite.Y)
        {
            return(Direction.North);
        }
        if (destinationSite.Y > startSite.Y)
        {
            return(Direction.South);
        }

        throw new Exception("Your destionation is the same as your start site.");
    }
Example #6
0
    public static void Main(string[] args)
    {
        Console.SetIn(Console.In);
        Console.SetOut(Console.Out);

        ushort       myID;
        var          map           = Networking.getInit(out myID);
        const ushort MAX_STRENGTH  = 255;
        const ushort HALF_STRENGTH = 128;

        /* ------
        *   Do more prep work, see rules for time limit
        *  ------ */

        Networking.SendInit(MyBotName); // Acknoweldge the init and begin the game

        var random = new Random();

        //var logFileName = string.Format(@"C:\Users\dolson\Source\Halite\Halite-C#-Starter-Package\Halite-C#-Starter-Package\log{0}.txt", DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"));
        var logFileName = string.Format("log{0}.txt", DateTime.Now.Ticks);

        AppendLog(logFileName, "Starting battle!");
        int frameNumber = 0;

        while (true)
        {
            try
            {
                Networking.getFrame(ref map); // Update the map to reflect the moves before this turn
            }
            catch (Exception)
            {
                return;
            }

            frameNumber++;

            AppendLog(logFileName, string.Format("Frame {0}", frameNumber));

            //Try to attack in a straight line to achive maximum "overkill"
            var previousAttackDirectionByLocation = new Dictionary <Location, Direction>();

            var moves = new List <Move>();
            for (ushort x = 0; x < map.Width; x++)
            {
                for (ushort y = 0; y < map.Height; y++)
                {
                    if (map[x, y].Owner == myID)
                    {
                        var activeSite = new SiteEx(map, x, y);

                        var neighbors = new List <SiteEx>()
                        {
                            GetNeighbor(map, activeSite, Direction.West),
                            GetNeighbor(map, activeSite, Direction.East),
                            GetNeighbor(map, activeSite, Direction.North),
                            GetNeighbor(map, activeSite, Direction.South)
                        };

                        var friendlySites       = neighbors.Where(c => c.Owner == myID);
                        var potentialLunchSites =
                            neighbors.Where(c => c.Strength < activeSite.Strength && c.Owner != myID);
                        var killSites   = potentialLunchSites.Where(c => c.Owner != 0);
                        var dangerSites =
                            neighbors.Where(c => c.Strength > activeSite.Strength && c.Owner != myID && c.Owner != 0); //TODO: what to do with danger sites?


                        //1. Continue an attack spearhead from previous turn first
                        if (previousAttackDirectionByLocation.ContainsKey(activeSite.Location))
                        {
                            var directionToMove = previousAttackDirectionByLocation[activeSite.Location];
                            previousAttackDirectionByLocation.Remove(activeSite.Location);

                            var neighbor = GetNeighbor(map, activeSite, directionToMove);
                            if (neighbor.Owner != myID && neighbor.Owner != 0)
                            {
                                previousAttackDirectionByLocation.Add(neighbor.Location, directionToMove);
                            }

                            moves.Add(new Move
                            {
                                Location  = activeSite.Location,
                                Direction = directionToMove
                            });
                        }
                        //2. Try to kill anything in sight
                        else if (killSites.Any())
                        {
                            var killSite        = killSites.First();
                            var directionToMove = GetMoveDirection(map, activeSite, killSite);


                            //AppendLog(logFileName, string.Format("Attack from [{0},{1}] (strength {4}) to [{2},{3}] (strength {5})",
                            //    activeSite.X, activeSite.Y, killSite.X, killSite.Y, activeSite.Strength,
                            //    killSite.Strength));

                            previousAttackDirectionByLocation.Add(GetNeighbor(map, activeSite, directionToMove).Location, directionToMove);

                            moves.Add(new Move
                            {
                                Location  = activeSite.Location,
                                Direction = directionToMove
                            });
                        }
                        //3. Try to take over neutral
                        else if (potentialLunchSites.Any())
                        {
                            var lunchSite       = potentialLunchSites.OrderByDescending(s => s.Production).First();
                            var directionToMove = GetMoveDirection(map, activeSite, lunchSite);

                            //AppendLog(logFileName, string.Format(
                            //    "Consume Neutral from [{0},{1}] (strength {4}) to [{2},{3}] (strength {5})",
                            //    activeSite.X, activeSite.Y, lunchSite.X, lunchSite.Y, activeSite.Strength,
                            //    lunchSite.Strength));


                            moves.Add(new Move
                            {
                                Location  = activeSite.Location,
                                Direction = directionToMove
                            });
                        }
                        //3. Find a buddy to merge with
                        //else if (friendlySites.Any(c => c.Strength < activeSite.Strength && c.Strength + activeSite.Strength > 25) && activeSite.Strength > 10)
                        //{
                        //    var friendSite = friendlySites.FirstOrDefault(c => c.Strength < activeSite.Strength && c.Strength + activeSite.Strength > 25);
                        //    var directionToMove = GetMoveDirection(map, activeSite, friendSite);

                        //    moves.Add(new Move
                        //    {
                        //        Location = activeSite.Location,
                        //        Direction = directionToMove
                        //    });
                        //}



                        //4. If all neighbors are friendly, move towards nearest edge.
                        else if (friendlySites.Count() == neighbors.Count && ((activeSite.Strength >= (activeSite.Production * 5)) || activeSite.Strength > HALF_STRENGTH))
                        {
                            var nearestNonPlayerDirection = GetNearestNonPlayerDirection(map, activeSite, myID);
                            if (nearestNonPlayerDirection != Direction.Still)
                            {
                                //AppendLog(logFileName, string.Format("Move to edge from [{0},{1}] (strength {3}) to {2}",
                                //    activeSite.X, activeSite.Y, nearestNonPlayerDirection, activeSite.Strength));

                                moves.Add(new Move
                                {
                                    Location  = activeSite.Location,
                                    Direction = nearestNonPlayerDirection
                                });
                            }
                            else //All orthagonal directions are occupied.
                            {
                                //TODO: could have logic here to find enemies or something, or go diagonally.
                            }
                        }

                        ////4. TODO: If large enough, move towards the closest neutral edge.
                        ////5. if all else fails, move randomly.
                        //else if (neighbors.Any(n => n.Strength < activeSite.Strength))
                        //{
                        //    moves.Add(new Move
                        //    {
                        //        Location = new Location { X = x, Y = y },
                        //        Direction = (Direction)random.Next(5)
                        //    });
                        //}
                    }
                }
            }

            Networking.SendMoves(moves); // Send moves
        }
    }
Example #7
0
    private static bool NeighborInDirectionIsNonPlayer(Map map, SiteEx site, Direction d, ushort myID)
    {
        var neighborSite = GetNeighbor(map, site, d);

        return(neighborSite.Owner != myID);
    }
Example #8
0
    private static Move?GetProductionSeekerBotMove(Map map, ushort x, ushort y)
    {
        //Borrows the code from ProductionSeekerBot2

        var activeSite = new SiteEx(map, x, y);

        if ((activeSite.Strength < activeSite.Production * 3) && (activeSite.Strength < MAX_STRENGTH / 12))
        {
            return(null);
        }

        var neighbors = new List <SiteEx>()
        {
            GetNeighbor(map, activeSite.Location, Direction.West),
            GetNeighbor(map, activeSite.Location, Direction.East),
            GetNeighbor(map, activeSite.Location, Direction.North),
            GetNeighbor(map, activeSite.Location, Direction.South)
        };

        var friendlySites = neighbors.Where(c => c.Owner == _MyID);
        var friendlySitesWorthVisiting =
            friendlySites.Where(
                f =>
                f.Strength > 0 && f.Strength + activeSite.Strength <MAX_STRENGTH &&
                                                                    f.Production> (_MaxProductionValue / 4));
        var neutralNeighbors  = neighbors.Where(c => c.Owner == 0);
        var weakNeighborSites = neighbors.Where(c => (activeSite.Strength == MAX_STRENGTH || c.Production > 0) && c.Strength < activeSite.Strength && c.Owner == 0);

        bool shouldCombine = false;

        if (!weakNeighborSites.Any())
        {
            if (activeSite.X + activeSite.Y % 2 == 1) //Only combine from every other square to prevent dancing.
            {
                shouldCombine = true;
            }
        }

        //Combine forces if we are a thin line.
        if (shouldCombine && friendlySitesWorthVisiting.Any())
        {
            var destination = friendlySitesWorthVisiting.FirstOrDefault(f => f.Production > activeSite.Production);
            if (destination != null)
            {
                var directionToMove = GetMoveDirection(map, activeSite.Location, destination.Location);
                DarreksLog.AppendLog("Combine Forces!");

                return(new Move
                {
                    Location = activeSite.Location,
                    Direction = directionToMove
                });
            }
        }

        //1. Try to grow
        if (weakNeighborSites.Any())
        {
            SiteEx lunchSiteToAttack = null;

            //Move Between enemies if possible for maximum damage!
            foreach (var pls in weakNeighborSites)
            {
                var nW = GetNeighbor(map, pls.Location, Direction.West);
                var nE = GetNeighbor(map, pls.Location, Direction.East);
                var nS = GetNeighbor(map, pls.Location, Direction.South);
                var nN = GetNeighbor(map, pls.Location, Direction.North);

                var enemyNeighborsCount = ((nW.Owner != _MyID && nW.Owner != 0) ? 1 : 0) +
                                          ((nE.Owner != _MyID && nE.Owner != 0) ? 1 : 0) +
                                          ((nS.Owner != _MyID && nS.Owner != 0) ? 1 : 0) +
                                          ((nN.Owner != _MyID && nN.Owner != 0) ? 1 : 0);

                if (enemyNeighborsCount > 1)
                {
                    lunchSiteToAttack = pls;
                }
            }

            if (lunchSiteToAttack == null)
            {
                lunchSiteToAttack = weakNeighborSites.OrderByDescending(s => s.Production - s.Strength / 10).First();
            }

            var directionToMove = GetMoveDirection(map, activeSite.Location, lunchSiteToAttack.Location);

            if (lunchSiteToAttack.Strength < activeSite.Strength)
            {
                return(new Move
                {
                    Location = activeSite.Location,
                    Direction = directionToMove
                });
            }
        }


        //2. If all neighbors are friendly, move towards nearest edge.
        else if (activeSite.Strength > 0 && friendlySites.Count() == neighbors.Count && ((activeSite.Strength >= (activeSite.Production * 3)) || activeSite.Strength > HALF_STRENGTH / 2))
        {
            ushort distanceFromEdge;
            var    nearestNonPlayerDirection = GetNearestNonPlayerDirection(map, activeSite, _MyID, out distanceFromEdge);
            if (nearestNonPlayerDirection != Direction.Still)
            {
                return(new Move
                {
                    Location = activeSite.Location,
                    Direction = nearestNonPlayerDirection
                });
            }
            else //All orthagonal directions are occupied.
            {
                return(new Move
                {
                    Location = activeSite.Location,
                    Direction = x % 2 == 1 ? Direction.North : Direction.South
                });
                //TODO: could have logic here to find enemies or something, or go diagonally.
            }
        }

        return(null);
    }
Example #9
0
    private static Direction GetNearestFreeHighProductionDirection(Map map, SiteEx activeSite) //TODO: This needs to take into account the allowed directions.
    {
        //DarrekLog.AppendLog(string.Format("GetNearestFreeHighProductionDirection... Active site is [{0},{1}]", activeSite.X, activeSite.Y));

        for (ushort distanceFromOrigin = 1; distanceFromOrigin < map.Width / 2; distanceFromOrigin++)
        {
            //DarrekLog.AppendLog("Distance 1...");
            //make a square around the origin.

            for (var x = distanceFromOrigin * -1; x <= distanceFromOrigin; x++)
            {
                for (var y = distanceFromOrigin * -1; y <= distanceFromOrigin; y++)
                {
                    if ((Math.Abs(y) != distanceFromOrigin) && (Math.Abs(x) != distanceFromOrigin))
                    {
                        continue; // don't need to check this space again
                    }
                    //DarrekLog.AppendLog("Relative: " + x + ", " + y);


                    var mapX = (ushort)((((int)activeSite.X) + x + map.Width) % map.Width);
                    var mapY = (ushort)((((int)activeSite.Y) + y + map.Height) % map.Height);

                    //DarrekLog.AppendLog(string.Format("Checking map[{0},{1}]...", mapX, mapY));

                    var toCheck = map[mapX, mapY];


                    if (toCheck.Owner != _MyID)// == 0)
                    {
                        //DarrekLog.AppendLog("Found neutral production area!");
                        if (toCheck.Production >= _TopProductionValuesGreaterThan)
                        {
                            DarrekLog.AppendLog(string.Format("Found acceptable neutral production area at [{1},{2}], value = {0}", toCheck.Production, mapX, mapY));
                            if (Math.Abs(x) <= Math.Abs(y))
                            {
                                //DarrekLog.AppendLog("Moving Horizontally towards high production area");
                                if (x < 0)
                                {
                                    DarrekLog.AppendLog("Heading West to HPA");
                                    return(Direction.West);
                                }
                                else if (x > 0)
                                {
                                    DarrekLog.AppendLog("Heading East to HPA");
                                    return(Direction.East);
                                }
                            }
                            else if (Math.Abs(x) > Math.Abs(y))
                            {
                                //DarrekLog.AppendLog("Moving Vertically towards high production area");
                                if (y < 0)
                                {
                                    DarrekLog.AppendLog("Heading North to HPA");
                                    return(Direction.North);
                                }
                                else if (y > 0)
                                {
                                    DarrekLog.AppendLog("Heading South to HPA");
                                    return(Direction.South);
                                }
                            }
                            else
                            {
                                DarrekLog.AppendLog("dammit!");
                                return(Direction.Still);
                            }
                        }
                    }
                }
            }
        }

        return(Direction.Still);
    }
Example #10
0
    public static void Main(string[] args)
    {
        Console.SetIn(Console.In);
        Console.SetOut(Console.Out);


        var map = Networking.getInit(out _MyID);

        DarrekLog.LogFileName = String.Format("log{0}.txt", _MyID);
        const ushort MAX_STRENGTH  = 255;
        const ushort HALF_STRENGTH = 128;

        /* ------
        *   Do more prep work, see rules for time limit
        *  ------ */


        Networking.SendInit(MyBotName); // Acknoweldge the init and begin the game

        var random = new Random();

        DarrekLog.AppendLog("Starting battle!");
        int frameNumber = 0;
        var movesTowardHighProductionByDirection = new Dictionary <Direction, ushort>();

        movesTowardHighProductionByDirection.Add(Direction.North, 0);
        movesTowardHighProductionByDirection.Add(Direction.South, 0);
        movesTowardHighProductionByDirection.Add(Direction.East, 0);
        movesTowardHighProductionByDirection.Add(Direction.West, 0);

        while (true)
        {
            //try
            //{
            Networking.getFrame(ref map); // Update the map to reflect the moves before this turn
            //}
            //catch (Exception)
            //{
            //    return;
            //}

            #region Check Production
            if (frameNumber == 0)
            {
                var sb = new StringBuilder();
                sb.Append("production values:");

                //TODO: find nearest high production zone and head there.
                for (ushort y = 0; y < map.Height; y++)
                {
                    sb.Append("\r\n");
                    for (ushort x = 0; x < map.Width; x++)
                    {
                        var prodVal = map[x, y].Production;
                        sb.Append(prodVal + " ");

                        if (_MaxProductionValue < prodVal)
                        {
                            _MaxProductionValue = prodVal;
                        }
                    }
                }

                DarrekLog.AppendLog(sb.ToString());

                _TopProductionValuesGreaterThan = (ushort)(_MaxProductionValue * .70);

                DarrekLog.AppendLog(string.Format("Max Production Value Found = {0}", _MaxProductionValue));
                DarrekLog.AppendLog(string.Format("Top Production Values >= {0}", _TopProductionValuesGreaterThan));
            }
            #endregion

            frameNumber++;

            DarrekLog.AppendLog(string.Format("Frame {0}", frameNumber));

            movesTowardHighProductionByDirection[Direction.North] = 0;
            movesTowardHighProductionByDirection[Direction.South] = 0;
            movesTowardHighProductionByDirection[Direction.East]  = 0;
            movesTowardHighProductionByDirection[Direction.West]  = 0;

            var moves = new List <Move>();
            for (ushort x = 0; x < map.Width; x++)
            {
                for (ushort y = 0; y < map.Height; y++)
                {
                    if (map[x, y].Owner == _MyID)
                    {
                        var activeSite = new SiteEx(map, x, y);

                        if (activeSite.Strength < MAX_STRENGTH / 10)
                        {
                            continue;
                        }

                        var neighbors = new List <SiteEx>()
                        {
                            GetNeighbor(map, activeSite, Direction.West),
                            GetNeighbor(map, activeSite, Direction.East),
                            GetNeighbor(map, activeSite, Direction.North),
                            GetNeighbor(map, activeSite, Direction.South)
                        };

                        var friendlySites       = neighbors.Where(c => c.Owner == _MyID);
                        var neutralNeighbors    = neighbors.Where(c => c.Owner == 0);
                        var potentialLunchSites =
                            neighbors.Where(c => c.Strength < activeSite.Strength && c.Owner == 0);

                        //1. Try to grow
                        if (potentialLunchSites.Any())
                        {
                            if (neutralNeighbors.Count() >= 3 || potentialLunchSites.Count() > 1)
                            {
                                var directionToMove = GetNearestFreeHighProductionDirection(map, activeSite);
                                movesTowardHighProductionByDirection[directionToMove]++;

                                if (GetNeighbor(map, activeSite, directionToMove).Strength < activeSite.Strength)
                                {
                                    moves.Add(new Move
                                    {
                                        Location  = activeSite.Location,
                                        Direction = directionToMove
                                    });
                                }
                            }
                            else
                            {
                                var lunchSite       = potentialLunchSites.OrderByDescending(s => s.Production).First();
                                var directionToMove = GetMoveDirection(map, activeSite, lunchSite);

                                moves.Add(new Move
                                {
                                    Location  = activeSite.Location,
                                    Direction = directionToMove
                                });

                                continue;
                            }
                        }



                        //2. If all neighbors are friendly, move where most of the blob is moving (toward high production)
                        if (friendlySites.Count() == neighbors.Count && ((activeSite.Strength >= (activeSite.Production * 5)) || activeSite.Strength > HALF_STRENGTH))
                        {
                            ushort distanceFromEdge;
                            var    nearestNonPlayerDirection = GetNearestNonPlayerDirection(map, activeSite, _MyID, out distanceFromEdge);

                            if (movesTowardHighProductionByDirection.All(m => m.Value == 0) || distanceFromEdge > 3)
                            {
                                if (nearestNonPlayerDirection != Direction.Still)
                                {
                                    moves.Add(new Move
                                    {
                                        Location  = activeSite.Location,
                                        Direction = nearestNonPlayerDirection
                                    });
                                }
                                else //All orthagonal directions are occupied.
                                {
                                    //TODO: could have logic here to find enemies or something, or go diagonally.
                                }
                            }
                            else
                            {
                                var blobMoveDirection = movesTowardHighProductionByDirection.First(m => m.Value == movesTowardHighProductionByDirection.Max(n => n.Value)).Key;

                                DarrekLog.AppendLog(string.Format("Moving with blob to the {0}", blobMoveDirection));

                                moves.Add(new Move
                                {
                                    Location  = activeSite.Location,
                                    Direction = blobMoveDirection
                                });
                            }
                        }
                    }
                }
            }

            Networking.SendMoves(moves); // Send moves
        }
    }
Example #11
0
    public static void Main(string[] args)
    {
        Console.SetIn(Console.In);
        Console.SetOut(Console.Out);

        ushort       myID;
        var          map           = Networking.getInit(out myID);
        const ushort MAX_STRENGTH  = 255;
        const ushort HALF_STRENGTH = 128;

        /* ------
        *   Do more prep work, see rules for time limit
        *  ------ */

        Networking.SendInit(MyBotName); // Acknoweldge the init and begin the game

        var random = new Random();

        //var logFileName = string.Format(@"C:\Users\dolson\Source\Halite\Halite-C#-Starter-Package\Halite-C#-Starter-Package\log{0}.txt", DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"));
        var logFileName = string.Format("log{0}.txt", DateTime.Now.Ticks);

        AppendLog(logFileName, "Starting battle!");
        int frameNumber = 0;

        while (true)
        {
            try
            {
                Networking.getFrame(ref map); // Update the map to reflect the moves before this turn
            }
            catch (Exception)
            {
                return;
            }
            frameNumber++;

            AppendLog(logFileName, string.Format("Frame {0}", frameNumber));

            var moves = new List <Move>();
            for (ushort x = 0; x < map.Width; x++)
            {
                for (ushort y = 0; y < map.Height; y++)
                {
                    if (map[x, y].Owner == myID)
                    {
                        var activeSite = new SiteEx(map, x, y);

                        if (activeSite.Strength < MAX_STRENGTH / 10)
                        {
                            continue;
                        }

                        var neighbors = new List <SiteEx>()
                        {
                            GetNeighbor(map, activeSite, Direction.West),
                            GetNeighbor(map, activeSite, Direction.East),
                            GetNeighbor(map, activeSite, Direction.North),
                            GetNeighbor(map, activeSite, Direction.South)
                        };

                        var friendlySites       = neighbors.Where(c => c.Owner == myID);
                        var potentialLunchSites =
                            neighbors.Where(c => c.Strength < activeSite.Strength && c.Owner == 0);

                        //1. Try to grow
                        if (potentialLunchSites.Any())
                        {
                            var lunchSite       = potentialLunchSites.OrderByDescending(s => s.Production).First();
                            var directionToMove = GetMoveDirection(map, activeSite, lunchSite);

                            moves.Add(new Move
                            {
                                Location  = activeSite.Location,
                                Direction = directionToMove
                            });
                        }

                        //2. If all neighbors are friendly, move towards nearest edge.
                        else if (friendlySites.Count() == neighbors.Count && ((activeSite.Strength >= (activeSite.Production * 5)) || activeSite.Strength > HALF_STRENGTH))
                        {
                            var nearestNonPlayerDirection = GetNearestNonPlayerDirection(map, activeSite, myID);
                            if (nearestNonPlayerDirection != Direction.Still)
                            {
                                moves.Add(new Move
                                {
                                    Location  = activeSite.Location,
                                    Direction = nearestNonPlayerDirection
                                });
                            }
                            else //All orthagonal directions are occupied.
                            {
                                //TODO: could have logic here to find enemies or something, or go diagonally.
                            }
                        }
                    }
                }
            }

            Networking.SendMoves(moves); // Send moves
        }
    }
Example #12
0
    public static void Main(string[] args)
    {
        Console.SetIn(Console.In);
        Console.SetOut(Console.Out);


        var map = Networking.getInit(out _MyID);

        DarrekLog.LogFileName = String.Format("log{0}.txt", _MyID);
        const ushort MAX_STRENGTH  = 255;
        const ushort HALF_STRENGTH = 128;

        /* ------
        *   Do more prep work, see rules for time limit
        *  ------ */


        Networking.SendInit(MyBotName); // Acknoweldge the init and begin the game

        var random = new Random();

        DarrekLog.AppendLog("Starting battle!");
        int frameNumber = 0;

        while (true)
        {
            try
            {
                Networking.getFrame(ref map); // Update the map to reflect the moves before this turn
            }
            catch (Exception)
            {
                return;
            }

            #region Check Production
            if (frameNumber == 0)
            {
                var sb = new StringBuilder();
                sb.Append("production values:");

                //TODO: find nearest high production zone and head there.
                for (ushort y = 0; y < map.Height; y++)
                {
                    sb.Append("\r\n");
                    for (ushort x = 0; x < map.Width; x++)
                    {
                        var prodVal = map[x, y].Production;
                        sb.Append(prodVal + " ");

                        if (_MaxProductionValue < prodVal)
                        {
                            _MaxProductionValue = prodVal;
                        }
                    }
                }

                DarrekLog.AppendLog(sb.ToString());

                _TopProductionValuesGreaterThan = (ushort)(_MaxProductionValue * .70);

                DarrekLog.AppendLog(string.Format("Max Production Value Found = {0}", _MaxProductionValue));
                DarrekLog.AppendLog(string.Format("Top Production Values >= {0}", _TopProductionValuesGreaterThan));
            }
            #endregion

            frameNumber++;

            DarrekLog.AppendLog(string.Format("Frame {0}", frameNumber));

            var moves = new List <Move>();
            for (ushort x = 0; x < map.Width; x++)
            {
                for (ushort y = 0; y < map.Height; y++)
                {
                    if (map[x, y].Owner == _MyID)
                    {
                        var activeSite = new SiteEx(map, x, y);

                        if ((activeSite.Strength < activeSite.Production * 3) && (activeSite.Strength < MAX_STRENGTH / 12))
                        {
                            continue;
                        }

                        var neighbors = new List <SiteEx>()
                        {
                            GetNeighbor(map, activeSite, Direction.West),
                            GetNeighbor(map, activeSite, Direction.East),
                            GetNeighbor(map, activeSite, Direction.North),
                            GetNeighbor(map, activeSite, Direction.South)
                        };

                        var friendlySites = neighbors.Where(c => c.Owner == _MyID);
                        var friendlySitesWorthVisiting =
                            friendlySites.Where(
                                f =>
                                f.Strength > 0 && f.Strength + activeSite.Strength <MAX_STRENGTH &&
                                                                                    f.Production> (_MaxProductionValue / 4));
                        var neutralNeighbors  = neighbors.Where(c => c.Owner == 0);
                        var weakNeighborSites = neighbors.Where(c => (activeSite.Strength == MAX_STRENGTH || c.Production > 0) && c.Strength < activeSite.Strength && c.Owner == 0);

                        bool shouldCombine = false;

                        if (!weakNeighborSites.Any())
                        {
                            if (activeSite.X + activeSite.Y % 2 == 1) //Only combine from every other square to prevent dancing.
                            {
                                shouldCombine = true;
                            }
                        }

                        //Combine forces if we are a thin line.
                        if (shouldCombine && friendlySitesWorthVisiting.Any())
                        {
                            var destination = friendlySitesWorthVisiting.FirstOrDefault(f => f.Production > activeSite.Production);
                            if (destination != null)
                            {
                                var directionToMove = GetMoveDirection(map, activeSite, destination);
                                DarrekLog.AppendLog("Combine Forces!");

                                moves.Add(new Move
                                {
                                    Location  = activeSite.Location,
                                    Direction = directionToMove
                                });
                                continue;
                            }
                        }

                        //1. Try to grow
                        if (weakNeighborSites.Any())
                        {
                            SiteEx lunchSiteToAttack = null;

                            //Move Between enemies if possible for maximum damage!
                            foreach (var pls in weakNeighborSites)
                            {
                                var nW = GetNeighbor(map, pls, Direction.West);
                                var nE = GetNeighbor(map, pls, Direction.East);
                                var nS = GetNeighbor(map, pls, Direction.South);
                                var nN = GetNeighbor(map, pls, Direction.North);

                                var enemyNeighborsCount = ((nW.Owner != _MyID && nW.Owner != 0) ? 1 : 0) +
                                                          ((nE.Owner != _MyID && nE.Owner != 0) ? 1 : 0) +
                                                          ((nS.Owner != _MyID && nS.Owner != 0) ? 1 : 0) +
                                                          ((nN.Owner != _MyID && nN.Owner != 0) ? 1 : 0);

                                if (enemyNeighborsCount > 1)
                                {
                                    lunchSiteToAttack = pls;
                                }
                            }

                            if (lunchSiteToAttack == null)
                            {
                                lunchSiteToAttack = weakNeighborSites.OrderByDescending(s => s.Production - s.Strength / 10).First();
                            }

                            var directionToMove = GetMoveDirection(map, activeSite, lunchSiteToAttack);

                            if (lunchSiteToAttack.Strength < activeSite.Strength)
                            {
                                moves.Add(new Move
                                {
                                    Location  = activeSite.Location,
                                    Direction = directionToMove
                                });
                                continue;
                            }
                        }


                        //2. If all neighbors are friendly, move towards nearest edge.
                        else if (activeSite.Strength > 0 && friendlySites.Count() == neighbors.Count && ((activeSite.Strength >= (activeSite.Production * 3)) || activeSite.Strength > HALF_STRENGTH / 2))
                        {
                            ushort distanceFromEdge;
                            var    nearestNonPlayerDirection = GetNearestNonPlayerDirection(map, activeSite, _MyID, out distanceFromEdge);
                            if (nearestNonPlayerDirection != Direction.Still)
                            {
                                moves.Add(new Move
                                {
                                    Location  = activeSite.Location,
                                    Direction = nearestNonPlayerDirection
                                });
                            }
                            else //All orthagonal directions are occupied.
                            {
                                moves.Add(new Move
                                {
                                    Location  = activeSite.Location,
                                    Direction = x % 2 == 1 ? Direction.North : Direction.South
                                });
                                //TODO: could have logic here to find enemies or something, or go diagonally.
                            }
                        }
                    }
                }
            }

            Networking.SendMoves(moves); // Send moves
        }
    }