Skip to main content

Simple Python tools for exploring dice outcomes and other finite discrete probabilities

Project description

Copyright and other protections apply. Please see the accompanying LICENSE file for rights and restrictions governing use of this software. All rights not expressly waived or licensed are reserved. If that file is missing or appears to be modified from its original, then please contact the author before viewing or using this software in any capacity.

Tests Coverage Version Development Stage License Supported Python Versions Supported Python Implementations pre-commit Bear-ified™

Now you’re playing with …

dyce logo

dyce – Simple Python tools for exploring dice outcomes and other finite discrete probabilities

💥 Now 100% Bear-ified™! 👌🏾🐻 (Details below.)

dyce is a pure-Python library for modeling arbitrarily complex dice mechanics. It strives for compact expression and efficient computation, especially for the most common cases. Its primary applications are:

  1. Computing finite discrete probability distributions for:
    • Game designers who want to understand or experiment with various dice mechanics and interactions; and
    • Design tool developers.
  2. Generating transparent, weighted random rolls for:
    • Game environment developers who want flexible dice mechanic resolution in, e.g., virtual tabletops (VTTs), chat servers, etc.

Beyond those audiences, dyce may be useful to anyone interested in exploring finite discrete probabilities but not in developing all the low-level math bits from scratch.

dyce is designed to be immediately and broadly useful with minimal additional investment beyond basic knowledge of Python. While not as compact as a dedicated grammar, dyce’s Python-based primitives are quite sufficient, and often more expressive. Those familiar with various game notations should be able to adapt quickly. If you’re looking at something on which to build your own grammar or interface, dyce can serve you well.

dyce should be able to replicate or replace most other dice probability modeling tools. It strives to be fully documented and relies heavily on examples to develop understanding.

dyce is licensed under the MIT License. See the accompanying LICENSE file for details. Non-experimental features should be considered stable (but an unquenchable thirst to increase performance remains). See the release notes for a summary of version-to-version changes. Source code is available on GitHub.

If you find it lacking in any way, please don’t hesitate to bring it to my attention.

Installation

Installation can be performed via PyPI.

% pip install dyce
...

Alternately, you can download the source and install manually.

% git clone https://github.com/posita/dyce.git
...
% cd dyce
% python3 -m pip install .  # -or- python3 -c 'from setuptools import setup ; setup()' install .
...

Requirements

dyce requires a relatively modern version of Python:

It has the following runtime dependencies:

  • optype for proper static and runtime numeric type-checking

dyce will opportunistically use the following, if available at runtime:

  • NumPy to supply dyce with an alternate random number generator implementation
  • Matplotlib for basic visualization helpers via dyce.viz

See the hacking quick-start for additional development and testing dependencies.

Design philosophy

dyce is fairly low-level by design, prioritizing ergonomics and composability. It explicitly avoids stochastic simulation, but instead determines outcomes through enumeration and discrete computation. That’s a highfalutin way of saying it doesn’t guess. It knows, even if knowing is harder or more limiting. Which, if we possess a modicum of humility, it often is.

!!! quote

“It’s frightening to think that you might not know something, but more frightening to think that, by and large, the world is run by people who have faith that they know exactly what is going on.”

—Amos Tversky

Because dyce exposes Python primitives rather than defining a dedicated grammar and interpreter, one can more easily integrate it with other tools.[^1] It can be installed and run anywhere[^2], and modified as desired. On its own, dyce is completely adequate for casual tinkering. However, it really shines when used in larger contexts such as with Matplotlib or Jupyter or embedded in a special-purpose application.

[^1]:

You won’t find any lexers, parsers, or tokenizers in `dyce`’s core, other than straight-up Python.
That being said, you can always “roll” your own (see what we did there?) and lean on `dyce` underneath.
It doesn’t mind.
<!-- TODO(posita): Figure out what we're doing with dyce.r -->
<!-- It actually [kind of *likes* it](https://posita.github.io/dyce/latest/rollin/). -->

[^2]:

<!-- Was: https://jokejet.com/guys-i-need-a-network-specialist-with-some-python-experience-its-urgent/ -->
Okay, maybe not *literally* anywhere, but [you’d be surprised](https://www.reddit.com/media?url=https%3A%2F%2Fi.redd.it%2Frd64erbk6nj41.jpg).
Void where prohibited.
[Certain restrictions](#requirements) apply.
[Do not taunt Happy Fun Ball](https://youtu.be/GmqeZl8OI2M).

In an intentional departure from RFC 1925, § 2.2, dyce includes some conveniences, such as minor computation optimizations (e.g., the H.lowest_terms method, various other shorthands, etc.) and formatting conveniences (e.g., the H.probability_items and H.format methods).

A taste

dyce provides several core primitives. H objects represent histograms for modeling finite discrete outcomes, like individual dice. P objects represent pools (ordered sequences) of histograms. expand for mechanics that include dependent variables.

>>> from dyce import H
>>> H(6)  # a standard six-sided die
H({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1})
>>> from dyce.d import d6  # dyce.d contains some convenient shorthands
>>> d6 == H(6)
True
>>> 2 @ d6 * 3 - 4  # 2d6 * 3 - 4
H({2: 1, 5: 2, 8: 3, 11: 4, 14: 5, 17: 6, 20: 5, 23: 4, 26: 3, 29: 2, 32: 1})
>>> d6.lt(d6)  # how often a first six-sided die shows a face less than a second
H({False: 21, True: 15})
>>> abs(d6 - d6)  # subtract the least of two six-sided dice from the greatest
H({0: 6, 1: 10, 2: 8, 3: 6, 4: 4, 5: 2})
>>> from dyce import P
>>> 2 @ P(d6)  # a pool of two six-sided dice
2@P(H({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1}))
>>> from dyce.d import p2d6
>>> p2d6 == 2 @ P(d6)
True
>>> p2d6.h()  # pools can be collapsed into histograms
H({2: 1, 3: 2, 4: 3, 5: 4, 6: 5, 7: 6, 8: 5, 9: 4, 10: 3, 11: 2, 12: 1})
>>> from dyce.d import h2d6
>>> p2d6 == h2d6 == 2 @ d6  # pools and histograms are comparable
True

By providing an optional argument to the P.h method, one can “take” individual dice from pools, ordered least to greatest. (The H.format method provides rudimentary visualization for convenience.)

>>> p2d6.h(0)  # take the lowest die of 2d6
H({1: 11, 2: 9, 3: 7, 4: 5, 5: 3, 6: 1})
>>> print(p2d6.h(0).format(width=65))
avg |    2.53
std |    1.40
var |    1.97
  1 |  30.56% |###############
  2 |  25.00% |############
  3 |  19.44% |#########
  4 |  13.89% |######
  5 |   8.33% |####
  6 |   2.78% |#
>>> p2d6.h(-1)  # take the highest die of 2d6
H({1: 1, 2: 3, 3: 5, 4: 7, 5: 9, 6: 11})
>>> print(p2d6.h(-1).format(width=65))
avg |    4.47
std |    1.40
var |    1.97
  1 |   2.78% |#
  2 |   8.33% |####
  3 |  13.89% |######
  4 |  19.44% |#########
  5 |  25.00% |############
  6 |  30.56% |###############

H objects provides a probability_items method to ease integration with plotting packages. dyce.viz provides Matplotlib-based visualization conveniences. anydyce provides additional interactive visualization tools.

--8<-- "docs/assets/plot_2d6_lo_hi.py:core"

Visualization: Try dyce

--8<-- "docs/assets/plot_2d6_lo_hi.py:viz"
Plot: Taking the lowest or highest die of 2d6

H objects and P objects can generate random rolls.

>>> from dyce.d import d6
>>> d6.roll()
4
>>> d0to9 = H(10) - 1
>>> p6d0to9 = 6 @ P(d0to9)
>>> p6d0to9.roll()
(0, 0, 2, 3, 5, 9)

See the tutorials on counting as well as the API guide for much more thorough treatments, including detailed examples.

Other efforts

dyce’s goal is to provide ergonomic and idiomatic Python interfaces to reasonably efficient discrete probability computations useful for gaming with minimal dependencies. Consider exploring the applications and translations for added color. But dyce does not stand alone. Other works include:

Please consider contributing an issue if you observe discrepancies or think something should be added to the list.

Donors

When one worries that the flickering light of humanity may be snuffed out at any moment, when one’s heart breaks at the perverse celebration of judgment, vengeance, and death and the demonizing of empathy, compassion, and love, sometimes all that is needed is the kindness of a single stranger to reinvigorate one’s faith that—while all may not be right in the world—there is hope for us human beings.

Customers dyce-powered!

  • This could be you! 👋

Do you have a project that uses dyce? Let me know, and I’ll promote it here!

And don’t forget to do your part in perpetuating gratuitous badge-ification!

<!-- Markdown -->
As of version 1.1, HighRollin is
[![dyce-powered](https://raw.githubusercontent.com/posita/dyce/latest/docs/dyce-powered.svg)][dyce-powered]!
[dyce-powered]: https://posita.github.io/dyce/ "dyce-powered!"
..
    reStructuredText - see https://docutils.sourceforge.io/docs/ref/rst/directives.html#image

As of version 1.1, HighRollin is |dyce-powered|!

.. |dyce-powered| image:: https://raw.githubusercontent.com/posita/dyce/latest/docs/dyce-powered.svg
   :align: top
   :target: https://posita.github.io/dyce/
   :alt: dyce-powered
<!-- HTML -->
As of version 1.1, HighRollin is <a href="https://posita.github.io/dyce/"><img
  src="https://raw.githubusercontent.com/posita/dyce/latest/docs/dyce-powered.svg"
  alt="dyce-powered"
  style="vertical-align: middle;"></a>!

License

dyce is licensed under the MIT License. See the included LICENSE file for details. Source code is available on GitHub.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dyce-0.7.0rc3.tar.gz (958.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dyce-0.7.0rc3-py3-none-any.whl (60.6 kB view details)

Uploaded Python 3

File details

Details for the file dyce-0.7.0rc3.tar.gz.

File metadata

  • Download URL: dyce-0.7.0rc3.tar.gz
  • Upload date:
  • Size: 958.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for dyce-0.7.0rc3.tar.gz
Algorithm Hash digest
SHA256 652249ef7be45558dd1c318617b9872ab7944063a131a034b0c4e18323850f4f
MD5 de6c74f3f07a574b5f20a8a373ddd857
BLAKE2b-256 22b42626d598faaff2893eddd07712a67848dfeea9ecd159e9d5cae61e2ce524

See more details on using hashes here.

Provenance

The following attestation bundles were made for dyce-0.7.0rc3.tar.gz:

Publisher: publish.yml on posita/dyce

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dyce-0.7.0rc3-py3-none-any.whl.

File metadata

  • Download URL: dyce-0.7.0rc3-py3-none-any.whl
  • Upload date:
  • Size: 60.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for dyce-0.7.0rc3-py3-none-any.whl
Algorithm Hash digest
SHA256 ae20e34206252688744a122cfdd1d6db216c59c8380b4dd2a0b8f64d463629df
MD5 973d46136489a85d8b95dca08b2e1f80
BLAKE2b-256 65bd873639a37483a673022d3eca030aa140aebff6693250282302af6d0f00e1

See more details on using hashes here.

Provenance

The following attestation bundles were made for dyce-0.7.0rc3-py3-none-any.whl:

Publisher: publish.yml on posita/dyce

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page