Skip to content

Commit 580568f

Browse files
committed
Synchronised Metrics and FeatureListeners
1 parent 1ebe068 commit 580568f

File tree

6 files changed

+19
-169
lines changed

6 files changed

+19
-169
lines changed

src/main/java/core/Game.java

Lines changed: 0 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -177,156 +177,6 @@ public static Game runOne(GameType gameToPlay, String parameterConfigFile, List<
177177
return game;
178178
}
179179

180-
/**
181-
* Runs several games with a given random seed.
182-
*
183-
* @param gamesToPlay - list of games to play.
184-
* @param players - list of players for the game.
185-
* @param nRepetitions - number of repetitions of each game.
186-
* @param seed - random seed for all games. If null, a new random seed is used for each game.
187-
* @param randomizeParameters - if true, game parameters are randomized for each run of each game (if possible).
188-
* @param detailedStatistics - if true, detailed statistics are printed, otherwise just average of wins
189-
*/
190-
public static void runMany(List<GameType> gamesToPlay, List<AbstractPlayer> players, Long seed,
191-
int nRepetitions, boolean randomizeParameters,
192-
boolean detailedStatistics, List<IGameListener> listeners, int turnPause) {
193-
int nPlayers = players.size();
194-
195-
// Save win rate statistics over all games
196-
TAGNumericStatSummary[] overall = new TAGNumericStatSummary[nPlayers];
197-
String[] agentNames = new String[nPlayers];
198-
for (int i = 0; i < nPlayers; i++) {
199-
String[] split = players.get(i).getClass().toString().split("\\.");
200-
String agentName = split[split.length - 1] + "-" + i;
201-
overall[i] = new TAGNumericStatSummary("Overall " + agentName);
202-
agentNames[i] = agentName;
203-
}
204-
205-
// For each game...
206-
for (GameType gt : gamesToPlay) {
207-
208-
// Save win rate statistics over all repetitions of this game
209-
TAGNumericStatSummary[] statSummaries = new TAGNumericStatSummary[nPlayers];
210-
for (int i = 0; i < nPlayers; i++) {
211-
statSummaries[i] = new TAGNumericStatSummary("{Game: " + gt.name() + "; Player: " + agentNames[i] + "}");
212-
}
213-
214-
// Play n repetitions of this game and record player results
215-
Game game = null;
216-
int offset = 0;
217-
for (int i = 0; i < nRepetitions; i++) {
218-
Long s = seed;
219-
if (s == null) s = System.currentTimeMillis();
220-
s += offset;
221-
game = runOne(gt, null, players, s, randomizeParameters, listeners, null, turnPause);
222-
if (game != null) {
223-
recordPlayerResults(statSummaries, game);
224-
offset = game.getGameState().getRoundCounter() * game.getGameState().getNPlayers();
225-
} else {
226-
break;
227-
}
228-
// System.out.println("Game " + i + "/" + nRepetitions);
229-
}
230-
231-
if (game != null) {
232-
System.out.println("---------------------");
233-
for (int i = 0; i < nPlayers; i++) {
234-
// Print statistics for this game
235-
if (detailedStatistics) {
236-
System.out.println(statSummaries[i].toString());
237-
} else {
238-
System.out.println(statSummaries[i].name + ": " + statSummaries[i].mean() + " (n=" + statSummaries[i].n() + ")");
239-
}
240-
241-
// Record in overall statistics
242-
overall[i].add(statSummaries[i]);
243-
}
244-
}
245-
}
246-
247-
// Print final statistics
248-
System.out.println("\n=====================\n");
249-
for (int i = 0; i < nPlayers; i++) {
250-
// Print statistics for this game
251-
if (detailedStatistics) {
252-
System.out.println(overall[i].toString());
253-
} else {
254-
System.out.println(overall[i].name + ": " + overall[i].mean());
255-
}
256-
}
257-
}
258-
259-
/**
260-
* Runs several games with a set of random seeds, one for each repetition of a game.
261-
*
262-
* @param gamesToPlay - list of games to play.
263-
* @param players - list of players for the game.
264-
* @param nRepetitions - number of repetitions of each game.
265-
* @param seeds - random seeds array, one for each repetition of a game.
266-
* @param ac - action controller for GUI interactions, null if playing without visuals.
267-
* @param randomizeParameters - if true, game parameters are randomized for each run of each game (if possible).
268-
*/
269-
public static void runMany(List<GameType> gamesToPlay, List<AbstractPlayer> players, int nRepetitions,
270-
long[] seeds, ActionController ac, boolean randomizeParameters, List<IGameListener> listeners, int turnPause) {
271-
int nPlayers = players.size();
272-
273-
// Save win rate statistics over all games
274-
TAGNumericStatSummary[] overall = new TAGNumericStatSummary[nPlayers];
275-
for (int i = 0; i < nPlayers; i++) {
276-
overall[i] = new TAGNumericStatSummary("Overall Player " + i);
277-
}
278-
279-
// For each game...
280-
for (GameType gt : gamesToPlay) {
281-
282-
// Save win rate statistics over all repetitions of this game
283-
TAGNumericStatSummary[] statSummaries = new TAGNumericStatSummary[nPlayers];
284-
for (int i = 0; i < nPlayers; i++) {
285-
statSummaries[i] = new TAGNumericStatSummary("Game: " + gt.name() + "; Player: " + i);
286-
}
287-
288-
// Play n repetitions of this game and record player results
289-
for (int i = 0; i < nRepetitions; i++) {
290-
Game game = runOne(gt, null, players, seeds[i], randomizeParameters, listeners, null, turnPause);
291-
if (game != null) {
292-
recordPlayerResults(statSummaries, game);
293-
}
294-
}
295-
296-
for (int i = 0; i < nPlayers; i++) {
297-
// Print statistics for this game
298-
System.out.println(statSummaries[i].toString());
299-
300-
// Record in overall statistics
301-
overall[i].add(statSummaries[i]);
302-
}
303-
}
304-
305-
// Print final statistics
306-
System.out.println("\n---------------------\n");
307-
for (int i = 0; i < nPlayers; i++) {
308-
// Print statistics for this game
309-
System.out.println(overall[i].toString());
310-
}
311-
}
312-
313-
/**
314-
* Records statistics of given game into the given StatSummary objects. Only WIN, LOSE or DRAW are valid results
315-
* recorded.
316-
*
317-
* @param statSummaries - object recording statistics
318-
* @param game - finished game
319-
*/
320-
public static void recordPlayerResults(TAGNumericStatSummary[] statSummaries, Game game) {
321-
int nPlayers = statSummaries.length;
322-
CoreConstants.GameResult[] results = game.getGameState().getPlayerResults();
323-
for (int p = 0; p < nPlayers; p++) {
324-
if (results[p] == CoreConstants.GameResult.WIN_GAME || results[p] == CoreConstants.GameResult.LOSE_GAME || results[p] == CoreConstants.GameResult.DRAW_GAME) {
325-
statSummaries[p].add(results[p].value);
326-
}
327-
}
328-
}
329-
330180
public void setTurnPause(int turnPause) {
331181
this.turnPause = turnPause;
332182
}

src/main/java/evaluation/listeners/ActionFeatureListener.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public String[] names() {
5151

5252

5353
@Override
54-
public double[] extractFeatureVector(AbstractAction action, AbstractGameState state, int perspectivePlayer) {
54+
protected double[] extractFeatureVector(AbstractAction action, AbstractGameState state, int perspectivePlayer) {
5555
// We put phi in first, and then psi
5656
double[] retValue = new double[psiFn.names().length + phiFn.names().length];
5757
double[] phi = cachedPhi == null ?
@@ -63,13 +63,13 @@ public double[] extractFeatureVector(AbstractAction action, AbstractGameState st
6363
return retValue;
6464
}
6565

66-
protected void processStateWithTargets(AbstractGameState state, AbstractAction action, Map<String, Map<AbstractAction, Double>> targets) {
66+
protected synchronized void processStateWithTargets(AbstractGameState state, AbstractAction action, Map<String, Map<AbstractAction, Double>> targets) {
6767
actionValues = targets;
6868
processState(state, action);
6969
}
7070

7171
@Override
72-
public void processState(AbstractGameState state, AbstractAction action) {
72+
public synchronized void processState(AbstractGameState state, AbstractAction action) {
7373
// we override this from FeatureListener, because we want to record the feature vector for each action
7474
if (action == null) return; // we do not record data for the GAME_OVER event
7575
cachedPhi = null;
@@ -109,7 +109,7 @@ private Map<String, Double> getActionScores(AbstractAction action) {
109109

110110

111111
@Override
112-
public String injectAgentAttributes(String raw) {
112+
public synchronized String injectAgentAttributes(String raw) {
113113
return raw.replaceAll(Pattern.quote("*PSI*"), psiFn.getClass().getCanonicalName())
114114
.replaceAll(Pattern.quote("*PHI*"), phiFn != null ? phiFn.getClass().getCanonicalName() : "NONE");
115115
}

src/main/java/evaluation/listeners/FeatureListener.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public void setLogger(IStatisticLogger logger) {
3838
}
3939

4040
@Override
41-
public void onEvent(Event event) {
41+
public synchronized void onEvent(Event event) {
4242

4343
if (event.type == frequency && frequency != Event.GameEvent.GAME_OVER) {
4444
// if GAME_OVER, then we cover this a few lines down
@@ -55,7 +55,7 @@ public void onEvent(Event event) {
5555
}
5656

5757
@Override
58-
public boolean setOutputDirectory(String... nestedDirectories) {
58+
public synchronized boolean setOutputDirectory(String... nestedDirectories) {
5959

6060
if (logger instanceof FileStatsLogger fileLogger) {
6161
fileLogger.setOutPutDirectory(nestedDirectories);
@@ -112,18 +112,18 @@ public void report() {
112112
}
113113

114114
@Override
115-
public void setGame(Game game) {
115+
public synchronized void setGame(Game game) {
116116
this.game = game;
117117
}
118118

119119
@Override
120-
public Game getGame() {
120+
public synchronized Game getGame() {
121121
return game;
122122
}
123123

124124
public abstract String[] names();
125125

126-
public abstract double[] extractFeatureVector(AbstractAction action, AbstractGameState state, int perspectivePlayer);
126+
protected abstract double[] extractFeatureVector(AbstractAction action, AbstractGameState state, int perspectivePlayer);
127127

128128

129129
/**

src/main/java/evaluation/listeners/MetricsGameListener.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public MetricsGameListener(IDataLogger.ReportDestination logTo, IDataLogger.Repo
7474
* @param event Event has information about its type and data fields for game, state, action and player.
7575
* It's not guaranteed that the data fields are different to null, so a check is necessary.
7676
*/
77-
public void onEvent(Event event) {
77+
public synchronized void onEvent(Event event) {
7878
if (!eventsOfInterest.contains(event.type))
7979
return;
8080

@@ -93,7 +93,7 @@ public void onEvent(Event event) {
9393
}
9494

9595
@Override
96-
public boolean setOutputDirectory(String... nestedDirectories) {
96+
public synchronized boolean setOutputDirectory(String... nestedDirectories) {
9797

9898
boolean success = true;
9999

@@ -166,22 +166,22 @@ private String eventToIndexingColumn(IGameEvent e) {
166166
}
167167

168168
/* Getters, setters */
169-
public final void setGame(Game game) {
169+
public synchronized final void setGame(Game game) {
170170
this.game = game;
171171
}
172172

173-
public final Game getGame() {
173+
public synchronized final Game getGame() {
174174
return game;
175175
}
176176

177-
public void reset() {
177+
public synchronized void reset() {
178178
for (AbstractMetric metric : metrics.values()) {
179179
metric.reset();
180180
}
181181
}
182182

183183
@Override
184-
public void init(Game game, int nPlayersPerGame, Set<String> playerNames) {
184+
public synchronized void init(Game game, int nPlayersPerGame, Set<String> playerNames) {
185185
this.game = game;
186186

187187
for (AbstractMetric metric : metrics.values()) {

src/main/java/evaluation/listeners/StateFeatureListener.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ public String[] names() {
3030
}
3131

3232
@Override
33-
public double[] extractFeatureVector(AbstractAction action, AbstractGameState state, int perspectivePlayer) {
33+
protected double[] extractFeatureVector(AbstractAction action, AbstractGameState state, int perspectivePlayer) {
3434
return phiFn.featureVector(state, perspectivePlayer);
3535
}
3636

3737
@Override
38-
public String injectAgentAttributes(String raw) {
38+
public synchronized String injectAgentAttributes(String raw) {
3939
return raw.replaceAll(Pattern.quote("*PHI*"), phiFn.getClass().getCanonicalName());
4040
}
4141
}

src/main/java/players/mcts/MCTSTreeActionStatisticsListener.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public MCTSTreeActionStatisticsListener(IActionFeatureVector actionFeatures, ISt
3131

3232

3333
@Override
34-
public void onEvent(Event event) {
34+
public synchronized void onEvent(Event event) {
3535
if (event.type == Event.GameEvent.ACTION_CHOSEN) {
3636
// We extract the root node from the current player's tree
3737
AbstractPlayer player = this.getGame().getPlayers().get(event.state.getCurrentPlayer());
@@ -44,7 +44,7 @@ public void onEvent(Event event) {
4444
// else we do nothing
4545
}
4646

47-
public void recordData(SingleTreeNode root, AbstractForwardModel forwardModel) {
47+
private void recordData(SingleTreeNode root, AbstractForwardModel forwardModel) {
4848

4949
if (root instanceof MultiTreeNode) {
5050
// access the root for the acting player instead

0 commit comments

Comments
 (0)