-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathAbstractRobot.cs
154 lines (134 loc) · 5.76 KB
/
AbstractRobot.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using System;
using Robocode;
using Robocode.Util;
namespace FDLearnAim
{
public class AbstractRobot
{
private readonly AdvancedRobot _robot;
private readonly Random _dodgeGenerator;
public double MovingDirection { get; set; }
public AbstractRobot(AdvancedRobot robot)
{
_dodgeGenerator = new Random();
MovingDirection = 1d;
_robot = robot;
}
internal void SetMoveToWallAndBack(double robotPositionX, double robotPositionY, bool shouldRam)
{
if (!SetMoveAhead(robotPositionX, robotPositionY, MovingDirection, shouldRam))
{
SetMoveAhead(robotPositionX, robotPositionY, -MovingDirection, shouldRam);
MovingDirection = -MovingDirection;
}
}
/// <summary>
/// Moves the robot ahead if there are no walls in the immediate vicinity
/// </summary>
/// <param name="robotPositionX"></param>
/// <param name="robotPositionY"></param>
/// <param name="direction"> should be 1 or -1</param>
/// <param name="shouldRam"> if true robot will ram lower health enemies</param>
/// <returns></returns>
internal bool SetMoveAhead(double robotPositionX, double robotPositionY, double direction, bool shouldRam)
{
var width = _robot.BattleFieldWidth - (_robot.Width / 2);
var height = _robot.BattleFieldHeight - (_robot.Height / 2);
var velocity = AddBrakeVelocity(Math.Abs(_robot.Velocity));
var x = Math.Round(robotPositionX + Math.Sin(_robot.HeadingRadians) * (velocity * direction + direction));
var y = Math.Round(robotPositionY + Math.Cos(_robot.HeadingRadians) * (velocity * direction + direction));
if (x >= width || x <= (_robot.Width/2) || y >= height || y <= (_robot.Height/2))
{
return false;
}
//TODO ram enemies only if their health is lower
_robot.SetAhead(direction * 30);
return true;
}
/// <summary>
/// Adds the speed of reversing into current velocity
/// </summary>
/// <param name="velocity"></param>
/// <returns></returns>
internal static double AddBrakeVelocity(double velocity)
{
if (Math.Abs(velocity - 0.0d) < 0.0001)
{
return 0;
}
var vel = Math.Abs(velocity - Rules.DECELERATION);
if (vel > 0.0d && vel < Rules.DECELERATION)
{
return AddBrakeVelocity(0) + velocity;
}
return AddBrakeVelocity(vel) + velocity;
}
internal void RandomDodge()
{
var randomTurn = Utilities.GetRandomNumber(_dodgeGenerator, -17d, 17d);
if (Math.Abs(randomTurn) < 5d)
{
randomTurn *= 2.5d;
}
_robot.SetTurnRight(randomTurn);
//Should the robot reverse?
var revProb = _dodgeGenerator.NextDouble();
if (revProb < .1d)
{
MovingDirection = -MovingDirection;
}
}
/// <summary>
/// Only fire the gun if the gun has stopped turning
/// </summary>
/// <param name="firepower"></param>
internal bool CheckFire(double firepower)
{
if (Math.Abs(_robot.GunTurnRemainingRadians) < 0.01d && _robot.GunHeat <= 0.0d)
{
_robot.SetFire(firepower);
return true;
}
return false;
}
/// <summary>
/// Move the gun to the desired bearing
/// </summary>
/// <param name="desiredGunBearingRadians"></param>
internal void SetMoveGunToDesiredBearing(double desiredGunBearingRadians)
{
var turnAmount = Utils.NormalRelativeAngle(desiredGunBearingRadians - _robot.GunHeadingRadians);
_robot.SetTurnGunRightRadians(turnAmount);
}
/// <summary>
/// Point the gun at the target robot.
/// Returns the desired gun bearing, so it is possible to check when the gun is at the position we want
/// </summary>
/// <param name="targetBearingRadians"></param>
/// <returns></returns>
internal double SetTurnGunToRobot(double targetBearingRadians)
{
// Calculate exact location of the robot
var desiredGunBearing = _robot.HeadingRadians + targetBearingRadians;
var bearingFromGun = Utils.NormalRelativeAngle(desiredGunBearing - _robot.GunHeadingRadians);
_robot.SetTurnGunRightRadians(bearingFromGun);
return desiredGunBearing;
}
/// <summary>
/// Keeps radar locked on a target. If you wish to move the radar independently from the robot make sure
/// "IsAdjustRadarForGunTurn" is set to true.
/// Since robots are 36*36 pixels and max velocity is 8px it is possible
/// to always keep the radar on a target. Usually you'd call this method on the OnScannedRobot event
/// </summary>
/// <param name="targetBearingRadians"></param>
internal void SetTurnMultiplierRadarLock(double targetBearingRadians)
{
var radarTurn =
// Absolute bearing to target
_robot.HeadingRadians + targetBearingRadians
// Subtract current radar heading to get turn required
- _robot.RadarHeadingRadians;
_robot.SetTurnRadarRightRadians(2.0 * Utils.NormalRelativeAngle(radarTurn));
}
}
}