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 🙏

© 2026 – Pkg Stats / Ryan Hefner

mjqt-scoring

v0.1.31

Published

Typescript Utilities to calculate a given hand's Mahjong score.

Downloads

8

Readme

mjqt-scoring

Typescript Utilities to calculate a given hand's Mahjong score.

For Consumers

Install mjqt-scoring as a dependency

mjqt-scoring is available via npm. Run npm install mjqt-scoring in your project.

Main Functionality

For consumers, the main function to calculate a hand's point value is within src/api/scorer.ts. evaluateHand() takes a Hand argument, a WinContext describing how the user won, the RoundContext describing the user's current seat and the prevailing wind, and a RootPointPredicateConfiguration that describes the current pointing rules (a default one is provided called defaultRootPointPredicateConfiguration that can be cloned and customized). It returns a PointEvaluation, which contains how many points the hand scored, a verbose result list describing which points the Hand successfully received, and a list of PointPredicateIDs that were ignored when adding up the hand's points (due to already being included by an encompassing successful pointing rule).

Deck

For ease of constructing tiles, the standard tileset used in Hong Kong and International rulesets are available in src/common/deck.ts.

For Contributors

Running Locally

After cloning the repo, run npm install. To compile, run npm run build. To run tests, run npm run test.

Model

Tile

A Tile has two main attributes: a group: TileGroup and a value: TileValue. For example, the One of Bamboo has group = TileGroup.BAMBOO and value = SuitedTileValue.ONE.

Meld

A Meld is a set of tiles that makes up a "meld" in the game of Mahjong, either a consecutive run (Chow), or a set of identical tiles: a pair (Pair), three of a kind (Pong), four of a kind (Kong).

PointPredicate, PointPredicateResult, and PointPredicateID

For a typical Mahjong hand, you are awarded points if your win passes certain conditions, e.g. your hand is made up of a pair and four Pong/Kongs. This condition is commonly called "All Triplets" (or, in Chinese, 對對糊). Such a condition in this code base is encompassed in what is called a PointPredicate.

A PointPredicate is a function that takes in a WinningHand and returns a PointPredicateResult. A PointPredicateResult contains whether the PointPredicate is true or false for this hand, with verbose explanations as to what in the hand caused the predicate to evaluate to true/false. This PointPredicate is assigned an ID in PointPredicateID to keep track of all the rules. For "All Triplets", it has been given the id of PointPredicateID.ALL_PONGS_AND_KONGS.

Hand => HandAnalyzer => WinningHand

A Hand is just a list of Tiles, the mostRecentTileContext, and an optional specification of pre-specified Melds. It represents a person's hand of tiles when it is their turn (i.e. in 13-Tile Mahjong, it is when the user has 14 tiles). After the hand has been analyzed for win conditions via HandAnalyzer's, the hand may transform into zero, one, or more WinningHands. A WinningHand is either a MeldBasedWinningHand (one that conforms to a typical one pair + four meld structure in 13-tile Mahjong) or a SpecialWinningHand (anything that does not conform to the aforementioned pattern e.g. "Thirteen Orphans" / 十三么).