// Finner farten og tiden det tar for kullen å gå avstanden // Finner hvor tanken vil være i samme tidsrom // Finner vinkelen du må skyte for å treffe tanksen // returnerer en vector for å kunne tegne boksen. public Vector2D AimInFront(double Firepower) { double bulletSpeed = (20 - Firepower * 3); long time = (long)(eData.Distance / bulletSpeed); Vector2D FuturePos = new Vector2D( eData.Position.X + Math.Sin(Utils.ToRadians(eData.Heading)) * eData.Velocity * time, eData.Position.Y + Math.Cos(Utils.ToRadians(eData.Heading)) * eData.Velocity * time); double enemyHeadingChange = eData.Heading - oldEnemyHeading; oldEnemyHeading = eData.Heading; if (Math.Abs(eData.TurnRate) > 0) { FuturePos = new Vector2D( eData.Position.X + Math.Sin(Utils.ToRadians(eData.Heading + enemyHeadingChange)) * eData.Velocity * time, eData.Position.Y + Math.Cos(Utils.ToRadians(eData.Heading + enemyHeadingChange)) * eData.Velocity * time); } double enemyPosHeading = Utils.ToDegrees(Math.Atan2(FuturePos.X - robo.Position.X, FuturePos.Y - robo.Position.Y)); double deltaAngle = enemyPosHeading - robo.GunHeading; robo.SetTurnGunRight(Utils.NormalRelativeAngleDegrees(deltaAngle)); return FuturePos; }
/// <summary> /// Method to find Vector2D from Robot to Target, according to the battlefield coordinate system. /// </summary> public static Vector2D CalculateTargetVector(double robotHeadingRadians, double bearingToTargetRadians, double distance) { double battlefieldRelativeTargetAngleRadians = Utils.NormalRelativeAngle(robotHeadingRadians + bearingToTargetRadians); Vector2D targetVector = new Vector2D(Math.Sin(battlefieldRelativeTargetAngleRadians) * distance, Math.Cos(battlefieldRelativeTargetAngleRadians) * distance); return targetVector; }
/// <summary> /// Creates a new Vector2D with the normalized values of the input vector. /// </summary> /// <returns>A new Vector2D, being a normalized version of the original vector.</returns> public static Vector2D Normalize(Vector2D v) { Vector2D vec = new Vector2D(v.X, v.Y); if (!vec.IsZero()) { double vector_length = vec.Length(); vec.X /= vector_length; vec.Y /= vector_length; } return vec; }
/// <summary> /// Returns the distance between this vector and the one passed as a parameter. /// </summary> public double Distance(Vector2D v2) { return Math.Sqrt(DistanceSq(v2)); }
/// <summary> /// Returns positive if v2 is clockwise of this vector, negative if anticlockwise. /// (Assuming the Y axis is pointing down, X axis to right, like a Window app.) /// </summary> public int Sign(Vector2D v2) { if ((Y * v2.X) > (X * v2.Y)) { // Anticlockwise. return -1; } else { // Clockwise. return 1; } }
/// <summary> /// Given a normalized vector this method reflects the vector it is operating upon. /// (Like the path of a ball bouncing off a wall.) /// </summary> public void Reflect(Vector2D norm) { Vector2D modifier = 2.0 * Dot(norm) * norm.GetReverse(); X += modifier.X; Y += modifier.Y; }
public bool Equals(Vector2D v) { // If parameter is null return false: if ((object)v == null) { return false; } // Return true if the fields match: return (X == v.X) && (Y == v.Y); }
public double Dot(Vector2D v2) { return ((X * v2.X) + (Y * v2.Y)); }
/// <summary> /// Returns the SQUARED distance between this vector and the one passed as a parameter. /// </summary> public double DistanceSq(Vector2D v2) { double ySeparation = v2.Y - Y; double xSeparation = v2.X - X; return ((ySeparation * ySeparation) + (xSeparation * xSeparation)); }
public RoboData() { position = new Vector2D(); velocity = new Vector2D(); clear(); }
// P U B L I C M E T H O D S // --------------------------- public EnemyData() { Bullets = new List<BulletData>(); Offset = new Vector2D(); Position = new Point2D(); }
/// <summary> /// Sets all EnemyData, EXCEPT bullets: Bullets are set when they're fired, the rest is set when enemy is scanned. /// </summary> public void SetEnemyData(long newTime, ScannedRobotEvent newEnemyData, Vector2D newOffset, Point2D newPosition) { // First we set the stuff that depends on last updates' values: TurnRate = Utils.NormalRelativeAngleDegrees(newEnemyData.Heading - Heading) / (newTime - Time); Acceleration = (newEnemyData.Velocity - Velocity) / (newTime - Time); // General data: Time = newTime; // Compared-to-us data: Bearing = newEnemyData.Bearing; Distance = newEnemyData.Distance; Offset = newOffset; // Enemy specific data: Name = newEnemyData.Name; Energy = newEnemyData.Energy; Position = newPosition; Velocity = newEnemyData.Velocity; Heading = newEnemyData.Heading; }
public override void Run() { IsAdjustGunForRobotTurn = true; IsAdjustRadarForRobotTurn = true; IsAdjustRadarForGunTurn = true; SetColors(Color.Black, Color.Gray, Color.Black); sB = new SteeringBehavior(ref eData, this); shootVector = new Vector2D(); driveVector = new Vector2D(); SetTurnRadarLeft(360); // used first in paint, so fast init it sB.WallAvoidance(); while (true) { getDriveState(); if (currentDriveState == DriveState.RAM) { Console.WriteLine("DriveState.RAM"); driveVector = sB.Pursuit(); } else if (currentDriveState == DriveState.ESCAPE) { //FLEE Console.WriteLine("DriveState.ESCAPE"); sB.OffsetPursuit(); } else if (currentDriveState == DriveState.AVOID) { Console.WriteLine("DriveState.AVOID"); sB.Evade(); } sB.WallAvoidance(); SetAhead(100 * moveDir); getTurretState(); //Bruker mye energi på kuler i attack if (currentTurretState == TurretState.ATTACK) { bulletStrength = Math.Min(400 / eData.Distance, 3); Console.WriteLine("TurretState.ATTACK"); shootVector = sB.AimInFront(bulletStrength); } // Sparer energi ved å ha svakere kuler else if(currentTurretState == TurretState.SAVEENERGY) { Console.WriteLine("TurretState.SAVEENERGY"); bulletStrength = Math.Min( 200 / eData.Distance, 3); shootVector = sB.AimInFront(bulletStrength); } else if(currentTurretState == TurretState.SCAN) { Console.WriteLine("TurretState.SCAN"); SetTurnRadarRight(180); } if (Math.Abs(GunTurnRemaining) < 1) SetFire(bulletStrength); Execute(); isOnTarget = false; Scan(); } }
// Setter noder i kjøreretningen // sjekker om nodene treffer veggen // svinger vekk fra veggen public void WallAvoidance() { int nodeSize = 100; //Pixels leftHorn = new Vector2D(Math.Sin(Utils.ToRadians(robo.Heading - 45)) * (nodeSize) * robo.moveDir, Math.Cos(Utils.ToRadians(robo.Heading - 45)) * (nodeSize) * robo.moveDir); midHorn = new Vector2D(Math.Sin(Utils.ToRadians(robo.Heading)) * nodeSize * robo.moveDir, Math.Cos(Utils.ToRadians(robo.Heading)) * nodeSize * robo.moveDir); rightHorn = new Vector2D(Math.Sin(Utils.ToRadians(robo.Heading + 45)) * (nodeSize) * robo.moveDir, Math.Cos(Utils.ToRadians(robo.Heading + 45)) * (nodeSize) * robo.moveDir); leftHorn += robo.Position; midHorn += robo.Position; rightHorn += robo.Position; if (midHorn.X < 0 || midHorn.X > robo.BattleFieldWidth || midHorn.Y < 0 || midHorn.Y > robo.BattleFieldHeight) { robo.SetTurnLeft(10); } if (leftHorn.X < 0 || leftHorn.X > robo.BattleFieldWidth || leftHorn.Y < 0 || leftHorn.Y > robo.BattleFieldHeight) { robo.SetTurnRight(10); if (midHorn.X < 0 || midHorn.X > robo.BattleFieldWidth || midHorn.Y < 0 || midHorn.Y > robo.BattleFieldHeight) { robo.SetTurnRight(20); } } if (rightHorn.X < 0 || rightHorn.X > robo.BattleFieldWidth || rightHorn.Y < 0 || rightHorn.Y > robo.BattleFieldHeight) { robo.SetTurnLeft(10); if (midHorn.X < 0 || midHorn.X > robo.BattleFieldWidth || midHorn.Y < 0 || midHorn.Y > robo.BattleFieldHeight) { robo.SetTurnLeft(20); } } }
// Finner hvor tanken befinner seg // kjører mot det punktet // returnerer en vector2D for å tegne boksen du kjører mot public Vector2D Pursuit() { Vector2D newPos = new Vector2D(eData.Position.X,eData.Position.Y); for (int i = 0; i < (int)(eData.Distance / Rules.MAX_VELOCITY); i++) { newPos += new Vector2D(eData.Velocity * Math.Sin(Utils.ToRadians(eData.Heading)),eData.Velocity * Math.Cos(Utils.ToRadians(eData.Heading))); } Vector2D relativeVector = newPos - robo.Position; double enemyPosHeading = Utils.ToDegrees(Math.Atan2(relativeVector.X, relativeVector.Y)); double deltaAngle = enemyPosHeading - robo.Heading; Seek(deltaAngle); return newPos; }