webclient/js/Games.js

110 lines
2.7 KiB
JavaScript

import Flower from Hanafuda;
import Messaging;
import player from Room;
import Save;
import Session;
import Table;
import Time;
var states = Table.make(function(o) {return 0;});
var metadata = Table.make(function(o) {return o.value.date;});
reload();
initMessageHandlers();
return {
metadata: metadata,
proposal: proposal,
reload: reload
};
function initMessageHandlers() {
Messaging.addEventListener(["Game"], function(o) {
var gameID = o.state.public.coordinates.gameID;
pushState(gameID, o.state);
metadata.insert(gameID, getMetadata(o.state));
metadata.save('games.metadata');
});
Messaging.addEventListener(["LogIn"], function(o) {
var gamesAgainst = states.getAll(
function(game) {return isAgainst(game.value, o.from);}
);
gamesAgainst.forEach(function(game) {
Messaging.send({
tag: "Sync",
latestKnown: game.value.latest.public.coordinates,
to: o.from
});
});
});
Messaging.addEventListener(["Relay", "Sync"], function(o) {
var gameID = o.message.latestKnown.gameID;
var state = states.get(gameID);
if(state != undefined) {
switch(compare(state.latest.public.coordinates, o.message.latestKnown)) {
case -1: Messaging.send({tag: "Yield", onGameID: gameID, to: o.from});
case 1: Messaging.send({tag: "Share", gameSave: state.latest});
}
}
});
Messaging.addEventListener(["Relay", "Yield"], function(o) {
var gameID = o.message.onGameID;
var state = states.get(gameID);
if(state != undefined && isAgainst(state, o.from)) {
Messaging.send({tag: "Share", gameSave: state.latest});
}
});
}
function isAgainst(state, playerID) {
return state.latest.public.nextPlayer[Session.getKey()] == playerID;
}
function compare(gameCoordinatesA, gameCoordinatesB) {
var monthIndexA = Flower[gameCoordinatesA.month];
var monthIndexB = Flower[gameCoordinatesB.month];
if(monthIndexA < monthIndexB) {
return -1;
} else if(monthIndexA > monthIndexB) {
return 1;
} else if(gameCoordinatesA.turn < gameCoordinatesB.turn) {
return -1;
} else if(gameCoordinatesA.turn > gameCoordinatesB.turn) {
return 1;
} else {
return 0;
}
}
function getMetadata(state) {
var sessionKey = Session.getKey();
return Time.timestamp({
vs: player(state.public.nextPlayer[sessionKey]),
yourTurn: state.public.playing == sessionKey
});
}
function proposal(playerID, yourTurn) {
metadata.insert(
playerID,
Time.timestamp({vs: player(playerID), yourTurn: yourTurn})
);
}
function pushState(gameID, newState) {
if(states.get(gameID) == undefined) {
states.insert(gameID, {});
}
var state = states.get(gameID);
state.former = state.latest;
state.latest = newState;
states.save('games.state');
}
function reload() {
states.load('games.state');
metadata.load('games.metadata');
}