double ProbabStrikeAfter(int swingTime, Hockeyist self, IEnumerable <MoveAction> actions, ActionType actionType) { var I = new AHock(self); if (Math.Abs(My.NetFront - I.X) < RinkWidth / 3) { return(0.0); } var power = GetPower(I, swingTime); var totalTime = 0; var opps = Hockeyists .Where(x => !x.IsTeammate && IsInGame(x)) .Select(x => new AHock(x)) .ToArray(); var goalie = Get(OppGoalie); foreach (var action in actions) { for (var i = 0; i < action.Ticks; i++) { GoalieMove(goalie, 1, I.PuckPos()); I.Move(action.SpeedUp, action.Turn); if (!Chase(opps, I)) { return(0.0); } } totalTime += action.Ticks; } var passAngle = PassAngleNorm(I.GetAngleTo(GetStrikePoint())); return(StrikeProbability(I, power, goalie, totalTime, actionType, passAngle, null)); }
public Point FindWayPoint(Hockeyist self) { var okDist = 5 * HoRadius; var bestTime = Inf; Point sel = null; //TimerStart(); var bot = Hockeyists.Count(x => !x.IsTeammate && IsInGame(x) && x.Y > RinkCenter.Y); var top = Hockeyists.Count(x => !x.IsTeammate && IsInGame(x) && x.Y <= RinkCenter.Y); foreach (Point p in WayPoints.ToArray().OrderBy(x => ((Point)x).GetDistanceTo(self)).Take(10)) { var I = new AHock(self); if (p.GetDistanceTo2(I) <= okDist * okDist || MyRight() && I.X < p.X || MyLeft() && I.X > p.X) { continue; } var cands = Hockeyists .Where(x => !x.IsTeammate && IsInGame(x)) .Select(x => new AHock(x)).ToArray(); var time = 0; var ok = true; while (p.GetDistanceTo2(I) > okDist * okDist && ok) { I.MoveTo(p); foreach (var c in cands) { c.MoveTo(I); if (CanStrike(c, I.PuckPos()) || // достанет шайбу CanStrike(c, I) || // достанет меня I.GetDistanceTo2(c) <= 2 * HoRadius * 2 * HoRadius // столкнется со мной ) { ok = false; break; } } time++; } if (ok) { if (p.Y > RinkCenter.Y && bot > top || p.Y <= RinkCenter.Y && top > bot) { time *= 3; } if (time < bestTime) { bestTime = time; sel = p.Clone(); } } } //Log("FindWayPoint " + TimerStop()); return(sel); }
bool NeedTrySubstitute(AHock hock) { if (!IsFinal()) { return(false); } var maxStamina = Hockeyists .Where(x => x.State == HockeyistState.Resting && x.IsTeammate) .Select(x => x.Stamina) .Max(); var to = Hockeyists.FirstOrDefault(x => Eq(x.Stamina, maxStamina)); if (to == null || maxStamina * 0.8 < hock.Stamina) { return(false); } return(true); }
Pair <int, long> GetFirstOnPuck(IEnumerable <Hockeyist> except, APuck pk, bool hard, int ticksLimit = 70, bool tryDown = true) { var cands = Hockeyists .Where(x => IsInGame(x) && except.Count(y => y.Id == x.Id) == 0) .ToArray(); var times = cands.Select(x => x.IsTeammate || hard ? GoToPuck(x, pk, ticksLimit, tryDown).Third : GetTicksToPuckDirect(new AHock(x), pk, 150)) .ToArray(); var whereMin = 0; for (var i = 1; i < times.Count(); i++) { if (times[i] < times[whereMin]) { whereMin = i; } } return(new Pair <int, long>(times[whereMin], cands[whereMin].Id)); }
double StrikeProbability(AHock striker, double strikePower, Point goalie, int leftTime, ActionType actionType, double passAngle, Point puckPos) { if (striker.CoolDown != 0) { return(0.0); } if (!Strike(striker, strikePower, goalie, actionType, passAngle, puckPos)) { return(0.0); } const int iters = 5; var deviation = (actionType == ActionType.Strike ? Game.StrikeAngleDeviation : Game.PassAngleDeviation) * 100 / striker.ADexterity; var range = deviation * 2; double upL = 0, upR = range; for (var it = 0; it < iters; it++) { var c = (upL + upR) / 2; if (StrikeWithDev(striker, strikePower, goalie, actionType, passAngle, c, puckPos)) { upL = c; } else { upR = c; } } double downL = -range, downR = 0; for (var it = 0; it < iters; it++) { var c = (downL + downR) / 2; if (StrikeWithDev(striker, strikePower, goalie, actionType, passAngle, c, puckPos)) { downR = c; } else { downL = c; } } double result = GaussIntegral(downL, upR, deviation); // Проверка что шайбу перехватят: if (leftTime != -1) { var pk = actionType == ActionType.Strike ? GetStrikePuck(striker, strikePower, goalie, puckPos) : GetPassPuck(striker, 1, passAngle, goalie); var opps = Hockeyists .Where(x => !x.IsTeammate && IsInGame(x)) .Select(x => new AHock(x)).ToArray(); pk.Clone().Move(300, true); var time = APuck.PuckLastTicks; for (var t = -leftTime; t < time; t++) { foreach (var opp in opps) { var hisTurn = TurnNorm(opp.GetAngleTo(pk), opp.AAgility); opp.Move(0.0, hisTurn); if (CanStrike(opp, pk)) { var pTake = (75.0 + Math.Max(opp.ADexterity, opp.AAgility) - pk.Speed.Length / 20 * 100) / 100; return(result * (1 - pTake)); } } if (t >= 0) { pk.Move(1); } } } return(result); }