Skip to content

Commit 90c0d74

Browse files
authored
Merge pull request #1 from JavaBWAPI/approx_sim
Added approx attacking behavior. No movement or range checks. Added A…
2 parents d831ee0 + 1482acc commit 90c0d74

File tree

5 files changed

+286
-118
lines changed

5 files changed

+286
-118
lines changed

src/jmh/java/org/bk/ass/SimulatorBenchmark.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.bk.ass;
22

3+
import org.bk.ass.sim.AgentUtil;
4+
import org.bk.ass.sim.ApproxAttackBehavior;
35
import org.bk.ass.sim.BWAPI4JAgentFactory;
46
import org.bk.ass.sim.Simulator;
57
import org.bk.ass.sim.Simulator.Builder;
@@ -16,21 +18,28 @@ public static class MyState {
1618

1719
Simulator simulator;
1820
Simulator simulatorFS4;
21+
Simulator approxSim;
1922
BWAPI4JAgentFactory factory = new BWAPI4JAgentFactory(null);
2023

2124
@Setup(Level.Invocation)
2225
public void setup() {
2326
simulator = new Builder().build();
2427
simulatorFS4 = new Builder().withFrameSkip(4).build();
28+
approxSim = new Builder().withFrameSkip(37).withPlayerABehavior(new ApproxAttackBehavior()).withPlayerABehavior(new ApproxAttackBehavior()).build();
2529

2630
for (int i = 0; i < 30; i++) {
2731
simulator.addAgentA(factory.of(UnitType.Zerg_Mutalisk));
2832
simulatorFS4.addAgentA(factory.of(UnitType.Zerg_Mutalisk));
33+
approxSim.addAgentA(factory.of(UnitType.Zerg_Mutalisk));
2934
}
3035
for (int i = 0; i < 30; i++) {
3136
simulator.addAgentB(factory.of(UnitType.Zerg_Hydralisk));
3237
simulatorFS4.addAgentB(factory.of(UnitType.Zerg_Hydralisk));
38+
approxSim.addAgentB(factory.of(UnitType.Zerg_Hydralisk));
3339
}
40+
41+
AgentUtil.randomizePositions(approxSim.getAgentsA(), 0, 0, 32, 32);
42+
AgentUtil.randomizePositions(approxSim.getAgentsB(), 32, 0, 64, 64);
3443
}
3544
}
3645

@@ -52,6 +61,11 @@ public int _30MutasVs30Hydras_fs4(MyState state) {
5261
return state.simulatorFS4.simulate(-1);
5362
}
5463

64+
@Benchmark
65+
public int _30MutasVs30Hydras_approx(MyState state) {
66+
return state.approxSim.simulate(-1);
67+
}
68+
5569
@Benchmark
5670
public int clearCollisionMaps(MyState state) {
5771
state.simulator.reset();
Lines changed: 14 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package org.bk.ass.sim;
22

3-
import org.bk.ass.collection.UnorderedCollection;
4-
3+
import java.util.Collection;
54
import java.util.SplittableRandom;
65

76
import static java.lang.Math.*;
@@ -45,99 +44,6 @@ public static int distanceSquared(Agent a, Agent b) {
4544
return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
4645
}
4746

48-
/** Deal splash damage to enemies and allies */
49-
public static void dealRadialSplashDamage(
50-
Weapon weapon,
51-
Agent mainTarget,
52-
UnorderedCollection<Agent> allies,
53-
UnorderedCollection<Agent> enemies) {
54-
for (int i = allies.size() - 1; i >= 0; i--) {
55-
Agent ally = allies.get(i);
56-
applySplashDamage(weapon, mainTarget, ally);
57-
}
58-
for (int i = enemies.size() - 1; i >= 0; i--) {
59-
Agent enemy = enemies.get(i);
60-
applySplashDamage(weapon, mainTarget, enemy);
61-
}
62-
}
63-
64-
private static void applySplashDamage(Weapon weapon, Agent mainTarget, Agent splashTarget) {
65-
if (splashTarget == mainTarget || splashTarget.isFlyer != mainTarget.isFlyer) {
66-
return;
67-
}
68-
69-
int distanceSquared = distanceSquared(splashTarget, mainTarget);
70-
if (distanceSquared <= weapon.innerSplashRadiusSquared) {
71-
applyDamage(splashTarget, weapon.damageType, weapon.damageShifted, weapon.hits);
72-
} else if (!splashTarget.burrowed) {
73-
if (distanceSquared <= weapon.medianSplashRadiusSquared) {
74-
applyDamage(splashTarget, weapon.damageType, weapon.damageShifted / 2, weapon.hits);
75-
} else if (distanceSquared <= weapon.outerSplashRadiusSquared) {
76-
applyDamage(splashTarget, weapon.damageType, weapon.damageShifted / 4, weapon.hits);
77-
}
78-
}
79-
}
80-
81-
/** Deal splash damage to enemies only */
82-
public static void dealRadialSplashDamage(
83-
Weapon weapon, Agent mainTarget, UnorderedCollection<Agent> enemies) {
84-
for (int i = enemies.size() - 1; i >= 0; i--) {
85-
Agent enemy = enemies.get(i);
86-
applySplashDamage(weapon, mainTarget, enemy);
87-
}
88-
}
89-
90-
public static void dealLineSplashDamage(
91-
Agent source, Weapon weapon, Agent mainTarget, UnorderedCollection<Agent> enemies) {
92-
int dx = mainTarget.x - source.x;
93-
int dy = mainTarget.y - source.y;
94-
// Same spot, chose "random" direction
95-
if (dx == 0 && dy == 0) {
96-
dx = 1;
97-
}
98-
int dxDistSq = dx * dx + dy * dy;
99-
int rangeWithSplashSquared =
100-
weapon.maxRangeSquared
101-
+ 2 * weapon.maxRange * weapon.innerSplashRadius
102-
+ weapon.innerSplashRadiusSquared;
103-
for (int i = enemies.size() - 1; i >= 0; i--) {
104-
Agent enemy = enemies.get(i);
105-
if (enemy == mainTarget || enemy.isFlyer != mainTarget.isFlyer) {
106-
continue;
107-
}
108-
int enemyDistSq = distanceSquared(enemy, source);
109-
if (enemyDistSq <= rangeWithSplashSquared) {
110-
int dot = (enemy.x - source.x) * dx + (enemy.y - source.y) * dy;
111-
if (dot >= 0) {
112-
int projdx = source.x + dot * dx / dxDistSq - enemy.x;
113-
int projdy = source.y + dot * dy / dxDistSq - enemy.y;
114-
int projDistSq = projdx * projdx + projdy * projdy;
115-
if (projDistSq <= weapon.innerSplashRadiusSquared) {
116-
applyDamage(enemy, weapon.damageType, weapon.damageShifted, weapon.hits);
117-
}
118-
}
119-
}
120-
}
121-
}
122-
123-
public static void dealBounceDamage(
124-
Weapon weapon, Agent lastTarget, UnorderedCollection<Agent> enemies) {
125-
int remainingBounces = 2;
126-
int damage = weapon.damageShifted / 3;
127-
for (int i = enemies.size() - 1; i >= 0 && remainingBounces > 0; i--) {
128-
Agent enemy = enemies.get(i);
129-
if (enemy != lastTarget
130-
&& enemy.healthShifted > 0
131-
&& abs(enemy.x - lastTarget.x) <= 96
132-
&& abs(enemy.y - lastTarget.y) <= 96) {
133-
lastTarget = enemy;
134-
applyDamage(enemy, weapon.damageType, damage, weapon.hits);
135-
damage /= 3;
136-
remainingBounces--;
137-
}
138-
}
139-
}
140-
14147
public static void dealDamage(Agent agent, Weapon wpn, Agent target) {
14248
int remainingDamage = wpn.damageShifted;
14349

@@ -156,7 +62,7 @@ public static void dealDamage(Agent agent, Weapon wpn, Agent target) {
15662
applyDamage(target, wpn.damageType, remainingDamage, wpn.hits);
15763
}
15864

159-
private static void applyDamage(Agent target, DamageType damageType, int damage, int hits) {
65+
public static void applyDamage(Agent target, DamageType damageType, int damage, int hits) {
16066
int shields = min(target.maxShieldsShifted, target.shieldsShifted) - damage + target.shieldUpgrades;
16167
if (shields > 0) {
16268
target.shieldsShifted = shields;
@@ -194,27 +100,18 @@ public static int reduceDamageByTargetSizeAndDamageType(
194100
return damageShifted;
195101
}
196102

197-
public static void attack(Agent agent, Weapon selectedWeapon, Agent selectedEnemy, UnorderedCollection<Agent> allies, UnorderedCollection<Agent> enemies) {
198-
dealDamage(agent, selectedWeapon, selectedEnemy);
199-
switch (selectedWeapon.splashType) {
200-
case BOUNCE:
201-
dealBounceDamage(selectedWeapon, selectedEnemy, enemies);
202-
break;
203-
case RADIAL_SPLASH:
204-
dealRadialSplashDamage(selectedWeapon, selectedEnemy, allies, enemies);
205-
break;
206-
case RADIAL_ENEMY_SPLASH:
207-
dealRadialSplashDamage(selectedWeapon, selectedEnemy, enemies);
208-
break;
209-
case LINE_SPLASH:
210-
dealLineSplashDamage(agent, selectedWeapon, selectedEnemy, enemies);
211-
break;
212-
default:
213-
// No splash
214-
}
215-
agent.cooldown = agent.maxCooldown;
216-
if (agent.remainingStimFrames > 0) {
217-
agent.cooldown /= 2;
103+
/**
104+
* Sets random positions for the given agents within the given rectangle.
105+
* The positions are <em>stable</em>: Calling this with the same arguments twice will not change any position
106+
* on the second invocation. More precisely, any {@link Agent} with position i in the collection will always
107+
* get the same position. Be sure to use different rectangles for different {@link Agent} collections, to
108+
* prevent them from getting assigned the same positions.
109+
*/
110+
public static void randomizePositions(Collection<Agent> agents, int ax, int ay, int bx, int by) {
111+
SplittableRandom posRnd = new SplittableRandom(1337L);
112+
for (Agent agent : agents) {
113+
agent.x = posRnd.nextInt(ax, bx - ax + 1);
114+
agent.y = posRnd.nextInt(ay, by - ay + 1);
218115
}
219116
}
220117
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package org.bk.ass.sim;
2+
3+
import org.bk.ass.collection.UnorderedCollection;
4+
import org.bk.ass.sim.Simulator.Behavior;
5+
6+
import static org.bk.ass.sim.AttackerBehavior.*;
7+
8+
public class ApproxAttackBehavior implements Behavior {
9+
@Override
10+
public boolean simUnit(int frameSkip, Agent agent, UnorderedCollection<Agent> allies, UnorderedCollection<Agent> enemies) {
11+
int i = enemies.size() - 1;
12+
while (agent.cooldown <= 0 && i >= 0) {
13+
Agent enemy = enemies.get(i);
14+
Weapon wpn = agent.weaponVs(enemy);
15+
if (enemy.healthShifted > 0
16+
&& wpn.damageShifted != 0
17+
&& enemy.detected
18+
&& !enemy.isStasised) {
19+
if (agent.canStim
20+
&& agent.remainingStimFrames <= 0
21+
&& agent.healthShifted >= agent.maxHealthShifted / 2) {
22+
agent.stim();
23+
}
24+
attack(agent, wpn, enemy, allies, enemies);
25+
} else
26+
i--;
27+
}
28+
29+
return agent.cooldown > 0;
30+
}
31+
32+
public static void attack(Agent agent, Weapon weapon, Agent enemy, UnorderedCollection<Agent> allies, UnorderedCollection<Agent> enemies) {
33+
AgentUtil.dealDamage(agent, weapon, enemy);
34+
switch (weapon.splashType) {
35+
case BOUNCE:
36+
dealBounceDamage(weapon, enemy, enemies);
37+
break;
38+
case RADIAL_SPLASH:
39+
dealRadialSplashDamage(weapon, enemy, allies, enemies);
40+
break;
41+
case RADIAL_ENEMY_SPLASH:
42+
dealRadialSplashDamage(weapon, enemy, enemies);
43+
break;
44+
case LINE_SPLASH:
45+
dealLineSplashDamage(agent, weapon, enemy, enemies);
46+
break;
47+
default:
48+
// No splash
49+
}
50+
51+
if (agent.remainingStimFrames <= 0)
52+
agent.cooldown += agent.maxCooldown;
53+
else
54+
agent.cooldown += agent.maxCooldown / 2;
55+
}
56+
}

0 commit comments

Comments
 (0)