package io.vivarium.graphing;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Map;
import java.util.Set;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.axis.LogAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import io.vivarium.audit.ActionFrequencyBlueprint;
import io.vivarium.audit.ActionFrequencyRecord;
import io.vivarium.audit.AuditBlueprint;
import io.vivarium.core.Action;
import io.vivarium.core.GridWorldBlueprint;
import io.vivarium.core.GridWorld;
import io.vivarium.graphing.util.Utils;
public class GenerationalActionGraph extends BaseGraph
{
public GenerationalActionGraph(ActionFrequencyRecord record)
{
boolean includeMales = true;
boolean includeFemales = false;
boolean includeNonPregnant = true;
boolean includePregnant = true;
int maximumGeneration = record.getMaximumGeneration();
Collection<Action> commonActions = Arrays.asList(Action.REST, Action.TURN_LEFT, Action.TURN_RIGHT, Action.MOVE,
Action.EAT, Action.BREED);
Set<Action> failableActions = EnumSet.of(Action.MOVE, Action.BREED, Action.EAT);
XYSeriesCollection dataset = new XYSeriesCollection();
Map<Action, XYSeries> successfulActionSeries = new EnumMap<>(Action.class);
Map<Action, XYSeries> failedActionSeries = new EnumMap<>(Action.class);
for (Action action : commonActions)
{
if (failableActions.contains(action))
{
XYSeries successSeries = new XYSeries(action.toString() + "_SUCCESS");
dataset.addSeries(successSeries);
successfulActionSeries.put(action, successSeries);
XYSeries failSeries = new XYSeries(action.toString() + "_FAIL");
dataset.addSeries(failSeries);
failedActionSeries.put(action, failSeries);
}
else
{
XYSeries successSeries = new XYSeries(action.toString());
dataset.addSeries(successSeries);
successfulActionSeries.put(action, successSeries);
}
}
for (int generation = 1; generation <= maximumGeneration; generation++)
{
double totalActionCount = 0;
Map<Action, Double> successfulActionCounts = new EnumMap<>(Action.class);
Map<Action, Double> failedActionCounts = new EnumMap<>(Action.class);
for (Action action : commonActions)
{
successfulActionCounts.put(action, 0.0);
failedActionCounts.put(action, 0.0);
if (includeMales)
{
if (includeNonPregnant)
{
successfulActionCounts.put(action, successfulActionCounts.get(action)
+ record.getRecord(generation, false, false, action, true));
if (failableActions.contains(action))
{
failedActionCounts.put(action, failedActionCounts.get(action)
+ record.getRecord(generation, false, false, action, false));
}
}
}
if (includeFemales)
{
if (includeNonPregnant)
{
successfulActionCounts.put(action, successfulActionCounts.get(action)
+ record.getRecord(generation, true, false, action, true));
if (failableActions.contains(action))
{
failedActionCounts.put(action, failedActionCounts.get(action)
+ record.getRecord(generation, true, false, action, false));
}
}
if (includePregnant)
{
successfulActionCounts.put(action, successfulActionCounts.get(action)
+ record.getRecord(generation, true, true, action, true));
if (failableActions.contains(action))
{
failedActionCounts.put(action, failedActionCounts.get(action)
+ record.getRecord(generation, true, true, action, false));
}
}
}
totalActionCount += successfulActionCounts.get(action);
totalActionCount += failedActionCounts.get(action);
}
for (Action action : commonActions)
{
successfulActionSeries.get(action).add(generation,
successfulActionCounts.get(action) / totalActionCount);
if (failableActions.contains(action))
{
failedActionSeries.get(action).add(generation, failedActionCounts.get(action) / totalActionCount);
}
}
}
PlotOrientation orientation = PlotOrientation.VERTICAL;
boolean urls = false;
boolean tooltips = false;
boolean legend = true;
_chart = ChartFactory.createXYLineChart("Creature Actions by Generation", "Generation", "Action Percent",
dataset, orientation, legend, tooltips, urls);
LogAxis yAxis = new LogAxis("Y");
yAxis.setRange(0.001, 1);
((XYPlot) _chart.getPlot()).setRangeAxis(yAxis);
// ((XYPlot) _chart.getPlot()).getRangeAxis().setRange(0, 1);
Utils.setChartToDefaultFont(_chart);
}
public static void main(String[] args) throws IOException
{
GridWorldBlueprint b = GridWorldBlueprint.makeDefault();
ArrayList<AuditBlueprint> auditBlueprints = new ArrayList<>();
ActionFrequencyBlueprint actionFrequencies = new ActionFrequencyBlueprint();
auditBlueprints.add(actionFrequencies);
b.setAuditBlueprints(auditBlueprints);
GridWorld w = new GridWorld(b);
for (int i = 0; i < 10_000; i++)
{
w.tick();
}
BaseGraph graph = new GenerationalActionGraph((ActionFrequencyRecord) w.getAuditRecords().get(0));
JFrame frame = new JFrame();
frame.add(graph.getPanel());
frame.setSize(1200, 800);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
graph.saveImage("/tmp/graph.png", "png", 800, 800);
}
}