UNPKG

scrabble-cheater

Version:

A simple Scrabble cheating tool.

101 lines (100 loc) 3.39 kB
import { promises as fs } from 'node:fs'; import readline from 'node:readline'; import clipboard from 'clipboardy'; const defaultOptions = { letters: '', maximum: 0, quietMode: false, singleMode: false, }; export class ScrabbleCheater { constructor(wordListPath, options) { this.dictionary = []; this.wordListPath = wordListPath; this.options = { ...defaultOptions, ...options }; } setLetters(letters) { this.options.letters = letters; return this; } async start() { const length = await this.loadWords(); if (!length) { throw new Error('No words loaded. Wordlist file corrupt?'); } this.log(`${length} word${length > 1 ? 's' : ''} loaded.`); const letters = this.options.letters ? this.formatLetters(this.options.letters) : await this.readLineAsync(); let matches = this.findMatches(letters); this.log(`ScrabbleCheater: ${matches.length} matches found`, true); if (this.options.maximum) { this.log(`, ${this.options.singleMode ? 'sending' : 'displaying'} the first ${this.options.maximum}`, true); matches = matches.slice(0, this.options.maximum); } this.log('.\n\n', true); if (this.options.singleMode) { this.singleOutput(matches); } return matches; } findMatches(letters) { const regex = new RegExp(`^[${letters}]+$`); return this.dictionary.filter(word => regex.test(word)).sort((wordA, wordB) => wordB.length - wordA.length); } formatLetters(letters) { const regex = new RegExp('[^A-Za-z]'); return letters.replace(regex, '').toLowerCase(); } async loadWords() { const regex = new RegExp('^[A-Za-z]+$'); const wordList = await fs.readFile(this.wordListPath, 'utf-8'); this.dictionary = wordList.split('\n').filter(value => regex.test(value)); return this.dictionary.length; } log(message, raw = false) { if (!this.options.quietMode) { if (!raw) { console.info(`ScrabbleCheater: ${message}`); } else { process.stdout.write(message); } } } readLineAsync() { return new Promise((resolve, reject) => { const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); rl.question('Letters? ', input => { const letters = this.formatLetters(input); if (letters) { resolve(letters); } else { reject(new Error('No letters entered.')); } rl.close(); }); }); } singleOutput(matches) { const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); let counter = 0; const next = () => { clipboard.writeSync(matches[counter]); if (counter < matches.length - 1) { this.log('Press Enter to copy the next word...'); counter++; } else { return rl.close(); } }; rl.on('line', next); next(); } }