예제 #1
0
        public QueuedAttack(PirateContainer p, List <Pirate> e)
        {
            P = p;
            E = e;
            queued.Add(this);

            foreach (Pirate t in e)
            {
                if (!targetMap.ContainsKey(t))
                {
                    targetMap.Add(t, new List <PirateContainer>());
                }
                targetMap[t].Add(p);
            }
        }
예제 #2
0
        public static void doAttacks(IPirateGame game, bool deadMap)
        {
            if (shot != null)
            {
                game.Debug("can only call doAttacks(IPirateGame) once per turn!");
                return;
            }
            shot = new List <Pirate>();

            foreach (Pirate p in targetMap.Keys)
            {
                foreach (PirateContainer c in targetMap[p])
                {
                    game.Debug(p.Id + " --> " + c.P.Id);
                }
            }

            for (int i = 1; i <= game.AllMyPirates().Count&& targetMap.Keys.Count > 0; i++)
            {
                List <Pirate> removed = new List <Pirate>();
                foreach (Pirate p in targetMap.Keys)
                {
                    if (targetMap[p].Count == i && p.DefenseExpirationTurns == 0 && (!deadMap || p.HasTreasure))
                    {
                        PirateContainer pc = targetMap[p][0];
                        pc.attack(p, game);
                        removed.Add(p);
                        foreach (Pirate k in targetMap.Keys)
                        {
                            targetMap[k].Remove(pc);
                        }
                    }
                }
                foreach (Pirate p in removed)
                {
                    targetMap.Remove(p);
                }
            }

            /*for (int i = 0; i < queued.Count; i++)
             * {
             *      if (queued[i].E.Count == 1 && !shot.Contains(queued[i].E[0]))
             *      {
             *              queued[i].P.attack(queued[i].E[0], game);// TODO: if kamikaze, and my target, ignore it
             *              shot.Add(queued[i].E[0]);
             *      }
             * }*/
        }
예제 #3
0
        // can we move the given Pirate to the given Location according to the number of moves?
        // if so --> move it!
        private static int move(PirateContainer p, Location t, int moves, IPirateGame game, bool dontHitEnemies = false)
        {
            if (moves == 0 || !p.AVALIBLE || p.P.Location.Equals(t))
            {
                return(0);
            }

            // calculate the best route
            foreach (Location l in game.GetSailOptions(p.P, t, moves))
            {
                if (!QueuedMotion.isOccupied(l, game, dontHitEnemies) && p.move(l, game))
                {
                    return(game.Distance(p.P, l));
                }
            }

            game.Debug("Failed to find a move for " + p.P.Id + " to " + t);
            return(0);
        }
예제 #4
0
        // this is the actual turn
        public void DoTurn(IPirateGame game)
        {
            if (game.GetTurn() == 1)
            {
                Location l = new Location(1, 1);
                foreach (Treasure t in game.Treasures())
                {
                    if (t.Location.Equals(l))
                    {
                        deadMap = true;
                        break;
                    }
                }

                game.Debug((deadMap ? "DEADMAP!!!" : "NIE!"));
                if (!deadMap)
                {
                    return;                    // this stops some fighting over treasures
                }
            }

            nowhere = (game.GetEnemyScore() == game.GetMyScore() && game.GetTurn() == (game.GetMaxTurns() / 3));
            if (nowhere)
            {
                game.Debug("ACTIVATING NOWHERE MODE!!!");
            }

            panic = (((game.Treasures().Count == 0 || game.GetEnemyScore() >= (game.GetMaxPoints() - 2))) && game.EnemyPiratesWithTreasures().Count > 0);
            if (panic)
            {
                game.Debug("ACTIVATING PANIC MODE!!!");
            }

            PirateContainer.init(game);
            QueuedAttack.init();
            QueuedMotion.init();
            int remaining = game.GetActionsPerTurn();
            int ships     = game.AllMyPirates().Count;

            try
            {
                // calculate the closest treasure to ps[i]
                PirateContainer[] ps = new PirateContainer[ships];
                int[]             ds = new int[ships];
                Treasure[]        ts = new Treasure[ships];
                for (int i = 0; i < ships; i++)
                {
                    ps[i] = new PirateContainer(game.GetMyPirate(i), (i % 2) == 1);
                    ds[i] = int.MaxValue;
                    foreach (Treasure t in game.Treasures())
                    {
                        if (game.Distance(ps[i].P, t) < ds[i])
                        {
                            ds[i] = game.Distance(ps[i].P, t);
                            ts[i] = t;
                        }
                    }
                }

                // control the kamikazes
                calcKamikazes(ps, ref ts, ref ds, game);

                // move Pirates that have treasures towards the base
                {
                    List <PirateContainer> ltp = PirateContainer.withTreasure;
                    foreach (PirateContainer p in ltp)
                    {
                        remaining -= move(p, p.P.InitialLocation, 1, game, true);
                    }
                }

                // search and destroy, TODO: prioritise this!!!
                Pirate k = null, tar = null;
                if (panic)
                {
                    int mx = (game.GetRows() + game.GetCols() - game.GetAttackRadius()) / game.GetActionsPerTurn(); // turns it takes to get from a corner to its opposing corner
                    int d  = int.MaxValue;
                    tar = game.EnemyPiratesWithTreasures()[0];                                                      // TODO: focus on closest to enemy base
                    // find closest Pirate
                    foreach (PirateContainer p in PirateContainer.free)                                             // notice all pirates with Treasure already moved, see: ltp
                    {
                        if (p.AVALIBLE && p.P.ReloadTurns < mx && d > game.Distance(p.P, tar))
                        {
                            d = game.Distance(p.P, tar);
                            k = p.P;
                        }
                    }
                    if (k == null)                                                         // no Pirate with ammo, so choose the closest to the InitialLocation then move to there
                    {
                        foreach (PirateContainer p in PirateContainer.free)                // notice all pirates with Treasure already moved, see: ltp
                        {
                            if (p.AVALIBLE && d > game.Distance(p.P, tar.InitialLocation)) // TODO: make the "6" generic to board size
                            {
                                d = game.Distance(p.P, tar.InitialLocation);
                                k = p.P;
                            }
                        }
                    }
                }

                List <int> dss = sortInto(ds);               // sort the ds into the dss

                // AAAAATTTTTTTTTTTTAAAAAAAAAAACCCCCCCCKKKKKKKKKKKKKKK!!!!!!!!!!!!!!!! (or defend...)
                for (int i = PirateContainer.free.Count; i > 0;)
                {
                    PirateContainer p = PirateContainer.free[--i];
                    if (p.P.ReloadTurns == 0 && !p.P.HasTreasure && p.AVALIBLE)
                    {
                        List <Pirate> es = findTargetsFor(p.P, game);
                        if (es.Count > 0)
                        {
                            new QueuedAttack(p, es);
                        }
                    }
                }
                QueuedAttack.doAttacks(game, deadMap);

                // move
                for (int j = 0; j < ships; j++)
                {
                    int i = dss[j];
                    if (ps[i].S == PirateContainer.State.none && ps[i].AVALIBLE && !ps[i].P.HasTreasure)
                    {
                        if (game.Treasures().Count > 0)                        // use typical motion
                        {
                            int mv = move(ps[i], ts[i].Location, remaining, game);
                            if (mv > 0)
                            {
                                remaining -= mv;
                                continue;
                            }
                        }
                        if (game.EnemyPiratesWithTreasures().Count > 0 && ps[i].P == k)                        // activate search and destroy
                        {
                            remaining -= move(ps[i], tar.Location, remaining, game);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                game.Debug("Crashed!");
                game.Debug(e.Message);
                game.Debug(e.StackTrace);
            }
            game.Debug("turn " + game.GetTurn() + ": ran " + (game.GetActionsPerTurn() - remaining) + " motions");
        }