ndice


Namendice JSON
Version 0.1.8 PyPI version JSON
download
home_pageNone
SummaryA dice rolling library for games.
upload_time2025-08-22 23:28:38
maintainerNone
docs_urlNone
authorDon McCaughey
requires_python>=3.13
licenseNone
keywords dice roll random game rpg
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # ndice

A dice rolling library for games.

[![builds.sr.ht status][badge]][builds]

[badge]: https://builds.sr.ht/~donmcc/ndice.svg
[builds]: https://builds.sr.ht/~donmcc/ndice

`ndice` is a package for rolling dice expressions like **d6+2** or **3d6-3x10**
with a compact API.

    >>> from ndice import d6, d8, d20, d100, plus, minus, times, rng, roll
    
    >>> if roll(rng, d100) <= 25:
    ...     copper = roll(rng, d6, times(1000))

    >>> str_mod = minus(1)
    >>> magic_sword_mod = plus(2)
    >>> ac = 13

    >>> if roll(rng, d20, str_mod, magic_sword_mod) >= ac:
    ...     damage = roll(rng, d8)


## Operations (Op)

The `Op` enum defines three operations used in dice expressions: `Op.PLUS` (+),
`Op.MINUS` (-) and `Op.TIMES` (x).


## Dice

A `Dice` object represents a single term in a dice expression like **2d6** or
**-2**.  The `Dice` object contains three attributes: `number`, `sides` and `op`. 
The values for `number` and `sides` must be zero or greater.  If not specified,
`op` defaults to `Op.PLUS`.

Rolling zero dice with any number of sides always returns 0.  Rolling any number
of zero-sided dice also always returns 0.

Constant modifiers ("mods") like **-2** or **x10** are defined as `Dice`
instances where `number` is the mod value and `sides` is 1.

`ndice` contains predefined common dice like `d6`, `d20` and `three_d6`.  A single
die type can be defined with the `d()` function, an alias for `Dice.die()`.

    >>> from ndice import d

    >>> d5 = d(5)

A number of dice can be defined with the `nd()` function, an alias for
`Dice.n_dice()`.

    >>> from ndice import nd

    >>> three_d8 = nd(3, 8)

Instances of `Dice` are immutable and cached, so `d(6)` will return the same `Dice`
instance that `d6` refers to.

    >>> from ndice import d, d6

    >>> d(6) is d6  # always true
    True

Individual `Dice` instances are ordered according to (`number`, `sides`, `op`),
where `Op.PLUS` comes first and `Op.TIMES` last.

    >>> from ndice import d6, two_d6, three_d6, minus, times

    >>> assert d6 < minus(d6) < times(d6) < two_d6 < three_d6

A `Dice` object is hashable and can be used in sets or as keys in dicts.


## Random Number Generator (RNG)

Rolling dice requires a "random" number generator.  A number generator is a
callable that take an `int` with the max die roll (i.e. the number of sides) and
returns an `int` value in the range `[1, sides]`.  The type alias `RNG` can be
used to annotate number generator variables.

The `rng` generator produces actual random numbers.  `PRNG()` creates a
deterministic pseudo-random number sequence given a seed value.

Fake generators `high` and `low` always roll the highest or lowest values
respectively.  The `mid` generator always rolls the middle value or lower of the
two middle values: when rolling a three-sided die, `mid` returns 2; when rolling
a six-sided die with middle values of 3 and 4, `mid` returns 3.

`AscendingRNG()` and `FixedRNG()` create other fake generators.  Creating a
custom fake generator can be as simple as creating a function or lambda.

    >>> from ndice import d100, RNG

    >>> always_2: RNG = lambda sides: 2
    >>> roll(always_2, d100)
    2


## Rolls

The `roll()` function takes a number generator and zero or more `Dice` instances
making up a _dice expression_.  It returns the total of the dice expression, or
zero if no dice are given.

    >>> from ndice import roll, d6, minus, times, rng, high

    >>> roll(rng)
    0

Note that dice expressions are always evaluated from left to right; `times()` or
`Op.TIMES` does not have higher precedence than plus or minus.  This is
different than the equivalent Python numeric expression, where `*` and `/` are
evaluated before `+` and `-`.

    >>> total = roll(high, d6, minus(1), times(10))
    >>> total
    50
    
    >>> assert 6 - 1 * 10 != total
    >>> assert (6 - 1) * 10 == total

The `min_roll()` and `max_roll()` functions are equivalent to `roll(low, ...)`
and `roll(high, ...)` respectively.


### Individual Die Rolls

Sometimes you need the individual die rolls rather than the total.  The
`roll_each_die()` function returns the individual die rolls of a `Dice` object
as a list.

    >>> from ndice import four_d6, PRNG, roll_each_die

    >>> prng = PRNG(1122334455)
    >>> roll_each_die(prng, four_d6)
    [4, 4, 2, 6]

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "ndice",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.13",
    "maintainer_email": null,
    "keywords": "dice, roll, random, game, rpg",
    "author": "Don McCaughey",
    "author_email": "Don McCaughey <don@donm.cc>",
    "download_url": "https://files.pythonhosted.org/packages/3f/e1/11133352f28a04fb755adc4cf703a839491ce21154624e35e925454a7fa7/ndice-0.1.8.tar.gz",
    "platform": null,
    "description": "# ndice\n\nA dice rolling library for games.\n\n[![builds.sr.ht status][badge]][builds]\n\n[badge]: https://builds.sr.ht/~donmcc/ndice.svg\n[builds]: https://builds.sr.ht/~donmcc/ndice\n\n`ndice` is a package for rolling dice expressions like **d6+2** or **3d6-3x10**\nwith a compact API.\n\n    >>> from ndice import d6, d8, d20, d100, plus, minus, times, rng, roll\n    \n    >>> if roll(rng, d100) <= 25:\n    ...     copper = roll(rng, d6, times(1000))\n\n    >>> str_mod = minus(1)\n    >>> magic_sword_mod = plus(2)\n    >>> ac = 13\n\n    >>> if roll(rng, d20, str_mod, magic_sword_mod) >= ac:\n    ...     damage = roll(rng, d8)\n\n\n## Operations (Op)\n\nThe `Op` enum defines three operations used in dice expressions: `Op.PLUS` (+),\n`Op.MINUS` (-) and `Op.TIMES` (x).\n\n\n## Dice\n\nA `Dice` object represents a single term in a dice expression like **2d6** or\n**-2**.  The `Dice` object contains three attributes: `number`, `sides` and `op`. \nThe values for `number` and `sides` must be zero or greater.  If not specified,\n`op` defaults to `Op.PLUS`.\n\nRolling zero dice with any number of sides always returns 0.  Rolling any number\nof zero-sided dice also always returns 0.\n\nConstant modifiers (\"mods\") like **-2** or **x10** are defined as `Dice`\ninstances where `number` is the mod value and `sides` is 1.\n\n`ndice` contains predefined common dice like `d6`, `d20` and `three_d6`.  A single\ndie type can be defined with the `d()` function, an alias for `Dice.die()`.\n\n    >>> from ndice import d\n\n    >>> d5 = d(5)\n\nA number of dice can be defined with the `nd()` function, an alias for\n`Dice.n_dice()`.\n\n    >>> from ndice import nd\n\n    >>> three_d8 = nd(3, 8)\n\nInstances of `Dice` are immutable and cached, so `d(6)` will return the same `Dice`\ninstance that `d6` refers to.\n\n    >>> from ndice import d, d6\n\n    >>> d(6) is d6  # always true\n    True\n\nIndividual `Dice` instances are ordered according to (`number`, `sides`, `op`),\nwhere `Op.PLUS` comes first and `Op.TIMES` last.\n\n    >>> from ndice import d6, two_d6, three_d6, minus, times\n\n    >>> assert d6 < minus(d6) < times(d6) < two_d6 < three_d6\n\nA `Dice` object is hashable and can be used in sets or as keys in dicts.\n\n\n## Random Number Generator (RNG)\n\nRolling dice requires a \"random\" number generator.  A number generator is a\ncallable that take an `int` with the max die roll (i.e. the number of sides) and\nreturns an `int` value in the range `[1, sides]`.  The type alias `RNG` can be\nused to annotate number generator variables.\n\nThe `rng` generator produces actual random numbers.  `PRNG()` creates a\ndeterministic pseudo-random number sequence given a seed value.\n\nFake generators `high` and `low` always roll the highest or lowest values\nrespectively.  The `mid` generator always rolls the middle value or lower of the\ntwo middle values: when rolling a three-sided die, `mid` returns 2; when rolling\na six-sided die with middle values of 3 and 4, `mid` returns 3.\n\n`AscendingRNG()` and `FixedRNG()` create other fake generators.  Creating a\ncustom fake generator can be as simple as creating a function or lambda.\n\n    >>> from ndice import d100, RNG\n\n    >>> always_2: RNG = lambda sides: 2\n    >>> roll(always_2, d100)\n    2\n\n\n## Rolls\n\nThe `roll()` function takes a number generator and zero or more `Dice` instances\nmaking up a _dice expression_.  It returns the total of the dice expression, or\nzero if no dice are given.\n\n    >>> from ndice import roll, d6, minus, times, rng, high\n\n    >>> roll(rng)\n    0\n\nNote that dice expressions are always evaluated from left to right; `times()` or\n`Op.TIMES` does not have higher precedence than plus or minus.  This is\ndifferent than the equivalent Python numeric expression, where `*` and `/` are\nevaluated before `+` and `-`.\n\n    >>> total = roll(high, d6, minus(1), times(10))\n    >>> total\n    50\n    \n    >>> assert 6 - 1 * 10 != total\n    >>> assert (6 - 1) * 10 == total\n\nThe `min_roll()` and `max_roll()` functions are equivalent to `roll(low, ...)`\nand `roll(high, ...)` respectively.\n\n\n### Individual Die Rolls\n\nSometimes you need the individual die rolls rather than the total.  The\n`roll_each_die()` function returns the individual die rolls of a `Dice` object\nas a list.\n\n    >>> from ndice import four_d6, PRNG, roll_each_die\n\n    >>> prng = PRNG(1122334455)\n    >>> roll_each_die(prng, four_d6)\n    [4, 4, 2, 6]\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A dice rolling library for games.",
    "version": "0.1.8",
    "project_urls": {
        "Changelog": "https://git.sr.ht/~donmcc/ndice/tree/main/item/CHANGELOG.md",
        "Documentation": "https://git.sr.ht/~donmcc/ndice",
        "Homepage": "https://git.sr.ht/~donmcc/ndice",
        "Repository": "https://git.sr.ht/~donmcc/ndice"
    },
    "split_keywords": [
        "dice",
        " roll",
        " random",
        " game",
        " rpg"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "a8fb329ead39427470999a3d6027f6228ca2e2e1251483a36a45c43393bfc967",
                "md5": "5ab75b1e0f414a67a428aaa92af5bbb7",
                "sha256": "cbb096d9c2623f975a9f56e56d3fc54bc855d6e820cac95c9e4ce94db9344cb7"
            },
            "downloads": -1,
            "filename": "ndice-0.1.8-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "5ab75b1e0f414a67a428aaa92af5bbb7",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.13",
            "size": 8242,
            "upload_time": "2025-08-22T23:28:37",
            "upload_time_iso_8601": "2025-08-22T23:28:37.054963Z",
            "url": "https://files.pythonhosted.org/packages/a8/fb/329ead39427470999a3d6027f6228ca2e2e1251483a36a45c43393bfc967/ndice-0.1.8-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "3fe111133352f28a04fb755adc4cf703a839491ce21154624e35e925454a7fa7",
                "md5": "9a6a5ec90e39a6c883ce771778256740",
                "sha256": "3154cac4479ef32adf3343a7fd3fc9e0c910aab2798f2e6f6061b94f12e7afd7"
            },
            "downloads": -1,
            "filename": "ndice-0.1.8.tar.gz",
            "has_sig": false,
            "md5_digest": "9a6a5ec90e39a6c883ce771778256740",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.13",
            "size": 6086,
            "upload_time": "2025-08-22T23:28:38",
            "upload_time_iso_8601": "2025-08-22T23:28:38.185974Z",
            "url": "https://files.pythonhosted.org/packages/3f/e1/11133352f28a04fb755adc4cf703a839491ce21154624e35e925454a7fa7/ndice-0.1.8.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-22 23:28:38",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "ndice"
}
        
Elapsed time: 1.41271s