4
4
5
5
import java .util .Collection ;
6
6
import java .util .Collections ;
7
+ import java .util .function .ToIntFunction ;
7
8
8
9
/**
9
10
* Used to simulate 2 groups of agents engaging each other. Either use the default constructor which
18
19
* <li>Before each simulation call <code>resetUnits()</code> before adding units
19
20
* </ol>
20
21
*
21
- * Do <b>not</b> modify {@link Agent}s, after adding them to the simulation.
22
+ * Be cautious when modifying {@link Agent}s after they have been added to the simulation.
22
23
*/
23
24
public class Simulator {
25
+ public static final ToIntFunction <Agent > HEALTH_AND_SHIELD =
26
+ agent -> agent .getHealth () + agent .getShields ();
24
27
25
28
private static final int MAX_MAP_DIMENSION = 8192 ;
26
29
private static final int TILE_SIZE = 16 ;
27
30
public static final int MIN_SIMULATION_RANGE =
28
- (TILE_SIZE + TILE_SIZE / 2 ) * (TILE_SIZE + TILE_SIZE / 2 );
31
+ (TILE_SIZE + TILE_SIZE / 2 ) * (TILE_SIZE + TILE_SIZE / 2 );
29
32
private static final int COLLISION_MAP_DIMENSION = MAX_MAP_DIMENSION / TILE_SIZE ;
30
33
private final UnorderedCollection <Agent > playerA = new UnorderedCollection <>();
31
34
private final UnorderedCollection <Agent > playerB = new UnorderedCollection <>();
@@ -52,6 +55,14 @@ public Simulator addAgentA(Agent agent) {
52
55
return this ;
53
56
}
54
57
58
+ public void removeAgentA (Agent agent ) {
59
+ playerA .remove (agent );
60
+ }
61
+
62
+ public void removeAgentB (Agent agent ) {
63
+ playerB .remove (agent );
64
+ }
65
+
55
66
public Simulator addAgentB (Agent agent ) {
56
67
checkBounds (agent );
57
68
playerB .add (agent );
@@ -76,8 +87,24 @@ public Collection<Agent> getAgentsB() {
76
87
return Collections .unmodifiableCollection (playerB );
77
88
}
78
89
90
+ /**
91
+ * Performs a summation of evaluations on agents of player a and b.
92
+ *
93
+ * @param agentEval the evaluation function to use
94
+ * @return the sum of evaluations for all agents, accumulated to an {@link IntEvaluation}.
95
+ */
96
+ public IntEvaluation evalToInt (ToIntFunction <Agent > agentEval ) {
97
+ int evalA = 0 ;
98
+ for (Agent agent : playerA ) evalA += agentEval .applyAsInt (agent );
99
+ int evalB = 0 ;
100
+ for (Agent agent : playerB ) evalB += agentEval .applyAsInt (agent );
101
+ return new IntEvaluation (evalA , evalB );
102
+ }
103
+
79
104
/**
80
105
* Simulates 4 seconds into the future.
106
+ *
107
+ * @return the actual number of frames simulated, 96 if the battle was not decided earlier
81
108
*/
82
109
public int simulate () {
83
110
return simulate (96 );
@@ -86,6 +113,8 @@ public int simulate() {
86
113
/**
87
114
* Simulate the given number of frames. If negative, simulation will only stop if one party has no
88
115
* agents left. If units decide to run away, this could be an endless loop - use with care!
116
+ *
117
+ * @return the actual number of frames simulated, usually the given number of frames
89
118
*/
90
119
public int simulate (int frames ) {
91
120
while (frames -- != 0 && !playerA .isEmpty () && !playerB .isEmpty ()) {
@@ -264,4 +293,32 @@ public interface Behavior {
264
293
boolean simUnit (
265
294
Agent agent , UnorderedCollection <Agent > allies , UnorderedCollection <Agent > enemies );
266
295
}
296
+
297
+ public static class IntEvaluation {
298
+ public final int evalA ;
299
+ public final int evalB ;
300
+
301
+ IntEvaluation (int evalA , int evalB ) {
302
+ this .evalA = evalA ;
303
+ this .evalB = evalB ;
304
+ }
305
+
306
+ /**
307
+ * Returns the delta of the evaluations for player a and b (evalA - evalB). Evaluating before
308
+ * and after a simulation, the 2 resulting deltas can be used to determine a positive or
309
+ * negative outcome.
310
+ */
311
+ public int delta () {
312
+ return evalA - evalB ;
313
+ }
314
+
315
+ /**
316
+ * Subtracts another evaluation and returns the result. Evaluating before and after a
317
+ * simulation, this can be used to calculate before - after. This in turn represents the loss
318
+ * each player had in the meantime.
319
+ */
320
+ public IntEvaluation subtract (IntEvaluation other ) {
321
+ return new IntEvaluation (evalA - other .evalA , evalB - other .evalB );
322
+ }
323
+ }
267
324
}
0 commit comments