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

@bedard/twister

v1.0.0-beta.19

Published

[![Build status](https://img.shields.io/github/workflow/status/scottbedard/twister/Test)](https://github.com/scottbedard/twister/actions) [![Codecov](https://img.shields.io/codecov/c/github/scottbedard/twister)](https://codecov.io/gh/scottbedard/twister)

Downloads

106

Readme

twister

Build status Codecov NPM Bundle size License

Twister is a library for modeling the state of twisty puzzles. To get started, check out the interactive playground.

Installation

The recommended way to install is through NPM.

npm install @bedard/twister

Alternatively, you can use the CDN. When using the CDN, the library will be exposed globally as Twister.

<script src="https://unpkg.com/@bedard/twister"></script>

Basic usage

Below is the recommended way to instantiate Twister models. Using destructured imports allows for unused puzzles to be tree-shaken from your application.

import { Cube } from '@bedard/twister'

const puzzle = new Cube({ size: 3 })

Once a puzzle has been instantiated, the following methods are available...

apply

Set the puzzle to a given state. State objects can be created using the output method.

puzzle.apply(state)

clone

Create a new puzzle instance with the same state and options.

const puzzle = new Puzzle()

const clone = puzzle.clone()

execute

Updates puzzle state using a parsed turn object. In most situations, it's simpler to use the turn method and make use of turn notation.

const turn = puzzle.parse('R')

puzzle.execute(turn)

generateScramble

Generates a scramble of a default or specified number of moves, but does not execute it.

const scramble = puzzle.generateScramble()

notation

Generate the string representation of a parsed turn object. This can be thought of as the opposite of parse.

const turn = puzzle.parse('R')

puzzle.notation(turn) // 'R'

output

Returns a minified version of the puzzle's state. This method is useful for saving state as JSON, then restoring that state via the apply method.

const state = puzzle.output()

parse

Convert a single piece of puzzle notation to a turn object. This method is generally used to interact with the execute method, but is also useful for testing if notation is valid. To parse a turn in reverse, provide true as the second argument.

const turn = puzzle.parse('R')

parseAlgorithm

Convert a space-delimited string of turns into an array of turn objects. To parse an algorithm in reverse, provide true as the second argument.

const turns = puzzle.parseAlgorithm('R U R-')

reset

Return a puzzle to its solved state.

puzzle.reset()

scramble

Scrambles a puzzle to a default or specified number of moves. This is similar to generateScramble, the only difference being that this method executes the resulting scramble. This method is also available via the CLI, more info here.

puzzle.scramble()

stickers

Get stickers affected by a turn. If no turn notation is provided, all stickers will be returned.

const stickers = puzzle.stickers('R')

test

Test if the puzzle is solved, or matches a specific state.

// test if the puzzle is solved
const solved = puzzle.test()

// test for a specific state
const isSame = puzzle.test(otherPuzzle.output())

turn

Executes an algorithm. This method is also available via the CLI, more info here.

puzzle.turn('R U R-')

unturn

Execute the reverse of an algorithm. Note that unturns are executed from right to left.

const scramble = puzzle.turn('R U R-')

puzzle.unturn('R U R-') // 'R U- R-'

Advanced usage

All stickers are stored as { value } objects. This allows for additional information, such as rendering data, to be attached to the stickers. To do this, simply instantiate the puzzle, and modify the objects that are part of puzzle.state.

import { Cube } from '@bedard/twister'

const puzzle = new Cube({ size: 3 })

puzzle.state.u[0].foo = 'bar'

For applications with advanced scrambling needs, a custom random function can be provided on instantiation. Below is an example using Rando.js to generate cryptographically strong scrambles. The random option must be a function that returns a floating point number between 0 and 1. By default, Math.random is used.

import { Cube } from '@bedard/twister'
import { rando } from '@nastyox/rando.js';

const puzzle = new Cube({
  random: rando,
  size: 3,
});

While this library does it's best to generate strong scrambles, it should never be used in WCA events. Always use the official TNoodle library for WCA purposes.

CLI

The following utilities are available from the command line. Constructor options can be provided via --options. Note that when providing JSON arguments, we use JSON5 syntax for a smoother user experience.

parse

Parse a single piece of turn notation.

$ twister parse cube R

parseAlgorithm

Parse multiple pieces of turn notation.

$ twister parseAlgorithm cube "R U R-"

scramble

Scramble a puzzle.

# scramble a puzzle
$ twister scramble cube

# scramble a puzzle to a specific number of moves
$ twister scramble cube --turns=10

turn

Execute an algorithm. This will be performed on a solved puzzle unless an initial state is provided.

# apply turns to a solved puzzle
$ twister turn cube "R U R-"

# apply turns from an initial state
$ twister turn cube "R U R-" --state="{...}"

# apply turns and test for a particular state
$ twister turn cube "R U R-" --test="{...}"

Puzzles

Cube

This puzzle represents an N-layered face turning cube.

import { Cube } from '@bedard/twister';

const puzzle = new Cube({ size: 3 });

Cube state is represented as an array of sticker objects. Each face array starts from the top left sticker and read sequentially to the bottom right. To picture how these values map onto an actual cube, imagine unfolding a cube while looking at the F face. Notice that the B face has the same orientation as the L, F, and R faces.

Our notation is a superset of WCA notation. Any algorithm produced by a WCA scrambler is compatible with this library. There are however, a couple of extensions we've made to the WCA notation. The first of which is the optional use of a - to indicate counter-clockwise turns. The second is the ability to annotate "slice turns" with a single move. To do this, simply omit the wide segment of a turn. For example, a 3F in our notation system would be equal to 3Fw 2Fw' in WCA notation.

Dodecaminx

This puzzle represents an N-layered face turning dodecahedron.

import { Dodecaminx } from '@bedard/twister';

const puzzle = new Dodecaminx({ size: 3 });

State for a dodecaminx is stored as an array of corner matrices, middle arrays, and a center value. These arrays start from the primary corner of a face, and continue clockwise around that face. The corner matrices are similar to that of a cube face, starting with the corner furthest from the center and reading sequentially towards the center. Middle arrays start with the sticker furthest from the center. Note that for even-layered puzzles, the middle and center values are omitted.

Notation for this puzzle is similar to that of cubes. The main difference is that whole-puzzle rotations are denoted by lowercase letters. Here are a few examples to demonstrate various turns around the U face.

  • U = outer layer turned once clockwise
  • U2 = outer layer turned twice clockwise
  • U2- = outer layer turned twice counter-clockwise
  • 2U = second layer turned once clockwise
  • Uw = second and outer layer turned once clockwise
  • u = entire puzzle rotated once clockwise
  • u2 = entire puzzle rotated twice clockwise
  • u2- = entire puzzle rotated twice counter-clockwise

License

MIT

Copyright (c) 2020-present, Scott Bedard