mirror of
https://github.com/AlecM33/Werewolf.git
synced 2025-12-26 15:57:50 +01:00
Added modal for role descriptions, learning page, fixed cron job
This commit is contained in:
28
server.js
28
server.js
@@ -6,28 +6,45 @@ const app = express();
|
|||||||
const server = http.Server(app);
|
const server = http.Server(app);
|
||||||
const io = socketIO(server);
|
const io = socketIO(server);
|
||||||
|
|
||||||
// cron job for periodically clearing finished games
|
|
||||||
const CronJob = require('cron').CronJob;
|
const CronJob = require('cron').CronJob;
|
||||||
|
|
||||||
var activeGames = {};
|
var activeGames = {};
|
||||||
|
|
||||||
|
// cron job for periodically clearing finished games
|
||||||
|
const job = new CronJob('0 0 */2 * * *', function() {
|
||||||
|
console.log(activeGames);
|
||||||
|
for (const key in activeGames) {
|
||||||
|
if (activeGames.hasOwnProperty(key) && activeGames[key].state === "ended") {
|
||||||
|
delete activeGames[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("Games pruned at: " + (new Date().toDateString()) + " " + (new Date()).toTimeString());
|
||||||
|
});
|
||||||
|
console.log("cron job created");
|
||||||
|
job.start();
|
||||||
|
|
||||||
app.set('port', 5000);
|
app.set('port', 5000);
|
||||||
app.use('/static', express.static(__dirname + '/static')); // Routing
|
app.use('/static', express.static(__dirname + '/static')); // Routing
|
||||||
app.use('/assets', express.static(__dirname + '/assets')); // Routing
|
app.use('/assets', express.static(__dirname + '/assets')); // Routing
|
||||||
app.get('/', function(request, response) {
|
app.get('/', function(request, response) {
|
||||||
response.sendFile(__dirname + '/index.html');
|
response.sendFile(__dirname + '/views/index.html');
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/learn', function(request, response) {
|
||||||
|
response.sendFile(__dirname + '/views/learn.html');
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/create', function(request, response) {
|
app.get('/create', function(request, response) {
|
||||||
response.sendFile(__dirname + '/create_game.html');
|
response.sendFile(__dirname + '/views/create_game.html');
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/join', function(request, response) {
|
app.get('/join', function(request, response) {
|
||||||
response.sendFile(__dirname + '/join_game.html');
|
response.sendFile(__dirname + '/views/join_game.html');
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/:code', function(request, response) {
|
app.get('/:code', function(request, response) {
|
||||||
response.sendFile(__dirname + '/game.html');
|
response.sendFile(__dirname + '/views/game.html');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Starts the server.
|
// Starts the server.
|
||||||
@@ -82,6 +99,7 @@ io.on('connection', function(socket) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// broadcast current game state to all sockets in the room with a particular access code
|
||||||
socket.on('requestState', function(data) {
|
socket.on('requestState', function(data) {
|
||||||
if(Object.keys(socket.rooms).includes(data.code) === false) {
|
if(Object.keys(socket.rooms).includes(data.code) === false) {
|
||||||
socket.join(data.code, function() {
|
socket.join(data.code, function() {
|
||||||
|
|||||||
@@ -5,28 +5,47 @@ export const cards = [
|
|||||||
description: "During the day, find the wolves and kill them.",
|
description: "During the day, find the wolves and kill them.",
|
||||||
powerRole: false
|
powerRole: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
role: "Werewolf",
|
||||||
|
team: "wolf",
|
||||||
|
description: "During the night, choose a villager to kill. Don't get killed.",
|
||||||
|
powerRole: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: "Minion",
|
||||||
|
team: "wolf",
|
||||||
|
description: "You are an evil villager - you know who the wolves are, and you want them to win.",
|
||||||
|
powerRole: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: "Wolf Cub",
|
||||||
|
team: "wolf",
|
||||||
|
description: "If a wolf dies, you then become a wolf. Until then, you do not wake up with the other wolves.",
|
||||||
|
powerRole: true
|
||||||
|
},
|
||||||
|
{
|
||||||
role: "Seer",
|
role: "Seer",
|
||||||
team: "village",
|
team: "village",
|
||||||
description: "During the night, choose one person. The moderator will tell you whether that player is evil.",
|
description: "During the night, choose one person. The moderator will tell you whether that player is a wolf.",
|
||||||
powerRole: true
|
powerRole: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: "Hunter",
|
role: "Hunter",
|
||||||
team: "village",
|
team: "village",
|
||||||
description: "If you are alive with a wolf at the end of the game, the village wins.",
|
description: "If you are alive with a wolf at the end of the game, you best the wolf, and the village wins.",
|
||||||
powerRole: true
|
powerRole: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: "Werewolf",
|
role: "Sorcerer",
|
||||||
team: "wolf",
|
team: "village",
|
||||||
description: "During the night, choose a villager to kill. Don't get killed.",
|
description: "Once a game, change who the wolves are going to kill to someone else, including yourself. You will" +
|
||||||
powerRole: false
|
" see who is going to die each night until you use this power.",
|
||||||
|
powerRole: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: "Minion",
|
role: "Prince",
|
||||||
team: "wolf",
|
team: "village",
|
||||||
description: "You are villager, but you know who the wolves are - and want them to win.",
|
description: "If you die, take someone else with you.",
|
||||||
powerRole: true
|
powerRole: true
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -199,7 +199,6 @@ function renderClock() {
|
|||||||
|
|
||||||
function endGameDueToTimeExpired() {
|
function endGameDueToTimeExpired() {
|
||||||
clearInterval(clock);
|
clearInterval(clock);
|
||||||
console.log("expired!");
|
|
||||||
socket.emit("timerExpired", currentGame.accessCode);
|
socket.emit("timerExpired", currentGame.accessCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,15 +36,25 @@ var atLeastOnePlayer = false;
|
|||||||
// register event listeners on buttons
|
// register event listeners on buttons
|
||||||
document.getElementById("reset-btn").addEventListener("click", resetCardQuantities);
|
document.getElementById("reset-btn").addEventListener("click", resetCardQuantities);
|
||||||
document.getElementById("create-btn").addEventListener("click", createGame);
|
document.getElementById("create-btn").addEventListener("click", createGame);
|
||||||
|
document.getElementById("role-btn").addEventListener("click", displayRoleModal);
|
||||||
|
document.getElementById("close").addEventListener("click", closeModal);
|
||||||
|
|
||||||
// render all of the available cards to the user
|
// render all of the available cards to the user
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
for (const card of cards) {
|
for (const card of cards) {
|
||||||
const newCard = new Card(card.role, card.team, card.description, card.powerRole);
|
const newCard = new Card(card.role, card.team, card.description, card.powerRole);
|
||||||
const cardContainer = document.createElement("div");
|
// put card info in the informational role description modal
|
||||||
|
const modalRole = document.createElement("div");
|
||||||
|
modalRole.setAttribute("class", "modal-role");
|
||||||
|
modalRole.innerHTML = card.team === "village" ?
|
||||||
|
"<h2 class='role-village'>" + card.role + "</h2><p>" + card.description + "</p>"
|
||||||
|
: "<h2 class='role-wolf'>" + card.role + "</h2><p>" + card.description + "</p>";
|
||||||
|
document.getElementById("roles").appendChild(modalRole);
|
||||||
|
|
||||||
fullDeck.push(newCard);
|
fullDeck.push(newCard);
|
||||||
|
|
||||||
|
const cardContainer = document.createElement("div");
|
||||||
|
|
||||||
cardContainer.setAttribute("class", "card");
|
cardContainer.setAttribute("class", "card");
|
||||||
cardContainer.innerHTML = "<p class='card-role'>" + newCard.role + "</p><br><p class='card-quantity'>" + newCard.quantity + "</p>";
|
cardContainer.innerHTML = "<p class='card-role'>" + newCard.role + "</p><br><p class='card-quantity'>" + newCard.quantity + "</p>";
|
||||||
|
|
||||||
@@ -84,6 +94,14 @@ function resetCardQuantities() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function displayRoleModal() {
|
||||||
|
document.getElementById("role-modal").classList.remove("hidden");
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeModal() {
|
||||||
|
document.getElementById("role-modal").classList.add("hidden");
|
||||||
|
}
|
||||||
|
|
||||||
function buildDeckFromQuantities() {
|
function buildDeckFromQuantities() {
|
||||||
let playerDeck = [];
|
let playerDeck = [];
|
||||||
for (const card of fullDeck) {
|
for (const card of fullDeck) {
|
||||||
|
|||||||
@@ -24,6 +24,30 @@
|
|||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
margin: 0 0.7em 0.7em 0;
|
margin: 0 0.7em 0.7em 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
width: 92%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-body {
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header {
|
||||||
|
padding: 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-role {
|
||||||
|
margin-right: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#learn-container {
|
||||||
|
margin: 3em 1em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(min-width: 750.01px) {
|
@media(min-width: 750.01px) {
|
||||||
@@ -52,6 +76,30 @@
|
|||||||
.app-content {
|
.app-content {
|
||||||
width: 80%;
|
width: 80%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#learn-container {
|
||||||
|
margin: 3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-body {
|
||||||
|
padding: 2em 4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
width: 92%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header {
|
||||||
|
padding: 0 3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-role {
|
||||||
|
margin-right: 3em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
@@ -221,8 +269,9 @@ button {
|
|||||||
|
|
||||||
#card-select-header {
|
#card-select-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
justify-content: center;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
#card-select-header h3 {
|
#card-select-header h3 {
|
||||||
@@ -233,6 +282,12 @@ button {
|
|||||||
|
|
||||||
#card-select-header button {
|
#card-select-header button {
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#card-select-header span {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#reset-btn {
|
#reset-btn {
|
||||||
@@ -571,3 +626,99 @@ label {
|
|||||||
font-family: 'diavlo', sans-serif;
|
font-family: 'diavlo', sans-serif;
|
||||||
color: #7d0b0b;
|
color: #7d0b0b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#learn-container h2 {
|
||||||
|
font-family: 'diavlo', sans-serif;
|
||||||
|
color: #7d0b0b;
|
||||||
|
font-size: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#learn-container button {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#roles {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-role {
|
||||||
|
width: 22em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 1;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
background-color: rgb(0,0,0);
|
||||||
|
background-color: rgba(0,0,0,0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header {
|
||||||
|
border-radius: 5px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
background-color: white;
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header h2 {
|
||||||
|
margin-top: 2em;
|
||||||
|
margin-bottom: 0;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-footer {
|
||||||
|
padding: 1em;
|
||||||
|
background-color: white;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
border-radius: 5px;
|
||||||
|
position: relative;
|
||||||
|
background-color: #fefefe;
|
||||||
|
margin: 1em auto;
|
||||||
|
padding: 0;
|
||||||
|
border: 1px solid #888;
|
||||||
|
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
|
||||||
|
animation-name: animatetop;
|
||||||
|
animation-duration: 0.4s
|
||||||
|
}
|
||||||
|
|
||||||
|
.role-wolf {
|
||||||
|
color: #7d0b0b;
|
||||||
|
font-family: 'diavlo', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.role-village {
|
||||||
|
color: #171469;
|
||||||
|
font-family: 'diavlo', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes animatetop {
|
||||||
|
from {top: -300px; opacity: 0}
|
||||||
|
to {top: 0; opacity: 1}
|
||||||
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
margin-top: 0.2em;
|
||||||
|
color: #aaa;
|
||||||
|
float: right;
|
||||||
|
font-size: 46px;
|
||||||
|
height: 1em;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close:hover,
|
||||||
|
.close:focus {
|
||||||
|
color: black;
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,10 +4,21 @@
|
|||||||
<title>Werewolf</title>
|
<title>Werewolf</title>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel = "stylesheet" type = "text/css" href = "static/styles.css" />
|
<link rel = "stylesheet" type = "text/css" href = "../static/styles.css" />
|
||||||
<script src="/socket.io/socket.io.js"></script>
|
<script src="/socket.io/socket.io.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<div class="modal hidden" id="role-modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h2>Role descriptions</h2>
|
||||||
|
<span id="close" class="close">×</span>
|
||||||
|
</div>
|
||||||
|
<div id="modal-body" class="modal-body">
|
||||||
|
<div id="roles"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="app-content">
|
<div class="app-content">
|
||||||
<div id="create-game-container">
|
<div id="create-game-container">
|
||||||
<h2 class="app-header-secondary">Create A Game</h2>
|
<h2 class="app-header-secondary">Create A Game</h2>
|
||||||
@@ -23,7 +34,10 @@
|
|||||||
<input id="time" type="number"/>
|
<input id="time" type="number"/>
|
||||||
</label>
|
</label>
|
||||||
<div id="card-select-header">
|
<div id="card-select-header">
|
||||||
<button id="reset-btn" class="app-btn">Reset Deck</button>
|
<span>
|
||||||
|
<button id="reset-btn" class="app-btn">Reset Deck</button>
|
||||||
|
<button id="role-btn" class="app-btn">View Role Info</button>
|
||||||
|
</span>
|
||||||
<span>
|
<span>
|
||||||
<h3 id="game-size">0 Players</h3>
|
<h3 id="game-size">0 Players</h3>
|
||||||
<p id="size-error"></p>
|
<p id="size-error"></p>
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<title>Werewolf</title>
|
<title>Werewolf</title>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel = "stylesheet" type = "text/css" href = "static/styles.css" />
|
<link rel = "stylesheet" type = "text/css" href = "../static/styles.css" />
|
||||||
<script src="/socket.io/socket.io.js"></script>
|
<script src="/socket.io/socket.io.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Werewolf</title>
|
<title>Werewolf</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel = "stylesheet" type = "text/css" href = "static/styles.css" />
|
<link rel = "stylesheet" type = "text/css" href = "../static/styles.css" />
|
||||||
<script src="/socket.io/socket.io.js"></script>
|
<script src="/socket.io/socket.io.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -19,9 +19,12 @@
|
|||||||
<a href="/join">
|
<a href="/join">
|
||||||
<button class="app-btn">Join</button>
|
<button class="app-btn">Join</button>
|
||||||
</a>
|
</a>
|
||||||
|
<a href="/learn">
|
||||||
|
<button class="app-btn">Learn the Game</button>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<footer id="footer">
|
<footer id="footer">
|
||||||
<img src="assets/images/vanilla_js.png">
|
<img src="../assets/images/vanilla_js.png">
|
||||||
<a href="https://github.com/AlecM33/Werewolf">Github</a>
|
<a href="https://github.com/AlecM33/Werewolf">Github</a>
|
||||||
</footer>
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
59
views/learn.html
Normal file
59
views/learn.html
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Title</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel = "stylesheet" type = "text/css" href = "../static/styles.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="learn-container">
|
||||||
|
<a href="/"><button class="app-btn">Back</button></a>
|
||||||
|
<h2>Introduction</h2>
|
||||||
|
<p>This is a social strategy game involving deception, deduction, cooperation, and any number of clever tactics.
|
||||||
|
There are two teams - the village and the werewolves. The village has the objective of finding and killing all
|
||||||
|
the wolves, and the wolves are trying to eat all the villagers. The game is divided into two phases: day and
|
||||||
|
night. At night is when the werewolves operate, deciding together which villager to kill off. The daytime is when
|
||||||
|
the village is active, deciding which among them seem evil and killing them to end the day. During the day, everyone
|
||||||
|
is disguised as a villager - even those that are actually wolves.
|
||||||
|
</p>
|
||||||
|
<h2>Setup</h2>
|
||||||
|
<p>At least 5 players are needed for a sensible game. Players can decide on which cards should go in the deck to create
|
||||||
|
a balanced experience. For example, a 7 player game might involve 2 werewolves, 3 villagers, a hunter, and a seer.
|
||||||
|
For larger games, this can be a bit trickier, but the goal is to create a game that isn't too easy for the wolves
|
||||||
|
or the villagers. Once the deck is chosen, the deck is dealt, and players see only their card.
|
||||||
|
</p>
|
||||||
|
<h2>Gameplay</h2>
|
||||||
|
<p>Play begins with the Night One. Everyone "goes to sleep," closing their eyes and creating some sort of white
|
||||||
|
noise (commonly a patting of the hand on the thigh). At this point, the moderator will ask the Werewolves to wake
|
||||||
|
up and see each other. If you do not have a designated moderator, choose someone arbitrarily for the first night,
|
||||||
|
and then the first player to die can moderate the rest of the game.<br><br>
|
||||||
|
|
||||||
|
First, The Werewolves will wake up and see the other wolves, giving them the knowledge that will guide the game.
|
||||||
|
Then, the werewolves go back to sleep. If you are playing with a Minion, next the Werewolves will raise their
|
||||||
|
hands (but not awake), and the Minion will awake to spot the wolves. You can also play with a "double-blind"
|
||||||
|
minion, who does not know who the wolves are, but is still playing on the same team as the wolves. This is all
|
||||||
|
that needs to happen on the first night.<br><br>
|
||||||
|
|
||||||
|
At this point, everyone wakes up, and Day One begins. This is an open debate between everyone in the circle about
|
||||||
|
who they should kill in suspicion of being a wolf. This can take any amount of time, but watch out, because the
|
||||||
|
wolves win if time expires! You should have some system for exhibiting votes to kill another player. If a player
|
||||||
|
receives a majority vote, they should press the "I'm dead" button on their screen, and everyone else will have
|
||||||
|
that player's role revealed to them. At this point, everyone immediately goes to sleep, and the next night begins.<br><br>
|
||||||
|
|
||||||
|
On every night after the first, wolves will, in silence, agree on someone in the circle (other than themselves)
|
||||||
|
to eat during the night. After this concludes, and everyone wakes up, the player that was killed will be revealed
|
||||||
|
by the moderator, and they will reveal their role. Then, of course, Day Two begins.<br><br>
|
||||||
|
|
||||||
|
The game continues in this alternating fashion until an endgame is reached. If a day ends with the same number of
|
||||||
|
wolves as villagers, the wolves win (as they can kill a villager at night, and then have the majority to kill the
|
||||||
|
remaining villager during the day). If the village manages to kill every wolf, then they win. In the scenario
|
||||||
|
where there is one villager and one wolf remaining, if the remaining villager is a Hunter, then the village wins.
|
||||||
|
There are several "power roles" such as the Hunter, which can help the village or the wolves. If you are a power
|
||||||
|
role, you can read the description on your card to find out what your special ability is.
|
||||||
|
</p>
|
||||||
|
<a href="/"><button class="app-btn">Back</button></a>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user