-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbrooklyngrant.java
244 lines (214 loc) · 8.32 KB
/
brooklyngrant.java
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
import java.awt.geom.*;
import java.awt.*;
import java.util.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
/**
* brooklyngrant (onyx username)
* By Brooklyn Grant and Megan Aker
*/
public class brooklyngrant extends ClobberBot {
private BufferedImage myImage;
private Map<BotPoint2D, Point2D> previousPositions = new HashMap<>();
ClobberBotAction currAction;
private final int SAFE_DISTANCE = 30;
private final int SHOOT_DISTANCE = 200;
/**
* Constructor
* @param game
*/
public brooklyngrant(Clobber game) {
super(game);
// load death star imageas avatar
try {
myImage = ImageIO.read(new File("deathstar.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Plan moves
* Execution time is less than 1/100 of a second
*/
public ClobberBotAction takeTurn(WhatIKnow currState) {
long startTime = System.currentTimeMillis(); // starting point of take turn logic
Point2D me = currState.me;
Vector<BulletPoint2D> bullets = currState.bullets;
Vector<BotPoint2D> bots = currState.bots;
updatePreviousPositions(bots); //update past bots position
BulletPoint2D nearestBullet = findNearestBullet(me, bullets);
if (nearestBullet != null && me.distance(nearestBullet) < SAFE_DISTANCE) {
currAction = moveAwayFromBullet(me, nearestBullet);
return currAction;
}
BotPoint2D nearestBot = findNearestBot(me, bots);
if (nearestBot != null) {
double distanceToBot = me.distance(nearestBot);
if (distanceToBot < SAFE_DISTANCE) {
// move away if too close
currAction = moveAwayFromBot(me, nearestBot);
return currAction;
} else if (distanceToBot < SHOOT_DISTANCE) {
// shoot if in range
currAction = shootAtBot(me, nearestBot);
return currAction;
} else {
// move to bot
currAction = moveTowardBot(me, nearestBot);
return currAction;
}
}
long elapsedTime = System.currentTimeMillis() - startTime; // difference between end time and start is elapsed
if (elapsedTime > 10) {
System.out.println("The execution time was longer than 1/100 of a second."); // if this is called then it is too long!
}
return currAction;
}
/**
* Update the previous positions of bots - this
* is used to calculate velocities and future
* positions
* @param bots
*/
private void updatePreviousPositions(Vector<BotPoint2D> bots) {
for (BotPoint2D bot : bots) {
previousPositions.put(bot, new Point2D.Double(bot.getX(), bot.getY()));
}
}
/**
* Locate the nearest bullet to dodge
* @param me
* @param bullets
* @return nearest bullet
*/
private BulletPoint2D findNearestBullet(Point2D me, Vector<BulletPoint2D> bullets) {
BulletPoint2D nearest = null;
double minDistance = Double.MAX_VALUE; // big value to set the first bullet to closest before going through
for (BulletPoint2D bullet : bullets) {
double distance = me.distance(bullet);
if (distance < minDistance) { // if less than the nearest distance
minDistance = distance;
nearest = bullet;
}
}
return nearest; // returning closest bullet
}
/**
* Move from bullet!
* @param me
* @param bullet
* @return
*/
private ClobberBotAction moveAwayFromBullet(Point2D me, BulletPoint2D bullet) {
double x = me.getX() - bullet.getX();
double y = me.getY() - bullet.getY();
if (Math.abs(x) > Math.abs(y)) { // if |x| > |y|, then you must move right or left
return new ClobberBotAction(ClobberBotAction.MOVE, x > 0 ? ClobberBotAction.RIGHT : ClobberBotAction.LEFT);
} else {
return new ClobberBotAction(ClobberBotAction.MOVE, y > 0 ? ClobberBotAction.DOWN : ClobberBotAction.UP);
}
}
/**
* Move away from bot!
* @param me
* @param bot
* @return action
*/
private ClobberBotAction moveAwayFromBot(Point2D me, BotPoint2D bot) {
double x = me.getX() - bot.getX();
double y = me.getY() - bot.getY();
if (Math.abs(x) > Math.abs(y)) { // if |x| > |y|, then you must move right or left
return new ClobberBotAction(ClobberBotAction.MOVE, x > 0 ? ClobberBotAction.RIGHT : ClobberBotAction.LEFT);
} else {
return new ClobberBotAction(ClobberBotAction.MOVE, y > 0 ? ClobberBotAction.DOWN : ClobberBotAction.UP);
}
}
/**
* Move toward bot !
* @param me
* @param bot
* @return action
*/
private ClobberBotAction moveTowardBot(Point2D me, BotPoint2D bot) {
double x = bot.getX() - me.getX();
double y = bot.getY() - me.getY();
if (Math.abs(x) > Math.abs(y)) { // if |x| > |y|, then you must move right or left
return new ClobberBotAction(1, x > 0 ? ClobberBotAction.RIGHT : ClobberBotAction.LEFT);
} else {
return new ClobberBotAction(1, y > 0 ? ClobberBotAction.DOWN : ClobberBotAction.UP);
}
}
/**
* Find the closest bot to us
* Same logic as findNearestBullet
* @param me
* @param bots
* @return
*/
private BotPoint2D findNearestBot(Point2D me, Vector<BotPoint2D> bots) {
BotPoint2D nearest = null;
double minDistance = Double.MAX_VALUE; // big value to set first to less
for (BotPoint2D bot : bots) {
double distance = me.distance(bot);
if (distance < minDistance) {
minDistance = distance;
nearest = bot;
}
}
return nearest;
}
/**
* Shoot at bot
* @param me
* @param bot
* @return
*/
private ClobberBotAction shootAtBot(Point2D me, BotPoint2D bot) {
Point2D previousPosition = previousPositions.get(bot);
double botVelocityX = 0;
double botVelocityY = 0;
// calculate velocity of bot if we have old positions to predict where it will move
if (previousPosition != null) {
botVelocityX = bot.getX() - previousPosition.getX();
botVelocityY = bot.getY() - previousPosition.getY();
}
// predict the bot's future position
double predictedX = bot.getX() + botVelocityX;
double predictedY = bot.getY() + botVelocityY;
// shoot this way
double deltaX = predictedX - me.getX();
double deltaY = predictedY - me.getY();
if (Math.abs(deltaX) > 0 && Math.abs(deltaY) > 0) {
if (deltaX > 0 && deltaY > 0) {
return new ClobberBotAction(ClobberBotAction.SHOOT, ClobberBotAction.DOWN | ClobberBotAction.RIGHT);
} else if (deltaX > 0 && deltaY < 0) {
return new ClobberBotAction(ClobberBotAction.SHOOT, ClobberBotAction.UP | ClobberBotAction.RIGHT);
} else if (deltaX < 0 && deltaY > 0) {
return new ClobberBotAction(ClobberBotAction.SHOOT, ClobberBotAction.DOWN | ClobberBotAction.LEFT);
} else {
return new ClobberBotAction(ClobberBotAction.SHOOT, ClobberBotAction.UP | ClobberBotAction.LEFT);
}
}
if (Math.abs(deltaX) > Math.abs(deltaY)) {
return new ClobberBotAction(ClobberBotAction.SHOOT, deltaX > 0 ? ClobberBotAction.RIGHT : ClobberBotAction.LEFT);
} else {
return new ClobberBotAction(ClobberBotAction.SHOOT, deltaY > 0 ? ClobberBotAction.DOWN : ClobberBotAction.UP);
}
}
/**
* Draw avatar
*/
public void drawMe(Graphics page, Point2D me) {
int x, y;
x = (int) me.getX() - Clobber.MAX_BOT_GIRTH / 2 - 1;
y = (int) me.getY() - Clobber.MAX_BOT_GIRTH / 2 - 1;
if (myImage != null) {
page.drawImage(myImage, x, y, Clobber.MAX_BOT_GIRTH, Clobber.MAX_BOT_GIRTH, null);
}
}
public String toString() {
return "Brooklyn Grant and Megan Aker";
}
}