Skip to content

Commit 1482acc

Browse files
author
Bytekeeper
committed
Added approx attacking behavior. No movement or range checks. Added AgentUtil.randomizePositions for approx simulation, because splash and bounce are still taken into account.
1 parent faf1e2b commit 1482acc

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)