Added timer expiration end game scenario, cron job for clearing stale games

This commit is contained in:
Alec Maier
2019-09-02 20:44:06 -04:00
parent 2a2691bc91
commit 1eae5f63f6
7 changed files with 67 additions and 19 deletions

View File

@@ -27,6 +27,7 @@
<div id="card-select-header">
<button id="reset-btn" class="app-btn">Reset Deck</button>
<h3 id="game-size">0 Players</h3>
<p id="size-error"></p>
</div>
<div id="card-select">

21
package-lock.json generated
View File

@@ -126,6 +126,14 @@
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
},
"cron": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/cron/-/cron-1.7.1.tgz",
"integrity": "sha512-gmMB/pJcqUVs/NklR1sCGlNYM7TizEw+1gebz20BMc/8bTm/r7QUp3ZPSPlG8Z5XRlvb7qhjEjq/+bdIfUCL2A==",
"requires": {
"moment-timezone": "^0.5.x"
}
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -379,6 +387,19 @@
"mime-db": "1.40.0"
}
},
"moment": {
"version": "2.24.0",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
"integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
},
"moment-timezone": {
"version": "0.5.26",
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.26.tgz",
"integrity": "sha512-sFP4cgEKTCymBBKgoxZjYzlSovC20Y6J7y3nanDc5RoBIXKlZhoYwBoZGe3flwU6A372AcRwScH8KiwV6zjy1g==",
"requires": {
"moment": ">= 2.9.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",

View File

@@ -9,6 +9,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"cron": "^1.7.1",
"express": "^4.17.1",
"socket.io": "^2.2.0"
}

View File

@@ -6,8 +6,18 @@ const app = express();
const server = http.Server(app);
const io = socketIO(server);
// cron job for periodically clearing finished games
const CronJob = require('cron').CronJob;
var activeGames = {};
const job = new CronJob('* * 2 * * *', function() {
activeGames = activeGames.filter((game) => game.state !== "ended");
console.log("Games pruned at: " + (new Date()).toDateString());
});
console.log("cron job created");
job.start();
app.set('port', 5000);
app.use('/static', express.static(__dirname + '/static')); // Routing
app.use('/assets', express.static(__dirname + '/assets')); // Routing
@@ -32,16 +42,6 @@ server.listen(process.env.PORT || 5000, function() {
console.log('Starting server on port 5000');
});
function didVillageWin(game) {
let liveCount = 0;
for (const player of game.players) {
if (player.card.role === "Werewolf" && !player.dead) {
return false;
}
}
return true;
}
function teamWon(game) {
let wolvesAlive = 0;
let villagersAlive = 0;
@@ -124,6 +124,12 @@ io.on('connection', function(socket) {
game.endTime = newDate.toJSON();
io.to(code).emit('state', game);
});
socket.on("timerExpired", function(code) {
let game = activeGames[Object.keys(activeGames).find((key) => key === code)];
game.winningTeam = "wolf";
game.state = "ended";
io.to(code).emit('state', game);
});
socket.on('killPlayer', function(id, code) {
let game = activeGames[Object.keys(activeGames).find((key) => key === code)];
let player = game.players.find((player) => player.id === id);

View File

@@ -187,8 +187,7 @@ function renderClock() {
clearInterval(clock);
}
if (delta <= 0) {
clearInterval(clock);
endGame(true);
endGameDueToTimeExpired();
} else {
let minutes = Math.floor((delta % (1000 * 60 * 60)) / (1000 * 60));
let seconds = Math.floor((delta % (1000 * 60)) / 1000);
@@ -198,9 +197,10 @@ function renderClock() {
}, 1000);
}
function endGame(timeExpired) {
if (timeExpired) {
}
function endGameDueToTimeExpired() {
clearInterval(clock);
console.log("expired!");
socket.emit("timerExpired", currentGame.accessCode);
}
function killPlayer() {

View File

@@ -30,7 +30,7 @@ class Game {
var fullDeck = [];
var gameSize = 0;
var time = null;
var atLeastOnePlayer = false;
// register event listeners on buttons
@@ -66,6 +66,12 @@ function updateGameSize() {
gameSize += card.quantity;
}
document.getElementById("game-size").innerText = gameSize + " Players";
if (gameSize > 0) {
atLeastOnePlayer = true;
} else {
atLeastOnePlayer = false;
}
return gameSize;
}
function resetCardQuantities() {
@@ -91,7 +97,7 @@ function buildDeckFromQuantities() {
}
function createGame() {
if (document.getElementById("name").value.length > 0) {
if (document.getElementById("name").value.length > 0 && atLeastOnePlayer) {
// generate 6 digit access code
let code = "";
let charPool = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
@@ -120,6 +126,13 @@ function createGame() {
window.location.replace('/' + code);
});
} else {
if (!atLeastOnePlayer) {
document.getElementById("game-size").classList.add("error");
document.getElementById("size-error").innerText = "Add at least one card";
} else {
document.getElementById("game-size").classList.remove("error");
document.getElementById("size-error").innerText = "";
}
document.getElementById("name").classList.add("error");
document.getElementById("name-error").innerText = "Name is required.";
}

View File

@@ -127,7 +127,7 @@ button {
background-color: rgba(189, 42, 42, 0.1) !important;
}
#join-error, #name-error {
#join-error, #name-error, #size-error {
color: #bd2a2a;
font-size: 0.9em;
height: 2em;
@@ -256,6 +256,12 @@ button {
margin: 3em 1em;
}
#game-size {
border-radius: 5px;
padding: 0.3em 0.5em;
margin-right: 0.5em !important;
}
#create-game-container, #lobby-container, #join-game-container, #game-container, #launch, #message-box {
animation: fadein 0.8s ease-in;
}
@@ -470,7 +476,7 @@ label {
.killed-btn {
border-radius: 5px;
width: 13em;
font-size: 1.2em;
font-size: 1em;
margin: 0
}