![JAR search and dependency download from the Maven repository](/logo.png)
org.ggp.base.apps.research.MatchArchiveProcessor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of alloy-ggp-base Show documentation
Show all versions of alloy-ggp-base Show documentation
A modified version of the GGP-Base library for Alloy.
The newest version!
package org.ggp.base.apps.research;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import external.JSON.JSONArray;
import external.JSON.JSONException;
import external.JSON.JSONObject;
/**
* MatchArchiveProcessor is a utility program that reads in serialized
* match archives, like those available at GGP.org/researchers, and runs
* some computation on every match in the archive.
*
* This can be used to do many useful tasks, like counting the number of
* matches that satisfy certain properties, totaling up averages across the
* set of all matches, and computing statistics and player ratings.
*
* Currently this computes three interesting example aggregations:
* - the frequency of wins for the second player, broken down by game
* - a histogram of how often each game is played
* - the average length of a nine-board tic-tac-toe match
*
* @author Sam Schreiber
*/
public final class MatchArchiveProcessor
{
// Set this to the path of the downloaded match archive file.
public static final File ARCHIVE_FILE = new File(new File(new File(new File(System.getProperty("user.home")), "matchArchive"), "data"), "allMatches");
private MatchArchiveProcessor() {
}
public static void main(String[] args) throws IOException, JSONException
{
AggregateData data = new AggregateData();
String line;
int nCount = 0;
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(ARCHIVE_FILE), Charset.forName("UTF-8")));
while ((line = br.readLine()) != null) {
JSONObject entryJSON = new JSONObject(line);
String url = entryJSON.getString("url");
JSONObject matchJSON = entryJSON.getJSONObject("data");
processMatch(url, matchJSON, data);
nCount++;
if (nCount % 1000 == 0) {
System.out.println("Processed " + nCount + " matches.");
}
}
br.close();
System.out.println("Second player win frequency:\n" + data.secondPlayerWinFrequency.toString());
System.out.println("Game histogram:\n" + data.gameHistogram.toString());
System.out.println("average matchLengthsFor9xTTT = " + data.matchLengthsFor9xTTT.toString());
}
// This class stores all of the data that needs to be aggregated between
// individual matches. It will include things like histograms, counters,
// weighted averages, etc. If you're adding a new aggregation, you'll likely
// want to add a new data structure here to keep track of the aggregate data
// between matches.
static class AggregateData {
public Histogram gameHistogram = new Histogram();
public WeightedAverage matchLengthsFor9xTTT = new WeightedAverage();
public FrequencyTable secondPlayerWinFrequency = new FrequencyTable();
}
// This method determines how each individual match is processed.
// Right now it aggregates data about how often individual games are played,
// how often the second player wins a match, and how long the average match
// of nine-board tic-tac-toe takes. If you want to add more aggregations, this
// is the place to do it.
private static void processMatch(String theURL, JSONObject matchJSON, AggregateData data) {
try {
String gameURL = matchJSON.getString("gameMetaURL");
// Add a data point to the histogram of how often games are used
data.gameHistogram.add(gameURL);
// And for completed signed matches...
if (matchJSON.has("isCompleted") && matchJSON.getBoolean("isCompleted") && matchJSON.has("matchHostPK")) {
// Add a data point to the average length of 9xTTT matches, if it's a 9xTTT match
if (gameURL.startsWith("http://games.ggp.org/base/games/nineBoardTicTacToe/")) {
data.matchLengthsFor9xTTT.addValue(matchJSON.getJSONArray("states").length());
}
// Add a data point to the frequency of second player wins, if this is a match that
// has a second player and recorded goal values.
if (matchJSON.has("goalValues") && matchJSON.getJSONArray("goalValues").length() > 1) {
boolean secondPlayerWon = true;
JSONArray goalValues = matchJSON.getJSONArray("goalValues");
for (int i = 0; i < goalValues.length(); i++) {
if (i == 1) continue;
if (goalValues.getInt(i) >= goalValues.getInt(1)) {
secondPlayerWon = false;
}
}
data.secondPlayerWinFrequency.add(gameURL, secondPlayerWon ? 1 : 0);
}
}
} catch (JSONException je) {
je.printStackTrace();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy