private void _carMoveFunc(ACar model, int from, int to, int step, AMove m, PassedInfo passed, CarCallback callback) { model = model.Clone(); passed = passed.Clone(); m.Times = 0; for (var t = 0; t < from; t++) { if (!_modelMove(model, m, passed)) { return; } m.Times++; } for (var t = from; t <= to; t += step) { _movesStack.Add(m); callback(model, passed); _movesStack.Pop(); for (var r = 0; r < step; r++) { if (!_modelMove(model, m, passed)) { return; } m.Times++; } } }
public double ComputeImportance(ACar model) { model = model.Clone(); var total = new PassedInfo(); foreach (var move in this) { for (var t = 0; t < move.Times; t++) { _modelMove(model, move, total); } } #if DEBUG if (ComputeTime() != total.Time) { throw new Exception("ComputeTime() != elapsedTime"); } #endif return(total.Time - total.Importance + Penalty); }
private void _validateLastSuccessStack() { if (_lastSuccessStack == null) { return; } var car = new ACar(Self); var stack = _lastSuccessStack.Clone(); var info = new PassedInfo(); while (stack.Count > 0) { if (!AMove.ModelMove(car, stack[0], info, new ABonus[] {}, new AOilSlick[] {}, new AProjectile[][] {}, new ACar[][] {})) { _lastSuccessStack = null; return; } stack[0].Times--; stack.Normalize(); } }
public bool _modelMove(ACar car, AMove m, PassedInfo total) { return(AMove.ModelMove(car, m, total, _bonusCandidates, _slickCandidates, _projCandidates, _carCandidates)); }
private void _doRecursive(ACar model, int patternIndex, PassedInfo total) { model = model.Clone(); total = total.Clone(); if (patternIndex == _patterns.Length) { var m = LastStageMove.Clone(); m.WheelTurn = _turnTo.Clone(); if (m.IsUseNitro && (model.Speed.Length > 22 || m.EnginePower < 0)) { return; } var penalty = 0.0; for (var i = 0; ; i++) { if (i == 200 && m.EnginePower >= 0 || i == 250 && m.EnginePower < 0) { return; } var dst = _turnTo.GetDistanceTo2(model); if (dst < _needDist * _needDist) { break; } if (!_modelMove(model, m, total)) { if (_useDist2 && m.EnginePower <= 1 && !LastStageMove.IsUseNitro) { if (dst < _needDist2 * _needDist2) { penalty = MagicConst.SecondDistDangerCoeff; total.Importance -= penalty; m.Times++; break; } } return; } m.Times++; } if (!total.WayPoint) { return; } if (!MyStrategy.CheckVisibility(Self.Original, model, penalty > 0 ? _turnTo2 : _turnTo, 20)) { return; } if (model.EnginePower < 0) { penalty += MagicConst.BackMoveDangerCoeff; total.Importance -= MagicConst.BackMoveDangerCoeff; } if (total.Time - total.Importance < _bestTime - _bestImportance) { _bestTime = total.Time; _bestImportance = total.Importance; _bestMovesStack = _movesStack.Clone(); _bestMovesStack.Add(m); _bestMovesStack.Penalty = penalty; } return; } var pattern = _patterns[patternIndex]; _carMoveFunc(model, pattern.From, pattern.To, pattern.Step, pattern.Move.Clone(), total, (aCar, passed) => { // ReSharper disable once ConvertToLambdaExpression _doRecursive(aCar.Clone(), patternIndex + 1, passed.Clone()); }); }
private void _validateLastSuccessStack() { if (_lastSuccessStack == null) return; var car = new ACar(Self); var stack = _lastSuccessStack.Clone(); var info = new PassedInfo(); while (stack.Count > 0) { if (!AMove.ModelMove(car, stack[0], info, new ABonus[] {}, new AOilSlick[] {}, new AProjectile[][] {}, new ACar[][] {})) { _lastSuccessStack = null; return; } stack[0].Times--; stack.Normalize(); } }
private void _doRecursive(ACar model, int patternIndex, PassedInfo total) { model = model.Clone(); total = total.Clone(); if (patternIndex == _patterns.Length) { var m = LastStageMove.Clone(); m.WheelTurn = _turnTo.Clone(); if (m.IsUseNitro && (model.Speed.Length > 22 || m.EnginePower < 0)) return; var penalty = 0.0; for (var i = 0; ; i++) { if (i == 200 && m.EnginePower >= 0 || i == 250 && m.EnginePower < 0) return; var dst = _turnTo.GetDistanceTo2(model); if (dst < _needDist*_needDist) break; if (!_modelMove(model, m, total)) { if (_useDist2 && m.EnginePower <= 1 && !LastStageMove.IsUseNitro) { if (dst < _needDist2 * _needDist2) { penalty = MagicConst.SecondDistDangerCoeff; total.Importance -= penalty; m.Times++; break; } } return; } m.Times++; } if (!total.WayPoint) return; if (!MyStrategy.CheckVisibility(Self.Original, model, penalty > 0 ? _turnTo2 : _turnTo, 20)) return; if (model.EnginePower < 0) { penalty += MagicConst.BackMoveDangerCoeff; total.Importance -= MagicConst.BackMoveDangerCoeff; } if (total.Time - total.Importance < _bestTime - _bestImportance) { _bestTime = total.Time; _bestImportance = total.Importance; _bestMovesStack = _movesStack.Clone(); _bestMovesStack.Add(m); _bestMovesStack.Penalty = penalty; } return; } var pattern = _patterns[patternIndex]; _carMoveFunc(model, pattern.From, pattern.To, pattern.Step, pattern.Move.Clone(), total, (aCar, passed) => { // ReSharper disable once ConvertToLambdaExpression _doRecursive(aCar.Clone(), patternIndex + 1, passed.Clone()); }); }
private void _carMoveFunc(ACar model, int from, int to, int step, AMove m, PassedInfo passed, CarCallback callback) { model = model.Clone(); passed = passed.Clone(); m.Times = 0; for (var t = 0; t < from; t++) { if (!_modelMove(model, m, passed)) return; m.Times++; } for (var t = from; t <= to; t += step) { _movesStack.Add(m); callback(model, passed); _movesStack.Pop(); for (var r = 0; r < step; r++) { if (!_modelMove(model, m, passed)) return; m.Times++; } } }
public bool _modelMove(ACar car, AMove m, PassedInfo total) { return AMove.ModelMove(car, m, total, _bonusCandidates, _slickCandidates, _projCandidates, _carCandidates); }
public static bool ModelMove(ACar car, AMove m, PassedInfo total, ABonus[] bonusCandidates, AOilSlick[] slickCandidates, AProjectile[][] projCandidates, ACar[][] carCandidates) { double prevStateX = 0, prevStateY = 0, prevStateAngle = 0; if (m.RangesMode) { prevStateX = car.X; prevStateY = car.Y; prevStateAngle = car.Angle; } var turn = m.WheelTurn is Point?MyStrategy.TurnRound(car.GetAngleTo(m.WheelTurn as Point)) : Convert.ToDouble(m.WheelTurn); var isBreak = m.IsBrake; // если сдаю назад но кочусь вперед if (m.EnginePower < 0 && car.EnginePower > 0) { isBreak = true; } // если еду вперед но кочусь назад else if (car.EnginePower < 0 && m.EnginePower > 0) { turn *= -1; isBreak = true; } var simpleMode = total.Time > 41; var checking = !simpleMode || (MyStrategy.world.Tick + total.Time) % 4 == 0; car.Move(m.EnginePower, turn, isBreak, m.IsUseNitro, simpleMode); if (checking) { for (var i = 0; i < bonusCandidates.Length; i++) { if (total.Bonuses[i]) // бонус уже взят { continue; } var bonus = bonusCandidates[i]; if (car.TakeBonus(bonus)) { total.Importance += bonus.GetImportance(car.Original) * MagicConst.BonusImportanceCoeff; total.Bonuses[i] = true; } } if (!total.Slicks) // если не въехал ни в одну лужу { foreach (var slick in slickCandidates) { if (total.Slicks) { break; } slick.RemainingLifetime -= total.Time; if (slick.Intersect(car, 9)) { total.Importance -= slick.GetDanger() * MagicConst.OilSlickDangerCoeff * (car.RemainingNitroTicks > 0 ? 2 : 1); total.Slicks = true; } slick.RemainingLifetime += total.Time; } } if (projCandidates.Length > 0 && total.Time < projCandidates[0].Length) { for (var i = 0; i < projCandidates.Length; i++) { if (total.Projectiles[i]) { continue; } var proj = projCandidates[i][total.Time]; if (proj.Intersect(car, 5)) { total.Importance -= proj.GetDanger() * MagicConst.TireDangerCoeff; total.Projectiles[i] = true; } } } if (!total.Cars) { for (var i = 0; i < carCandidates.Length; i++) { if (total.Time >= carCandidates[i].Length) { continue; } var opp = carCandidates[i][total.Time]; if (car.IntersectWith(opp, opp.Original.IsTeammate ? 20 : 0)) { if ((car.Speed.Length > 8 || car.Original.IsTeammate) && MyStrategy.world.Tick > 400) { // чтобы не боялся протаранить на маленькой скорости total.Importance -= car.RemainingNitroTicks > 0 ? MagicConst.InactiveCarNitroDangerCoeff : MagicConst.InactiveCarDangerCoeff; } total.Cars = true; break; } } } } total.Time++; var res = true; if (checking) { // проверка на стены res = car.GetRectEx().All(p => !MyStrategy.IntersectTail(p, m.SafeMargin)); // проверка что можно проехать точно возле стены if (!res && car.RemainingNitroTicks == 0 && m.ExactlyMargin < m.SafeMargin && car.GetRectEx().All(p => !MyStrategy.IntersectTail(p, m.ExactlyMargin))) { if (!total.ExactlyBorder) { total.Importance -= MagicConst.ExactlyBorderDangerCoeff; } total.ExactlyBorder = true; res = true; } // проверка что можно проскользнуть по стене if (!m.RangesMode && !res && car.RemainingNitroTicks == 0 && m.ExtraMargin < m.ExactlyMargin && car.GetRectEx().All(p => !MyStrategy.IntersectTail(p, total.Time < 20 ? -2 : m.ExtraMargin))) { if (!total.OutOfBoreder) { total.Importance -= MagicConst.OutOfBorederDangerCoeff; total.OutOfBoreder = true; } res = true; } if (!total.WayPoint) { total.WayPoint = MyStrategy.GetNextWayPoint(car.Original).Equals(MyStrategy.GetCell(car)); } if (!res && m.RangesMode) { res = true; // HACK car.X = prevStateX; car.Y = prevStateY; car.Angle = prevStateAngle; car.Speed = Point.Zero; car.AngularSpeed = 0; } } return(res); }
private bool _modelMove(ACar car, AMove m, PassedInfo total) { return(AMove.ModelMove(car, m, total, MyStrategy.Bonuses, MyStrategy.OilSlicks, MyStrategy.Tires, MyStrategy.Others)); }