UNPKG

boggle-game-solver

Version:

Expansion of node-boggle-solver by adding multiple dictionary options.

109 lines (85 loc) 2.95 kB
const config = require('./config') const findAdjacents = require('./findAdjacents') const utils = require('./utils') const triePrefixTree = require('trie-prefix-tree') const MIN_WORD_LEN = config.minWordLen; module.exports=function initSolver(boggle, boggleSize, trie, minWordLen) { // allow the user to customise the minimum word length returned // the default is 3 minWordLen = minWordLen || MIN_WORD_LEN; // create the matrix const boggleMatrix = utils.getBoggleMatrix(boggleSize, boggle); // create the full object that will contain // a word and corresponding co-ordinates const full = []; const list = []; // recursive solve algorithm const solve = function(word, position, deepCoords = [], deepUsed = []) { const [row, col] = position; const wordLen = word.length; // create new copies of both coords and used positions // for each letter const coords = deepCoords.slice(); const used = deepUsed.slice(); // push the current position into the co-ordinates array coords.push(position); // check if the current word is valid if (wordLen >= minWordLen) { const isValid = trie.hasWord(word); const isFound = list.includes(word); if (isValid && !isFound) { full.push({ word, coords }); list.push(word); // reset co-ordinates ready for the next word deepCoords = []; } } // find adjacent letters in the matrix const adjacents = findAdjacents(position, boggleSize, deepUsed); // filter adjacents that are not valid prefixes const validAdjacents = adjacents.filter((adjacent) => { const [x, y] = adjacent; const isPrefix = trie.isPrefix(word + boggleMatrix[x][y]); return isPrefix; }); validAdjacents.forEach((adjacent) => { used.push(position); const [x, y] = adjacent; const letter = boggleMatrix[x][y]; const currentWord = word + letter; solve(currentWord, adjacent, coords, used); }); }; // solve each letter in turn boggleMatrix.forEach((row, rowIndex) => { row.forEach((col, colIndex) => { solve(boggleMatrix[rowIndex][colIndex], [rowIndex, colIndex]); }); }); // create a trie from the resulting word list const resultTrie = triePrefixTree(list); return { full, list, hasWord(word) { return resultTrie.hasWord(word); }, contains(letters) { const arr = Array.from(letters); return list.filter(word => arr.every(letter => word.includes(letter))); }, startsWith(prefix) { return resultTrie.getPrefix(prefix); }, endsWith(suffix) { return list.filter((word) => { const wordLen = word.length; const startAt = wordLen - suffix.length; return word.substring(startAt, wordLen) === suffix.toLowerCase(); }); }, lengthOf(length) { return list.filter(word => word.length === length); }, }; };