npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

pf-boggle

v1.3.0

Published

NxN Boggle generator and solver.

Downloads

8

Readme

pf-boggle

Boggle generator and solver - A Boggle utility for 4x4, 5x5, and 6x6 boards that can be extended to NxN.

http://pf-n.co/github/pf-boggle

Examples

// Require the module to use it
const boggle = require('pf-boggle')

// Create a 5x5 board
const board = boggle.generate(5)
// [ 'E', 'O', 'T', 'I', 'I',
//   'T', 'H', 'I', 'C', 'I',
//   'C', 'N', 'N', 'G', 'F',
//   'O', 'T', 'W', 'D', 'E',
//   'S', 'D', 'E', 'X', 'T' ]

// Solve the above board
const solution = boggle.solve(board)
// [ { word: 'ET', sequence: [ 0, 5 ] },
//   { word: 'ETH', sequence: [ 0, 5, 6 ] },
//   { word: 'ETHIC', sequence: [ 0, 5, 6, 7, 8 ] },
//   ...
//   { word: 'TEF', sequence: [ 24, 19, 14 ] },
//   { word: 'TED', sequence: [ 24, 19, 18 ] },
//   { word: 'TEX', sequence: [ 24, 19, 23 ] } ]

// Find maximum score
const _ = require('lodash')
_.chain(solution)
  .map('word')
  .uniq()
  .reduce((total, word) => total + boggle.points(word, 5), 0)
  .value()
// 226

Since boggle.solve() imports the SOWPODS dictionary (which is huge), you can instead import just the base solver and initialize it with a dictionary of your choice. In this case, the dictionary argument is not optional.

const solve = require('pf-boggle/src/base-solve')
solve.initialize(myDictionary)

solve(board, myDictionary)

API

boggle.generate([size = 4], [dice = boggle.diceSets[size]])

Arguments

  1. [size = 4] (Number): The size (number of rows/columns) of the board.
  2. [dice = boggle.diceSets[size]] (Array): An array of dice to use.

Returns

  • (Array): An array of strings, each string representing a spot on the board. (Note: this is not a 2D array).

dice can be an array of dice (each die being an array of strings). See boggle.diceSets for the included lists of dice. This module includes default dice sets for size equal to 4, 5, 6. For other sizes, dice is required. The length of dice should be greater than or equal to size * size.

// Create a 4x4 board using the Classic Boggle dice
boggle.generate(4, boggle.diceSets['classic4'])

// Create a 7x7 board using two sets of the 6x6 dice
// Every die has an equal chance of being used in the board
boggle.generate(7, [ ...boggle.diceSets[6], ...boggle.diceSets[6] ])

Since the return value is a flat array, it should be interpreted in row-major (or column-major) order to get the 2D board. If you want a 2D array, chunk the values (but boggle.solve() only works on the flat array).

const _ = require('lodash')
const board = _.chunk(boggle.generate(5), 5)
// [ [ 'E', 'O', 'T', 'I', 'I' ],
//   [ 'T', 'H', 'I', 'C', 'I' ],
//   [ 'C', 'N', 'N', 'G', 'F' ],
//   [ 'O', 'T', 'W', 'D', 'E' ],
//   [ 'S', 'D', 'E', 'X', 'T' ] ]

const solution = boggle.solve(_.flatten(board))

boggle.solve(board, [dictionary = SOWPODS])

Arguments

  1. board (Array): The board to solve.
  2. [dictionary = SOWPODS] (Array): A list of words to consider.

Returns

  • (Array): All possible words with their sequences on the board.

dict is an array of strings (case insensitive). The default dictionary used is Scrabble's SOWPODS dictionary (see pf-sowpods).

boggle.solve([ 'E', 'O', 'T', 'I', 'I',
               'T', 'H', 'I', 'C', 'I',
               'C', 'N', 'N', 'G', 'F',
               'O', 'T', 'W', 'D', 'E',
               'S', 'D', 'E', 'X', 'T' ])
// [ { word: 'ET', sequence: [ 0, 5 ] },
//   { word: 'ETH', sequence: [ 0, 5, 6 ] },
//   { word: 'ETHIC', sequence: [ 0, 5, 6, 7, 8 ] },
//   ...
//   { word: 'TEF', sequence: [ 24, 19, 14 ] },
//   { word: 'TED', sequence: [ 24, 19, 18 ] },
//   { word: 'TEX', sequence: [ 24, 19, 23 ] } ]

Words can appear multiple times in the solution if there are multiple sequences on the board which create the same word. In the above example, 'TINTED' appears 4 times.

{ word: 'TINTED', sequence: [ 2, 7, 11, 16, 22, 18 ] }
{ word: 'TINTED', sequence: [ 2, 7, 11, 16, 22, 21 ] }
{ word: 'TINTED', sequence: [ 2, 7, 12, 16, 22, 18 ] }
{ word: 'TINTED', sequence: [ 2, 7, 12, 16, 22, 21 ] }

Before solving occurs, a trie structure is made on dictionary. Since this operation is memoized, be careful when modifying your dictionary.

const _ = require('lodash')
const board = boggle.generate()

const dictionary = require('pf-sowpods')
const solution1 = boggle.solve(board, dictionary)
_.find(solution1, sol => sol.word.length === 2)
// { word: 'ES', sequence: [ 2, 5 ] }

// Remove all 2-letter words from the dictionary since they award no points
_.remove(dictionary, word => word.length === 2)

// Resolve the board with the "new" dictionary
const solution2 = boggle.solve(board, dictionary)
_.find(solution2, sol => sol.word.length === 2)
// { word: 'ES', sequence: [ 2, 5 ] }

// Actually use the new dictionary
const filteredDictionary = dictionary.slice()
const solution3 = boggle.solve(board, filteredDictionary)
_.find(solution3, sol => sol.word.length === 2)
// undefined

boggle.points(word, [size = 4])

Arguments

  1. word (String|Number): The word to score.
  2. [size = 4] (Number): The size of board scoring takes place on.

Returns

  • (Number): Number of points awarded for the word.

Since only the length of the word (and the size of the board) matters when scoring a word, word can also be passed as a number representing the length of a word.

boggle.points('abcdef') === boggle.points(6) // true

Scoring is determined by the following table

| Word Length: | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9+ | |:--------------:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:--:|:-------------------:| | Board Size = 4 | 0 | 0 | 1 | 1 | 2 | 3 | 5 | 11 | 11 | | Board Size = 5 | 0 | 0 | 0 | 1 | 2 | 3 | 5 | 11 | 11 | | Board Size = 6 | 0 | 0 | 0 | 1 | 2 | 3 | 5 | 11 | 2 points per letter |

(See Boggle 4x4, Boggle 5x5, Boggle 6x6 instruction manuals)

boggle.diceSets

({Object}): Included dice sets for use with boggle.generate().

  • boggle.diceSets['4'] - The new 4x4 Boggle dice set
  • boggle.diceSets['classic4'] - The classic 4x4 Boggle dice set
  • boggle.diceSets['czech4'] - The 4x4 Boggle dice set for Czech
  • boggle.diceSets['french4'] - The 4x4 Boggle dice set for French
  • boggle.diceSets['5'] - The 5x5 Boggle dice set
  • boggle.diceSets['italian5'] - The 5x5 Boggle dice set for Italian
  • boggle.diceSets['spanish5'] - The 5x5 Boggle dice set for Spanish
  • boggle.diceSets['6'] - The 6x6 Boggle dice set

In boggle.diceSets['6'], a represents the "blank" or "blue-square" face.

See the following for references:

  • https://boardgames.stackexchange.com/questions/29264/boggle-what-is-the-dice-configuration-for-boggle-in-various-languages
  • https://boardgamegeek.com/thread/300883/letter-distribution
  • https://boardgamegeek.com/thread/1071406/looking-letter-distribution