JSON Game States
There are three key GameInterface methods related to the generation of JSON GameStates, namely
- getInitialGameStateJSON()
- getMidGameStateJSON(String jsonSafeMove, String jsonSafeStderrArray, int player)
- getFinalGameStateJSON()
As you might expect, getInitialGameStateJSON() is called once before the game has begun. getMidGameStateJSON(...) is called after each valid move is performed. And getFinalGameStateJSON() is called once after the game has ended.
The following section attempts to formally define these game states and how they are handled by the Test Arena.
Components of a GameState
Each game state whether, initial, mid, or final, may have the following top level properties.
"{ "messageType":"initialGameState"|"midGameState"|"finalGameState", "gameData": { // Arbitrary game specific object }, "debugData": { // Arbitrary game specific object } "animatableEvents":[ // Array of arbitrary game specific objects. ], "enableHumanInput": truthy|falsy, }"
"messageType" : "initialGameState"|"midGameState"|"finalGameState"
-
Tells the built in testArena.js file how to interpret your message
-
initialGameState: Receipt of a GameState with this special messageType triggers the test arena to reset itself and prepare to animate a new game, to do so the following actions are performed.
-
Transition to the gameStarted page state.
-
-
midGameState: Indicates that the game is still in progress. The following actions are performed.
Continue requesting more GameStates from the server
-
finalGameState: Receipt of a GameState with the "finalGameState" messageType informs the Test Arena that the game is ending. The following actions are performed.
Transition to gameFinished page state.
"enableHumanInput" : truthy|falsy
-
If falsey (including undefined or not present), the Test Arena javascript will do nothing.
-
If truthy, you're indicating to the Test Arena javascript that the human player is up next. In response the Test Arena performs the following actions in order.
-
The humanInputElements div is then displayed to the user. And the application waits for their input.
-
After sending the move out to the GameManager the contents of the humanInputElements div are cleared, and the Test Arena continues to wait for new GameStates from your java Game class.
passGameStateToGame()
Upon receipt of every JSON GameState, regardless of its messageType and value for enableHumanInput, this private Test Arena function is called to sequence the processing of the game specific information by your GAME object. Your GAME methods will be called in the following order. See the definitions of these methods for more details.
Below you'll find some psuedocode to emphazise the order and sceduling of the calls to your GAME methods.
This was actually implemented using the aysnc node module. Which makes running javascript functions in series or parallel very easy and is exportable as a single javascript file for use in client side javascript.
function passGameStateToGame() { GAME.processGameData(messageType, gameData, function() { GAME.processDebugData(messageType, debugData, function() { foreach (animatableEvent in animatableEvents) { GAME.processAnimatableEvent(animatableEvent, function() { // Move to next iteration of this loop }); } }); }); }
JSON Game State Examples
The following section has some actual game states used by the save the island game.
InitialGameState
"{ "messageType":"initialGamestate", "enableHumanInput":false, "gameData":{"player1Tiles":[3,4,3,4,4], "player2Tiles":[1,4,1,2,3], "turnDescription":"The game has started"} }"
MidGameState
"{ "messageType":"midGamestate", "enableHumanInput":false, "animatableEvents":[ { "event":"move", "data": { "player":"player1", "endPosition":4, "startPosition":0 } } ], "gameData": { "player1Tiles":[3,4,3,4,4], "player2Tiles":[1,4,1,2,3], "turnDescription":"Player 1 moves forward 4 spaces." }, "debugData": { "board":"1;34344;000010000000002", "stderr":["Player 1: \"1;34344;100000000000002\""], "stdout":"Player 1: \"move;4\"" } }"
FinalGameState
"{ "messageType":"finalGamestate", "enableHumanInput":false, "gameData":{ "player1Tiles":[3,2,3,3,3], "player2Tiles":[3,3,2,3,2], "turnDescription":"Player 2 has won the game." } }"