Exemple #1
0
 public static bool CanPath(UnitJob job, Player player, Tile tile, bool ignoreUnits = false)
 {
     if (job == AI.WORKER)
     {
         return((ignoreUnits || tile.Unit == null) && tile.IsGrass && tile.Owner != player.Opponent && tile.Tower == null);
     }
     return(tile.IsPath && (ignoreUnits || tile.Unit == null || (tile.Unit.Job == job && tile.NumUnits(job) < job.PerTile)));
 }
Exemple #2
0
 public static bool canAttackJob(TowerJob towerJ, UnitJob unitJ)
 {
     if (unitJ == AI.WORKER)
     {
         return(false);
     }
     if (towerJ == AI.CASTLE)
     {
         return(true);
     }
     if (towerJ == AI.CLEANSING)
     {
         return(unitJ == AI.WRAITH || unitJ == AI.ABOMINATION);
     }
     return(unitJ != AI.WRAITH);
 }
Exemple #3
0
        public static int NumUnits(this Tile tile, UnitJob job)
        {
            if (tile.Unit == null)
            {
                return(0);
            }
            if (tile.Unit.Job.PerTile == 1)
            {
                return(1);
            }
            switch (job.Title)
            {
            case "zombie":
                return(tile.NumZombies);

            case "ghoul":
                return(tile.NumGhouls);

            case "hound":
                return(tile.NumHounds);
            }
            return(1);
        }
Exemple #4
0
        /// <summary>
        /// This is automatically called when the game first starts, once the Game and all GameObjects have been initialized, but before any players do anything.
        /// </summary>
        /// <remarks>
        /// This is a good place to initialize any variables you add to your AI or start tracking game objects.
        /// </remarks>
        public override void Start()
        {
            // <<-- Creer-Merge: start -->> - Code you add between this comment and the end comment will be preserved between Creer re-runs.
            base.Start();

            AI.GAME = this.Game;
            AI.US   = this.Player;
            AI.THEM = this.Game.Players.First(p => p != AI.US);

            AI.CASTLE    = this.Game.TowerJobs.First(t => t.Title == "castle");
            AI.CLEANSING = this.Game.TowerJobs.First(t => t.Title == "cleansing");
            AI.BALLISTA  = this.Game.TowerJobs.First(t => t.Title == "ballista");
            AI.ARROW     = this.Game.TowerJobs.First(t => t.Title == "arrow");
            AI.AOE       = this.Game.TowerJobs.First(t => t.Title == "aoe");

            AI.WORKER      = this.Game.UnitJobs.First(t => t.Title == "worker");
            AI.ZOMBIE      = this.Game.UnitJobs.First(t => t.Title == "zombie");
            AI.GHOUL       = this.Game.UnitJobs.First(t => t.Title == "ghoul");
            AI.HOUND       = this.Game.UnitJobs.First(t => t.Title == "hound");
            AI.ABOMINATION = this.Game.UnitJobs.First(t => t.Title == "abomination");
            AI.WRAITH      = this.Game.UnitJobs.First(t => t.Title == "wraith");
            AI.HORSEMAN    = this.Game.UnitJobs.First(t => t.Title == "horseman");

            AI.UNIT_SPAWNER   = this.Game.Tiles.First(t => t.IsUnitSpawn && t.Owner == AI.US);
            AI.WORKER_SPAWNER = this.Game.Tiles.First(t => t.IsWorkerSpawn && t.Owner == AI.US);

            AI.OUR_CASTLE   = AI.US.Towers.First(t => t.Job == AI.CASTLE);
            AI.THEIR_CASTLE = AI.THEM.Towers.First(t => t.Job == AI.CASTLE);

            AI.GOLD_MINES        = new HashSet <Tile>(AI.GAME.Tiles.Where(t => t.IsGoldMine && t.Owner == AI.US));
            AI.ISLAND_GOLD_MINES = new HashSet <Tile>(AI.GAME.Tiles.Where(t => t.IsIslandGoldMine));
            AI.RIVER_NEIGHBORS   = new HashSet <Tile>(AI.GAME.Tiles.Where(t => t.IsRiver).SelectMany(t => t.GetNeighbors()).Where(t => t.IsGrass));

            AI.CASTLE_TOWER = AI.US.Towers.First(t => t.Job == AI.CASTLE);

            var castleTile = AI.CASTLE_TOWER.Tile;

            if (castleTile.TileNorth.TileNorth.IsPath)
            {
                var leftX  = castleTile.X - 1;
                var rightX = castleTile.X + 2;
                var startY = castleTile.Y - 3;
                AI.LEFT_TOWERS  = Enumerable.Range(0, 15).Select(o => AI.GAME.GetTileAt(leftX, startY - o)).ToList();
                AI.RIGHT_TOWERS = Enumerable.Range(0, 15).Select(o => AI.GAME.GetTileAt(rightX, startY - o)).ToList();
            }
            else
            {
                var leftX  = castleTile.X - 2;
                var rightX = castleTile.X + 1;
                var startY = castleTile.Y + 3;
                AI.LEFT_TOWERS  = Enumerable.Range(0, 15).Select(o => AI.GAME.GetTileAt(leftX, startY + o)).ToList();
                AI.RIGHT_TOWERS = Enumerable.Range(0, 15).Select(o => AI.GAME.GetTileAt(rightX, startY + o)).ToList();
            }

            AI.TOWER_PATTERN = new List <TowerJob>()
            {
                AI.CLEANSING, AI.AOE, AI.ARROW
            };

            string[][] patterns = new string[][] {
                new[] { "0110110", "1001001", "1000001", "0100010", "0010100", "0001000" },                               // Heart
                new[] { "00111100", "01000010", "10100101", "10000001", "10100101", "10011001", "01000010", "00100100" }, // Smiley
                new[] { "01010", "10001", "11011", "01110", "00100", "00100", "00100" },                                  // Wrench
                new[] { "01100", "00010", "00101", "01001", "10000" },                                                    // Pick axe
                new[] { "100010010", "100101010", "110010011" },                                                          // L O L
                new[] { "00011000", "00100100", "01000010", "10000001", "01111110" },                                     // Delta
                new[] { "0001000", "0011100", "0000000", "0100010", "1110111" } // Triforce
            };
            ;
            var pattern = patterns[new Random().Next(patterns.Length)];

            Console.WriteLine(String.Join("\n", pattern));

            AI.PATTERN = new HashSet <Tile>();
            Tile patternAnchor;

            if (AI.CASTLE_TOWER.Tile.TileNorth.TileNorth.IsPath)
            {
                patternAnchor = AI.GAME.GetTileAt(36, 11);
            }
            else
            {
                patternAnchor = AI.GAME.GetTileAt(27 - pattern[0].Length, 11);
            }

            for (int x = 0; x < pattern[0].Length; x++)
            {
                for (int y = 0; y < pattern.Length; y++)
                {
                    if (pattern[y][x] == '1')
                    {
                        AI.PATTERN.Add(AI.GAME.GetTileAt(patternAnchor.X + x, patternAnchor.Y + y));
                    }
                }
            }

            // <<-- /Creer-Merge: start -->>
        }
Exemple #5
0
        public static void MoveAndSpreadAndAttack(Unit unit, IEnumerable <Tower> targets, UnitJob job)
        {
            if (unit.Acted || unit.Moves == 0)
            {
                return;
            }

            var targetNeighbors = new HashSet <Tile>(targets.SelectMany(t => t.Tile.GetNeighbors()));

            var pathsToNeighbors         = FindPaths(unit.Tile.ToEnumerable(), targetNeighbors, t => CanPath(job, AI.US, t));
            var reachableTargetNeighbors = pathsToNeighbors.Keys.Where(t => pathsToNeighbors[t].Count <= unit.Moves + 1);

            LinkedList <Tile> path = null;

            if (reachableTargetNeighbors.Any())
            {
                path = pathsToNeighbors[reachableTargetNeighbors.MinByValue(t => t.NumUnits(job))];
            }
            else
            {
                var pathsIgnore = FindPaths(unit.Tile.ToEnumerable(), targetNeighbors, t => CanPath(job, AI.US, t, true));
                if (pathsIgnore.Count > 0)
                {
                    path = pathsIgnore.MinByValue(kvp => kvp.Value.Count).Value;
                }
            }

            if (path == null)
            {
                return;
            }

            path.RemoveFirst();
            while (unit.Moves > 0 && path.Count > 0 && CanPath(job, AI.US, path.First()))
            {
                unit.Move(path.First());
                path.RemoveFirst();
            }

            var target = targets.FirstOrDefault(t => t.Tile.HasNeighbor(unit.Tile));

            if (target != null)
            {
                unit.Attack(target.Tile);
            }
        }
Exemple #6
0
        public static Tuple <Unit, Tile> MoveNearest(IEnumerable <Unit> units, IEnumerable <Tile> targets, UnitJob job)
        {
            var movable = units.Where(u => !u.Acted && u.Moves > 0);

            if (!movable.Any())
            {
                return(null);
            }

            var steps = FindPath(movable.Select(u => u.Tile), targets, t => CanPath(job, AI.US, t));

            if (steps.Count == 0)
            {
                steps = FindPath(movable.Select(u => u.Tile), targets, t => CanPath(job, AI.US, t, true));
                if (steps.Count == 0)
                {
                    return(null);
                }
            }

            var moverTile = steps.First();
            var mover     = units.First(u => u.Tile == moverTile);
            var target    = steps.Last();

            steps.RemoveFirst();
            while (mover.Moves > 0 && steps.Count > 0 && CanPath(job, AI.US, steps.First()))
            {
                mover.Move(steps.First());
                steps.RemoveFirst();
            }

            return(Tuple.Create(mover, target));
        }
Exemple #7
0
 public static bool CanAfford(Player player, UnitJob job, int count = 1)
 {
     return(player.Gold >= job.GoldCost * count && player.Mana >= job.ManaCost * count);
 }