예제 #1
0
        public void AirWallRecovery(GameState gamestate, BotCalculations botCalculations)
        {
            if (gamestate.myCar.player.Physics.Rotation.Roll > .5)
            {
                botCalculations.controller.Steer = 1;
                botCalculations.controller.Roll  = -1;
            }
            else if (gamestate.myCar.player.Physics.Rotation.Roll < -.5)
            {
                botCalculations.controller.Steer = -1;
                botCalculations.controller.Roll  = 1;
            }
            if (!gamestate.myCar.player.HasWheelContact)
            {
                if (gamestate.myCar.player.Physics.Rotation.Pitch > .5)
                {
                    botCalculations.controller.Pitch = -1;
                }
                else if (gamestate.myCar.player.Physics.Rotation.Pitch < -.5)
                {
                    botCalculations.controller.Pitch = 1;
                }

                float angle = Utils.AngleBetween(Vector3.Zero, gamestate.myCar.player.Physics.Rotation, gamestate.myCar.player.Physics.Velocity);
                angle = Utils.Clamp(angle, -1, 1);
                botCalculations.controller.Yaw = angle;
            }
        }
예제 #2
0
        public void ContactBall(GameState gamestate, BotCalculations botCalculations)
        {
            // Simple Jump.
            // Find where the ball is relative to us.
            Vector3 ballLocation         = gamestate.ballPhysics.Location;
            Vector3 ballRelativeLocation = Orientation.RelativeLocation(gamestate.myCar.player.Physics.Location, ballLocation, gamestate.myCar.player.Physics.Rotation);

            if (Math.Abs(ballRelativeLocation.X) < 400 &&
                Math.Abs(ballRelativeLocation.Y) < 150 &&
                ballLocation.Z > 100 && ballLocation.Z < 300)
            {
                botCalculations.controller.Jump = true;
            }
        }
예제 #3
0
        public Tactic ChooseTactic(GameState gameState, BotCalculations botCalculations)
        {
            Vector3 meToBallDirection    = Vector3.Normalize(gameState.ballPhysics.Location - gameState.myCar.player.Physics.Location);
            Vector3 meToOwnGoalDirection = Vector3.Normalize(gameState.fieldState.ownGoalLocation - gameState.myCar.player.Physics.Location);

            if (Vector3.Dot(meToBallDirection, meToOwnGoalDirection) > .95f)
            {
                return(new Defend());
            }
            else if (botCalculations.predictedBallLocation.Z > 300)
            {
                return(new Patience());
            }
            else
            {
                return(new Attack());
            }
        }
예제 #4
0
        public override void DoWork(GameState gameState, BotCalculations botCalculations)
        {
            // Drive towards safest post.
            Vector3 directionToBall     = Vector3.Normalize(gameState.ballPhysics.Location - gameState.myCar.player.Physics.Location);
            float   YDistanceFromGoal   = gameState.fieldState.ownGoalLocation.Y - gameState.myCar.player.Physics.Location.Y;
            float   distanceFactor      = YDistanceFromGoal / directionToBall.Y;
            Vector3 OwnWallIntersection = directionToBall * distanceFactor;
            Vector3 safePosition        = gameState.fieldState.ownGoalLocation;

            if (OwnWallIntersection.X > 0)
            {
                safePosition.X -= Utils.GoalPostOffset;
            }
            else
            {
                safePosition.X += Utils.GoalPostOffset;
            }

            float angleToSafePosition = Utils.AngleBetween(gameState.myCar.player.Physics.Location, gameState.myCar.player.Physics.Rotation, safePosition);

            botCalculations.primaryTarget = safePosition;
            botCalculations.primaryAngle  = angleToSafePosition;

            if (Math.Abs(angleToSafePosition) < 0.2f)
            {
                // TODO: don't boost when unnecessary. Both for worthless hits, and lack of urgency?
                botCalculations.controller.Boost = true;
            }

            // Turn to safe position.
            botCalculations.controller.Throttle = 1;
            botCalculations.controller.Steer    = Utils.Clamp(angleToSafePosition * 6.0f, -1, 1);

            // Fixups.
            AirWallRecovery(gameState, botCalculations);

            // Jump.
            ContactBall(gameState, botCalculations);
        }
예제 #5
0
        public override void DoWork(GameState gameState, BotCalculations botCalculations)
        {
            Vector3 safePosition        = Utils.ProjectLocationTowardsTarget(gameState.fieldState.ownGoalLocation, gameState.fieldState.oppGoalLocation, 150);
            float   angleToSafePosition = Utils.AngleBetween(gameState.myCar.player.Physics.Location, gameState.myCar.player.Physics.Rotation, safePosition);

            botCalculations.primaryTarget = safePosition;
            botCalculations.primaryAngle  = angleToSafePosition;

            if (Math.Abs(angleToSafePosition) > Math.PI * 0.5f)
            {
                // Reverse to safe position.
                botCalculations.controller.Throttle = -1;
                float reverseAngle;
                if (angleToSafePosition > 0)
                {
                    reverseAngle = (float)Math.PI - angleToSafePosition;
                }
                else
                {
                    reverseAngle = -(float)Math.PI + angleToSafePosition;
                }
                botCalculations.controller.Steer = Utils.Clamp(reverseAngle, -1, 1);
            }
            else
            {
                // Turn to safe position.
                botCalculations.controller.Throttle = 0.2f;
                botCalculations.controller.Steer    = Utils.Clamp(angleToSafePosition, -1, 1);
            }

            // Fixups.
            AirWallRecovery(gameState, botCalculations);

            // Jump.
            ContactBall(gameState, botCalculations);
        }
예제 #6
0
        public override Controller GetOutput(rlbot.flat.GameTickPacket gameTickPacket)
        {
            // Convert the current frame data into our own structures and helpers.
            GameState gameState = InitializeGameState(gameTickPacket);

            if (gameState == null)
            {
                return(new Controller());
            }

            BotCalculations botCalculations = new BotCalculations
            {
                controller = new Controller()
            };

            botCalculations.predictedBallLocation = gameState.GetPredictionLocation();

            botCalculations.primaryMechanic = currentMechanic;

            // Decide on a tactic and run it.
            if (currentMechanic == null)
            {
                currentTactic = ChooseTactic(gameState, botCalculations);
            }
            currentTactic.DoWork(gameState, botCalculations);

            currentMechanic = botCalculations.primaryMechanic;

            // Examples of rendering in the game
            Renderer.DrawString3D("Ball", Colors.Black, botCalculations.predictedBallLocation, 3, 3);
            if (botCalculations.controller.Steer != 0)
            {
                Renderer.DrawString3D(botCalculations.controller.Steer > 0 ? "Right" : "Left", Colors.Aqua, gameState.myCar.player.Physics.Location, 3, 3);
            }
            if (botCalculations.controller.Jump)
            {
                Renderer.DrawString3D("Jump", Colors.Green, gameState.myCar.player.Physics.Location, 3, 3);
            }

            Color tacticColor = Colors.Red;

            switch (currentTactic.tacticType)
            {
            case TacticType.Attack:
                tacticColor = Colors.Magenta;
                break;

            case TacticType.Defend:
                tacticColor = Colors.Purple;
                break;

            case TacticType.Patience:
                tacticColor = Colors.DarkGreen;
                break;
            }

            Renderer.DrawLine3D(tacticColor, gameState.myCar.player.Physics.Location, botCalculations.primaryTarget);
            Renderer.DrawCenteredRectangle3D(tacticColor, botCalculations.primaryTarget, 50, 50, false);
            Renderer.DrawCenteredRectangle3D(Colors.LimeGreen, botCalculations.predictedBallLocation, 20, 20, false);
            Renderer.DrawString2D(currentTactic.tacticType.ToString(), Colors.WhiteSmoke, new Vector2(), 5, 5);

            return(botCalculations.controller);
        }
예제 #7
0
        public override void DoWork(GameState gameState, BotCalculations botCalculations)
        {
            // Get the data required to drive to the ball.
            Vector3     ballActualLocation = gameState.ballPhysics.Location;
            Vector3     carLocation        = gameState.myCar.player.Physics.Location;
            Orientation carRotation        = gameState.myCar.player.Physics.Rotation;

            Vector3 ballLocation = gameState.GetPredictionLocation();

            botCalculations.predictedBallLocation = ballLocation;

            // Target the side of the ball to shoot at their goal.
            Vector3 ballEdgeLocation = Utils.ProjectLocationTowardsTarget(ballLocation, gameState.fieldState.oppGoalLocation, -Utils.BallRadius * 1.25f);
            float   distanceToBall   = Utils.DistanceBetween(carLocation, ballEdgeLocation);

            // How far away from the ball should we be aiming?
            float   glidepathAimAmount  = Math.Min(.25f * distanceToBall * distanceToBall / 1000.0f, 800);
            float   distanceToBallToAim = Utils.BallRadius + glidepathAimAmount;
            Vector3 targetLocation      = Utils.ProjectLocationTowardsTarget(ballLocation, gameState.fieldState.oppGoalLocation, -distanceToBallToAim);

            targetLocation = Utils.ClampToField(targetLocation);
            botCalculations.primaryTarget = targetLocation;

            // Check the angle to the ball and steer that way.
            float angleToBallTarget = Utils.AngleBetween(carLocation, carRotation, targetLocation);

            botCalculations.primaryAngle = angleToBallTarget;

            // Specify steer strength as less when ball is far. (unnecessary?)
            const float minTurnEasingDistance = 300;
            const float maxTurnEasingDistance = 1000;
            float       distanceFactor        = Utils.Clamp(distanceToBall, minTurnEasingDistance, maxTurnEasingDistance);
            float       steerStrength         = Utils.Lerp(6.0f, 10, (maxTurnEasingDistance - distanceFactor) / (maxTurnEasingDistance - minTurnEasingDistance));

            // Steer stronger when moving fast.
            if (gameState.myCar.player.Physics.Velocity.Length() > 1000)
            {
                steerStrength *= 2;
            }

            botCalculations.controller.Steer = Utils.Clamp(angleToBallTarget * steerStrength, -1, 1);

            if (Math.Abs(angleToBallTarget) < 0.2f)
            {
                // TODO: don't boost when unnecessary. Both for worthless hits, and lack of urgency?
                botCalculations.controller.Boost = true;
            }
            botCalculations.controller.Throttle = 1;


            if (Math.Abs(angleToBallTarget) > 1.6f)
            {
                botCalculations.controller.Handbrake = true;
            }

            // TODO: Pass the direction to the ball instead of using steer.
            bool shouldDodge = distanceToBall < 400 && ballLocation.Z < 200; // && Math.Abs(angleToBallTarget) < 0.5f;

            if (shouldDodge || botCalculations.primaryMechanic != null)      // fixup
            {
                if (botCalculations.primaryMechanic == null)
                {
                    botCalculations.primaryMechanic = new ForwardDodge();
                }
                bool hasWork = botCalculations.primaryMechanic.Update(gameState, botCalculations.primaryAngle, ref botCalculations.controller);
                if (!hasWork)
                {
                    botCalculations.primaryMechanic = null;
                }
            }
            else
            {
                // Fixups.
                AirWallRecovery(gameState, botCalculations);

                // Jump.
                ContactBall(gameState, botCalculations);
            }
        }
예제 #8
0
 public abstract void DoWork(GameState gameState, BotCalculations botCalculations);