public static bool CanShoot(MyPosition startPos, MyPosition endPos, SimGame game, SimUnit unit, double bulletSpeed) { var hitPos = GetHitPos(startPos, endPos, game, bulletSpeed, unit); var spread = AimService.GetSpread(unit); var posses = spread.Select(s => GetHitPos(startPos, s, game, bulletSpeed, unit)).ToArray(); foreach (var p in posses) { LogService.DrawLine(p, unit.Position, 0, 0, 1); } if (unit.WeaponType == WeaponType.RocketLauncher) { if (posses.Any(p => p.Dist(unit.TargetEnemy.Position) > p.Dist(unit.Position) && p.Dist(endPos) > unit.Weapon.Parameters.Explosion.Value.Radius - 1)) { return(false); } if (unit.TargetEnemy.Position.Dist(endPos) - unit.Weapon.Parameters.Explosion.Value.Radius > unit.Position.Dist(endPos)) { return(false); } } return(hitPos.Dist(endPos) < 1); }
public static void Search(SimGame game) { while (!Const.IsDone()) { DoOneRound(game); } }
public static MyPosition GetRealTarget(SimGame game, SimUnit unit) { //if (game.Game.CurrentTick > 1000) return Attack(game); if (!unit.HasWeapon) { return(GetWeapon(game.game, unit)); } var weaps = game.game.Weapons.Where(w => (w.Item as Item.Weapon).WeaponType == WeaponType.AssaultRifle).ToList(); if (unit.Weapon.Typ != AiCup2019.Model.WeaponType.AssaultRifle && weaps.Any(w => unit.Position.Dist(new MyPosition(w.Position)) < 4)) { return(new MyPosition(weaps.First(w => unit.Position.Dist(new MyPosition(w.Position)) < 4).Position)); } if (unit.NeedsHealing && game.game.HasHealing) { return(GetHealing(game.game, unit)); } //return new MyPosition(game.Enemy.Center.MoveTowards(me.Center, 3).X, game.Height-2); if (unit.Weapon.FireTimer > 0.2 && unit.Position.Dist(unit.TargetEnemy.Position) < 3) { return(Hide(game, unit)); } //LogService.WriteLine("Diff: " + game.ScoreDiff + " Tick: " + game.Game.CurrentTick + " " + game.Width + " " + game.Height); if (unit.Position.Dist(unit.TargetEnemy.Position) < 4 && Math.Abs(unit.Position.Y - unit.TargetEnemy.Position.Y) < 1) { return(Attack(game.game, unit)); } // if (unit.Player.ScoreDiff > 0) return Hide(game, unit); if (unit.Player.ScoreDiff == 0 && game.game.Game.CurrentTick < 300 && unit.TargetEnemy.HasWeapon) { return(Hide(game, unit)); } return(Attack(game.game, unit)); }
public static bool ShouldSwap(SimGame game, SimUnit unit) { if (!unit.HasWeapon) { return(true); } if (unit.WeaponType == WeaponType.AssaultRifle) { return(false); } var weaponBoxes = game.game.Weapons; var closest = weaponBoxes.OrderBy(w => new MyPosition(w.Position).Dist(unit.Position)).Cast <LootBox?>().FirstOrDefault(); if (closest == null) { return(false); } var weapon = closest.Value.Item as Item.Weapon; var rect = Rect.FromMovingBullet(closest.Value.Position, closest.Value.Size.X); if (rect.Overlapping(unit.Rect) && unit.WeaponType != weapon.WeaponType) { if (weapon.WeaponType == WeaponType.AssaultRifle) { return(true); } if (weapon.WeaponType == WeaponType.Pistol) { return(true); } //return weapon.WeaponType > game.Me.Weapon.Typ; } return(false); }
public static void Initialize(SimGame game) { if (m_isRun) { return; } var t = Const.GetTime; m_isRun = true; var max = Const.Width * Const.Height; canShootMap = new bool[max, max]; for (var x = 0; x < Const.Width; x++) { for (var y = 0; y < Const.Height; y++) { if (game.GetTile(x, y) == Tile.Wall) { continue; } Init(x, y, game); } } Console.Error.WriteLine("Shoot time: " + (Const.GetTime - t)); }
public override void Update(SimGame game) { if (Pm.Position.Team == game.Player.Team) { game.OnboardPokemons[Pm.Position.X] = new SimOnboardPokemon(game.Pokemons[Pm.Id], Pm); game.Team[Pm.TeamIndex].SwitchPokemon(Pm.PokemonIndex, FormerIndex); } }
public override void Update(SimGame game) { var pm = GetPokemon(game, Pm); if (pm != null) { pm.SetHp(Hp); } }
public override void Update(SimGame game) { SimPokemon p = GetPokemon(game, Pm); if (p != null) { p.State = State; } }
public override void Update(SimGame game) { var pm = GetOnboardPokemon(game, Pm); if (pm != null && pm.Pokemon.Owner == game.Player) { pm.ChangeMove(Ms.MIMIC, Move); } }
public override void Update(SimGame game) { var pm = GetPokemon(game, Pm); if (pm != null) { pm.Item = Item; } }
public static MyPosition GetHitPos(MyPosition startPos, MyPosition endPos, SimGame game, double bulletSpeed, SimUnit firering, bool stopOnEnd = true) { var dist = endPos.Dist(startPos); var time = GetShootTime(dist, bulletSpeed) * Const.Properties.TicksPerSecond * 15; var dx = (endPos.X - startPos.X) / time; var dy = (endPos.Y - startPos.Y) / time; var x = startPos.X; var y = startPos.Y; var d = startPos.Dist(endPos); for (var i = 0; i < time * 2; i++) { x += dx; y += dy; if (!game.game.OnBoard(x, y)) { return(new MyPosition(x, y)); } var tile = game.GetTileD(x, y); if (tile == Tile.Wall) { return(new MyPosition(x, y)); } tile = game.GetTileD(x - firering.Weapon.Parameters.Bullet.Size * 0.5, y - firering.Weapon.Parameters.Bullet.Size * 0.5); if (tile == Tile.Wall) { return(new MyPosition(x, y)); } tile = game.GetTileD(x + firering.Weapon.Parameters.Bullet.Size * 0.5, y - firering.Weapon.Parameters.Bullet.Size * 0.5); if (tile == Tile.Wall) { return(new MyPosition(x, y)); } var nextD = Math.Sqrt(MyPosition.Pow(x - endPos.X) + MyPosition.Pow(y - endPos.Y)); if (nextD > d && stopOnEnd || nextD < 0.3) { return(endPos); } d = nextD; foreach (var u in game.Units) { if (u == firering || u.unit.PlayerId != firering.unit.PlayerId) { continue; } var unit = u.unit; if (!(Math.Abs(x - unit.Position.X) > firering.Weapon.Parameters.Bullet.Size / 2 + unit.Size.X / 2 || Math.Abs(y - unit.Position.Y) > firering.Weapon.Parameters.Bullet.Size / 2 + unit.Size.Y / 2)) { return(new MyPosition(x, y)); } } } return(endPos); }
internal PlayerController(RoomController room, IPokemonData[] pokemons, IPokemonData[] partner) { Client = room._Client; var team = room.User.Seat.TeamId(); var pli = room.User.Seat.TeamIndex(); var pl = new SimPlayer(team, pli, pokemons); var pa = partner == null ? null : new SimPlayer(team, 1 - pli, partner); _game = new SimGame(room.Room.Settings, pl, pa); }
public override void Update(SimGame game) { for (int i = 0; i < Pms.Length; ++i) { var pm = GetPokemon(game, Pms[i]); if (pm != null) { pm.SetHp(pm.Hp.Value - Damages[i]); } } }
public override void Update(SimGame game) { if (team == game.Player.Team) { var pm = game.OnboardPokemons[x].Pokemon; game.OnboardPokemons[x] = null; pm.ResetForm(); if (pm.Hp.Value == 0) { pm.State = PokemonState.Faint; } } }
public static bool ShouldShoot(SimGame game, SimUnit unit) { LogService.WriteLine("FireTimer: " + unit.FireTimer); if (!unit.HasWeapon) { return(false); } // return (CanShootAt(unit.Position, unit.TargetEnemy.Position)); //if (me.Unit.Weapon.Value.Spread > me.Unit.Weapon.Value.Parameters.MinSpread + 0.1 && me.Center.Dist(aimPos) > 5) return false; if (!CanShoot(unit.Position, unit.AimTarget, game, unit, unit.Weapon.Parameters.Bullet.Speed)) { return(false); } return(true); }
public UnitAction GetAction(Unit unit, Game game, AiCup2019.Debug debug) { if (m_lastTick >= game.CurrentTick) // Verify this number { //TODO: Check number of bullets LogService.WriteLine("Cached choice"); return(CreateAction(m_lastGame.Units.First(u => u.unit.Id == unit.Id), m_lastGame)); } Const.Reset(game.Properties, game); Debug = debug; var myGame = new MyGame(game, unit); var sim = m_lastGame = new SimGame(myGame, unit); m_lastTick = game.CurrentTick; DistService.CalcDists(sim); ShootService.Initialize(sim); foreach (var b in sim.Bullets) { b.CalcCollisionTime(sim); } foreach (var u in sim.Units) { u.WalkTarget = WalkService.FindWalkTarget(sim, u); u.AimTarget = AimService.GetAimTarget(sim, u); u.Shoot = ShootService.ShouldShoot(sim, u); if (u.Player.Id == unit.PlayerId) { u.IsMine = true; } } LogService.WriteLine("FIRETIMER: " + m_lastGame.Units.First(u => u.unit.Id == unit.Id).FireTimer); MCTSService.Search(sim); //foreach (var u in sim.Units) u.debug = true; MCTSService.DoOneRound(sim, true); //foreach (var u in sim.Units) u.debug = false; if (game.CurrentTick % 300 == 10) { Console.Error.WriteLine("Time: " + Const.GetTime + " Evals: " + Const.Evals + " Sims: " + Const.Sims); } var targetUnit = m_lastGame.Units.First(u => u.unit.Id == unit.Id); DistService.DrawPath(targetUnit.Position, targetUnit.WalkTarget); return(CreateAction(targetUnit, m_lastGame)); }
public override void Update(SimGame game) { var pm = GetOnboardPokemon(game, Pm); if (pm != null) { foreach (var m in pm.Moves) { if (m != null && m.Type.Id == Move) { m.PP.Value = PP; break; } } } }
public static MyPosition FindWalkTarget(SimGame game, SimUnit unit) { var target = GetRealTarget(game, unit); for (var y = (int)target.Y; y < game.game.Height; y++) { var p = new MyPosition(target.X, y); var d = DistService.GetDist(p, unit.Position); if (d < game.game.Width * game.game.Height * 4) { target = p; break; } } LogService.DrawLine(target, unit.Position, 1, 0, 0); return(target); }
public override void Update(SimGame game) { if (Number == 0) { var pm = GetPokemon(game, Pm); if (pm != null) { pm.ChangeForm(Form, Forever); } } else if (Moves != null) { var pm = GetOnboardPokemon(game, Pm); if (pm != null && pm.Pokemon.Owner == game.Player) { pm.ChangeMoves(Moves); } } }
public static void DoOneRound(SimGame game, bool draw = false) { Const.Evals++; for (var i = 0; i < Const.Depth; i++) { SimService.Simulate(game, i, draw); if (draw) { foreach (var u in game.Units) { u.Draw(u.Health < u._health); } } } foreach (var unit in game.Units) { unit.AfterRound(); } game.Reset(); }
private static UnitAction CreateAction(SimUnit unit, SimGame game) { var selectedAction = unit.GetBestNode(); var aim = unit.AimTarget; var pos = unit.Position; var shoot = unit.Shoot; var enemies = unit.Enemies.OrderBy(e => e.Position.Dist(pos) + e.Health * 0.01).ToList(); var targetPos = enemies.First().Position; UnitAction action = new UnitAction { Velocity = selectedAction.Dx * Const.Properties.UnitMaxHorizontalSpeed, Jump = selectedAction.JumpUp, JumpDown = selectedAction.JumpDown, Aim = new Vec2Double(aim.X - pos.X, aim.Y - pos.Y), Shoot = shoot, Reload = !shoot && unit.HasWeapon && pos.Dist(targetPos) > 5 && unit.HasWeapon && unit.Weapon.Magazine < unit.Weapon.Parameters.MagazineSize * 0.3, SwapWeapon = SwapService.ShouldSwap(game, unit), PlantMine = unit.Position.Dist(unit.TargetEnemy.Position) < 3 }; return(action); }
public static MyPosition GetAimTarget(SimGame game, SimUnit unit) { var pos = unit.Position; var targetPos = unit.TargetEnemy.Position; //if (!unit.HasWeapon) return(targetPos); foreach (var e in unit.Enemies.OrderBy(e => e.Position.Dist(unit.Position))) { if (ShootService.CanHitDirect(unit.Position, e.Position, game, unit)) { targetPos = e.Position; break; } } var dist = pos.Dist(targetPos); var requested = unit.WeaponType == AiCup2019.Model.WeaponType.RocketLauncher ? GetClosestGround(game.game, targetPos) : targetPos; if (dist < 3 || Math.Abs(targetPos.Y - pos.Y) < 0.1) { requested = targetPos; } var angle = Math.Atan2(requested.Y - pos.Y, requested.X - pos.X); var prevAngle = unit.AimAngle; if (Math.Abs(angle - prevAngle) < 0.1 || unit.FireTimer > 0 && Math.Abs(angle - prevAngle) < 0.2) { angle = prevAngle; } var dx = Math.Cos(angle) * dist; var dy = Math.Sin(angle) * dist; var target = new MyPosition(pos.X + dx, pos.Y + dy); //LogService.DrawLine(target, unit.Position, 1, 0, 0); return(target); }
private static void Init(int startX, int startY, SimGame game) { var pos = Const.GetPos(startX, startY); for (var i = 0; i < 360; i += 1) { var angle = i / 180 * Math.PI; var dx = Math.Cos(angle); var dy = Math.Sin(angle); for (var s = 0.0; s < 10; s += 0.3) { var x = (int)(startX + dx * s); var y = (int)(startY + dy * s); if (game.GetTile(x, y) == Tile.Wall || !game.OnBoard(x, y)) { break; } var pos2 = Const.GetPos(x, y); canShootMap[pos, pos2] = true; canShootMap[pos2, pos] = true; } } }
public static bool CanHitDirect(MyPosition startPos, MyPosition endPos, SimGame game, SimUnit firering) { var hitPos = GetHitPos(startPos, endPos, game, 5, firering); return(hitPos.Dist(endPos) < 1); }
private static MyPosition Hide(SimGame game, SimUnit unit) { var heights = game.game.GetHideouts(); return(heights.OrderByDescending(p => DistService.GetDist(p, unit.TargetEnemy.Position) - DistService.GetDist(unit.Position, p) * 0.5).FirstOrDefault() ?? unit.TargetEnemy.Position); }
public static void Simulate(SimGame game, int depth, bool draw = false) { foreach (var unit in game.Units) { unit.GetNextMove(depth); } var steps = Const.Steps * Const.DepthPerMove; Const.Sims += Const.DepthPerMove; var timer = 0; for (var s = 0; s < steps; s++) { foreach (var u in game.Units) { u.ApplyAction(u.CurrentAction, game, Const.Time, timer == 0); } if (timer == 3) { foreach (var b in game.Bullets) { b.Move(game, Const.Time * Const.Steps); } } if (timer-- <= 0) { timer = Const.Steps; } } foreach (var u in game.Units) { if (draw) { u.Draw(u.Health < u._health); } if (u.DidTouch) { u.Score += DistService.GetDist(u.Position, u.WalkTarget); } else { var d = DistService.GetDist(u.Position, u.WalkTarget) + Math.Abs(u.Position.X - u.WalkTarget.X) * 0.5; u.Score -= d; if (d < 0.6) { u.DidTouch = true; } } if (!u.HasWeapon) { continue; } foreach (var u2 in game.Units) { if (u == u2) { continue; } if (u.TeamId == u2.TeamId) { if (Math.Abs(u.Position.X - u2.Position.X) < 3 && Math.Abs(u.Position.Y - u2.Position.Y) < 4) { u.Score -= 1000; } } else if (Math.Abs(u.Position.X - u2.Position.X) < 3 && Math.Abs(u.Position.Y - u2.Position.Y) < 4) { u.Score -= 100; } } } }
public static void CalcDists(SimGame game) { Game = game; if (m_isRun) { return; } for (var i = game.game.Height - 1; i >= 0; i--) { var line = ""; for (var j = 0; j < game.game.Width; j++) { var tile = game.game.Game.Level.Tiles[j][i]; if (tile == AiCup2019.Model.Tile.Wall) { line += "#"; } else if (tile == AiCup2019.Model.Tile.Ladder) { line += "H"; } else if (tile == AiCup2019.Model.Tile.Platform) { line += "^"; } else if (tile == AiCup2019.Model.Tile.JumpPad) { line += "T"; } else { var possible = "."; foreach (var unit in game.Units) { var X = (int)unit.Position.X; var Y = (int)(unit.Position.Y - unit.HalffHeight); if (X == j && Y == i) { possible = "P"; } } line += possible; } } Console.Error.WriteLine(line); } var t = Const.GetTime; m_isRun = true; var max = Game.game.Width * Game.game.Height; Dists = new int[max, max]; Ground = new bool[max]; for (var i = 0; i < game.game.Width; i++) { for (var j = 1; j < game.game.Height; j++) { if (game.game.GetTile(i, j) == AiCup2019.Model.Tile.Wall) { continue; } var pos = Const.GetPos(i, j); Ground[pos] = game.game.GetTile(i, j - 1) != AiCup2019.Model.Tile.Empty; } } for (var i = 0; i < max; i++) { for (var j = 0; j < max; j++) { if (i == j) { Dists[i, j] = 0; } else { Dists[i, j] = 10000; } } } for (var i = 0; i < Game.game.Width; i++) { for (var j = 0; j < Game.game.Height; j++) { FindDists(i, j); } } Console.Error.WriteLine("Dist time: " + (Const.GetTime - t)); Const.Stopwatch = Stopwatch.StartNew(); }