public ABonus(ABonus bonus) : base(bonus) { Type = bonus.Type; RemainingAppearanceTicks = bonus.RemainingAppearanceTicks; Skip = bonus.Skip; }
MovingInfo FindBonusTarget(AWizard self) { var minTime = int.MaxValue; var selGo = 0; Point selMoveTo = null; foreach (var _bonus in BonusesObserver.Bonuses) { if (_bonus.GetDistanceTo(self) - self.Radius - _bonus.Radius > Game.StaffRange * 3) { continue; } if (_bonus.RemainingAppearanceTicks > 60) { continue; } var nearest = Combats .Where(x => x.Id != self.Id && self.GetDistanceTo2(x) < Geom.Sqr(self.VisionRange)) .ToArray(); foreach (var angle in Utility.Range(self.Angle, Math.PI * 2 + self.Angle, 24, false)) { var bonus = new ABonus(_bonus); var my = new AWizard(self); var moveTo = my + Point.ByAngle(angle) * self.VisionRange; int time = 0; int go = 0; while (my.GetDistanceTo(bonus) > my.Radius + bonus.Radius && time < 60) { if (!my.MoveTo(moveTo, null, w => !CheckIntersectionsAndTress(w, nearest))) { break; } var wait = !bonus.Exists; bonus.SkipTick(); time++; if (my.GetDistanceTo(bonus) <= my.Radius + bonus.Radius) { while (!bonus.Exists) { bonus.SkipTick(); time++; } if (wait) { time++; } if (time < minTime) { minTime = time; selMoveTo = moveTo; selGo = go; } break; } go++; } } } var moving = new MovingInfo(selMoveTo, minTime, new FinalMove(new Move())); if (selMoveTo != null) { if (minTime == 1 || selGo > 0) { moving.Move.MoveTo(selMoveTo, null); } else { moving.Target = self; } } return(moving); }
public static void Update() { foreach (var b in Bonuses) { for (var t = MyStrategy.PrevTickIndex + 1; t < MyStrategy.World.TickIndex; t++) // это если убили { b.SkipTick(); } } var interval = MyStrategy.Game.BonusAppearanceIntervalTicks; var newDict = new Dictionary <int, ABonus>(); var curStage = (MyStrategy.World.TickIndex - 1) / interval; foreach (var b in MyStrategy.World.Bonuses) { var visibleBonus = new ABonus(b); newDict[visibleBonus.Order] = visibleBonus; _lastVisibleStage[visibleBonus.Order] = curStage; } foreach (var oldBonus in _bonuses.Values) { if (!MyStrategy.IsPointVisible(oldBonus)) { // он точно не прилетел в World, т.к. не виден // остается на текущей тик oldBonus.SkipTick(); newDict[oldBonus.Order] = oldBonus; } else { _lastVisibleStage[oldBonus.Order] = curStage; if (!oldBonus.Exists && !newDict.ContainsKey(oldBonus.Order)) { // вижу, но он ещё не появился oldBonus.SkipTick(); if (!oldBonus.Exists) // если он не должен был появиться только что { newDict[oldBonus.Order] = oldBonus; } } } } for (var i = 0; i < 2; i++) { if (!newDict.ContainsKey(i)) { var remains = curStage > _lastVisibleStage[i] ? 0 : (MyStrategy.World.TickIndex == 0 ? interval + 1 : (interval - MyStrategy.World.TickIndex % interval) % interval + 1 ); if (MyStrategy.World.TickIndex + remains >= MyStrategy.Game.TickCount) { remains = 100500; } newDict[i] = new ABonus { X = Const.BonusAppearencePoints[i].X, Y = Const.BonusAppearencePoints[i].Y, Id = i - 2, RemainingAppearanceTicks = remains, Radius = MyStrategy.Game.BonusRadius, }; } } _bonuses = newDict; }
bool _tryDodgeProjectile() { var obstacles = Combats.Where(x => x.Id != Self.Id && x.GetDistanceTo(ASelf) < 300).ToArray(); var minTicks = int.MaxValue; var minDamage = 1000.0; Point selMoveTo = null; Point selTurnTo = null; foreach (var doTurn in new[] { false, true }) { foreach (var angle in Utility.Range(0, Math.PI * 2, 40, false)) { if (minTicks == 0 && minDamage < Const.Eps) // ничего не грозит { break; } var ticks = 0; var my = new AWizard(ASelf); var bonus = new ABonus(BonusesObserver.Bonuses.ArgMin(b => b.GetDistanceTo(Self))); var moveTo = my + Point.ByAngle(angle) * 1000; var turnTo = doTurn ? moveTo : null; var myStates = new List <AWizard> { new AWizard(my) }; while (ticks < ProjectilesCheckTicks) { var totalDamage = _getProjectilesDamage(myStates); if (Utility.Less(totalDamage, minDamage) || Utility.Equals(totalDamage, minDamage) && ticks < minTicks) { minTicks = ticks; minDamage = totalDamage; selMoveTo = moveTo; selTurnTo = turnTo; } bonus.SkipTick(); my.MoveTo(moveTo, turnTo, w => { if (CheckIntersectionsAndTress(w, obstacles)) { return(false); } if (bonus.RemainingAppearanceTicks < 15 && bonus.IntersectsWith(w)) { return(false); } return(true); }); myStates.Add(new AWizard(my)); ticks++; } } } if (minTicks == 0 || minTicks == int.MaxValue) // нет необходимости уворачиваться { return(false); } if (selTurnTo != null || Math.Abs(ASelf.GetAngleTo(selMoveTo)) < Math.PI / 2) { FinalMove.Turn = 0; } FinalMove.MoveTo(selMoveTo, selTurnTo); return(true); }