コード例 #1
0
ファイル: FindPath.cs プロジェクト: znsoft/AiCup
        bool TrySubstitute(AHock hock)
        {
            if (!IsFinal() ||
                hock.Speed.Length > Game.MaxSpeedToAllowSubstitute ||
                !IsInSubstArea(hock) ||
                hock.Base.RemainingCooldownTicks > 0 ||
                hock.Base.RemainingKnockdownTicks > 0
                )
            {
                return(false);
            }

            var maxStamina = MyRest
                             .Select(x => x.Stamina)
                             .Max();
            var maxStrength = MyRest
                              .Where(x => Eq(maxStamina, x.Stamina))
                              .Select(x => x.Strength)
                              .Max();

            var to = Hockeyists.FirstOrDefault(x => Eq(x.Stamina, maxStamina) && Eq(x.Strength, maxStrength));

            if (to == null || maxStamina < hock.Stamina)
            {
                return(false);
            }
            move.Action        = ActionType.Substitute;
            move.TeammateIndex = to.TeammateIndex;
            return(true);
        }
コード例 #2
0
ファイル: Attack.cs プロジェクト: znsoft/AiCup
        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));
        }
コード例 #3
0
ファイル: Attack.cs プロジェクト: znsoft/AiCup
        public bool TryStrikeWithoutTakeIfSwinging(AHock _hock, APuck _pk)
        {
            var hock       = _hock.Clone();
            var pk         = _pk.Clone();
            var bestProbab = 0.0;
            var swTime     = Inf;

            for (var sw = 0; sw <= Game.MaxEffectiveSwingTicks; sw++)
            {
                if (CanStrike(hock, pk))
                {
                    var pr = StrikeProbability(hock, GetPower(hock, sw + hock.Base.SwingTicks), pk.Goalie, -1, ActionType.Strike, 0, pk);
                    if (pr > bestProbab)
                    {
                        bestProbab = pr;
                        swTime     = sw;
                    }
                }
                hock.Move(0, 0);
                pk.Move(1);
            }

            if (swTime == Inf)
            {
                return(false);
            }
            if (swTime == 0)
            {
                move.Action = ActionType.Strike;
            }
            return(true);
        }
コード例 #4
0
ファイル: FindPath.cs プロジェクト: znsoft/AiCup
        Pair<Point, int> GetSubstitutePoint(AHock hock)
        {
            Point bestPoint = null;
            var selDir = 0;
            var minTicks = Inf;
            for (var x = Game.RinkLeft; x <= Game.RinkRight; x += RinkWidth/100)
            {
                if (MyLeft() && x > RinkCenter.X - 100 || MyRight() && x < RinkCenter.X + 100)
                    continue;

                var to = new Point(x, Game.RinkTop);
                var up = GetTicksToUp(hock, to);
                var down = GetTicksToDown(hock, to);
                if (up < minTicks)
                {
                    minTicks = up;
                    selDir = 1;
                    bestPoint = to;
                }
                if (down < minTicks)
                {
                    minTicks = down;
                    selDir = -1;
                    bestPoint = to;
                }
            }
            return new Pair<Point, int>(bestPoint, selDir);
        }
コード例 #5
0
ファイル: Utility.cs プロジェクト: znsoft/AiCup
        public static double GetPower(AHock self, int swingTime)
        {
            var res = Math.Min(Game.MaxEffectiveSwingTicks, swingTime) * 0.25 / Game.MaxEffectiveSwingTicks + 0.75;

            res = res * self.AStrength / 100;
            return(res);
        }
コード例 #6
0
ファイル: Attack.cs プロジェクト: znsoft/AiCup
        private bool StrikePrimitiveValidate(AHock striker)
        {
            var puckPos = striker.PuckPos();

            if (Math.Abs(puckPos.X - Opp.NetFront) > RinkWidth / 3 * 2)
            {
                return(false);
            }

            if (Math.Abs(puckPos.X - Opp.NetFront) < 3.5 * HoRadius)
            {
                return(false);
            }

            if (MyRight() && Math.Cos(striker.Angle) > 0)
            {
                return(false);
            }
            if (MyLeft() && Math.Cos(striker.Angle) < 0)
            {
                return(false);
            }

            return(true);
        }
コード例 #7
0
ファイル: FindPath.cs プロジェクト: znsoft/AiCup
        Pair <Point, int> GetSubstitutePoint(AHock hock)
        {
            Point bestPoint = null;
            var   selDir    = 0;
            var   minTicks  = Inf;

            for (var x = Game.RinkLeft; x <= Game.RinkRight; x += RinkWidth / 100)
            {
                if (MyLeft() && x > RinkCenter.X - 100 || MyRight() && x < RinkCenter.X + 100)
                {
                    continue;
                }

                var to   = new Point(x, Game.RinkTop);
                var up   = GetTicksToUp(hock, to);
                var down = GetTicksToDown(hock, to);
                if (up < minTicks)
                {
                    minTicks  = up;
                    selDir    = 1;
                    bestPoint = to;
                }
                if (down < minTicks)
                {
                    minTicks  = down;
                    selDir    = -1;
                    bestPoint = to;
                }
            }
            return(new Pair <Point, int>(bestPoint, selDir));
        }
コード例 #8
0
ファイル: PuckMoving.cs プロジェクト: znsoft/AiCup
 public APuck GetPassPuck(AHock striker, double PassPower, double PassAngle, Point goalie)
 {
     var puckSpeedAbs = striker.AStrength / 100 * Game.PassPowerFactor * Game.StruckPuckInitialSpeedFactor * PassPower + striker.Speed.Length * Math.Cos(striker.Angle + PassAngle - striker.Speed.GetAngle());
     var puckAngle = AngleNormalize(PassAngle + striker.Angle);
     var puckSpeed = new Point(puckAngle)*puckSpeedAbs;
     return new APuck(striker.PuckPos(), puckSpeed, goalie);
 }
コード例 #9
0
        bool TryPass(AHock striker)
        {
            if (striker.Base.RemainingCooldownTicks != 0)
            {
                return(false);
            }

            TimerStart();

            const int passAnglesCount = 7;
            double    minTime         = Inf,
                      bestAngle       = 0.0,
                      bestPower       = 0.0;

            foreach (var power in new[] { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.8, 1.0 })
            {
                for (var passDir = -1; passDir <= 1; passDir += 2)
                {
                    for (var absPassAngle = 0.0; absPassAngle <= Game.PassSector / 2; absPassAngle += Game.PassSector / 2 / passAnglesCount)
                    {
                        var passAngle = absPassAngle * passDir;
                        var pk        = GetPassPuck(striker, power, passAngle, Get(OppGoalie)); // TODO: проверять на автогол
                        var on        = GetFirstOnPuck(new[] { striker.Base }, pk, IsFinal(), 100, false);
                        pk.Move(300);
                        if (APuck.PuckLastTicks < on.First)
                        {
                            continue;
                        }
                        var toHock = new AHock(Get(on.Second));
                        if (!toHock.Base.IsTeammate)
                        {
                            continue;
                        }
                        var time = on.First;
                        if (IsWaitingSwing(toHock))
                        {
                            time /= 5;
                        }
                        if (time < minTime)
                        {
                            minTime   = time;
                            bestAngle = passAngle;
                            bestPower = power;
                        }
                    }
                }
            }

            Log("TryPass " + TimerStop());

            if (minTime >= Inf - Eps)
            {
                return(false);
            }
            move.Action    = ActionType.Pass;
            move.PassAngle = bestAngle;
            move.PassPower = bestPower;
            return(true);
        }
コード例 #10
0
ファイル: Attack.cs プロジェクト: znsoft/AiCup
        bool Strike(AHock striker, double strikePower, Point goalie, ActionType actionType, double passAngle, Point puckPos)
        {
            var pk = actionType == ActionType.Strike
                ? GetStrikePuck(striker, strikePower, goalie, puckPos)
                : GetPassPuck(striker, 1, passAngle, goalie);

            return(PuckPrimitiveValidate(pk) && pk.Move(300, true) == 1);
        }
コード例 #11
0
        public APuck GetPassPuck(AHock striker, double PassPower, double PassAngle, Point goalie)
        {
            var puckSpeedAbs = striker.AStrength / 100 * Game.PassPowerFactor * Game.StruckPuckInitialSpeedFactor * PassPower + striker.Speed.Length * Math.Cos(striker.Angle + PassAngle - striker.Speed.GetAngle());
            var puckAngle    = AngleNormalize(PassAngle + striker.Angle);
            var puckSpeed    = new Point(puckAngle) * puckSpeedAbs;

            return(new APuck(striker.PuckPos(), puckSpeed, goalie));
        }
コード例 #12
0
ファイル: PuckMoving.cs プロジェクト: znsoft/AiCup
 bool IsWaitingSwing(AHock hock)
 {
     var str = GetStrikePoint();
     if (Math.Abs(hock.GetAngleTo(str)) > Deg(60))
         return false;
     return Math.Abs(My.NetFront - hock.X) > RinkWidth / 3
         && (hock.Y < Game.GoalNetTop || hock.Y > Game.GoalNetTop + Game.GoalNetHeight);
 }
コード例 #13
0
ファイル: FindPath.cs プロジェクト: znsoft/AiCup
        public bool FindPath(Hockeyist self, Point to, Point lookAt)
        {
            if (lookAt == null)
            {
                return(StopOn(new AHock(self), to));
            }

            var okDist = HoRadius * 1.5;

            var minTime = Inf;
            var selTurn = 0.0;
            var selSpUp = 0.0;

            for (var dir = -1; dir <= 1; dir += 2)
            {
                var hock = new AHock(self);
                for (var ticksDirect = 0; ticksDirect < 100; ticksDirect++)
                {
                    var curTime = ticksDirect;
                    var ho      = hock.Clone();
                    while (Math.Abs(ho.GetAngleTo(lookAt)) > Deg(8))
                    {
                        ho.Move(0, TurnNorm(ho.GetAngleTo(lookAt), ho.AAgility));
                        curTime++;
                    }
                    if (curTime < minTime && ho.GetDistanceTo(to) < okDist)
                    {
                        minTime = curTime;
                        if (ticksDirect == 0)
                        {
                            selSpUp = 0.0;
                            selTurn = TurnNorm(ho.GetAngleTo(lookAt), hock.AAgility);
                        }
                        else if (dir > 0)
                        {
                            selTurn = self.GetAngleTo(to.X, to.Y);
                            selSpUp = GetSpeedTo(selTurn);
                        }
                        else
                        {
                            selTurn = RevAngle(self.GetAngleTo(to.X, to.Y));
                            selSpUp = -GetSpeedTo(selTurn);
                        }
                    }
                    if (dir > 0)
                    {
                        GetTicksToUpN(hock, to, 0, 1);
                    }
                    else
                    {
                        GetTicksToDownN(hock, to, 0, 1);
                    }
                }
            }
            move.SpeedUp = selSpUp;
            move.Turn    = selTurn;
            return(minTime != Inf);
        }
コード例 #14
0
ファイル: MyStrategy.cs プロジェクト: znsoft/AiCup
 public int GetTicksTo(Point to, Hockeyist my, bool tryDown = true)
 {
     var ho = new AHock(my);
     var up = GetTicksToUp(ho, to);
     var down = tryDown ? GetTicksToDown(ho, to) : Inf;
     if (up <= down)
         return up;
     return -down;
 }
コード例 #15
0
ファイル: Attack.cs プロジェクト: znsoft/AiCup
        APuck GetStrikePuck(AHock striker, double strikePower, Point goalie, Point puckPos)
        {
            var strikerDirection   = new Point(striker.Angle);
            var speedAngleStriker  = striker.Speed.GetAngle();
            var puckSpeed          = 20.0 * strikePower + striker.Speed.Length * Math.Cos(striker.Angle - speedAngleStriker);
            var puckSpeedDirection = strikerDirection * puckSpeed;

            return(new APuck(puckPos ?? striker.PuckPos(), puckSpeedDirection, goalie));
        }
コード例 #16
0
ファイル: MyStrategy.cs プロジェクト: znsoft/AiCup
 public int GetTicksToUpN(AHock ho, Point to, double takePuck = -1, int limit = 500)
 {
     var result = 0;
     for (; result < limit && (takePuck < 0 ? !CanStrike(ho, to) : ho.GetDistanceTo2(to) > takePuck*takePuck); result++)
     {
         ho.MoveTo(to);
     }
     return result;
 }
コード例 #17
0
ファイル: Attack.cs プロジェクト: znsoft/AiCup
        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);
        }
コード例 #18
0
ファイル: Research.cs プロジェクト: znsoft/AiCup
        // Проверка движение хоккеиста
        void Research3(Hockeyist self)
        {
            var range = TurnRange(new AHock(self).AAgility);

            move.Turn    = range / 2;
            move.SpeedUp = 0.8;
            var pl = new AHock(self);

            pl.Move(0.8, range / 2, 20);
        }
コード例 #19
0
ファイル: MyStrategy.cs プロジェクト: znsoft/AiCup
        public int GetTicksToUpN(AHock ho, Point to, double takePuck = -1, int limit = 500)
        {
            var result = 0;

            for (; result < limit && (takePuck <0 ? !CanStrike(ho, to) : ho.GetDistanceTo2(to)> takePuck * takePuck); result++)
            {
                ho.MoveTo(to);
            }
            return(result);
        }
コード例 #20
0
        bool IsWaitingSwing(AHock hock)
        {
            var str = GetStrikePoint();

            if (Math.Abs(hock.GetAngleTo(str)) > Deg(60))
            {
                return(false);
            }
            return(Math.Abs(My.NetFront - hock.X) > RinkWidth / 3 &&
                   (hock.Y < Game.GoalNetTop || hock.Y > Game.GoalNetTop + Game.GoalNetHeight));
        }
コード例 #21
0
ファイル: MyStrategy.cs プロジェクト: znsoft/AiCup
 public int GetTicksToDownN(AHock ho, Point to, double takePuck = -1, int limit = 300)
 {
     var result = 0;
     for (; result < limit && (takePuck < 0 ? !CanStrike(ho, to) : ho.GetDistanceTo2(to) > takePuck * takePuck); result++)
     {
         var turn = RevAngle(ho.GetAngleTo(to));
         var speedUp = -GetSpeedTo(turn);
         ho.Move(speedUp, TurnNorm(turn, ho.AAgility));
     }
     return result >= limit ? Inf : result;
 }
コード例 #22
0
ファイル: PuckMoving.cs プロジェクト: znsoft/AiCup
 Point PuckMove(int ticks, APuck pk, AHock hock)
 {
     if (hock == null)
     {
         pk.Move(ticks);
         return new Point(pk);
     }
     if (Math.Abs(hock.GetAngleTo(hock + hock.Speed)) < Deg(15) && hock.Speed.Length > 2)
         hock.Move(1, 0, ticks); // TODO
     return hock.PuckPos();
 }
コード例 #23
0
ファイル: Attack.cs プロジェクト: znsoft/AiCup
        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;
        }
コード例 #24
0
ファイル: MyStrategy.cs プロジェクト: znsoft/AiCup
        public int GetTicksToDownN(AHock ho, Point to, double takePuck = -1, int limit = 300)
        {
            var result = 0;

            for (; result < limit && (takePuck <0 ? !CanStrike(ho, to) : ho.GetDistanceTo2(to)> takePuck * takePuck); result++)
            {
                var turn    = RevAngle(ho.GetAngleTo(to));
                var speedUp = -GetSpeedTo(turn);
                ho.Move(speedUp, TurnNorm(turn, ho.AAgility));
            }
            return(result >= limit ? Inf : result);
        }
コード例 #25
0
ファイル: Attack.cs プロジェクト: znsoft/AiCup
 bool Chase(IEnumerable <AHock> opps, AHock I)
 {
     foreach (var opp in opps)
     {
         opp.MoveTo(I);
         if (CanStrike(opp, I) || CanStrike(opp, I.PuckPos()))
         {
             return(false);
         }
     }
     return(true);
 }
コード例 #26
0
ファイル: MyStrategy.cs プロジェクト: znsoft/AiCup
        public int GetTicksTo(Point to, Hockeyist my, bool tryDown = true)
        {
            var ho   = new AHock(my);
            var up   = GetTicksToUp(ho, to);
            var down = tryDown ? GetTicksToDown(ho, to) : Inf;

            if (up <= down)
            {
                return(up);
            }
            return(-down);
        }
コード例 #27
0
ファイル: Research.cs プロジェクト: znsoft/AiCup
 // определение силы паса
 bool ResearchPass(AHock hock)
 {
     if (puck.OwnerHockeyistId == hock.Base.Id && hock.CoolDown == 0)
     {
         var t = GetPassPuck(hock, 1, 0, null);
         move.Action    = ActionType.Pass;
         move.PassPower = 1;
         move.PassAngle = 0;
         return(true);
     }
     return(false);
 }
コード例 #28
0
ファイル: PuckMoving.cs プロジェクト: znsoft/AiCup
 int GetTicksToPuckDirect(AHock _hock, APuck _puck, int limit)
 {
     var hock = _hock.Clone();
     var pk = _puck.Clone();
     int result;
     for (result = 0; result < limit && !CanStrike(hock, pk); result++)
     {
         hock.MoveTo(pk);
         pk.Move(1);
     }
     return result;
 }
コード例 #29
0
ファイル: FindPath.cs プロジェクト: znsoft/AiCup
        bool StopOn(AHock _hock, Point to)
        {
            var minTime = Inf;
            var selTurn = 0.0;
            var selSpUp = 0.0;

            for (var dir = -1; dir <= 1; dir += 2)
            {
                var hock = _hock.Clone();
                for (var ticksDirect = 0; ticksDirect < 100; ticksDirect++)
                {
                    var curTime   = ticksDirect;
                    var ho        = hock.Clone();
                    var prevSpeed = ho.Speed.Length;
                    for (var _ = 0; _ < 100; _++)
                    {
                        var spUp = dir < 0 ? 1 : -1;
                        ho.Move(spUp, 0.0);
                        var curSpeed = ho.Speed.Length;
                        if (curSpeed > prevSpeed)
                        {
                            break;
                        }
                        prevSpeed = curSpeed;
                        curTime++;
                    }
                    if (curTime < minTime && prevSpeed < Game.MaxSpeedToAllowSubstitute && IsInSubstArea(ho))
                    {
                        minTime = curTime;
                        if (ticksDirect == 0)
                        {
                            selSpUp = dir < 0 ? 1 : -1;
                            selTurn = 0;
                        }
                        else if (dir > 0)
                        {
                            selTurn = _hock.GetAngleTo(to.X, to.Y);
                            selSpUp = GetSpeedTo(selTurn);
                        }
                        else
                        {
                            selTurn = RevAngle(_hock.GetAngleTo(to.X, to.Y));
                            selSpUp = -GetSpeedTo(selTurn);
                        }
                    }
                    hock.MoveTo(to, dir);
                }
            }
            move.Turn    = selTurn;
            move.SpeedUp = selSpUp;
            return(minTime < Inf);
        }
コード例 #30
0
 Point PuckMove(int ticks, APuck pk, AHock hock)
 {
     if (hock == null)
     {
         pk.Move(ticks);
         return(new Point(pk));
     }
     if (Math.Abs(hock.GetAngleTo(hock + hock.Speed)) < Deg(15) && hock.Speed.Length > 2)
     {
         hock.Move(1, 0, ticks); // TODO
     }
     return(hock.PuckPos());
 }
コード例 #31
0
        int GetTicksToPuckDirect(AHock _hock, APuck _puck, int limit)
        {
            var hock = _hock.Clone();
            var pk   = _puck.Clone();
            int result;

            for (result = 0; result < limit && !CanStrike(hock, pk); result++)
            {
                hock.MoveTo(pk);
                pk.Move(1);
            }
            return(result);
        }
コード例 #32
0
ファイル: FindPath.cs プロジェクト: znsoft/AiCup
        public bool FindPath(Hockeyist self, Point to, Point lookAt)
        {
            if (lookAt == null)
                return StopOn(new AHock(self), to);

            var okDist = HoRadius * 1.5;

            var minTime = Inf;
            var selTurn = 0.0;
            var selSpUp = 0.0;
            for (var dir = -1; dir <= 1; dir += 2)
            {
                var hock = new AHock(self);
                for (var ticksDirect = 0; ticksDirect < 100; ticksDirect++)
                {
                    var curTime = ticksDirect;
                    var ho = hock.Clone();
                    while (Math.Abs(ho.GetAngleTo(lookAt)) > Deg(8))
                    {
                        ho.Move(0, TurnNorm(ho.GetAngleTo(lookAt), ho.AAgility));
                        curTime++;
                    }
                    if (curTime < minTime && ho.GetDistanceTo(to) < okDist)
                    {
                        minTime = curTime;
                        if (ticksDirect == 0)
                        {
                            selSpUp = 0.0;
                            selTurn = TurnNorm(ho.GetAngleTo(lookAt), hock.AAgility);
                        }
                        else if (dir > 0)
                        {
                            selTurn = self.GetAngleTo(to.X, to.Y);
                            selSpUp = GetSpeedTo(selTurn);
                        }
                        else
                        {
                            selTurn = RevAngle(self.GetAngleTo(to.X, to.Y));
                            selSpUp = -GetSpeedTo(selTurn);
                        }
                    }
                    if (dir > 0)
                        GetTicksToUpN(hock, to, 0, 1);
                    else
                        GetTicksToDownN(hock, to, 0, 1);
                }
            }
            move.SpeedUp = selSpUp;
            move.Turn = selTurn;
            return minTime != Inf;
        }
コード例 #33
0
ファイル: MyStrategy.cs プロジェクト: znsoft/AiCup
        public int MoveHockTo(AHock ho, Point to)
        {
            var result = 0;

            for (; !CanStrike(ho, to); result++)
            {
                ho.MoveTo(to);

                if (result > 500)
                {
                    return(result);
                }
            }
            return(result);
        }
コード例 #34
0
ファイル: Attack.cs プロジェクト: znsoft/AiCup
        bool StrikeWithDev(AHock striker, double strikePower, Point goalie, ActionType actionType, double passAngle, double dev, Point puckPos)
        {
            var result = false;

            if (actionType == ActionType.Strike)
            {
                striker.Angle += dev;
            }
            if (Strike(striker, strikePower, goalie, actionType, passAngle + dev, puckPos))
            {
                result = true;
            }
            if (actionType == ActionType.Strike)
            {
                striker.Angle -= dev;
            }
            return(result);
        }
コード例 #35
0
ファイル: FindPath.cs プロジェクト: znsoft/AiCup
        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);
        }
コード例 #36
0
ファイル: Attack.cs プロジェクト: znsoft/AiCup
        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;
        }
コード例 #37
0
ファイル: Attack.cs プロジェクト: znsoft/AiCup
        private bool StrikePrimitiveValidate(AHock striker)
        {
            var puckPos = striker.PuckPos();
            if (Math.Abs(puckPos.X - Opp.NetFront) > RinkWidth/3*2)
                return false;

            if (Math.Abs(puckPos.X - Opp.NetFront) < 3.5*HoRadius)
                return false;

            if (MyRight() && Math.Cos(striker.Angle) > 0)
                return false;
            if (MyLeft() && Math.Cos(striker.Angle) < 0)
                return false;

            return true;
        }
コード例 #38
0
ファイル: Research.cs プロジェクト: znsoft/AiCup
 // определение силы паса
 bool ResearchPass(AHock hock)
 {
     if (puck.OwnerHockeyistId == hock.Base.Id && hock.CoolDown == 0)
     {
         var t = GetPassPuck(hock, 1, 0, null);
         move.Action = ActionType.Pass;
         move.PassPower = 1;
         move.PassAngle = 0;
         return true;
     }
     return false;
 }
コード例 #39
0
ファイル: PuckMoving.cs プロジェクト: znsoft/AiCup
        bool TryPass(AHock striker)
        {
            if (striker.Base.RemainingCooldownTicks != 0)
                return false;

            TimerStart();

            const int passAnglesCount = 7;
            double minTime = Inf,
                bestAngle = 0.0,
                bestPower = 0.0;

            foreach (var power in new[] { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.8, 1.0 })
            {
                for (var passDir = -1; passDir <= 1; passDir += 2)
                {
                    for (var absPassAngle = 0.0; absPassAngle <= Game.PassSector/2; absPassAngle += Game.PassSector/2/passAnglesCount)
                    {
                        var passAngle = absPassAngle*passDir;
                        var pk = GetPassPuck(striker, power, passAngle, Get(OppGoalie)); // TODO: проверять на автогол
                        var on = GetFirstOnPuck(new[] {striker.Base}, pk, IsFinal(), 100, false);
                        pk.Move(300);
                        if (APuck.PuckLastTicks < on.First)
                            continue;
                        var toHock = new AHock(Get(on.Second));
                        if (!toHock.Base.IsTeammate)
                            continue;
                        var time = on.First;
                        if (IsWaitingSwing(toHock))
                            time /= 5;
                        if (time < minTime)
                        {
                            minTime = time;
                            bestAngle = passAngle;
                            bestPower = power;
                        }
                    }
                }
            }

            Log("TryPass " + TimerStop());

            if (minTime >= Inf - Eps)
                return false;
            move.Action = ActionType.Pass;
            move.PassAngle = bestAngle;
            move.PassPower = bestPower;
            return true;
        }
コード例 #40
0
ファイル: Utility.cs プロジェクト: znsoft/AiCup
 public static bool CanStrike(AHock hock, Point to)
 {
     return(Math.Abs(hock.GetAngleTo(to)) <= Game.StickSector / 2 &&
            hock.GetDistanceTo2(to) <= Game.StickLength * Game.StickLength &&
            hock.KnockDown == 0 && hock.CoolDown == 0);
 }
コード例 #41
0
ファイル: MyStrategy.cs プロジェクト: znsoft/AiCup
        public void Move(Hockeyist self, World world, Game game, Move move)
        {
            if (self.State == HockeyistState.Resting)
                return;

            ShowWindow();

            // // fill globals
            _strikePoint = null;
            Hockeyists = world.Hockeyists;
            MyRest = Hockeyists.Where(x => x.IsTeammate && x.State == HockeyistState.Resting).ToArray();
            this.puck = world.Puck;
            this.move = move;
            World = world;
            Game = game;
            Opp = world.GetOpponentPlayer();
            My = world.GetMyPlayer();
            RinkWidth = game.RinkRight - game.RinkLeft;
            RinkHeight = game.RinkBottom - game.RinkTop;
            OppGoalie = Hockeyists.FirstOrDefault(x => !x.IsTeammate && x.Type == HockeyistType.Goalie);
            MyGoalie = Hockeyists.FirstOrDefault(x => x.IsTeammate && x.Type == HockeyistType.Goalie);
            HoRadius = self.Radius;
            RinkCenter = new Point(game.RinkLeft + RinkWidth/2, game.RinkTop + RinkHeight/2);
            PuckRadius = puck.Radius;
            var friends = Hockeyists
                .Where(x => x.IsTeammate && x.Id != self.Id && x.Type != HockeyistType.Goalie && x.State != HockeyistState.Resting)
                .ToArray();
            var friend1 = friends.Count() < 2 || friends[0].TeammateIndex < friends[1].TeammateIndex ? friends[0] : friends[1];
            var friend2 = friends.Count() > 1 ? friends[0].TeammateIndex < friends[1].TeammateIndex ? friends[1] : friends[0] : null;
            FillWayPoints();
            // //

            if (Game.OvertimeTickCount == 200) // костыль чтобы пройти верификацию
                return;

            TimerStart();

            var hock = new AHock(self);
            var needSubst = NeedTrySubstitute(hock);

            if (My.IsJustMissedGoal || My.IsJustScoredGoal)
            {
                SubstSignal = false;
                StayOn(self, GetSubstitutePoint(hock).First, null);
                TrySubstitute(hock);
            }
            else
            {
                var range = TurnRange(hock.AAgility);
                move.SpeedUp = Inf;
                if (self.State == HockeyistState.Swinging && self.Id != puck.OwnerHockeyistId)
                {
                    if (!TryStrikeWithoutTakeIfSwinging(hock, new APuck(puck, OppGoalie)))
                        move.Action = ActionType.CancelStrike;
                }
                else if (puck.OwnerHockeyistId == self.Id)
                {
                    var wait = Inf;
                    double selTurn = 0, selSpeedUp = 0;
                    var willSwing = false;
                    var maxProb = 0.15;
                    var selAction = ActionType.Strike;
                    TimerStart();
                    if (self.State != HockeyistState.Swinging)
                    {
                        var spUps = self.RemainingCooldownTicks == 0 || Math.Abs(self.X - My.NetFront) < RinkWidth / 2
                            ? (Math.Abs(self.X - Opp.NetFront) < RinkWidth / 3 ? new[] { 0.0, 1.0 } : new[] { 1.0 })
                            : new[] { 1.0, 0.5, 0.0, -0.5 };

                        var moveDirBase = MyRight() && self.Y > RinkCenter.Y || MyLeft() && self.Y < RinkCenter.Y ? 1 : -1;

                        // если не замахнулся
                        for (var ticks = 0; ticks < 50; ticks++)
                        {
                            // если буду замахиваться (ТО В КОНЦЕ!!!), то нужно подождать минимум game.SwingActionCooldownTicks

                            const int turns = 4;
                            for (var moveDir = -1; moveDir <= 1; moveDir += 2)
                            {
                                for (var moveTurn = 0.0; moveTurn - Eps <= range; moveTurn += range/turns)
                                {
                                    var turn = moveDir*moveTurn;
                                    foreach (var spUp in spUps)
                                    {
                                        if (moveDir == moveDirBase || spUp <= Eps && IsFinal())
                                        {
                                            var end = ticks + game.SwingActionCooldownTicks;
                                            var start = Math.Max(0, end - game.MaxEffectiveSwingTicks);
                                            // когда начинаем замахиваться
                                            var p = ProbabStrikeAfter(end - start, self, new[]
                                            {
                                                new MoveAction {Ticks = start, SpeedUp = spUp, Turn = turn},
                                                new MoveAction {Ticks = end - start, SpeedUp = 0, Turn = 0},
                                            }, ActionType.Strike);
                                            if (p > maxProb)
                                            {
                                                wait = start;
                                                willSwing = true;
                                                maxProb = p;
                                                selTurn = turn;
                                                selSpeedUp = spUp;
                                                selAction = ActionType.Strike;
                                            }

                                            // если не буду
                                            p = ProbabStrikeAfter(0, self,
                                                new[] {new MoveAction {Ticks = ticks, SpeedUp = spUp, Turn = turn}},
                                                ActionType.Strike);
                                            if (p > maxProb)
                                            {
                                                wait = ticks;
                                                willSwing = false;
                                                maxProb = p;
                                                selTurn = turn;
                                                selSpeedUp = spUp;
                                                selAction = ActionType.Strike;
                                            }

                                            // если пасом
                                            p = ProbabStrikeAfter(0, self,
                                                new[] {new MoveAction {Ticks = ticks, SpeedUp = spUp, Turn = turn}},
                                                ActionType.Pass);
                                            if (p > maxProb)
                                            {
                                                wait = ticks;
                                                willSwing = false;
                                                maxProb = p;
                                                selTurn = turn;
                                                selSpeedUp = spUp;
                                                selAction = ActionType.Pass;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        // если уже замахнулся
                        for (var ticks = Math.Max(0, game.SwingActionCooldownTicks - self.SwingTicks); ticks < 80; ticks++)
                        {
                            var p = ProbabStrikeAfter(ticks + self.SwingTicks, self,
                                new[] {new MoveAction {Ticks = ticks, SpeedUp = 0, Turn = 0}}, ActionType.Strike);
                            if (p > maxProb)
                            {
                                wait = ticks;
                                willSwing = true;
                                maxProb = p;
                                selAction = ActionType.Strike;
                            }
                        }
                    }
                    Log("STRIKE   " + TimerStop());
                    if (wait < Inf)
                    {
                        SubstSignal = true;
                    }
                    drawInfo.Enqueue((wait == Inf ? 0 : maxProb) + "");
                    if (!willSwing && self.State == HockeyistState.Swinging)
                    {
                        move.Action = ActionType.CancelStrike;
                    }
                    else if (willSwing && wait == 0 && self.State != HockeyistState.Swinging)
                    {
                        move.Action = ActionType.Swing;
                    }
                    else if (wait == Inf)
                    {
                        var wayPoint = FindWayPoint(self);
                        if (wayPoint == null)
                        {
                            needPassQueue.Enqueue(Get(self));
                            if (!TryPass(hock))
                            {
                                var pt = Math.Abs(Opp.NetFront - self.X) < RinkWidth/3
                                    ? Get(friend2 == null || (MyLeft() ? friend2.X > friend1.X : friend2.X < friend1.X) ? friend1 : friend2)
                                    : GetStrikePoint();
                                DoMove(self, pt, 1);
                            }
                        }
                        else
                        {
                            DoMove(self, wayPoint, 1);
                        }
                    }
                    else if (wait == 0)
                    {
                        move.Action = selAction;
                        if (selAction == ActionType.Pass)
                        {
                            move.PassPower = 1;
                            move.PassAngle = PassAngleNorm(hock.GetAngleTo(GetStrikePoint()));
                        }
                    }
                    else
                    {
                        move.SpeedUp = selSpeedUp;
                        move.Turn = selTurn;
                    }
                }
                else if (puck.OwnerPlayerId != -1 || !TryStrikeWithoutTake(hock, new APuck(puck, OppGoalie)))
                {
                    var owner = Hockeyists.FirstOrDefault(x => x.Id == puck.OwnerHockeyistId);
                    var pk = new APuck(puck, MyGoalie) {IsDefend = true};

                    if (puck.OwnerPlayerId == Opp.Id && (CanStrike(self, owner) || CanStrike(self, puck)))
                    { // попытаться выбить
                        move.Action = ActionType.Strike;
                    }
                    else if (puck.OwnerPlayerId != self.PlayerId && CanStrike(self, puck))
                    {
                        // проверяем что не летит в чужие ворота
                        var cpk = new APuck(puck, OppGoalie);
                        if (cpk.Move(200, true) == 0)
                        {
                            if (pk.Move(200, goalCheck: true) == 1) // если вратарь не отобьёт
                                move.Action = ActionType.Strike;
                            else
                                move.Action = ActionType.TakePuck;
                        }
                    }
                    else
                    {
                        var toPuck = GoToPuck(self, null);
                        var toPuck1 = GoToPuck(friend1, null);
                        var toPuck2 = friend2 == null ? null : GoToPuck(friend2, null);
                        if (friend2 != null && toPuck1.Third < toPuck2.Third)
                        {
                            Swap(ref friend1, ref friend2);
                            Swap(ref toPuck1, ref toPuck2);
                        }
                        var def = GetDefendPos2();
                        var have = puck.OwnerPlayerId == My.Id;
                        // 1 - дольше всего идет до шайбы
                        var net = new Point(My.NetFront, RinkCenter.Y);
                        double ii = net.GetDistanceTo(self) < 300 ? 1.0 : 1.0;
                        double jj = net.GetDistanceTo(friend1) < 300 ? 1.0 : 1.0;

                        var myFirst = GetFirstOnPuck(new[] {self},
                            new APuck(puck, OppGoalie),
                            true, 100, false).Second == (friend2 == null ? -1 : friend2.Id);

                        if (have
                            ? (friend2 == null || ii*GetTicksTo(def, self) < jj*GetTicksTo(def, friend1)) // если я ближе, то иду на ворота
                            : toPuck.Third/ii > toPuck1.Third/jj) // если я дольше всего, то иду на ворота
                        {
                            if (needSubst && (SubstSignal || puck.OwnerPlayerId != Opp.Id && self.Y <= Game.RinkTop + 0.666 * RinkHeight || self.Y <= Game.SubstitutionAreaHeight + Game.RinkTop))
                            {
                                if (TrySubstitute(hock))
                                    SubstSignal = false;
                                else
                                    StayOn(self, GetSubstitutePoint(hock).First, null);
                            }
                            else
                            {
                                StayOn(self, def, Get(puck));
                            }
                        }
                            // иначе 1 идет на воротаpuck.OwnerPlayerId != My.Id
                        else if (friend2 == null
                            || (puck.OwnerPlayerId != My.Id && (
                               toPuck.Third < toPuck2.Third
                               //|| Math.Abs(Opp.NetFront - puck.X) < RinkWidth / 2 // шайба не у нас и на чужой половине
                               || !myFirst
                            )))
                        {
                            var bestTime = Inf;
                            double bestTurn = 0.0;
                            var needTime = GetFirstOnPuck(Hockeyists.Where(x => x.IsTeammate),
                                new APuck(puck, OppGoalie), true, -1).First;
                            var lookAt = new Point(Opp.NetFront, RinkCenter.Y);
                            for (var turn = -range; turn <= range; turn += range / 10)
                            {
                                var I = hock.Clone();
                                var P = new APuck(puck, OppGoalie);
                                for (var t = 0; t < needTime - 10 && t < 70; t++)
                                {
                                    if (CanStrike(I, P))
                                    {
                                        var cl = I.Clone();
                                        var tm = GetTicksToUp(cl, lookAt) + t;
                                        if (tm < bestTime)
                                        {
                                            bestTime = tm;
                                            bestTurn = turn;
                                        }
                                    }
                                    I.Move(0, turn);
                                    P.Move(1);
                                }
                            }
                            var i = hock.Clone();
                            var direct = MoveHockTo(i, toPuck.First);
                            direct += MoveHockTo(i, lookAt);
                            if (bestTime < direct && bestTime < Inf)
                            {
                                move.Turn = bestTurn;
                                move.SpeedUp = 0.0;
                            }
                            DoMove(self, toPuck.First, toPuck.Second);
                        }
                        else
                        {
                            if (needSubst && (SubstSignal || puck.OwnerPlayerId != Opp.Id && self.Y <= RinkCenter.Y || self.Y <= Game.SubstitutionAreaHeight + Game.RinkTop))
                            {
                                if (TrySubstitute(hock))
                                    SubstSignal = false;
                                else
                                    StayOn(self, GetSubstitutePoint(hock).First, null);
                            }
                            else
                            {
                                var c1 = new Point(RinkCenter.X, Game.RinkTop + 2*HoRadius);
                                var c2 = new Point(RinkCenter.X, Game.RinkBottom - 2*HoRadius);
                                var c = c1.GetDistanceTo(puck) > c2.GetDistanceTo(puck) ? c1 : c2;
                                var s = GetStrikePoint();
                                StayOn(self, c, s);
                            }
                        }
                    }
                }
                if (Eq(move.SpeedUp, Inf))
                    move.SpeedUp = 1;
            }

            Log(self.TeammateIndex + " >>>>>>>>>>>> " + TimerStop());
            if (move.Action != ActionType.None)
                Log(move.Action);
            #if DEBUG
            draw();
            Thread.Sleep(8);
            #endif
            drawInfo.Clear();
            needPassQueue.Clear();
        }
コード例 #42
0
ファイル: FindPath.cs プロジェクト: znsoft/AiCup
        bool TrySubstitute(AHock hock)
        {
            if (!IsFinal()
                || hock.Speed.Length > Game.MaxSpeedToAllowSubstitute
                || !IsInSubstArea(hock)
                || hock.Base.RemainingCooldownTicks > 0
                || hock.Base.RemainingKnockdownTicks > 0
                )
                return false;

            var maxStamina = MyRest
                .Select(x => x.Stamina)
                .Max();
            var maxStrength = MyRest
                .Where(x => Eq(maxStamina, x.Stamina))
                .Select(x => x.Strength)
                .Max();

            var to = Hockeyists.FirstOrDefault(x => Eq(x.Stamina, maxStamina) && Eq(x.Strength, maxStrength));
            if (to == null || maxStamina < hock.Stamina)
                return false;
            move.Action = ActionType.Substitute;
            move.TeammateIndex = to.TeammateIndex;
            return true;
        }
コード例 #43
0
ファイル: Attack.cs プロジェクト: znsoft/AiCup
        public bool TryStrikeWithoutTakeIfSwinging(AHock _hock, APuck _pk)
        {
            var hock = _hock.Clone();
            var pk = _pk.Clone();
            var bestProbab = 0.0;
            var swTime = Inf;

            for (var sw = 0; sw <= Game.MaxEffectiveSwingTicks; sw++)
            {
                if (CanStrike(hock, pk))
                {
                    var pr = StrikeProbability(hock, GetPower(hock, sw + hock.Base.SwingTicks), pk.Goalie, -1, ActionType.Strike, 0, pk);
                    if (pr > bestProbab)
                    {
                        bestProbab = pr;
                        swTime = sw;
                    }
                }
                hock.Move(0, 0);
                pk.Move(1);
            }

            if (swTime == Inf)
                return false;
            if (swTime == 0)
                move.Action = ActionType.Strike;
            return true;
        }
コード例 #44
0
ファイル: MyStrategy.cs プロジェクト: znsoft/AiCup
 public int GetTicksToUp(AHock ho, Point to, double takePuck = -1, int limit = 500)
 {
     return GetTicksToUpN(ho.Clone(), to, takePuck, limit);
 }
コード例 #45
0
ファイル: Attack.cs プロジェクト: znsoft/AiCup
        public bool TryStrikeWithoutTake(AHock _hock, APuck _pk)
        {
            if (!StrikePrimitiveValidate(_hock))
            {
                return(false);
            }

            TimerStart();

            var moveDirBase = MyRight() && _hock.Y > RinkCenter.Y || MyLeft() && _hock.Y < RinkCenter.Y ? 1 : -1;

            var bestTurn   = 0.0;
            var bestSpUp   = 0.0;
            var bestProbab = 0.0;
            var bestWait   = Inf;
            var swTime     = 0;
            var range      = TurnRange(_hock.AAgility);

            const int turns = 9;
            const int spUps = 8;

            for (var moveDir = -1; moveDir <= 1; moveDir += 2)
            {
                for (var moveTurn = 0.0; moveTurn <= range + Eps; moveTurn += range / turns)
                {
                    var turn = moveDir * moveTurn;

                    for (var spUp = 0.0; spUp <= 1.0; spUp += 1.0 / spUps)
                    {
                        var hock      = _hock.Clone();
                        var pk        = _pk.Clone();
                        var ticksWait = 0;
                        for (var startDist2 = hock.GetDistanceTo2(pk); !CanStrike(hock, pk) && ticksWait < 150; ticksWait++)
                        {
                            if (moveDir == moveDirBase || IsFinal() && moveTurn < range / 2)
                            {
                                var I = hock.Clone();
                                var p = pk.Clone();
                                for (var sw = 0; sw <= Game.MaxEffectiveSwingTicks; sw++)
                                {
                                    if (sw >= Game.SwingActionCooldownTicks && CanStrike(I, p))
                                    {
                                        var pr = StrikeProbability(I, GetPower(I, sw), p.Goalie, -1, ActionType.Strike, 0, p);
                                        if (pr > bestProbab)
                                        {
                                            bestProbab = pr;
                                            bestTurn   = turn;
                                            bestSpUp   = spUp;
                                            bestWait   = ticksWait;
                                            swTime     = sw;
                                        }
                                    }
                                    I.Move(0, 0);
                                    p.Move(1);
                                }
                            }
                            hock.Move(spUp, turn);
                            pk.Move(1);
                            var dist2 = hock.GetDistanceTo2(pk);
                            if (dist2 > startDist2)
                            {
                                break;
                            }
                            startDist2 = dist2;
                        }
                        if (CanStrike(hock, pk))
                        {
                            var p = StrikeProbability(hock, GetPower(hock, 0), pk.Goalie, -1, ActionType.Strike, 0, pk);
                            if (p > bestProbab)
                            {
                                bestProbab = p;
                                bestTurn   = turn;
                                bestSpUp   = spUp;
                                bestWait   = ticksWait;
                                swTime     = 0;
                            }
                        }
                    }
                }
            }
            Log("SWING " + TimerStop());

            if (bestWait == Inf)
            {
                return(false);
            }
            move.Turn    = bestTurn;
            move.SpeedUp = bestSpUp;

            if (bestWait == 0)
            {
                move.Action = swTime == 0 ? ActionType.Strike : ActionType.Swing;
            }
            return(true);
        }
コード例 #46
0
ファイル: FindPath.cs プロジェクト: znsoft/AiCup
 bool StopOn(AHock _hock, Point to)
 {
     var minTime = Inf;
     var selTurn = 0.0;
     var selSpUp = 0.0;
     for (var dir = -1; dir <= 1; dir += 2)
     {
         var hock = _hock.Clone();
         for (var ticksDirect = 0; ticksDirect < 100; ticksDirect++)
         {
             var curTime = ticksDirect;
             var ho = hock.Clone();
             var prevSpeed = ho.Speed.Length;
             for(var _ = 0; _ < 100; _++)
             {
                 var spUp = dir < 0 ? 1 : -1;
                 ho.Move(spUp, 0.0);
                 var curSpeed = ho.Speed.Length;
                 if (curSpeed > prevSpeed)
                     break;
                 prevSpeed = curSpeed;
                 curTime++;
             }
             if (curTime < minTime && prevSpeed < Game.MaxSpeedToAllowSubstitute && IsInSubstArea(ho))
             {
                 minTime = curTime;
                 if (ticksDirect == 0)
                 {
                     selSpUp = dir < 0 ? 1 : -1;
                     selTurn = 0;
                 }
                 else if (dir > 0)
                 {
                     selTurn = _hock.GetAngleTo(to.X, to.Y);
                     selSpUp = GetSpeedTo(selTurn);
                 }
                 else
                 {
                     selTurn = RevAngle(_hock.GetAngleTo(to.X, to.Y));
                     selSpUp = -GetSpeedTo(selTurn);
                 }
             }
             hock.MoveTo(to, dir);
         }
     }
     move.Turn = selTurn;
     move.SpeedUp = selSpUp;
     return minTime < Inf;
 }
コード例 #47
0
ファイル: MyStrategy.cs プロジェクト: znsoft/AiCup
        public Tuple<Point, int, int> GoToPuck(Hockeyist my, APuck pk, int ticksLimit = 300, bool tryDown = true)
        {
            if (my.Id == puck.OwnerHockeyistId)
                return new Tuple<Point, int, int>(null, 0, 0);

            if (ticksLimit == -1)
                ticksLimit = 300;

            const int noBs = 100;

            var res = Inf;
            var dir = 1;
            var owner = Hockeyists.FirstOrDefault(x => x.Id == puck.OwnerHockeyistId);
            var ho = owner == null ? null : new AHock(owner);
            if (pk == null)
                pk = new APuck(puck, OppGoalie);
            else
                ho = null;

            var result = new Point(pk);
            int tLeft = 0, tRight = ticksLimit;
            var pks = new APuck[tRight + 1];
            var hhs = new AHock[tRight + 1];
            pks[0] = pk.Clone();
            hhs[0] = ho;
            for (var i = 1; i <= tRight; i++)
            {
                pks[i] = pks[i - 1].Clone();
                hhs[i] = ho == null ? null : hhs[i - 1].Clone();
                PuckMove(1, pks[i], hhs[i]);
            }
            while (ticksLimit > noBs && tLeft <= tRight)
            {
                var c = (tLeft + tRight)/2;
                var needTicks = GetTicksTo(PuckMove(0, pks[c], hhs[c]), my, tryDown);
                if (Math.Abs(needTicks) < c)
                {
                    tRight = c - 1;
                    res = c;
                    result = PuckMove(0, pks[c], hhs[c]);
                    dir = needTicks >= 0 ? 1 : -1;
                }
                else
                {
                    tLeft = c + 1;
                }
            }
            const int by = 10;
            for (var c = 0; c <= noBs && c <= ticksLimit; c += c < by ? 1 : by)
            {
                var needTicks = GetTicksTo(PuckMove(0, pks[c], hhs[c]), my, tryDown);
                if (Math.Abs(needTicks) <= c)
                {
                    for (var i = 0; i < by; i++, c--)
                    {
                        if (Math.Abs(needTicks) <= c)
                        {
                            res = c;
                            result = PuckMove(0, pks[c], hhs[c]);
                            dir = needTicks >= 0 ? 1 : -1;
                        }
                    }
                    break;
                }
            }
            return new Tuple<Point, int, int>(result, dir, res);
        }
コード例 #48
0
ファイル: Attack.cs プロジェクト: znsoft/AiCup
 bool StrikeWithDev(AHock striker, double strikePower, Point goalie, ActionType actionType, double passAngle, double dev, Point puckPos)
 {
     var result = false;
     if (actionType == ActionType.Strike)
         striker.Angle += dev;
     if (Strike(striker, strikePower, goalie, actionType, passAngle + dev, puckPos))
         result = true;
     if (actionType == ActionType.Strike)
         striker.Angle -= dev;
     return result;
 }
コード例 #49
0
ファイル: Attack.cs プロジェクト: znsoft/AiCup
 bool Chase(IEnumerable<AHock> opps, AHock I)
 {
     foreach (var opp in opps)
     {
         opp.MoveTo(I);
         if (CanStrike(opp, I) || CanStrike(opp, I.PuckPos()))
             return false;
     }
     return true;
 }
コード例 #50
0
ファイル: MyStrategy.cs プロジェクト: znsoft/AiCup
        public void Move(Hockeyist self, World world, Game game, Move move)
        {
            if (self.State == HockeyistState.Resting)
            {
                return;
            }

            ShowWindow();

            // // fill globals
            _strikePoint = null;
            Hockeyists   = world.Hockeyists;
            MyRest       = Hockeyists.Where(x => x.IsTeammate && x.State == HockeyistState.Resting).ToArray();
            this.puck    = world.Puck;
            this.move    = move;
            World        = world;
            Game         = game;
            Opp          = world.GetOpponentPlayer();
            My           = world.GetMyPlayer();
            RinkWidth    = game.RinkRight - game.RinkLeft;
            RinkHeight   = game.RinkBottom - game.RinkTop;
            OppGoalie    = Hockeyists.FirstOrDefault(x => !x.IsTeammate && x.Type == HockeyistType.Goalie);
            MyGoalie     = Hockeyists.FirstOrDefault(x => x.IsTeammate && x.Type == HockeyistType.Goalie);
            HoRadius     = self.Radius;
            RinkCenter   = new Point(game.RinkLeft + RinkWidth / 2, game.RinkTop + RinkHeight / 2);
            PuckRadius   = puck.Radius;
            var friends = Hockeyists
                          .Where(x => x.IsTeammate && x.Id != self.Id && x.Type != HockeyistType.Goalie && x.State != HockeyistState.Resting)
                          .ToArray();
            var friend1 = friends.Count() < 2 || friends[0].TeammateIndex < friends[1].TeammateIndex ? friends[0] : friends[1];
            var friend2 = friends.Count() > 1 ? friends[0].TeammateIndex < friends[1].TeammateIndex ? friends[1] : friends[0] : null;

            FillWayPoints();
            // //

            if (Game.OvertimeTickCount == 200) // костыль чтобы пройти верификацию
            {
                return;
            }

            TimerStart();

            var hock      = new AHock(self);
            var needSubst = NeedTrySubstitute(hock);

            if (My.IsJustMissedGoal || My.IsJustScoredGoal)
            {
                SubstSignal = false;
                StayOn(self, GetSubstitutePoint(hock).First, null);
                TrySubstitute(hock);
            }
            else
            {
                var range = TurnRange(hock.AAgility);
                move.SpeedUp = Inf;
                if (self.State == HockeyistState.Swinging && self.Id != puck.OwnerHockeyistId)
                {
                    if (!TryStrikeWithoutTakeIfSwinging(hock, new APuck(puck, OppGoalie)))
                    {
                        move.Action = ActionType.CancelStrike;
                    }
                }
                else if (puck.OwnerHockeyistId == self.Id)
                {
                    var    wait = Inf;
                    double selTurn = 0, selSpeedUp = 0;
                    var    willSwing = false;
                    var    maxProb   = 0.15;
                    var    selAction = ActionType.Strike;
                    TimerStart();
                    if (self.State != HockeyistState.Swinging)
                    {
                        var spUps = self.RemainingCooldownTicks == 0 || Math.Abs(self.X - My.NetFront) < RinkWidth / 2
                            ? (Math.Abs(self.X - Opp.NetFront) < RinkWidth / 3 ? new[] { 0.0, 1.0 } : new[] { 1.0 })
                            : new[] { 1.0, 0.5, 0.0, -0.5 };

                        var moveDirBase = MyRight() && self.Y > RinkCenter.Y || MyLeft() && self.Y < RinkCenter.Y ? 1 : -1;

                        // если не замахнулся
                        for (var ticks = 0; ticks < 50; ticks++)
                        {
                            // если буду замахиваться (ТО В КОНЦЕ!!!), то нужно подождать минимум game.SwingActionCooldownTicks

                            const int turns = 4;
                            for (var moveDir = -1; moveDir <= 1; moveDir += 2)
                            {
                                for (var moveTurn = 0.0; moveTurn - Eps <= range; moveTurn += range / turns)
                                {
                                    var turn = moveDir * moveTurn;
                                    foreach (var spUp in spUps)
                                    {
                                        if (moveDir == moveDirBase || spUp <= Eps && IsFinal())
                                        {
                                            var end   = ticks + game.SwingActionCooldownTicks;
                                            var start = Math.Max(0, end - game.MaxEffectiveSwingTicks);
                                            // когда начинаем замахиваться
                                            var p = ProbabStrikeAfter(end - start, self, new[]
                                            {
                                                new MoveAction {
                                                    Ticks = start, SpeedUp = spUp, Turn = turn
                                                },
                                                new MoveAction {
                                                    Ticks = end - start, SpeedUp = 0, Turn = 0
                                                },
                                            }, ActionType.Strike);
                                            if (p > maxProb)
                                            {
                                                wait       = start;
                                                willSwing  = true;
                                                maxProb    = p;
                                                selTurn    = turn;
                                                selSpeedUp = spUp;
                                                selAction  = ActionType.Strike;
                                            }

                                            // если не буду
                                            p = ProbabStrikeAfter(0, self,
                                                                  new[] { new MoveAction {
                                                                              Ticks = ticks, SpeedUp = spUp, Turn = turn
                                                                          } },
                                                                  ActionType.Strike);
                                            if (p > maxProb)
                                            {
                                                wait       = ticks;
                                                willSwing  = false;
                                                maxProb    = p;
                                                selTurn    = turn;
                                                selSpeedUp = spUp;
                                                selAction  = ActionType.Strike;
                                            }

                                            // если пасом
                                            p = ProbabStrikeAfter(0, self,
                                                                  new[] { new MoveAction {
                                                                              Ticks = ticks, SpeedUp = spUp, Turn = turn
                                                                          } },
                                                                  ActionType.Pass);
                                            if (p > maxProb)
                                            {
                                                wait       = ticks;
                                                willSwing  = false;
                                                maxProb    = p;
                                                selTurn    = turn;
                                                selSpeedUp = spUp;
                                                selAction  = ActionType.Pass;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        // если уже замахнулся
                        for (var ticks = Math.Max(0, game.SwingActionCooldownTicks - self.SwingTicks); ticks < 80; ticks++)
                        {
                            var p = ProbabStrikeAfter(ticks + self.SwingTicks, self,
                                                      new[] { new MoveAction {
                                                                  Ticks = ticks, SpeedUp = 0, Turn = 0
                                                              } }, ActionType.Strike);
                            if (p > maxProb)
                            {
                                wait      = ticks;
                                willSwing = true;
                                maxProb   = p;
                                selAction = ActionType.Strike;
                            }
                        }
                    }
                    Log("STRIKE   " + TimerStop());
                    if (wait < Inf)
                    {
                        SubstSignal = true;
                    }
                    drawInfo.Enqueue((wait == Inf ? 0 : maxProb) + "");
                    if (!willSwing && self.State == HockeyistState.Swinging)
                    {
                        move.Action = ActionType.CancelStrike;
                    }
                    else if (willSwing && wait == 0 && self.State != HockeyistState.Swinging)
                    {
                        move.Action = ActionType.Swing;
                    }
                    else if (wait == Inf)
                    {
                        var wayPoint = FindWayPoint(self);
                        if (wayPoint == null)
                        {
                            needPassQueue.Enqueue(Get(self));
                            if (!TryPass(hock))
                            {
                                var pt = Math.Abs(Opp.NetFront - self.X) < RinkWidth / 3
                                    ? Get(friend2 == null || (MyLeft() ? friend2.X > friend1.X : friend2.X < friend1.X) ? friend1 : friend2)
                                    : GetStrikePoint();
                                DoMove(self, pt, 1);
                            }
                        }
                        else
                        {
                            DoMove(self, wayPoint, 1);
                        }
                    }
                    else if (wait == 0)
                    {
                        move.Action = selAction;
                        if (selAction == ActionType.Pass)
                        {
                            move.PassPower = 1;
                            move.PassAngle = PassAngleNorm(hock.GetAngleTo(GetStrikePoint()));
                        }
                    }
                    else
                    {
                        move.SpeedUp = selSpeedUp;
                        move.Turn    = selTurn;
                    }
                }
                else if (puck.OwnerPlayerId != -1 || !TryStrikeWithoutTake(hock, new APuck(puck, OppGoalie)))
                {
                    var owner = Hockeyists.FirstOrDefault(x => x.Id == puck.OwnerHockeyistId);
                    var pk    = new APuck(puck, MyGoalie)
                    {
                        IsDefend = true
                    };

                    if (puck.OwnerPlayerId == Opp.Id && (CanStrike(self, owner) || CanStrike(self, puck)))
                    { // попытаться выбить
                        move.Action = ActionType.Strike;
                    }
                    else if (puck.OwnerPlayerId != self.PlayerId && CanStrike(self, puck))
                    {
                        // проверяем что не летит в чужие ворота
                        var cpk = new APuck(puck, OppGoalie);
                        if (cpk.Move(200, true) == 0)
                        {
                            if (pk.Move(200, goalCheck: true) == 1) // если вратарь не отобьёт
                            {
                                move.Action = ActionType.Strike;
                            }
                            else
                            {
                                move.Action = ActionType.TakePuck;
                            }
                        }
                    }
                    else
                    {
                        var toPuck  = GoToPuck(self, null);
                        var toPuck1 = GoToPuck(friend1, null);
                        var toPuck2 = friend2 == null ? null : GoToPuck(friend2, null);
                        if (friend2 != null && toPuck1.Third < toPuck2.Third)
                        {
                            Swap(ref friend1, ref friend2);
                            Swap(ref toPuck1, ref toPuck2);
                        }
                        var def  = GetDefendPos2();
                        var have = puck.OwnerPlayerId == My.Id;
                        // 1 - дольше всего идет до шайбы
                        var    net = new Point(My.NetFront, RinkCenter.Y);
                        double ii  = net.GetDistanceTo(self) < 300 ? 1.0 : 1.0;
                        double jj  = net.GetDistanceTo(friend1) < 300 ? 1.0 : 1.0;

                        var myFirst = GetFirstOnPuck(new[] { self },
                                                     new APuck(puck, OppGoalie),
                                                     true, 100, false).Second == (friend2 == null ? -1 : friend2.Id);

                        if (have
                            ? (friend2 == null || ii * GetTicksTo(def, self) < jj * GetTicksTo(def, friend1)) // если я ближе, то иду на ворота
                            : toPuck.Third / ii > toPuck1.Third / jj)                                         // если я дольше всего, то иду на ворота
                        {
                            if (needSubst && (SubstSignal || puck.OwnerPlayerId != Opp.Id && self.Y <= Game.RinkTop + 0.666 * RinkHeight || self.Y <= Game.SubstitutionAreaHeight + Game.RinkTop))
                            {
                                if (TrySubstitute(hock))
                                {
                                    SubstSignal = false;
                                }
                                else
                                {
                                    StayOn(self, GetSubstitutePoint(hock).First, null);
                                }
                            }
                            else
                            {
                                StayOn(self, def, Get(puck));
                            }
                        }
                        // иначе 1 идет на воротаpuck.OwnerPlayerId != My.Id
                        else if (friend2 == null ||
                                 (puck.OwnerPlayerId != My.Id && (
                                      toPuck.Third < toPuck2.Third
                                      //|| Math.Abs(Opp.NetFront - puck.X) < RinkWidth / 2 // шайба не у нас и на чужой половине
                                      || !myFirst
                                      )))
                        {
                            var    bestTime = Inf;
                            double bestTurn = 0.0;
                            var    needTime = GetFirstOnPuck(Hockeyists.Where(x => x.IsTeammate),
                                                             new APuck(puck, OppGoalie), true, -1).First;
                            var lookAt = new Point(Opp.NetFront, RinkCenter.Y);
                            for (var turn = -range; turn <= range; turn += range / 10)
                            {
                                var I = hock.Clone();
                                var P = new APuck(puck, OppGoalie);
                                for (var t = 0; t < needTime - 10 && t < 70; t++)
                                {
                                    if (CanStrike(I, P))
                                    {
                                        var cl = I.Clone();
                                        var tm = GetTicksToUp(cl, lookAt) + t;
                                        if (tm < bestTime)
                                        {
                                            bestTime = tm;
                                            bestTurn = turn;
                                        }
                                    }
                                    I.Move(0, turn);
                                    P.Move(1);
                                }
                            }
                            var i      = hock.Clone();
                            var direct = MoveHockTo(i, toPuck.First);
                            direct += MoveHockTo(i, lookAt);
                            if (bestTime < direct && bestTime < Inf)
                            {
                                move.Turn    = bestTurn;
                                move.SpeedUp = 0.0;
                            }
                            DoMove(self, toPuck.First, toPuck.Second);
                        }
                        else
                        {
                            if (needSubst && (SubstSignal || puck.OwnerPlayerId != Opp.Id && self.Y <= RinkCenter.Y || self.Y <= Game.SubstitutionAreaHeight + Game.RinkTop))
                            {
                                if (TrySubstitute(hock))
                                {
                                    SubstSignal = false;
                                }
                                else
                                {
                                    StayOn(self, GetSubstitutePoint(hock).First, null);
                                }
                            }
                            else
                            {
                                var c1 = new Point(RinkCenter.X, Game.RinkTop + 2 * HoRadius);
                                var c2 = new Point(RinkCenter.X, Game.RinkBottom - 2 * HoRadius);
                                var c  = c1.GetDistanceTo(puck) > c2.GetDistanceTo(puck) ? c1 : c2;
                                var s  = GetStrikePoint();
                                StayOn(self, c, s);
                            }
                        }
                    }
                }
                if (Eq(move.SpeedUp, Inf))
                {
                    move.SpeedUp = 1;
                }
            }

            Log(self.TeammateIndex + " >>>>>>>>>>>> " + TimerStop());
            if (move.Action != ActionType.None)
            {
                Log(move.Action);
            }
#if DEBUG
            draw();
            Thread.Sleep(8);
#endif
            drawInfo.Clear();
            needPassQueue.Clear();
        }
コード例 #51
0
ファイル: Attack.cs プロジェクト: znsoft/AiCup
 APuck GetStrikePuck(AHock striker, double strikePower, Point goalie, Point puckPos)
 {
     var strikerDirection = new Point(striker.Angle);
     var speedAngleStriker = striker.Speed.GetAngle();
     var puckSpeed = 20.0 * strikePower + striker.Speed.Length * Math.Cos(striker.Angle - speedAngleStriker);
     var puckSpeedDirection = strikerDirection * puckSpeed;
     return new APuck(puckPos ?? striker.PuckPos(), puckSpeedDirection, goalie);
 }
コード例 #52
0
ファイル: MyStrategy.cs プロジェクト: znsoft/AiCup
 public int GetTicksToDown(AHock ho, Point to, double takePuck = -1, int limit = 300)
 {
     return(GetTicksToDownN(ho.Clone(), to, takePuck, limit));
 }
コード例 #53
0
ファイル: Attack.cs プロジェクト: znsoft/AiCup
        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);
        }
コード例 #54
0
ファイル: FindPath.cs プロジェクト: znsoft/AiCup
 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;
 }
コード例 #55
0
ファイル: MyStrategy.cs プロジェクト: znsoft/AiCup
        public int MoveHockTo(AHock ho, Point to)
        {
            var result = 0;
            for(; !CanStrike(ho, to); result++)
            {
                ho.MoveTo(to);

                if (result > 500)
                    return result;
            }
            return result;
        }
コード例 #56
0
ファイル: MyStrategy.cs プロジェクト: znsoft/AiCup
        public Tuple <Point, int, int> GoToPuck(Hockeyist my, APuck pk, int ticksLimit = 300, bool tryDown = true)
        {
            if (my.Id == puck.OwnerHockeyistId)
            {
                return(new Tuple <Point, int, int>(null, 0, 0));
            }

            if (ticksLimit == -1)
            {
                ticksLimit = 300;
            }

            const int noBs = 100;

            var res   = Inf;
            var dir   = 1;
            var owner = Hockeyists.FirstOrDefault(x => x.Id == puck.OwnerHockeyistId);
            var ho    = owner == null ? null : new AHock(owner);

            if (pk == null)
            {
                pk = new APuck(puck, OppGoalie);
            }
            else
            {
                ho = null;
            }

            var result = new Point(pk);
            int tLeft = 0, tRight = ticksLimit;
            var pks = new APuck[tRight + 1];
            var hhs = new AHock[tRight + 1];

            pks[0] = pk.Clone();
            hhs[0] = ho;
            for (var i = 1; i <= tRight; i++)
            {
                pks[i] = pks[i - 1].Clone();
                hhs[i] = ho == null ? null : hhs[i - 1].Clone();
                PuckMove(1, pks[i], hhs[i]);
            }
            while (ticksLimit > noBs && tLeft <= tRight)
            {
                var c         = (tLeft + tRight) / 2;
                var needTicks = GetTicksTo(PuckMove(0, pks[c], hhs[c]), my, tryDown);
                if (Math.Abs(needTicks) < c)
                {
                    tRight = c - 1;
                    res    = c;
                    result = PuckMove(0, pks[c], hhs[c]);
                    dir    = needTicks >= 0 ? 1 : -1;
                }
                else
                {
                    tLeft = c + 1;
                }
            }
            const int by = 10;

            for (var c = 0; c <= noBs && c <= ticksLimit; c += c < by ? 1 : by)
            {
                var needTicks = GetTicksTo(PuckMove(0, pks[c], hhs[c]), my, tryDown);
                if (Math.Abs(needTicks) <= c)
                {
                    for (var i = 0; i < by; i++, c--)
                    {
                        if (Math.Abs(needTicks) <= c)
                        {
                            res    = c;
                            result = PuckMove(0, pks[c], hhs[c]);
                            dir    = needTicks >= 0 ? 1 : -1;
                        }
                    }
                    break;
                }
            }
            return(new Tuple <Point, int, int>(result, dir, res));
        }
コード例 #57
0
ファイル: Attack.cs プロジェクト: znsoft/AiCup
 bool Strike(AHock striker, double strikePower, Point goalie, ActionType actionType, double passAngle, Point puckPos)
 {
     var pk = actionType == ActionType.Strike
         ? GetStrikePuck(striker, strikePower, goalie, puckPos)
         : GetPassPuck(striker, 1, passAngle, goalie);
     return PuckPrimitiveValidate(pk) && pk.Move(300, true) == 1;
 }
コード例 #58
0
ファイル: Attack.cs プロジェクト: znsoft/AiCup
        public bool TryStrikeWithoutTake(AHock _hock, APuck _pk)
        {
            if (!StrikePrimitiveValidate(_hock))
                return false;

            TimerStart();

            var moveDirBase = MyRight() && _hock.Y > RinkCenter.Y || MyLeft() && _hock.Y < RinkCenter.Y ? 1 : -1;

            var bestTurn = 0.0;
            var bestSpUp = 0.0;
            var bestProbab = 0.0;
            var bestWait = Inf;
            var swTime = 0;
            var range = TurnRange(_hock.AAgility);

            const int turns = 9;
            const int spUps = 8;

            for (var moveDir = -1; moveDir <= 1; moveDir += 2)
            {
                for (var moveTurn = 0.0; moveTurn <= range + Eps; moveTurn += range/turns)
                {
                    var turn = moveDir*moveTurn;

                    for (var spUp = 0.0; spUp <= 1.0; spUp += 1.0/spUps)
                    {
                        var hock = _hock.Clone();
                        var pk = _pk.Clone();
                        var ticksWait = 0;
                        for (var startDist2 = hock.GetDistanceTo2(pk); !CanStrike(hock, pk) && ticksWait < 150; ticksWait++)
                        {
                            if (moveDir == moveDirBase || IsFinal() && moveTurn < range / 2)
                            {
                                var I = hock.Clone();
                                var p = pk.Clone();
                                for (var sw = 0; sw <= Game.MaxEffectiveSwingTicks; sw++)
                                {
                                    if (sw >= Game.SwingActionCooldownTicks && CanStrike(I, p))
                                    {
                                        var pr = StrikeProbability(I, GetPower(I, sw), p.Goalie, -1, ActionType.Strike, 0, p);
                                        if (pr > bestProbab)
                                        {
                                            bestProbab = pr;
                                            bestTurn = turn;
                                            bestSpUp = spUp;
                                            bestWait = ticksWait;
                                            swTime = sw;
                                        }
                                    }
                                    I.Move(0, 0);
                                    p.Move(1);
                                }
                            }
                            hock.Move(spUp, turn);
                            pk.Move(1);
                            var dist2 = hock.GetDistanceTo2(pk);
                            if (dist2 > startDist2)
                                break;
                            startDist2 = dist2;
                        }
                        if (CanStrike(hock, pk))
                        {
                            var p = StrikeProbability(hock, GetPower(hock, 0), pk.Goalie, -1, ActionType.Strike, 0, pk);
                            if (p > bestProbab)
                            {
                                bestProbab = p;
                                bestTurn = turn;
                                bestSpUp = spUp;
                                bestWait = ticksWait;
                                swTime = 0;
                            }
                        }
                    }
                }
            }
            Log("SWING " + TimerStop());

            if (bestWait == Inf)
                return false;
            move.Turn = bestTurn;
            move.SpeedUp = bestSpUp;

            if (bestWait == 0)
                move.Action = swTime == 0 ? ActionType.Strike : ActionType.Swing;
            return true;
        }
コード例 #59
0
ファイル: Research.cs プロジェクト: znsoft/AiCup
 // Проверка движение хоккеиста
 void Research3(Hockeyist self)
 {
     var range = TurnRange(new AHock(self).AAgility);
     move.Turn = range / 2;
     move.SpeedUp = 0.8;
     var pl = new AHock(self);
     pl.Move(0.8, range / 2, 20);
 }