public override Controller GetOutput(rlbot.flat.GameTickPacket gameTickPacket) { gameInfo.Update(gameTickPacket, GetRigidBodyTick()); ballPrediction.Update(GetBallPrediction()); if (timeout > 5) { GameState gamestate = new GameState(); gamestate.BallState.PhysicsState.Location = new DesiredVector3(RandomFloat(-3000, 3000), 2000, 100); gamestate.BallState.PhysicsState.AngularVelocity = new DesiredVector3(0, 0, 0); gamestate.BallState.PhysicsState.Velocity = new DesiredVector3(RandomFloat(2000, 2000), RandomFloat(1000, 2000), RandomFloat(1500, 1600)); CarState carstate = new CarState(); carstate.PhysicsState.AngularVelocity = new DesiredVector3(0, 0, 0); carstate.PhysicsState.Velocity = new DesiredVector3(0, 0, 0); carstate.PhysicsState.Location = new DesiredVector3(0, 0, 17); carstate.PhysicsState.Rotation = new DesiredRotator(0, (float)(Math.PI / 2), 0); gamestate.SetCarState(index, carstate); SetGameState(gamestate); timeout = 0; aerial = null; } timeout += gameInfo.DeltaTime; Controller controller = new Controller(); Car car = gameInfo.Cars[index]; Ball ball = gameInfo.Ball; Slice[] slices = ballPrediction.ToArray(); if (timeout > 0.3) { if (aerial == null) { aerial = Aerial.FindAerialOpportunity(car, slices, gameInfo.Time, settings); } else { controller = aerial.Step(ball, 0.016667f, gameInfo.Time); Renderer.DrawLine3D(Colors.Red, car.Position, aerial.Target); if (aerial.Finished) { aerial = null; } else { aerial.UpdateAerialTarget(slices, gameInfo.Time); } } } return(controller); }
public override Controller GetOutput(rlbot.flat.GameTickPacket gameTickPacket) { gameInfo.Update(gameTickPacket, GetRigidBodyTick()); ballPrediction.Update(GetBallPrediction()); Controller controller = new Controller(); if (timeout > 6) { double angle = random.NextDouble() * Math.PI * 2; GameState gamestate = new GameState(); gamestate.BallState.PhysicsState.Location = new DesiredVector3(700 * (float)Math.Cos(angle), 700 * (float)Math.Sin(angle), 100); gamestate.BallState.PhysicsState.AngularVelocity = new DesiredVector3(0, 0, 0); gamestate.BallState.PhysicsState.Velocity = new DesiredVector3(300 * (float)Math.Cos(angle), 300 * (float)Math.Sin(angle), 1500); CarState carstate = new CarState(); carstate.PhysicsState.AngularVelocity = new DesiredVector3(0, 0, 0); carstate.PhysicsState.Velocity = new DesiredVector3(0, 0, 0); carstate.PhysicsState.Location = new DesiredVector3(0, 0, 17); carstate.PhysicsState.Rotation = new DesiredRotator(0, (float)(Math.PI / 2), 0); gamestate.SetCarState(index, carstate); SetGameState(gamestate); timeout = 0; flipReset = null; recovery = null; recoveryState = false; } Car car = gameInfo.Cars[index]; Slice[] slices = ballPrediction.ToArray(); if (timeout > 0.3) { if (flipReset == null) { for (int i = 0; i < slices.Length; i++) { if (slices[i].Velocity.Z < 100) { Vector3 A = FlipReset.CalculateCourse(car, slices[i].Position, slices[i].Time - gameInfo.Time); if (A.Length() < 800 && A.Length() > 700) { flipReset = new FlipReset(car, slices[i].Position, gameInfo.Time, slices[i].Time); } } } } if (flipReset != null && !recoveryState) { controller = flipReset.Step(gameInfo.Ball, 1f / 60f, gameInfo.Time); Car c = new Car(car); Vector3 lastpoint = c.Position; for (int i = 0; i < ((flipReset.ArrivalTime - gameInfo.Time) / (5f / 60f)); i++) { c.Simulate(new Controller(), 5f / 60f); Renderer.DrawLine3D(Colors.White, c.Position, lastpoint); lastpoint = c.Position; } if (flipReset.Finished) { controller.Roll = 0; controller.Pitch = -1; controller.Yaw = 0; controller.Jump = true; recoveryState = true; recovery = new Recovery(car); } } else if (recovery != null) { controller = recovery.Step(1f / 60f); } } timeout += gameInfo.DeltaTime; return(controller); }
public override Controller GetOutput(GameTickPacket gameTickPacket) { // This controller object will be returned at the end of the method. // This controller will contain all the inputs that we want the bot to perform. Controller controller = new Controller(); // Wrap gameTickPacket retrieving in a try-catch so that the bot doesn't crash whenever a value isn't present. // A value may not be present if it was not sent. // These are nullables so trying to get them when they're null will cause errors, therefore we wrap in try-catch. try { if (gameInfo == null) { gameInfo = new KipjeBot.GameInfo(index, team, name); SetTeammates(); } if (fieldInfo == null) { fieldInfo = new KipjeBot.GameTickPacket.FieldInfo(GetFieldInfo()); } if (ballPrediction == null) { ballPrediction = new BallPredictionCollection(); } gameInfo.Update(gameTickPacket, GetRigidBodyTick()); ballPrediction.Update(GetBallPrediction()); Car car = gameInfo.Cars[index]; Ball ball = gameInfo.Ball; PlayerInfo playerInfo = gameTickPacket.Players(this.index).Value; if (playerInfo.Name == "BrokenJoey") { controller.Throttle = 1; controller.Steer = -0.3f; controller.Boost = true; return(controller); } target = Target.Undecided; // Store the required data from the gameTickPacket. BallInfo ballInfo = gameTickPacket.Ball.Value; Vector3 ballLocation = ballInfo.Physics.Value.Location.Value; Vector3 carLocation = playerInfo.Physics.Value.Location.Value; Rotator carRotation = playerInfo.Physics.Value.Rotation.Value; Vector3 ballVelocity = ballInfo.Physics.Value.Velocity.Value; Vector3 carVelocityStruct = playerInfo.Physics.Value.Velocity.Value; System.Numerics.Vector3 carVelocity = new System.Numerics.Vector3(carVelocityStruct.X, carVelocityStruct.Y, carVelocityStruct.Z); var velocityValue = Math.Sqrt(carVelocity.LengthSquared()); int ownGoalY = team == 0 ? -5000 : 5000; int oppGoalY = team == 0 ? 5000 : -5000; // Calculate to get the angle from the front of the bot's car to the target. //If car is in front of ball aim for goal, else aim for ball var ballTrajectoryX = ballLocation.X; var ballTrajectoryY = ballLocation.Y; var ballTrajectoryZ = ballLocation.Z; double botToTargetAngle = 0; double botToBallAngle; double botToOppGoalAngle; var DistanceToBall = Get2DDistance(carLocation.X, ballLocation.X, carLocation.Y, ballLocation.Y); botToBallAngle = Math.Atan2(ballLocation.Y - carLocation.Y, ballLocation.X - carLocation.X); double botFrontToBallAngle = botToBallAngle - carRotation.Yaw; botFrontToBallAngle = CorrectAngle(botFrontToBallAngle); float goalY = Math.Abs(GetFieldInfo().Goals(0).Value.Location.Value.Y); if (GetFieldInfo().GoalsLength > 2) { mode = GameMode.Dropshot; } else if (goalY == 5120) { mode = GameMode.Soccar; } else { mode = GameMode.Hoops; } botToOppGoalAngle = Math.Atan2(oppGoalY - carLocation.Y, 0 - carLocation.X); double botFrontToOppGoalAngle = botToOppGoalAngle - carRotation.Yaw; botFrontToOppGoalAngle = CorrectAngle(botFrontToOppGoalAngle); int fieldLength = GetFieldLength(mode); controller.Jump = false; controller.Handbrake = false; //work out state code if (teammates == null) { SetTeammates(); } if (prevTarget == Target.Waiting && gameInfo.IsKickOffPause) { target = Target.Waiting; } else if (gameInfo.IsKickOffPause && gameInfo.IsRoundActive) { target = Target.Kickoff; } //goalkeeper mode else if (teammates.Count() >= MinTeammatesForGK && ((ownGoalY < 0 && carLocation.Y < (from x in teammates select x.Position.Y).Min()) || (ownGoalY > 0 && carLocation.Y > (from x in teammates select x.Position.Y).Max()))) { //if (target != Target.AwayFromGoal) //{ //team 0 = blue team, defending negative, attacking positive if (team == 0) { if (ballLocation.Y < GoalieBallTargetY * -1) { target = Target.Ball; botToTargetAngle = Math.Atan2(ballLocation.Y - carLocation.Y, ballLocation.X - carLocation.X); } else if (ballLocation.Y > 1000) { if (Math.Abs(ballLocation.X) < 800) { target = Target.Ball; botToTargetAngle = Math.Atan2(ballLocation.Y - carLocation.Y, ballLocation.X - carLocation.X); } else if (carLocation.Y < -1000 || Math.Abs(botFrontToBallAngle) > DegreesToRadians(30)) { target = Target.SpecificPoint; TargetPointX = 0; TargetPointY = 0; } else { target = Target.Waiting; } } else if (carLocation.Y < GoalieWaitY * -1 && Math.Abs(carLocation.X) < 700 && Math.Abs(botFrontToBallAngle) < DegreesToRadians(45)) { target = Target.Waiting; } else { target = Target.Goal; botToTargetAngle = Math.Atan2(goalY * -1 - carLocation.Y, 0 - carLocation.X); } } else //team 1 = orange team, defending positive, attacking negative { if (ballLocation.Y > GoalieBallTargetY) { target = Target.Ball; botToTargetAngle = Math.Atan2(ballLocation.Y - carLocation.Y, ballLocation.X - carLocation.X); } else if (ballLocation.Y < -1000) { if (Math.Abs(ballLocation.X) < 800) { target = Target.Ball; botToTargetAngle = Math.Atan2(ballLocation.Y - carLocation.Y, ballLocation.X - carLocation.X); } else if (carLocation.Y > 1000 || Math.Abs(botFrontToBallAngle) > DegreesToRadians(30)) { target = Target.SpecificPoint; TargetPointX = 0; TargetPointY = 0; } else { target = Target.Waiting; } } else if (carLocation.Y > GoalieWaitY && Math.Abs(carLocation.X) < 700 && Math.Abs(botFrontToBallAngle) < DegreesToRadians(45)) { target = Target.Waiting; } else { target = Target.Goal; botToTargetAngle = Math.Atan2(goalY - carLocation.Y, 0 - carLocation.X); } } //} } //car is in goal else if (GetFieldInfo().GoalsLength == 2 && ((Math.Abs(carLocation.Y) > Math.Abs(goalY) - ownGoalTurnDistance && (prevTarget == Target.Goal || prevTarget == Target.AwayFromGoal)) || carLocation.Y > Math.Abs(goalY))) { botToTargetAngle = Math.Atan2(-carLocation.Y, 0); if (Math.Abs(ballLocation.X) < 1000) { target = Target.Ball; } else { target = Target.AwayFromGoal; } } else if (ballLocation.X == 0 && ballLocation.Y == 0) { target = Target.Ball; botToTargetAngle = Math.Atan2(0 - carLocation.Y, 0 - carLocation.X); } //defending when blue else if (GetFieldInfo().GoalsLength == 2 && team == 0 && (carLocation.Y > ballLocation.Y || (prevTarget == Target.Goal && carLocation.Y > ballLocation.Y - 1000)) && ballVelocity.Y < 0) { botToTargetAngle = Math.Atan2(goalY * -1 - carLocation.Y, 0 - carLocation.X); controller.Boost = true; target = Target.Goal; } //defending when orange else if (GetFieldInfo().GoalsLength == 2 && team == 1 && (carLocation.Y < ballLocation.Y || (prevTarget == Target.Goal && carLocation.Y < ballLocation.Y + 1000)) && ballVelocity.Y > 0) { botToTargetAngle = Math.Atan2(goalY - carLocation.Y, 0 - carLocation.X); controller.Boost = true; target = Target.Goal; } else { var goForBall = true; if (teammates.Count >= MinTeammatesForWait) { var distanceToBall = car.DistanceToBall(ball); var teammateDistance = (from x in teammates select x.DistanceToBall(ball)).Min(); if (teammateDistance < distanceToBall && teammateDistance < 2000) { goForBall = false; } if (Math.Abs(ballLocation.X) < 1000 && teammateDistance > 500 && teammateDistance < 1500) { goForBall = true; } } if (goForBall) { botToTargetAngle = botToBallAngle; var trajectoryAngle = Math.Atan2(ballVelocity.Y - carVelocity.Y, ballVelocity.X - carVelocity.X); if (playerInfo.Boost > 10 && ballLocation.Z > 700 && Math.Abs(botFrontToBallAngle) < Math.Abs(DegreesToRadians(20)) && (Math.Abs(trajectoryAngle) < DegreesToRadians(maxAerialTrajectoryAngleDegrees) || Math.Abs(trajectoryAngle) > 180 - maxAerialTrajectoryAngleDegrees)) { target = Target.BallInAir; } else { if (ballLocation.Z > ballLandingPointHeight) { target = Target.BallLandingPoint; } else { target = Target.Ball; } } botToTargetAngle = botToBallAngle; } else { if (Math.Abs(carLocation.X) < 800 && Math.Abs(botFrontToOppGoalAngle) < DegreesToRadians(30)) { //if ball behind, reposition other side of ball target = Target.Waiting; //blue if (team == 0) { if (carLocation.Y > ballLocation.Y) { target = Target.SpecificPoint; TargetPointX = carLocation.X; TargetPointY = ballLocation.Y - 1000; } } //orange else { if (carLocation.Y < ballLocation.Y) { target = Target.SpecificPoint; TargetPointX = carLocation.X; TargetPointY = ballLocation.Y + 1000; } } } else { TargetPointX = 0; TargetPointY = team == 0 ? 2000 : -2000; if (team == 0 && ballLocation.Y < 2000) { TargetPointY = ballLocation.Y - 1000; } if (team == 1 && ballLocation.Y > -2000) { TargetPointY = ballLocation.Y + 1000; } target = Target.SpecificPoint; } } } double botFrontToTargetAngle = botToTargetAngle - carRotation.Yaw; // Correct the angle botFrontToTargetAngle = CorrectAngle(botFrontToTargetAngle); if (DistanceToBall <= 300 && botFrontToTargetAngle < MinimumSteeringAngleRadians / 2 && ballLocation.Z < 200 && ballLocation.X != 0 && ballLocation.Y != 0) { target = Target.GuidingBall; } if (target == Target.Ball) { Slice[] slices = ballPrediction.ToArray(); float targetTime = 0; double ballVelocityUnit = Math.Sqrt(ballVelocity.X * ballVelocity.X + ballVelocity.Y * ballVelocity.Y); if (ballVelocityUnit < 200 || DistanceToBall < 600) { targetTime = 0.1f; } else if (ballVelocityUnit < 400) { targetTime = 0.6f; } else if (ballVelocityUnit < 600) { targetTime = 1.25f; } else { targetTime = 2; } Slice?targetSlice = slices.Where(x => x.Time - gameInfo.Time >= targetTime).FirstOrDefault(); if (targetSlice != null) { target = Target.SpecificPoint; TargetPointX = targetSlice.Value.Position.X; TargetPointY = targetSlice.Value.Position.Y; } } switch (target) { case Target.BallInAir: Slice[] slices = ballPrediction.ToArray(); if (aerial == null) { for (int i = 0; i < slices.Length; i++) { float B_avg = Aerial.CalculateCourse(car, slices[i].Position, slices[i].Time - gameInfo.Time).Length(); if (B_avg < 970) { aerial = new Aerial(car, slices[i].Position, gameInfo.Time, slices[i].Time); break; } } controller.Jump = true; } else { controller = aerial.Step(ball, 0.0083335f, gameInfo.Time); controller.Boost = true; if (aerial.Finished) { aerial = null; } else { for (int i = 0; i < slices.Length; i++) { if (Math.Abs(slices[i].Time - aerial.ArrivalTime) < 0.02) { if ((aerial.Target - slices[i].Position).Length() > 40) { aerial = null; } break; } } } } break; case Target.BallLandingPoint: if (ballVelocity.X == 0 && ballVelocity.Y == 0) { controller.Throttle = 1; controller.Boost = true; } else { //speed calculation based on height of ball var slice = ballPrediction.GetNextGroundTouch(); if (slice != null) { var target = slice.Value; var distance = Math.Abs(Get2DDistance(target.Position.X, carLocation.X, target.Position.Y, carLocation.Y)) + 100; var time = target.Time - gameTickPacket.GameInfo.Value.SecondsElapsed; var ticks = time * 120; var currentDistance = ticks * velocityValue; if (currentDistance < distance) { controller.Throttle = 1; controller.Boost = true; } else { controller.Throttle = 0.1f; controller.Boost = false; } } controller = SetSteeringBasedOnTarget(controller, botFrontToTargetAngle); } break; case Target.GuidingBall: var complete = false; ballTrajectoryX = ballLocation.X; ballTrajectoryY = ballLocation.Y; while (!complete) { if (ballTrajectoryY > GetFieldLength(mode)) { if (oppGoalY == 5000 && mode == GameMode.Soccar) { if (ballLocation.X < 700 && ballLocation.X > -700) { complete = true; } else { if (ballLocation.X < -700) { controller.Steer = -largeSteering; } else { controller.Steer = largeSteering; } complete = true; } } else { controller.Steer = 1; complete = true; } } else if (ballTrajectoryY < GetFieldLength(mode) * -1) { if (oppGoalY == -5000 && mode == GameMode.Soccar) { if (ballLocation.X < 700 && ballLocation.X > -700) { complete = true; } else { if (ballLocation.X < -700) { controller.Steer = -largeSteering; } else { controller.Steer = largeSteering; } complete = true; } } else { controller.Steer = 1; complete = true; } } else if (ballTrajectoryX < -700 && ballLocation.X > -700 && mode == GameMode.Soccar) { controller.Steer = -smallSteering; complete = true; } else if (ballTrajectoryX > 700 && ballLocation.X < 700 && mode == GameMode.Soccar) { controller.Steer = smallSteering; complete = true; } if (botFrontToBallAngle > DegreesToRadians(180)) { controller.Steer *= -1; } if (ballVelocity.X == 0 && ballVelocity.Y == 0) { complete = true; } if (!complete) { ballTrajectoryX += ballVelocity.X; ballTrajectoryY += ballVelocity.Y; } } controller.Throttle = 1; break; case Target.Kickoff: if (teammates == null) { SetTeammates(); } if (teammates.Count() == 0) { controller = GoForKickoff(gameTickPacket, controller); SetJump(ref controller, ref ballLocation, ref carLocation, DistanceToBall, botFrontToBallAngle); } else { var furthestTeammate = (from x in teammates select x.DistanceToCentre()).Max(); if (gameInfo.MyCar.DistanceToCentre() <= furthestTeammate) { controller = GoForKickoff(gameTickPacket, controller); SetJump(ref controller, ref ballLocation, ref carLocation, DistanceToBall, botFrontToBallAngle); } else { target = Target.Waiting; controller.Throttle = 0; controller.Handbrake = true; controller.Steer = 0; } } break; case Target.SpecificPoint: botToTargetAngle = Math.Atan2(TargetPointY - carLocation.Y, TargetPointX - carLocation.X); botFrontToTargetAngle = botToTargetAngle - carRotation.Yaw; // Correct the angle botFrontToTargetAngle = CorrectAngle(botFrontToTargetAngle); SetHandbrakeAndBoost(ref controller, ref carLocation, carVelocity, botFrontToTargetAngle); SetJump(ref controller, ref ballLocation, ref carLocation, DistanceToBall, botFrontToBallAngle); SetThrottle(ref controller, ref ballLocation, ref carLocation, ballVelocity, DistanceToBall, botFrontToTargetAngle); controller = SetSteeringBasedOnTarget(controller, botFrontToTargetAngle); break; case Target.Waiting: controller.Throttle = 0; break; default: SetHandbrakeAndBoost(ref controller, ref carLocation, carVelocity, botFrontToTargetAngle); SetJump(ref controller, ref ballLocation, ref carLocation, DistanceToBall, botFrontToBallAngle); SetThrottle(ref controller, ref ballLocation, ref carLocation, ballVelocity, DistanceToBall, botFrontToTargetAngle); controller = SetSteeringBasedOnTarget(controller, botFrontToTargetAngle); if (target == Target.AwayFromGoal && Math.Abs(botFrontToTargetAngle) > DegreesToRadians(90)) { controller.Handbrake = true; } if (target == Target.AwayFromGoal) { controller.Boost = false; } break; } switch (target) { case Target.Ball: Renderer.DrawLine3D(System.Windows.Media.Color.FromRgb(255, 0, 0), new System.Numerics.Vector3(carLocation.X, carLocation.Y, carLocation.Z), new System.Numerics.Vector3(ballLocation.X, ballLocation.Y, ballLocation.Z)); break; case Target.BallInAir: Renderer.DrawLine3D(System.Windows.Media.Color.FromRgb(255, 255, 0), new System.Numerics.Vector3(carLocation.X, carLocation.Y, carLocation.Z), new System.Numerics.Vector3(ballLocation.X, ballLocation.Y, ballLocation.Z)); break; case Target.BallLandingPoint: Renderer.DrawLine3D(System.Windows.Media.Color.FromRgb(0, 255, 0), new System.Numerics.Vector3(carLocation.X, carLocation.Y, carLocation.Z), new System.Numerics.Vector3(ballTrajectoryX, ballTrajectoryY, ballTrajectoryZ)); break; case Target.Goal: Renderer.DrawLine3D(System.Windows.Media.Color.FromRgb(0, 0, 255), new System.Numerics.Vector3(carLocation.X, carLocation.Y, carLocation.Z), new System.Numerics.Vector3(0, ownGoalY, 10)); break; case Target.AwayFromGoal: Renderer.DrawLine3D(System.Windows.Media.Color.FromRgb(0, 0, 0), new System.Numerics.Vector3(carLocation.X, carLocation.Y, carLocation.Z), new System.Numerics.Vector3(ballLocation.X, ballLocation.Y, ballLocation.Z)); break; case Target.Undecided: Renderer.DrawLine3D(System.Windows.Media.Color.FromRgb(255, 255, 255), new System.Numerics.Vector3(carLocation.X, carLocation.Y, carLocation.Z), new System.Numerics.Vector3(ballLocation.X, ballLocation.Y, ballLocation.Z)); break; } prevTarget = target; LastPositionX = carLocation.X; LastPositionY = carLocation.Y; LastBallPositionX = ballLocation.X; LastBallPositionY = ballLocation.Y; LastBallPositionZ = ballLocation.Z; if (DateTime.Now > lastChat.AddSeconds(10) && random.NextDouble() < 0.00033) { int chatNo = (int)(random.NextDouble() * 63); try { SendQuickChatFromAgent(false, (QuickChatSelection)chatNo); } catch { Console.WriteLine("QuickChat Exception: " + chatNo); } lastChat = DateTime.Now; } } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); } return(controller); }