Package org.ggp.base.apps.research

Source Code of org.ggp.base.apps.research.MatchArchiveProcessor$AggregateData

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");

  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();
    }
  }
}
TOP

Related Classes of org.ggp.base.apps.research.MatchArchiveProcessor$AggregateData

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.