public void Raider(Wizard w) { Snaffle nearSnaf = GetNearSnuffle(w); if (nearSnaf != null) { Entity snafToFlip = FlipendoOn(w); if (snafToFlip != null && mana > 20) { mana -= 20; Console.WriteLine($"FLIPENDO {snafToFlip.Id}"); } else if (mana > 25) { Entity b = (Entity)GetNear(w, new List <Point>(Bludger)); Console.WriteLine($"OBLIVIATE {b.Id}"); } else { nearSnaf.Reserve = true; Point p = nearSnaf; p.X += nearSnaf.VX; p.Y += nearSnaf.VY; Console.Error.WriteLine($"MOVE {p} 150"); Console.WriteLine($"MOVE {p.Pos()} 150"); } } else { Point o = GetNear(OppGoal, new List <Point>(Opponents)); Console.WriteLine($"MOVE {o.Pos()} 150"); } }
private bool IsFlipendoGoal(Game game, Snaffle s, Wizard w) { // Leave if not in appropriate side if (game.MyTeamId == 0 && s.Position.X < w.Position.X) { return(false); } if (game.MyTeamId == 1 && s.Position.X > w.Position.X) { return(false); } // Compute line var line = Line.Compute(s, w); var y = line.GetValueAt(game.MyTeamId == 0 ? Board.TEAM_1_X : Board.TEAM_0_X); // Compute bounce if (y < 0) { // Wizard not too close to top (weird bounce) if (w.Position.Y < 2250) { return(false); } var line2 = new Line() { A = -line.A, B = -line.B }; y = line2.GetValueAt(game.MyTeamId == 0 ? Board.TEAM_1_X : Board.TEAM_0_X); } else if (y > Board.HEIGHT) { // Wizard not too close to bottom (weird bounce) if (w.Position.Y > Board.HEIGHT - 2250) { return(false); } var line2 = new Line() { A = -line.A, B = 2 * Board.HEIGHT - line.B }; y = line2.GetValueAt(game.MyTeamId == 0 ? Board.TEAM_1_X : Board.TEAM_0_X); } if (y > Board.GOALS_CENTER_HEIGHT - Board.GOALS_LENGTH / 2 + 2 * Board.PILAR_RADIUS + Snaffle.RADIUS && y < Board.GOALS_CENTER_HEIGHT + Board.GOALS_LENGTH / 2 - 2 * Board.PILAR_RADIUS - Snaffle.RADIUS) { Console.Error.WriteLine($"Line : {line.A} x + {line.B} to y = {y}"); return(true); } return(false); }
public void Defender(Wizard w) { List <Snaffle> toDef = Snaffles.Where(x => x.PrecisionLength(MyGoal) <= 8000).ToList(); Snaffle nearSnaf = GetNearSnuffle(w, toDef); Snaffle acio = AccioOn(w); Snaffle fastSnaf = Snaffles .Where(x => ((x.VX + Math.Abs(x.VY) <= -1200 && myTeamId == 0) || (x.VX + Math.Abs(x.VY) >= 1200 && myTeamId == 1)) && !x.Reserve) .FirstOrDefault(); if (nearSnaf != null) { Snaffle snafToFlip = FlipendoOn(w); if (snafToFlip != null && mana > 20) { snafToFlip.Reserve = true; mana -= 20; Console.Error.WriteLine($"{snafToFlip} {snafToFlip.VX} {snafToFlip.VY}"); Console.WriteLine($"FLIPENDO {snafToFlip.Id}"); } else if (fastSnaf != null && mana > 10) { fastSnaf.Reserve = true; mana -= 10; Console.Error.WriteLine($"{fastSnaf} {fastSnaf.VX} {fastSnaf.VY}"); Console.WriteLine($"PETRIFICUS {fastSnaf.Id}"); } else if (acio != null && mana > 20) { acio.Reserve = true; mana -= 20; Console.Error.WriteLine($"{acio} {acio.VX} {acio.VY}"); Console.WriteLine($"ACCIO {acio.Id}"); } else { nearSnaf.Reserve = true; Point p = nearSnaf; p.X += nearSnaf.VX; p.Y += nearSnaf.VY; Console.Error.WriteLine($"MOVE {p} 150"); Console.WriteLine($"MOVE {p.Pos()} 150"); } } else { Point o = GetNear(OppGoal, new List <Point>(Opponents)); Console.WriteLine($"MOVE {o.Pos()} 150"); } }
public static GameState ParseCurrentGameStateInput(int turnNumber, int teamId) { string[] inputs; inputs = Console.ReadLine().Split(' '); int myScore = int.Parse(inputs[0]); int myMagic = int.Parse(inputs[1]); inputs = Console.ReadLine().Split(' '); int opponentScore = int.Parse(inputs[0]); int opponentMagic = int.Parse(inputs[1]); int entities = int.Parse(Console.ReadLine()); // number of entities still in game var gameState = new GameState(teamId, myScore, opponentScore, myMagic, opponentMagic, entities); for (int i = 0; i < entities; i++) { inputs = Console.ReadLine().Split(' '); int entityId = int.Parse(inputs[0]); // entity identifier string entityType = inputs[1]; // "WIZARD", "OPPONENT_WIZARD" or "SNAFFLE" (or "BLUDGER" after first league) int x = int.Parse(inputs[2]); // position int y = int.Parse(inputs[3]); // position int vx = int.Parse(inputs[4]); // velocity int vy = int.Parse(inputs[5]); // velocity int state = int.Parse(inputs[6]); // 1 if the wizard is holding a Snaffle, 0 otherwise if (entityType == "WIZARD") { var wizard = new Wizard(entityId, x, y, 400 /*wizards are radius 400 according to game definition*/, vx, vy, state, entityType); gameState.Wizards.Add(wizard); } else if (entityType == "OPPONENT_WIZARD") { var wizard = new Wizard(entityId, x, y, 400 /*wizards are radius 400 according to game definition*/, vx, vy, state, entityType); gameState.OpponentWizards.Add(wizard); } else if (entityType == "SNAFFLE") { var snaffle = new Snaffle(entityId, x, y, 150 /*snaffled are radius 400 according to game definition*/, vx, vy, state); gameState.Snaffles.Add(snaffle); } else if (entityType == "BLUDGER") { var bludger = new Bludger(entityId, x, y, 0 /*unknown, snaffles not unlocked until next level*/, vx, vy, state); gameState.Bludgers.Add(bludger); } } return(gameState); }
public Snaffle GetNearSnuffle(Point point, List <Snaffle> cur = null) { cur = cur == null ? Snaffles : cur; double min = 16000D; int vx = myTeamId == 0 ? 150 : -150; Snaffle s = null; for (int i = 0; i < cur.Count; i++) { double buf = point.PrecisionLength(cur[i]); if (buf < min && (!Snaffles[i].Reserve || Snaffles.Count == 1)) { s = cur[i]; min = buf; } } return(s); }
public Snaffle AccioOn(Wizard w) { Point w2 = new Point() { X = w.X + w.VX, Y = w.Y + w.VY }; bool op = Opponents.Any(x => Between(x.X + x.VX, w2.X, MyGoal.X)); List <Snaffle> snf = Snaffles.Where(x => Between(x.X, w2.X, MyGoal.X)).ToList(); if (snf.Count > 0 && op) { Snaffle s = GetNearSnuffle(w2, snf); if (w2.PrecisionLength(s) < 2000) { return(s); } } return(null); }
static void Main(string[] args) { int myTeamId = int.Parse(Console.ReadLine()); // if 0 you need to score on the right of the map, if 1 you need to score on the left Game game = new Game() { Turn = 0, MyTeamId = myTeamId }; // game loop while (true) { string[] inputs = Console.ReadLine().Split(' '); int myScore = int.Parse(inputs[0]); int myMagic = int.Parse(inputs[1]); game.Board.MyScore = myScore; game.Board.MyMana = myMagic; inputs = Console.ReadLine().Split(' '); int opponentScore = int.Parse(inputs[0]); int opponentMagic = int.Parse(inputs[1]); game.Board.EnnemyScore = opponentScore; game.Board.EnnemyMana = opponentMagic; // Change this later to keep trace game.Board.Entities.Clear(); int entities = int.Parse(Console.ReadLine()); // number of entities still in game for (int i = 0; i < entities; i++) { inputs = Console.ReadLine().Split(' '); int entityId = int.Parse(inputs[0]); // entity identifier string entityType = inputs[1]; // "WIZARD", "OPPONENT_WIZARD" or "SNAFFLE" (or "BLUDGER" after first league) int x = int.Parse(inputs[2]); // position int y = int.Parse(inputs[3]); // position int vx = int.Parse(inputs[4]); // velocity int vy = int.Parse(inputs[5]); // velocity int state = int.Parse(inputs[6]); // 1 if the wizard is holding a Snaffle, 0 otherwise Entity entity = game.Board.Entities.FirstOrDefault(e => e.Id == entityId); // Add or update specific if (entity == null) { switch (entityType) { case "WIZARD": entity = new Wizard() { TeamId = myTeamId }; break; case "OPPONENT_WIZARD": entity = new Wizard() { TeamId = 1 - myTeamId }; break; case "SNAFFLE": entity = new Snaffle(); break; case "BLUDGER": entity = new Bludger(); break; default: throw new Exception("Unknown entity"); } game.Board.Entities.Add(entity); } else { switch (entityType) { case "WIZARD": case "OPPONENT_WIZARD": ((Wizard)entity).LastAccioTurn++; ((Wizard)entity).LastFlipendoTurn++; ((Wizard)entity).Action = null; break; default: break; } } // Update common entity.Id = entityId; entity.Position.X = x; entity.Position.Y = y; entity.Velocity.VX = vx; entity.Velocity.VY = vy; entity.State = state; Console.Error.WriteLine(entity.GetDescription()); } Console.Error.WriteLine("Launching SimpleStrategy"); var stragegy = new SimpleStrategy(); stragegy.Compute(game); // Write an action using Console.WriteLine() // To debug: Console.Error.WriteLine("Debug messages..."); // Edit this line to indicate the action for each wizard (0 ≤ thrust ≤ 150, 0 ≤ power ≤ 500) // i.e.: "MOVE x y thrust" or "THROW x y power" //Console.WriteLine("MOVE 8000 3750 100"); game.Turn++; } }
// For each wizard, rush to the closest Snaffle public void Compute(Game game) { List <Wizard> myWizards = game.Board.GetAll <Wizard>().Where(w => w.TeamId == game.MyTeamId).OrderBy(e => e.Id).ToList(); myWizards.ForEach(w => { if (w.Carrying) { // Throw w.Action = $"THROW {(game.MyTeamId == 0 ? Board.TEAM_1_X : Board.TEAM_0_X) - w.Velocity.VX} {Board.GOALS_CENTER_HEIGHT - w.Velocity.VY} {Wizard.MAX_THROW}"; } }); while (game.Board.MyMana >= 20 && myWizards.Any(w => w.Action == null)) { // Flipendo if on direction to ennemy goals var availableWizards = myWizards.Where(w => w.Action == null && w.LastFlipendoTurn > 3).ToList(); var candidates = new Dictionary <Wizard, List <Snaffle> >(); availableWizards.ForEach(w => { candidates.Add(w, new List <Snaffle>()); var snaffles = game.Board.GetAll <Snaffle>().OrderBy(s => s.DistanceTo(w)).ToList(); snaffles.ForEach(s => { if (this.IsFlipendoGoal(game, s, w) && s.DistanceTo(w) > 3 * Snaffle.RADIUS) { //&& s.Position.DistanceTo(new Position() { X = game.MyTeamId == 0 ? Board.TEAM_1_X : Board.TEAM_0_X, Y = Board.GOALS_CENTER_HEIGHT }) > 0.75 * Wizard.MAX_THROW ) candidates[w].Add(s); } }); }); if (candidates.Count(kvp => kvp.Value.Count > 0) == 0) { break; } var winner = candidates.Where(kvp => kvp.Value.Count > 0).OrderBy(kvp => kvp.Key.DistanceTo(kvp.Value.First())).First(); winner.Key.Action = $"FLIPENDO {winner.Value.First().Id}"; winner.Key.LastFlipendoTurn = 0; game.Board.MyMana -= 20; } while (game.Board.MyMana >= 20 && myWizards.Any(w => w.Action == null)) { // Accio snaffle closest to matching ennemy var availableWizards = myWizards.Where(w => w.Action == null && w.LastAccioTurn > 6).ToList(); var candidates = new Dictionary <Wizard, List <Snaffle> >(); availableWizards.ForEach(w => { candidates.Add(w, new List <Snaffle>()); var matchingEnnemy = game.Board.GetAll <Wizard>().First(ew => ew.Id == (w.Id + 2) % 4); var snaffles = game.Board.GetAll <Snaffle>().OrderBy(s => s.DistanceTo(matchingEnnemy)).ToList(); snaffles.ForEach(s => candidates[w].Add(s)); }); if (candidates.Count(kvp => kvp.Value.Count > 0) == 0) { break; } var winner = candidates.Where(kvp => kvp.Value.Count > 0).OrderBy(kvp => kvp.Key.DistanceTo(kvp.Value.First())).First(); winner.Key.Action = $"ACCIO {winner.Value.First().Id}"; winner.Key.LastAccioTurn = 0; game.Board.MyMana -= 15; } while (game.Board.MyMana >= 10 && myWizards.Any(w => w.Action == null)) { // Petrificus var availableWizards = myWizards.Where(w => w.Action == null && w.LastAccioTurn > 6).ToList(); if (availableWizards.Count() == 0) { break; } var orderedSnaffles = game.Board.GetAll <Snaffle>().OrderBy(s => s.Position.DistanceTo(new Position() { X = game.MyTeamId == 0 ? Board.TEAM_0_X : Board.TEAM_1_X, Y = Board.GOALS_CENTER_HEIGHT })).ToList(); var candidates = new List <Snaffle>(); orderedSnaffles.ForEach(s => { double estimatedX = s.Position.X + s.Velocity.VX * ((1 - Math.Pow(0.75, 3)) / (1 - 0.75)); // Compute position in 3 turns if ((game.MyTeamId == 0 && estimatedX < Board.TEAM_0_X) || (game.MyTeamId == 1 && estimatedX > Board.TEAM_1_X)) { candidates.Add(s); } }); if (candidates.Count() == 0) { break; } var winner = candidates.First(); var wizard = availableWizards.OrderBy(w => w.DistanceTo(winner)).First(); wizard.Action = $"PETRIFICUS {winner.Id}"; game.Board.MyMana -= 10; } myWizards.Where(w => w.Action == null).ToList().ForEach(w => { // Go to closest snaffle Snaffle target = game.Board.GetAll <Snaffle>().OrderBy(s => s.DistanceTo(w)).FirstOrDefault(); Position nextPosition = new Position() { X = target.Position.X + target.Velocity.VX, Y = target.Position.Y + target.Velocity.VY }; if (target.Carried) { // Ennemy would throw it to our goals Position myGoal = new Position() { X = game.MyTeamId == 0 ? Board.TEAM_0_X : Board.TEAM_1_X, Y = Board.GOALS_CENTER_HEIGHT }; double distance = nextPosition.DistanceTo(myGoal); nextPosition.X = (int)(nextPosition.X + (myGoal.X - target.Position.X) * Wizard.MAX_THROW / distance); nextPosition.Y = (int)(nextPosition.Y + (myGoal.Y - target.Position.Y) * Wizard.MAX_THROW / distance); } w.Action = $"MOVE {nextPosition.X} {nextPosition.Y} {Wizard.MAX_THRUST}"; }); // Print actions myWizards.ForEach(w => { Console.WriteLine(w.Action); }); }
private static void Main(string[] args) { string[] inputs; _myTeamId = int.Parse(Console.ReadLine()); // if 0 you need to score on the right of the map, if 1 you need to score on the left var oppReflex = new ReflexBot(_myTeamId == 0 ? 3 : 1); var meReflex = new ReflexBot(_myTeamId == 0 ? 1 : 3); var oppSearch = new ReflexBot(oppReflex.Id - 1); var meSearch = new SearchBot(meReflex.Id - 1); meSearch.Opponents = new List <Bot>() { oppReflex, meReflex, oppSearch }; // game loop while (true) { round++; _snaffles.Clear(); inputs = Console.ReadLine().Split(' '); int myScore = int.Parse(inputs[0]); int myMagic = int.Parse(inputs[1]); inputs = Console.ReadLine().Split(' '); int opponentScore = int.Parse(inputs[0]); int opponentMagic = int.Parse(inputs[1]); int entities = int.Parse(Console.ReadLine()); // number of entities still in game int wizCount = 0; int oppWizCount = 0; for (int i = 0; i < entities; i++) { inputs = Console.ReadLine().Split(' '); int entityId = int.Parse(inputs[0]); // entity identifier EntityType entityType = (EntityType)Enum.Parse(typeof(EntityType), inputs[1], true); // "WIZARD", "OPPONENT_WIZARD" or "SNAFFLE" or "BLUDGER" int x = int.Parse(inputs[2]); // position int y = int.Parse(inputs[3]); // position int vx = int.Parse(inputs[4]); // velocity int vy = int.Parse(inputs[5]); // velocity int state = int.Parse(inputs[6]); // 1 if the wizard is holding a Snaffle, 0 otherwise switch (entityType) { case EntityType.Wizard: case EntityType.Opponent_Wizard: var wiz = _wizards.FirstOrDefault(w => w.Id == entityId); if (wiz == null) { wiz = new Wizard(entityId, x, y, vx, vy, Convert.ToBoolean(state)); wiz.TeamId = entityType == EntityType.Wizard ? _myTeamId : Math.Abs(_myTeamId - 1); _wizards.Add(wiz); if (wiz.TeamId == _myTeamId) { _myWiz[wizCount++] = wiz; if (meSearch.Wizard == null) { meSearch.Wizard = wiz; } else { meReflex.Wizard = wiz; } } else { _oppWiz[oppWizCount++] = wiz; if (oppSearch.Wizard == null) { oppSearch.Wizard = wiz; } else { oppReflex.Wizard = wiz; } } } else { wiz.X = x; wiz.Y = y; wiz.Velocity.X = vx; wiz.Velocity.Y = vy; wiz.Carrying = Convert.ToBoolean(state); } wiz.MP = myMagic; if (wiz.ActiveSpell != null) { wiz.ActiveSpell.Duration--; } wiz.Save(); _entities[entityId] = wiz; break; case EntityType.Snaffle: var snaffle = new Snaffle(entityId, x, y, vx, vy, Convert.ToBoolean(state)); _snaffles.Add(snaffle); snaffle.Save(); _entities[entityId] = snaffle; break; case EntityType.Bludger: var bludger = _bludgers.FirstOrDefault(w => w.Id == entityId); if (bludger == null) { bludger = new Bludger(entityId, x, y, vx, vy); _bludgers.Add(bludger); } else { bludger.X = x; bludger.Y = y; bludger.Velocity.X = vx; bludger.Velocity.Y = vy; } bludger.LastTarget = _wizards.FirstOrDefault(w => w.Id == state); bludger.Save(); _entities[entityId] = bludger; break; } } for (int i = 0; i < 4; i++) { _wizards[i].Snaffle = _snaffles.FirstOrDefault(s => s.Distance(_wizards[i]) < _wizards[i].Radius); _wizards[i].Save(); } _stopwatch = Stopwatch.StartNew(); int time = round == 0 ? 980 : 92; meSearch.Solve(time, round > 0); Solution.Output(meSearch.Solution.Moves[0], _wizards.First(w => w.Id == meSearch.Id)); Console.Error.WriteLine("Score {0}\nNew Pos: {1}", meSearch.Solution.Score, _myWiz[0] as Point); //meSearch.Solution.Output(meSearch.Solution.Moves[Chromosones], _wizards.First(w => w.Id == meSearch.Id + 1)); Console.WriteLine("MOVE 0 0 0 " + _myWiz[0]); if (round > 0) { Console.Error.WriteLine(string.Format("Sims Per Round: {0}, Avg: {1}", _simulations / round, _simulations * Chromosones / round)); } continue; foreach (var wizard in _wizards.Where(w => w.TeamId == _myTeamId)) { // Write an action using Console.WriteLine() To debug: // Console.Error.WriteLine("Debug messages..."); // Edit this line to indicate the action for each wizard (0 ≤ thrust ≤ 150, 0 ≤ // power ≤ 500) i.e.: "MOVE x y thrust" or "THROW x y power" if (wizard.Carrying) { var x = _myTeamId == 0 ? Width : 0 - wizard.Velocity.X; var y = GoalY - wizard.Velocity.Y; Console.WriteLine(string.Format("THROW {0} {1} {2}", x, y, MaxPower)); } else { //check bludger if (myMagic >= Flipendo.Cost) { int myGoal = _myTeamId == 0 ? 0 : Width; bool cast = false; foreach (var s in _snaffles.OrderByDescending(s => s.Distance(wizard))) { var spell = new Flipendo() { Source = wizard, Target = s }; Console.Error.WriteLine("Old {0}", wizard); spell.GetPower(); // s.Thrust((int)spell.Power, new Point(myGoal, GoalY)); s.Move(1.0); Console.Error.WriteLine("New {0}", wizard); if (s.X > Width || s.X < 0) { wizard.ActiveSpell.Cast(s); myMagic -= Flipendo.Cost; cast = true; break; } s.Load(); //if ((_myTeamId == 0 && s.X < 3000 && wizard.X > s.X) || (_myTeamId == 1 && s.X > Width - 3000 && wizard.X < s.X)) //{ // wizard.ActiveSpell = new Flipendo() // { // Target = s // }; // wizard.ActiveSpell.Cast(s); // cast = true; // myMagic -= Flipendo.Cost; // break; //} } if (cast) { continue; } } /* * if (myMagic > Obliviate.Cost) * { * var minBludgerDistance = 10000.0; * Bludger minBludger = null; * for (int i = 0; i < 2; i++) * { * var d = _bludgers[i].Distance(wizard); * if (d < minBludgerDistance) * { * minBludgerDistance = d; * minBludger = _bludgers[i]; * } * } * if (minBludgerDistance < 1000 && minBludger.LastTarget != wizard) * { * wizard.ActiveSpell = new Obliviate(); * wizard.ActiveSpell.Cast(minBludger); * Console.Error.WriteLine("Oblivia D: {0}", minBludgerDistance); * myMagic -= Obliviate.Cost; * continue; * } * }*/ if (myMagic >= Accio.Cost) { bool cast = false; foreach (var s in _snaffles) { if ((_myTeamId == 0 && s.X < 2000) || (_myTeamId == 1 && s.X > Width - 2000)) { wizard.ActiveSpell = new Accio(); wizard.ActiveSpell.Cast(s); cast = true; myMagic -= Accio.Cost; break; } } if (cast) { continue; } }/* * if (myMagic >= Petrificus.Cost) * { * bool cast = false; * foreach (var enemy in _wizards.Where(w => w.TeamId != _myTeamId && !_wizards.Any(w1 => w1.ActiveSpell?.Target == w))) * { * if ((_myTeamId == 0 && enemy.X < 3000) || (_myTeamId == 1 && enemy.X > Width - 3000)) * { * wizard.ActiveSpell = new Petrificus(); * wizard.ActiveSpell.Target = enemy; * wizard.ActiveSpell.Cast(enemy); * myMagic -= Petrificus.Cost; * cast = true; * break; * } * } * if (cast) continue; * } */ var snaff = _snaffles.OrderBy(s => s.Distance2(wizard)).FirstOrDefault(s => !s.BeingCarried); if (snaff == null) { snaff = _snaffles.FirstOrDefault(); } snaff.BeingCarried = true; Console.WriteLine(string.Format("MOVE {0} {1} {2}", snaff.X, snaff.Y, MaxThrust)); } } } }