Пример #1
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
        }
    }
Пример #2
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);
    }
Пример #3
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
        }
    }