org.ggp.base.apps.utilities.SimpleGameSim 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.utilities;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.ggp.base.server.GameServer;
import org.ggp.base.server.event.ServerCompletedMatchEvent;
import org.ggp.base.server.event.ServerNewGameStateEvent;
import org.ggp.base.server.event.ServerNewMovesEvent;
import org.ggp.base.util.crypto.BaseCryptography.EncodedKeyPair;
import org.ggp.base.util.crypto.SignableJSON;
import org.ggp.base.util.files.FileUtils;
import org.ggp.base.util.game.Game;
import org.ggp.base.util.game.GameRepository;
import org.ggp.base.util.gdl.grammar.GdlSentence;
import org.ggp.base.util.match.Match;
import org.ggp.base.util.observer.Event;
import org.ggp.base.util.observer.Observer;
import org.ggp.base.util.statemachine.MachineState;
import org.ggp.base.util.statemachine.Role;
import external.JSON.JSONException;
import external.JSON.JSONObject;
/**
* SimpleGameSim is a utility program that lets you simulate play through a
* given game, and see which propositions become true/false in each state as
* the game is played. This can be used to understand how a game runs, or to
* debug issues in the state machine implementation.
*
* It can also hide the step counter / control proposition, though this is
* done in a very naive way, by just looking for (step ?x) and (control ?x)
* propositions. None the less, it's still useful to have.
*
* @author Sam Schreiber
*/
public class SimpleGameSim {
public static final boolean hideStepCounter = true;
public static final boolean hideControlProposition = true;
public static final boolean showCurrentState = false;
public static void main(String[] args) throws InterruptedException {
final Game theGame = GameRepository.getDefaultRepository().getGame("nineBoardTicTacToe");
final Match theMatch = new Match("simpleGameSim." + Match.getRandomString(5), -1, 0, 0, theGame, "");
try {
// Load a sample set of cryptographic keys. These sample keys are not secure,
// since they're checked into the public GGP Base SVN repository. They are provided
// merely to illustrate how the crypto key API in Match works. If you want to prove
// that you ran a match, you need to generate your own pair of cryptographic keys,
// keep them secure and hidden, and pass them to "setCryptographicKeys" in Match.
// The match will then be signed using those keys. Do not use the sample keys if you
// want to actually prove anything.
theMatch.setCryptographicKeys(new EncodedKeyPair(FileUtils.readFileAsString(new File("src/main/resources/org/ggp/base/apps/utilities/SampleKeys.json"))));
} catch (JSONException e) {
System.err.println("Could not load sample cryptograhic keys: " + e);
}
// Set up fake players to pretend to play the game
List fakeHosts = new ArrayList();
List fakePorts = new ArrayList();
for (int i = 0; i < Role.computeRoles(theGame.getRules()).size(); i++) {
fakeHosts.add("SamplePlayer" + i);
fakePorts.add(9147+i);
}
// Set up a game server to play through the game, with all players playing randomly.
final GameServer theServer = new GameServer(theMatch, fakeHosts, fakePorts);
for (int i = 0; i < fakeHosts.size(); i++) {
theServer.makePlayerPlayRandomly(i);
}
// TODO: Allow a custom state machine to be plugged into the GameServer so that we can
// simulate games using this tool with custom state machines, to verify they're sane.
final Set oldContents = new HashSet();
final int[] nState = new int[1];
theServer.addObserver(new Observer() {
@Override
public void observe(Event event) {
if (event instanceof ServerNewGameStateEvent) {
MachineState theCurrentState = ((ServerNewGameStateEvent)event).getState();
if(nState[0] > 0) System.out.print("State[" + nState[0] + "]: ");
Set newContents = theCurrentState.getContents();
for(GdlSentence newSentence : newContents) {
if(hideStepCounter && newSentence.toString().contains("step")) continue;
if(hideControlProposition && newSentence.toString().contains("control")) continue;
if(!oldContents.contains(newSentence)) {
System.out.print("+" + newSentence + ", ");
}
}
for(GdlSentence oldSentence : oldContents) {
if(hideStepCounter && oldSentence.toString().contains("step")) continue;
if(hideControlProposition && oldSentence.toString().contains("control")) continue;
if(!newContents.contains(oldSentence)) {
System.out.print("-" + oldSentence + ", ");
}
}
System.out.println();
oldContents.clear();
oldContents.addAll(newContents);
if(showCurrentState) System.out.println("State[" + nState[0] + "] Full: " + theCurrentState);
nState[0]++;
} else if (event instanceof ServerNewMovesEvent) {
System.out.println("Move taken: " + ((ServerNewMovesEvent)event).getMoves());
} else if (event instanceof ServerCompletedMatchEvent) {
System.out.println("State[" + nState[0] + "] Full (Terminal): " + oldContents);
System.out.println("Match information: " + theMatch);
System.out.println("Goals: " + ((ServerCompletedMatchEvent)event).getGoals());
try {
System.out.println("Match information cryptographically signed? " + SignableJSON.isSignedJSON(new JSONObject(theMatch.toJSON())));
System.out.println("Match information cryptographic signature valid? " + SignableJSON.verifySignedJSON(new JSONObject(theMatch.toJSON())));
} catch (JSONException je) {
je.printStackTrace();
}
System.out.println("Game over.");
}
}
});
theServer.start();
theServer.join();
}
}