Skip to content

public goods extensibility example

Morgan Grant edited this page Sep 19, 2017 · 1 revision

The following page discusses and implements a public goods game via ConG's extensibility feature. The payoff function and display is very similar to the [wiki:Public], but relies on the .java file below to define its payoff function and draw function.

For a more broad, abstract discussion of ConG's extensibility feature, refer to the following page.

Table of Contents

Group Strategies

Group strategies are maps which contain the subjects in the group. For each subject, there is an array which contains their respective strategies.

In the getPayoff function of Public Goods, the variable Map popStrategies contains the group strategy. You can use a foreach loop to iterate through the subjects and use them for calculations.

Payoff Function

The payoff function is the Java function in the source file that performs calculations relevant to the experiment to obtain values for the subjects. Generally, the payoff function will determine the location of the subjects' bubbles on the graph. This is the payoff function for Public Goods.

 public float getPayoff(
        int id, // the id of the subject to calculate the payoff for, can be used as an index into popStrategies
        float percent, // ignore
        Map<Integer, float[]> popStrategies, // the set of strategies for each subject in the group
        Map<Integer, float[]> matchPopStrategies,   // var can be ignored for the purposes of this payoff 
  function
        Config config) {
 
    // smin/smax are used to map the strategies from their range of [0, 1] to [smin, smax]
    float smin = 0;
    float smax = 100;
    float A = config.get("Alpha");
 
    float sum = 0;
    for (int i : popStrategies.keySet()) {
        // retrieve the 0th strategy for subject i
        // remember, strategies for a given subject are represented as an array
        // but in the case of this one-strategy game, we only care about the strategy at index 0
        float s = popStrategies.get(i)[0];
        sum += smin + s * (smax - smin);
    }
    float s = smin + (popStrategies.get(id)[0] * (smax - smin)); // map our own strategy to the range [smin, smax]
    float n = popStrategies.size();
    return (smax - s) + (A / n) * sum; 
    // returns the result of the public goods payoff func as a floating point number
 }

popStrategies is a map containing the IDs of each subject. You can perform a foreach loop through popStrategies to go through all of the subjects strategies and use them in calculation. For example, the above code uses popStrategies to compute the total of all subjects strategies, then uses this total in its payoff calculations. Other functions could use popStrategies to compute the min, max, etc.

The function must finally return a floating point number (the "flow payoff") which will be used by ConG to compute the subjects' payoff for the period.

Draw Function

The draw function draws to the screen using a simple draw loop architecture. Drawing is performed at 60 frames per second, or however fast the client computer will allow. OpenGL calls may be used. ConG uses OpenGL, Processing, and Java AWT for drawing.

This is a small snippet of code from PublicGoodsScripted.java. It is from the drawStrategy function which is called in the draw function. (Note that the full drawStrategy function for this experiment is over one-hundred lines of code, but most of that code trivially describes how to draw the boxes, lines, formating, etc. subjects see during the experiment.)

 a.stroke(color.getRed(), color.getGreen(), color.getBlue());
         a.fill(color.getRed(), color.getGreen(), color.getBlue());
         if (id != FIRE.client.getID() && config.subperiods == 0 || Client.state.subperiod != 0) {
             a.strokeWeight(3);
             a.line(x, a.height * scale - 5, x, a.height * scale + 5);
         }
         if (config.subperiods == 0 || Client.state.subperiod != 0) {
             a.strokeWeight(1);
             if (id == FIRE.client.getID()) {
                 a.ellipse(x, y, 11, 11);
             } else {
                 a.ellipse(x, y, 8, 8);
             }
         }
 

In this snippet of code, a is of type Client and extends PApplet, which is from the Processing library. In this code, we have the Processing calls: stroke, fill, strokeWeight, and ellipse.

Configuration File

The config file used to implement this experiment now needs to make reference to the PublicGoodsScripted.java file used here. Thus the config file to run a four-player version of this game, with some treatment variation, is the following:

Experiment Files

To run this experiment on your own, place the PublicGoodsScripted.java and PublicGoodsScripted.csv files next to the Test.jar, Control.jar and Client.jar files, and load the following configuration file. PublicGoodsScripted.java (to download, click "Original Format" at bottom of page) PublicGoodsScripted.csv (to download, click "Original Format" at bottom of page)

Steps to run a test one a single computer:

  1. Open Test.jar
  2. Select 2 subjects (Three windows should open, two client windows and a Control window. The Control window should show subjects (1) and (2) connecting.)
  3. Click "Load Period Config", and select PublicGoodsScripted.csv
  4. Click "Start Period"