Detection of end-game scenarios, end games with splash screen listing winning team and who wolves were.

This commit is contained in:
Alec Maier
2019-09-02 19:47:06 -04:00
parent e7c27a5293
commit 2a2691bc91
8 changed files with 258 additions and 49 deletions

View File

@@ -14,7 +14,10 @@
<form>
<label>
Name
<span>
<input id="name" type="text"/>
<p id="name-error"></p>
</span>
</label>
<label>
Time (Minutes, Optional)

View File

@@ -12,6 +12,7 @@
<div id="message-box"></div>
<div id="lobby-container"></div>
<div id="game-container"></div>
<div id="end-container"></div>
<div id="launch"></div>
</div>
<script type="module" src="/static/game.js"></script>

View File

@@ -14,11 +14,17 @@
<form>
<label>
Name
<input id="name" type="text"/>
<span>
<input id="name" type="text"/>
<p id="name-error"></p>
</span>
</label>
<label>
Access Code
<input id="code" type="text"/>
<span>
<input id="code" type="text"/>
<p id="join-error"></p>
</span>
</label>
</form>
<a href="/">

View File

@@ -32,24 +32,69 @@ 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;
let hunterAlive = false;
for (const player of game.players) {
if (player.card.team === "village" && !player.dead) {
villagersAlive++;
}
if (player.card.team === "wolf" && !player.dead) {
wolvesAlive++;
}
if (player.card.role === "Hunter" && !player.dead) {
hunterAlive = true;
}
}
console.log("wolves: " + wolvesAlive + " villagers: " + villagersAlive);
if ((wolvesAlive === villagersAlive) && (wolvesAlive + villagersAlive !== 2)) {
return "wolf";
}
if (wolvesAlive === 0) {
return "village"
}
if (wolvesAlive + villagersAlive === 2) {
return hunterAlive ? "village" : "wolf"
}
return false;
}
// Add the WebSocket handlers
io.on('connection', function(socket) {
socket.on('newGame', function(game, onSucess) {
socket.on('newGame', function(game, onSuccess) {
activeGames[game.accessCode] = game;
onSucess();
onSuccess();
});
socket.on('joinGame', function(playerInfo) {
activeGames[Object.keys(activeGames).find((key) => key === playerInfo.code)].players.push({name: playerInfo.name, id: playerInfo.id});
const game = activeGames[Object.keys(activeGames).find((key) => key === playerInfo.code)];
if (game && game.players.length < game.size) {
activeGames[Object.keys(activeGames).find((key) => key === playerInfo.code)].players.push({name: playerInfo.name, id: playerInfo.id});
socket.emit('success');
} else {
if (game && game.players.length === game.size) {
socket.emit("joinError", "This game is full - sorry!")
} else {
socket.emit("joinError", "No game found");
}
}
});
socket.on('requestState', function(data) {
if(Object.keys(socket.rooms).includes(data.code) === false) {
console.log("new socket");
socket.join(data.code, function() {
console.log("request for state");
io.to(data.code).emit('state', activeGames[Object.keys(activeGames).find((key) => key === data.code)]);
});
} else {
console.log("old socket");
io.to(data.code).emit('state', activeGames[Object.keys(activeGames).find((key) => key === data.code)]);
}
});
@@ -84,7 +129,18 @@ io.on('connection', function(socket) {
let player = game.players.find((player) => player.id === id);
game.players.find((player) => player.id === id).dead = true;
game.message = player.name + ", a " + player.card.role + ", has been killed!";
io.to(code).emit('state', game);
const winCheck = teamWon(game);
if (winCheck === "wolf") {
game.winningTeam = "wolf";
game.state = "ended";
io.to(code).emit('state', game);
} else if (winCheck === "village") {
game.winningTeam = "village";
game.state = "ended";
io.to(code).emit('state', game);
} else {
io.to(code).emit('state', game);
}
});
});

View File

@@ -12,7 +12,6 @@ socket.on('state', function(game) {
if (game.message) {
document.getElementById("message-box").innerText = game.message;
}
console.log(currentGame);
buildGameBasedOnState();
});
@@ -24,6 +23,9 @@ function buildGameBasedOnState() {
case "started":
renderGame();
break;
case "ended":
renderEndSplash();
break;
default:
break;
}
@@ -54,6 +56,26 @@ function getLiveCount() {
return liveCount;
}
function renderEndSplash() {
document.getElementById("game-container").classList.add("hidden");
document.getElementById("message-box").classList.add("hidden");
currentGame.winningTeam === "village"
? document.getElementById("end-container").innerHTML ="<div class='winner-header'><p class='winner-village'>Village</p> wins!</div>"
: document.getElementById("end-container").innerHTML ="<div class='winner-header'><p class='winner-wolf'>Wolves</p>win!</div>";
const wolfContainer = document.createElement("div");
wolfContainer.setAttribute("id", "wolves");
let wolfContent = "<div class='evil-header'><span>The</span><p class='evil-subheader'>evil</p> <span>players were:</span></div>";
for (const player of currentGame.players) {
if (player.card.role === "Werewolf" || player.card.role === "Minion") {
wolfContent += "<div class='evil-list-item'>" + player.name + ": " + player.card.role + "</div>"
}
}
wolfContent += "<a href='/'><button class='app-btn'>Home</button></a>";
wolfContainer.innerHTML = wolfContent;
document.getElementById("end-container").appendChild(wolfContainer);
}
function renderGame() {
const player = currentGame.players.find((player) => player.id === sessionStorage.getItem("id"));
@@ -133,17 +155,29 @@ function pauseOrResumeGame() {
}
function getFlipState() {
console.log(cardFlippedOver);
return cardFlippedOver ? "flip-down" : "flip-up";
}
function flipCard() {
cardFlippedOver ?
document.getElementById("game-card").setAttribute("class", "flip-down")
: document.getElementById("game-card").setAttribute("class", "flip-up");
cardFlippedOver
? flipUp()
: flipDown();
cardFlippedOver = !cardFlippedOver;
}
function flipUp(){
const card = document.getElementById("game-card");
card.classList.add("flip-up");
card.classList.remove("flip-down");
}
function flipDown(){
const card = document.getElementById("game-card");
card.classList.add("flip-down");
card.classList.remove("flip-up");
}
function renderClock() {
clock = setInterval(function() {
const start = currentGame.paused ? new Date(currentGame.pauseTime) : new Date();
@@ -166,7 +200,6 @@ function renderClock() {
function endGame(timeExpired) {
if (timeExpired) {
console.log("expired");
}
}

View File

@@ -1,12 +1,40 @@
const socket = io();
import { utility } from './util.js'
document.getElementById("join-btn").addEventListener("click", function() {
sessionStorage.setItem("code", document.getElementById("code").value);
let playerId = utility.generateID();
sessionStorage.setItem("id", playerId);
const playerInfo = {name: document.getElementById("name").value, id: playerId, code: document.getElementById("code").value};
socket.emit('joinGame', playerInfo);
// respond to the game state received from the server
socket.on('joinError', function(message) {
document.getElementById("code").classList.add("error");
document.getElementById("join-error").innerText = message;
});
// respond to the game state received from the server
socket.on('success', function() {
if (document.getElementById("code").classList.contains("error")) {
document.getElementById("code").classList.remove("error");
document.getElementById("join-error").innerText = "";
}
// If a player was a host of a previous game, don't make them the host of this one
if (sessionStorage.getItem("host")) {
sessionStorage.removeItem("host");
}
window.location.replace('/' + document.getElementById("code").value);
});
document.getElementById("join-btn").addEventListener("click", function() {
if (document.getElementById("name").value.length > 0) {
if (document.getElementById("name").classList.contains("error")) {
document.getElementById("name").classList.remove("error");
document.getElementById("name-error").innerText = "";
}
sessionStorage.setItem("code", document.getElementById("code").value);
let playerId = utility.generateID();
sessionStorage.setItem("id", playerId);
const playerInfo = {name: document.getElementById("name").value, id: playerId, code: document.getElementById("code").value};
socket.emit('joinGame', playerInfo);
} else {
document.getElementById("name").classList.add("error");
document.getElementById("name-error").innerText = "Name is required.";
}
});

View File

@@ -52,7 +52,6 @@ window.onload = function() {
if(!newCard.powerRole || (newCard.powerRole && newCard.quantity === 0)) {
newCard.quantity += 1;
}
console.log(newCard);
cardContainer.getElementsByClassName("card-quantity")[0].innerHTML = newCard.quantity;
updateGameSize();
});
@@ -92,32 +91,36 @@ function buildDeckFromQuantities() {
}
function createGame() {
// generate 6 digit access code
let code = "";
let charPool = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
for (let i = 0; i < 6; i++) {
code += charPool[utility.getRandomInt(61)]
if (document.getElementById("name").value.length > 0) {
// generate 6 digit access code
let code = "";
let charPool = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
for (let i = 0; i < 6; i++) {
code += charPool[utility.getRandomInt(61)]
}
// generate unique player Id for session
let id = utility.generateID();
sessionStorage.setItem("id", id);
// player who creates the game is the host
sessionStorage.setItem("host", true);
// send a new game to the server, and then join it
const playerInfo = {name: document.getElementById("name").value, code: code, id: id};
const game = new Game(
code,
gameSize,
buildDeckFromQuantities(),
document.getElementById("time").value
);
socket.emit('newGame', game, function(data) {
socket.emit('joinGame', playerInfo);
sessionStorage.setItem('code', code);
window.location.replace('/' + code);
});
} else {
document.getElementById("name").classList.add("error");
document.getElementById("name-error").innerText = "Name is required.";
}
// generate unique player Id for session
let id = utility.generateID();
sessionStorage.setItem("id", id);
// player who creates the game is the host
sessionStorage.setItem("host", true);
// send a new game to the server, and then join it
const playerInfo = {name: document.getElementById("name").value, code: code, id: id};
const game = new Game(
code,
gameSize,
buildDeckFromQuantities(),
document.getElementById("time").value
);
socket.emit('newGame', game, function(data) {
console.log(data);
socket.emit('joinGame', playerInfo);
sessionStorage.setItem('code', code);
window.location.replace('/' + code);
});
}

View File

@@ -122,6 +122,33 @@ button {
font-family: 'sitewide-sans-serif', sans-serif;
}
.error {
border: 1px solid #bd2a2a !important;
background-color: rgba(189, 42, 42, 0.1) !important;
}
#join-error, #name-error {
color: #bd2a2a;
font-size: 0.9em;
height: 2em;
margin: 0;
font-weight: bold;
}
#join-game-container span {
display: flex;
flex-direction: column;
}
#join-game-container form {
margin-bottom: 2em;
}
#join-game-container input[type=text], #create-game-container input[type=text] {
margin-right: 0.5em;
margin-bottom: 0;
}
.app-btn {
background-color: #f8f8f8;
color: #bd2a2a;
@@ -245,6 +272,7 @@ input[type=text] {
margin: 0.5em 0 1em 0;
color: gray;
padding: 0.7em;
height: 1.2em;
width: 9em;
border-radius: 5px;
font-size: 1.1em;
@@ -258,6 +286,7 @@ input[type=number] {
margin: 0.5em 0 1em 0;
color: gray;
padding: 0.7em;
height: 1.2em;
width: 4em;
font-size: 1.1em;
}
@@ -486,3 +515,53 @@ label {
opacity: 0.4;
transform: scale(0.90);
}
/* end splash */
#end-container {
margin: 0 auto;
display: inline-block;
text-align: left;
}
#end-container .winner-header {
display: flex;
align-items: center;
margin: 0;
font-size: 30px;
}
#end-container .evil-subheader {
font-family: 'diavlo', sans-serif;
color: #7d0b0b;
margin: 0 0.3em;
font-size: 1.5em;
}
#end-container .evil-header {
display: flex;
align-items: center;
font-size: 20px;
margin-bottom: 2em;
}
#end-container p {
font-weight: bold;
margin-right: 0.3em;
font-size: 50px;
}
#end-container button {
margin-top: 3em;
}
#end-container .winner-village {
font-family: 'diavlo', sans-serif;
color: #171469;
}
#end-container .winner-wolf {
font-family: 'diavlo', sans-serif;
color: #7d0b0b;
}