'use strict';
/* This file will be used by server for online game, and by app for local game
Therfore it should not have any dependency on any of those environments.
It is a state machine that follows the game steps
It receives a dataStore to get and share data but doesn't care what is
behind (socket.io comm for online, direct call to vuex store for local)
Is gives an interface in order to receive notifications
Receiving interface :
- dataStore : provides methods :
- .load() : to get saved game data
- .save(data) : to store game data and propagate (returns true if it succeeded, false otherwise)
- .getHeroesJson() : to get JSON file with all heroes cards described
Provides interface :
- duelControllerProxy : provides methods :
- endTurn(data) : notifies the controller that players ended current turn with attached data */
import { initHeroesFromJson } from './heroesHelper';
import gameStates from './gameStates/gameStates';
let DuelController = function(dataStore) {
let gameData = {
game: {},
bluePlayer: {},
redPlayer: {}
};
let allHeroes = null;
/** ***** STATE MACHINE internal methods ***** */
// Holds current running state
let currentGameState = null;
// Set new current State
let setCurrentState = stateName => {
currentGameState = states[stateName];
gameData.game.gameState = stateName;
console.log('Set new state : ', stateName);
};
// get new State
let getCurrentState = () => {
return currentGameState;
};
// Start the current state
let startCurrentState = (payload = null) => {
currentGameState.start(payload);
};
// Update the current state
let updateCurrentState = (payload = null) => {
currentGameState.update(payload);
};
// End the current state
let endCurrentState = (payload = null) => {
currentGameState.end(payload);
};
let getGameData = () => gameData;
// Interface to set data and store it
let storeData = (data = null) => {
if (data) {
setData(data);
}
return dataStore.save(gameData);
};
// Interface to set data only
let setData = data => {
gameData = data;
};
// Interface to load data
let loadData = () => {
gameData = dataStore.load();
};
// Interface to get set of all heroes
let getAllHeroes = () => {
if (!allHeroes) {
allHeroes = initHeroesFromJson(dataStore.getHeroesJson());
}
return allHeroes;
};
// Pass those state machine methods to each state
let stateCtrl = {
setCurrentState,
getCurrentState,
startCurrentState,
updateCurrentState,
endCurrentState,
storeData,
setData,
getGameData,
loadData,
getAllHeroes
};
// declare all states
// First state to be set after public APIs (start or resume game) are called
let states = {
'0_INIT': new gameStates.initState(stateCtrl),
'1_SELECT_FACTION': new gameStates.selectFactionState(stateCtrl),
'1_SELECT_DRAFT': new gameStates.selectDraftState(stateCtrl),
'1_SELECT_TOURNAMENT': new gameStates.selectTournamentState(stateCtrl),
'2_CHANGE_UP_TO_3_CARDS': new gameStates.changeUpTo3Cards(stateCtrl)
};
/** ***** Following are public methods ***** */
// Method to create and start a new game (both players are there)
let startNewGame = function(player1Name, player2Name, gameOptions) {
// 1st state is init
setCurrentState('0_INIT');
//Start it
startCurrentState({
player1Name,
player2Name,
gameOptions
});
};
// Method to resume existing game, gameData is passed already
let resumeGame = function(data) {
gameData = data;
// Just set state per data in DB
// This state will wait for update
setCurrentState(gameData.game.gameState);
};
// Provide an interface so that players can notify the DuelController
let DuelControllerProxy = () => {
return {
endTurn: data => {
console.log('data from player :>> ', data);
currentGameState.update(data);
}
};
};
// Return public methods
return {
startNewGame,
resumeGame,
duelControllerProxy: new DuelControllerProxy()
};
};
export default DuelController;