Skip to content

Commit

Permalink
Merge pull request #77 from lycan-city/feature/32/screenplay
Browse files Browse the repository at this point in the history
Feature/32/screenplay
  • Loading branch information
mamodom authored Jun 11, 2017
2 parents 626b234 + f344a12 commit 27e5a04
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 48 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
},
"globals": {
"describe": true,
"it": true
"it": true,
"beforeEach": true
}
}
3 changes: 0 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
language: node_js
node_js:
- "7"
- "6"
- "5"
- "4"
7 changes: 6 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ exports.getDeck = decks.get;
exports.getScriptFromDeck = moderator.getScriptFromDeck;
exports.getLanguages = languages.getLanguages;
exports.translateDeck = languages.translateDeck;
exports.translations = require('./src/data/translations');

exports.filterLevels = moderator.levels;

exports.getGame = (players, options = {}) => {
const language = options.language || 'en';
Expand All @@ -27,6 +30,8 @@ exports.getGame = (players, options = {}) => {
return game.create(players, language, cards.inCustomDeck(deck), mode);
}

if (deck) console.warn('Custom deck ignored, deckName has more precedence.');
if (deck) {
console.warn('Custom deck ignored, deckName has more precedence.');
}
return game.create(players, language, cards.inDeck(deckName), mode);
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "werewolf-brain",
"version": "2.0.0",
"version": "2.1.0",
"description": "Werewolf game brain",
"main": "./dist/index.js",
"scripts": {
Expand All @@ -26,6 +26,7 @@
"babel-loader": "^6.2.10",
"babel-preset-es2015": "^6.24.0",
"babel-register": "^6.24.0",
"chai": "^4.0.1",
"eslint": "^3.14.0",
"eslint-config-airbnb-base": "^11.1.2",
"eslint-plugin-import": "^2.2.0",
Expand Down
22 changes: 22 additions & 0 deletions src/data/firstNight.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"apprentice_seer": 1,
"big_bad_wolf": 1,
"cupid": 1,
"cursed": 1,
"dire_wolf": 1,
"diseased": 1,
"doppelganger": 1,
"fruit_brute": 1,
"hoodlum": 1,
"hunter": 1,
"lovebirds": 1,
"lycan": 1,
"mason": 1,
"minion": 1,
"nostradamus": 1,
"the_count": 1,
"tough_guy": 1,
"wild_child": 1,
"wolf_man": 1,
"wolverine": 1
}
2 changes: 1 addition & 1 deletion src/data/sequence.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@
"old_hag",
"spellcaster",
"meeting"
]
]
3 changes: 3 additions & 0 deletions src/game.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const { fromGame: screenplayFromGame } = require('./moderator');

const languages = require('./languages');

const BALANCEDFLEX = 1;
Expand Down Expand Up @@ -119,6 +121,7 @@ function getGame(players, language, chosenCards, flexibility) {
if (tries > 5000) break;
}
gameCandidate.deck = languages.translateDeck(gameCandidate.deck, language);
gameCandidate.screenplay = screenplayFromGame(gameCandidate.deck, chosenCards);
return gameCandidate;
}

Expand Down
29 changes: 29 additions & 0 deletions src/moderator.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
const bindings = require('./data/bindings');
const sequence = require('./data/sequence');
const languages = require('./data/translations');
const firstNight = require('./data/firstNight');

const levels = {
game: 1,
deck: 2,
all: 3,
};

exports.levels = levels;

exports.getScriptFromDeck = (deck, lang = 'en') => {
const roles = new Set();
Expand All @@ -17,3 +26,23 @@ exports.getScriptFromDeck = (deck, lang = 'en') => {

return seq.map(key => pack[key]);
};

exports.fromGame = (gameDeck, deck) => sequence.map((callKey) => {
const callGeneratingRoles = Object
.keys(bindings)
.filter(roleKey => bindings[roleKey].includes(callKey));
let level = '';
if (gameDeck.some(c => callGeneratingRoles.includes(c.key))) {
level = levels.game;
} else if (deck.some(c => callGeneratingRoles.includes(c.key))) {
level = levels.deck;
} else {
level = levels.all;
}

return {
key: callKey,
level,
firstNight: !!firstNight[callKey],
};
});
95 changes: 54 additions & 41 deletions tests/game.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint-disable no-unused-vars*/
/* eslint-disable func-names */
const should = require('should');
const game = require('../src/game');

Expand All @@ -13,65 +14,77 @@ const cards = [
{ key: 'wolf_cub', value: -8, amount: 1 }
];

const language = 'en';

describe('Game', () => {
const players = 25;


it('should have both modes.', () => {
game.mode.should.have.property('NORMAL');
game.mode.should.have.property('CHAOS');
});

let normalGame = {};
const language = 'en';
it('should create a normal game.', () => {
normalGame = game.create(players, language, cards, game.mode.NORMAL);
normalGame.should.not.be.empty();
});
describe('Create', () => {
describe('given mode is NORMAL', () => {
beforeEach(function () {
this.game = game.create(players, language, cards, game.mode.NORMAL);
});

it('should contain the weight on each normal game created.', () => {
normalGame.should.have.property('weight').which.is.a.Number();
});
it('should create a normal game.', function () {
this.game.should.not.be.empty();
});

it('should give a weight within -10 and 10 on each normal game created.', () => {
normalGame.weight.should.be.within(-10, 10);
});

it('should contain a deck in each normal game created.', () => {
normalGame.should.have.property('deck');
});
it('should contain the weight on each normal game created.', function () {
this.game.should.have.property('weight').which.is.a.Number();
});

it('should contain the amount of players on each normal game created.', () => {
normalGame.should.have.property('players').which.is.a.Number();
});
it('should give a weight within -10 and 10 on each normal game created.', function () {
this.game.weight.should.be.within(-10, 10);
});

it('should includes the maximun number of players on each normal game created.', () => {
normalGame.players.should.be.equal(players);
});
normalGame = {};
it('should contain a deck in each normal game created.', function () {
this.game.should.have.property('deck');
});

let chaosGame = {};
it('should create a chaos game.', () => {
chaosGame = game.create(players, language, cards, game.mode.CHAOS);
chaosGame.should.not.be.empty();
});
it('should contain the amount of players on each normal game created.', function () {
this.game.should.have.property('players').which.is.a.Number();
});

it('should contain the weight on each chaos game created.', () => {
chaosGame.should.have.property('weight').which.is.a.Number();
});
it('should includes the maximun number of players on each normal game created.', function () {
this.game.players.should.be.equal(players);
});
});

it('should give a weight within -20 and 20 on each chaos game created.', () => {
chaosGame.weight.should.be.within(-20, 20);
});
describe('given mode is CHAOS', () => {
beforeEach(function () {
this.game = game.create(players, language, cards, game.mode.CHAOS);
});

it('should contain a deck in each chaos game created.', () => {
chaosGame.should.have.property('deck');
});
it('should create a chaos game.', function () {
this.game.should.not.be.empty();
});

it('should contain the amount of players on each chaos game created.', () => {
chaosGame.should.have.property('players').which.is.a.Number();
});
it('should contain the weight on each chaos game created.', function () {
this.game.should.have.property('weight').which.is.a.Number();
});

it('should give a weight within -20 and 20 on each chaos game created.', function () {
this.game.weight.should.be.within(-20, 20);
});

it('should contain a deck in each chaos game created.', function () {
this.game.should.have.property('deck');
});

it('should contain the amount of players on each chaos game created.', function () {
this.game.should.have.property('players').which.is.a.Number();
});

it('should includes the maximun number of players on each chaos game created.', () => {
chaosGame.players.should.be.equal(players);
it('should includes the maximun number of players on each chaos game created.', function () {
this.game.players.should.be.equal(players);
});
});
});
});
46 changes: 46 additions & 0 deletions tests/screenplay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/* eslint-disable no-undef*/
/* eslint-disable no-unused-expressions*/
/* eslint-disable func-names */
const chai = require('chai');
const moderator = require('../src/moderator');

const expect = chai.expect;

describe('Screenplay', () => {
describe('fromGame()', () => {
beforeEach(function () {
const deck = [
{ key: 'villager', amount: 25, },
{ key: 'werewolf', amount: 12, },
{ key: 'seer', amount: 1, },
{ key: 'cupid', amount: 1, },
{ key: 'cult_leader', amount: 1, },
];

const gameDeck = [
{ key: 'werewolf', amount: 1, },
{ key: 'cult_leader', amount: 1, },
{ key: 'villager', amount: 7, },
{ key: 'cupid', amount: 1 }
];

this.screenplay = moderator.fromGame(gameDeck, deck);
});

it('is expected to not be null or undefined', function () {
expect(this.screenplay)
.to.not.be.undefined
.and.to.not.be.null;
});

it('is expected to be an array', function () {
expect(this.screenplay).to.be.an('array');
});

it('is expected to have `key` and `level`', function () {
this.screenplay.forEach(call =>
expect(call).to.have.all.keys('key', 'level', 'firstNight')
);
});
});
});

0 comments on commit 27e5a04

Please sign in to comment.