diff --git a/config/default.js b/config/default.js index 2ea7932..82868ea 100644 --- a/config/default.js +++ b/config/default.js @@ -35,6 +35,6 @@ module.exports = { }, letters: { length: 9, - timeout: 30, + timeout: 60, }, }; diff --git a/src/games/letters.js b/src/games/letters.js index 2475315..1a6fc28 100644 --- a/src/games/letters.js +++ b/src/games/letters.js @@ -3,15 +3,18 @@ const config = require('config'); const timers = require('timers/promises'); -const shuffle = require('../utils/shuffle'); +const crypto = require('crypto'); const style = require('../utils/style'); const getLeaders = require('../utils/get-leaders'); const getWordKey = require('../utils/get-word-key'); const words = require('../../assets/mash-words.json'); -const availableVowels = ['a', 'e', 'i', 'o', 'u']; -const availableConsonants = ['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z']; // Countdown regards y as a consonant -const types = { v: 'vowels', c: 'consonants' }; +const availableLetters = { + vowel: ['a', 'e', 'i', 'o', 'u'], + consonant: ['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z'], // Countdown regards y as a consonant +}; + +const types = { v: 'vowel', c: 'consonant' }; const settings = { ...config.letters }; const games = new Map(); @@ -19,28 +22,18 @@ const games = new Map(); function getBoard(context) { const game = games.get(context.room.id); - return `${game.word.split('').map((letter) => `${style.grey('[')}${letter.toUpperCase()}${style.grey(']')}`).join('')}${`${style.silver('[')} ${style.silver(']')}`.repeat(config.letters.length - game.word.length)}`; + return `${style.grey('[')} ${game.word.split('').concat(Array.from({ length: config.letters.length - game.word.length })).map((letter) => letter?.toUpperCase() || ' ').join(style.grey(' | '))} ${style.grey(']')}`; } function countLetters(word) { return word.split('').reduce((counts, letter) => ({ ...counts, [letter]: (counts[letter] || 0) + 1 }), {}); } -function shuffleLetters(letters, acc = []) { - const shuffled = shuffle(letters, config.letters.length); - - if (acc.length + shuffled.length < config.letters.length) { - return shuffleLetters(letters, [...acc, ...shuffled, ...letters]); - } - - return [...acc, ...shuffled].slice(0, config.letters.length); -} - function playWord(rawWord, context) { const game = games.get(context.room.id); const word = rawWord.trim().toLowerCase(); - if (!word || word.length > game.word.length) { + if (!word || word.length < 3 || word.length > game.word.length) { return; } @@ -112,11 +105,11 @@ function pickLetters(type, context) { return; } - if (type === 'consonants' || type === 'vowels') { - game.word = `${game.word}${game[type].pop()}`; + if (type === 'consonant' || type === 'vowel') { + game.word = `${game.word}${availableLetters[type][crypto.randomInt(0, availableLetters[type].length)]}`; } else { type.toLowerCase().slice(0, config.letters.length - game.word.length).split('').forEach((typeKey) => { - game.word = `${game.word}${game[types[typeKey]].pop()}`; + game.word = `${game.word}${availableLetters[types[typeKey]][crypto.randomInt(0, availableLetters[types[typeKey]].length)]}`; }); } @@ -138,8 +131,6 @@ function start(context) { games.set(context.room.id, { state: 'letters', word: '', - vowels: shuffleLetters(availableVowels), - consonants: shuffleLetters(availableConsonants), played: new Set(), points: {}, ac: new AbortController(), // eslint-disable-line no-undef @@ -176,12 +167,12 @@ function onMessage(message, context) { } if (/(^|\b)cons?(onant)?($|\b)/i.test(message.body)) { - pickLetters('consonants', context); + pickLetters('consonant', context); return; } if (/(^|\b)vow(el)?($|\b)/i.test(message.body)) { - pickLetters('vowels', context); + pickLetters('vowel', context); return; } }