From 8da85f87b30f6bfa523e174932afc08d4d74c065 Mon Sep 17 00:00:00 2001 From: Vetom Date: Thu, 12 Apr 2018 01:09:44 -0400 Subject: [PATCH] Refactor + Enhance game.js --- src/game.js | 105 +++++++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 51 deletions(-) diff --git a/src/game.js b/src/game.js index 82db5d9..dddde9c 100644 --- a/src/game.js +++ b/src/game.js @@ -2,6 +2,11 @@ const { fromGame: screenplayFromGame } = require('./moderator'); const languages = require('./languages'); +const mode = { + CHAOS: 'CHAOS', + NORMAL: 'NORMAL' +}; + const BALANCEDFLEX = 1; const CHAOSFLEX = 2; const SUCCESS = 1; @@ -9,8 +14,11 @@ const FAIL = 0; let game; let allPlayers; -let availableCards; +let cards; +let negatives; +let nonnegatives; let gameCandidate; +let pivot; function newGame() { game = { @@ -19,7 +27,9 @@ function newGame() { players: 0 }; allPlayers = true; - availableCards = {}; + cards = {}; + negatives = -1; + nonnegatives = -1; gameCandidate = { deck: {}, weight: 100, @@ -27,97 +37,95 @@ function newGame() { }; } -function resetValues(chosenCards) { +function resetValues(classifiedCards) { game = { deck: {}, weight: 0, players: 0 }; allPlayers = true; - availableCards = JSON.parse(JSON.stringify(chosenCards)); + negatives = classifiedCards.negatives.reduce((a, c) => a + c.amount, 0); + nonnegatives = classifiedCards.nonnegatives.reduce((a, c) => a + c.amount, 0); + cards = JSON.parse(JSON.stringify(classifiedCards)); } -function getRandom(min, max) { - const floor = Math.ceil(min); - const top = Math.floor(max); - return Math.floor(Math.random() * ((top - floor) + 1)) + floor; +function getRandom(max) { + return Math.floor(Math.random() * Math.floor(max)) + 1; } + function addRandomCard(selectedCard) { game.weight += selectedCard.value; game.players++; if (game.deck[selectedCard.key]) game.deck[selectedCard.key]++; else game.deck[selectedCard.key] = 1; } + function addCardToDeck(isNegative) { if (isNegative) { - if (availableCards.negatives.length < 1) { + if (negatives < 1) { allPlayers = false; return FAIL; } - const rand = getRandom(0, availableCards.negatives.length - 1); - if (availableCards.negatives[rand].amount > 0) { - addRandomCard(availableCards.negatives[rand]); - availableCards.negatives.splice(rand, 1); - return SUCCESS; + let rand = getRandom(negatives); + for (let i = 0; i < cards.negatives.length; i++) { + rand -= cards.negatives[i].amount; + if (rand < 1) { + cards.negatives[i].amount--; + negatives--; + addRandomCard(cards.negatives[i]); + return SUCCESS; + } } } else { - if (availableCards.nonnegatives.length < 1) { + if (nonnegatives < 1) { allPlayers = false; return FAIL; } - const rand = getRandom(0, availableCards.nonnegatives.length - 1); - if (availableCards.nonnegatives[rand].amount > 0) { - addRandomCard(availableCards.nonnegatives[rand]); - availableCards.nonnegatives.splice(rand, 1); - return SUCCESS; + let rand = getRandom(nonnegatives); + for (let i = 0; i < cards.nonnegatives.length; i++) { + rand -= cards.nonnegatives[i].amount; + if (rand < 1) { + cards.nonnegatives[i].amount--; + nonnegatives--; + addRandomCard(cards.nonnegatives[i]); + return SUCCESS; + } } } return FAIL; } -function setGame(players, chosenCards) { - resetValues(chosenCards); +function setGame(players, classifiedCards) { + resetValues(classifiedCards); // get first card randomly let playersAdded = addCardToDeck(getRandom(0, 1)); while (playersAdded < players) { - const added = addCardToDeck(game.weight >= 0); + const added = addCardToDeck(game.weight >= pivot); if (added === FAIL) break; playersAdded += added; } } -function classifyCards(cards) { +function classifyCards(chosenCards) { const classifiedCards = { negatives: [], nonnegatives: [] }; - cards.forEach((card) => { - if (card.value < 0) { - for (let i = 0; i < card.amount; i++) { - classifiedCards.negatives.push({ key: card.key, value: card.value, amount: 1 }); - } - } else { - for (let i = 0; i < card.amount; i++) { - classifiedCards.nonnegatives.push({ - key: card.key, - value: card.value, - amount: 1, - }); - } - } - }); - + classifiedCards.negatives = chosenCards.filter(x => x.value < 0); + classifiedCards.nonnegatives = chosenCards.filter(x => x.value >= 0); return classifiedCards; } -function getGame(players, language, chosenCards, flexibility) { +function getGame(players, language, chosenCards, gameMode) { const classifiedCards = classifyCards(chosenCards); - let flex = flexibility; + let flex = gameMode === mode.NORMAL ? BALANCEDFLEX : CHAOSFLEX; + pivot = gameMode === mode.NORMAL ? 0 : -4; let tries = 0; while (!allPlayers || game.weight < -1 * flex || game.weight > flex) { tries++; setGame(players, classifiedCards); if (gameCandidate.players <= game.players) gameCandidate = game; - if (tries % 500 === 0) flex++; - if (tries > 5000) break; + const totalCards = negatives + nonnegatives; + if (tries % (totalCards * 10) === 0) flex++; + if (tries > (totalCards * 100)) break; } gameCandidate.deck = languages.translateDeck(gameCandidate.deck, language); gameCandidate.screenplay = screenplayFromGame(gameCandidate.deck, chosenCards); @@ -126,12 +134,7 @@ function getGame(players, language, chosenCards, flexibility) { exports.create = function create(playerCount, language, deck, gameMode) { newGame(); - return getGame(playerCount, language, deck, gameMode === this.mode.NORMAL - ? BALANCEDFLEX - : CHAOSFLEX); + return getGame(playerCount, language, deck, gameMode); }; -exports.mode = { - CHAOS: 'CHAOS', - NORMAL: 'NORMAL' -}; +exports.mode = mode;