} // calculates the closest powerups to ps[i] // 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.S != PirateContainer.State.moved) || p.P.Location.Equals(t)) { return(0); } var X = from l in game.GetSailOptions(p.P, t, moves) where (!QueuedMotion.isOccupied(l, game, dontHitEnemies) && p.move1(l, game, moves)) select l; if (X.Count() > 0) { PirateContainer.free.Remove(p); Location loc = X.ElementAt(rand.Next(X.Count())); game.SetSail(p.P, loc); new QueuedMotion(p.P, loc); return(game.Distance(p.P, loc)); } game.Debug("Failed to find a move for " + p.P.Id + " to " + t); return(0); }
private void locatePowerups(IPirateGame game, int ships, ref PirateContainer[] ps, ref int[] ds, ref Powerup[] pu) { for (int i = 0; i < ships; i++) { //if (game.GetMyPirate(i).HasTreasure) //break; ps[i] = new PirateContainer(game.GetMyPirate(i), (i % 2) == 1); ds[i] = int.MaxValue; foreach (Powerup p in pu) { if (p == null) { break; } //game.Debug("here is the prub: " + i + " - " + p); int d = game.Distance(ps[i].P.Location, p.Location); if (d < ds[i]) { ds[i] = d; pu[i] = p; game.Debug("Powerup found in distance " + d + " for ship " + i); } } } } // calculates the closest powerups to ps[i]
} //manages panic mode private void attack(IPirateGame game) { 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); } } } } //manages attacks
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); } }
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("Pirate " + p.Id + " attacked enemy pirate " + 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]); * } * }*/ }
} // checks wether to activate nowhere mode private void calcBestTreasure(IPirateGame game, int ships, ref PirateContainer[] ps, ref int[] ds, ref Treasure[] ts) { 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()) { int d = game.Distance(ps[i].P, t) / t.Value; if (powerup(ps[i].P.Location, t.Location, game) != null) { d -= 3; } if (d < ds[i]) { ds[i] = d; ts[i] = t; } } } } // calculates the closest treasure to ps[i]
// this is the actual turn public void DoTurn(IPirateGame game) { int remaining = game.GetActionsPerTurn(); if (game.GetTurn() == 1) { game.Debug("moves per turn: " + remaining); } try { #region init if (game.GetTurn() == 1) { chooseMap(game); } nowhere = inNowhereMode(game); if (nowhere) { game.Debug("ACTIVATING NOWHERE MODE"); } panic = inPanicMode(game); if (panic) { game.Debug("ACTIVATING PANIC MODE"); } PirateContainer.init(game); QueuedAttack.init(); QueuedMotion.init(); int ships = game.AllMyPirates().Count; PirateContainer[] ps = new PirateContainer[ships]; int[] ds = new int[ships]; Treasure[] ts = new Treasure[ships]; #endregion calcBestTreasure(game, ships, ref ps, ref ds, ref ts); // calculate the closest treasure to ps[i] BringBackTreasure(game, ref remaining); // move Pirates that have treasures towards the base calcKamikazes(ps, ref ts, ref ds, game); // control the kamikazes //BringBackTreasure(game, ref remaining); // move Pirates that have treasures towards the base //Powerup pt = new SpeedPowerup(-1, new Location(0, 0), 0, 0, 0); #region power up calculations Powerup[] pu = (from l in game.Powerups() where l.Type == "Speed" select l).ToArray(); if (pu.Count() > 0) { Powerup[] puu = new Powerup[ships]; for (int i = pu.Count() - 1; i >= 0; i--) { puu[i] = pu[i]; } game.Debug("A speed powerup was found"); int[] dis = new int[ships]; locatePowerups(game, ships, ref ps, ref dis, ref puu); int chosen = -1; for (int i = 0, min = int.MaxValue; i < ships; ++i) { if (dis[i] < min && ps[i].AVALIBLE && dis[i] != 0) //&& !ps[i].P.HasTreasure { min = dis[i]; chosen = i; } } game.Debug("Moving pirate " + chosen + " towards powerup"); if (chosen != -1) { game.Debug("Distance of chosen powerup - " + dis[chosen]); if (puu[chosen] == null) { game.Debug("we found the problem"); } remaining -= move(ps[chosen], puu[chosen].Location, remaining, game); } } #endregion #region panic mode Pirate k = null, tar = null; if (panic) { search_n_destroy(game, ref tar, ref k); // search and destroy, TODO: prioritise this!!! } #endregion List <int> dss = sortInto(ds); // sort the ds into the dss attack(game); QueuedAttack.doAttacks(game, deadMap); #region move // 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 { Location l = powerup(ps[i].P.Location, ts[i].Location, game); int mv; if (l != null) { mv = move(ps[i], l, remaining, game); } else { 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); } } } #endregion } catch (Exception e) { game.Debug("Crashed!"); game.Debug(e.Message); game.Debug(e.StackTrace); } finally { WastedTurnsCounter += remaining; game.Debug("________"); game.Debug("turn " + game.GetTurn() + " - moves summary"); game.Debug("turns used: " + (game.GetActionsPerTurn() - remaining)); game.Debug("turns wasted: " + remaining); game.Debug("________"); game.Debug("game summary"); game.Debug("turns used: " + (game.GetTurn() * game.GetActionsPerTurn() - WastedTurnsCounter) + "/" + (game.GetTurn() * game.GetActionsPerTurn()) + ", " + Math.Round((100 - (float)WastedTurnsCounter * 100 / (float)(game.GetTurn() * game.GetActionsPerTurn())), 2) + "% efficiency"); game.Debug("turns wasted: " + WastedTurnsCounter); } }