Skip to main content

Simple Python tools for exploring dice probabilities and outcomes

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.

v0.2.3 Version v0.2.3 Development Stage v0.2.3 License v0.2.3 Supported Python Versions v0.2.3 Supported Python Implementations

dyce – simple Python tools for exploring dice probabilities and outcomes

dyce is a pure-Python library for computing discrete probability distributions. It 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.

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. If you find it lacking in any way, please consider contributing an issue to start a discussion.

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

A taste

dyce provides two key primitives. H objects represent histograms for modeling discrete outcomes, like individual dice. P objects objects represent pools (ordered sequences) of histograms. Both support a variety of operations.

>>> from dyce import H
>>> d6 = H(6)  # a standard six-sided die
>>> 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
>>> p_2d6 = 2@P(d6)  # a pool of two six-sided dice
>>> p_2d6.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})
>>> p_2d6 == 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.)

>>> p_2d6.h(0)  # take the lowest die of 2d6
H({1: 11, 2: 9, 3: 7, 4: 5, 5: 3, 6: 1})
>>> print(p_2d6.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% |#
>>> p_2d6.h(-1)  # take the highest die of 2d6
H({1: 1, 2: 3, 3: 5, 4: 7, 5: 9, 6: 11})
>>> print(p_2d6.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 provide a distribution method and a distribution_xy method to ease integration with plotting packages like matplotlib:

>>> import matplotlib  # doctest: +SKIP
>>> matplotlib.pyplot.style.use("dark_background")  # doctest: +SKIP

>>> outcomes, probabilities = p_2d6.h(0).distribution_xy()
>>> matplotlib.pyplot.bar(
...   [str(v) for v in outcomes],
...   probabilities,
...   alpha=0.75,
...   width=0.5,
...   label="Lowest",
... )  # doctest: +SKIP

>>> outcomes, probabilities = p_2d6.h(-1).distribution_xy()
>>> matplotlib.pyplot.bar(
...   [str(v) for v in outcomes],
...   probabilities,
...   alpha=0.75,
...   width=0.5,
...   label="Highest",
... )  # doctest: +SKIP

>>> matplotlib.pyplot.legend()  # doctest: +SKIP
>>> matplotlib.pyplot.title(r"Taking the lowest or highest die of 2d6")  # doctest: +SKIP
>>> matplotlib.pyplot.show()  # doctest: +SKIP

Plot: Taking the lowest or highest die of 2d6

See the tutorial and the API guide for a much more thorough treatment, including detailed examples.

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. Because it exposes Python primitives rather than defining a dedicated grammar and interpreter, one can more easily integrate it with other tools. It can be installed and run anywhere, and modified as desired. On its own, it is completely adequate for casual tinkering. However, it really shines when used in larger contexts such as with Matplotlib or Jupyter.

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.distribution, H.distribution_xy, and H.format methods).

Comparison to alternatives

The following is a best-effort¹ summary of the differences between various available tools in this space. Consider exploring the applications and translations for added color.

dyce
Bogosian et al.
dice_roll.py
Karonen
AnyDice
Flick
python_dice
Robson et al.
d20
Curse LLC
DnDice
“LordSembor”
dice
Clemens et al.
dice-notation
Garrido
dyce
Eyk
Actively maintained and documented ⚠²
Discrete outcome enumeration
Arbitrary expressions ⚠³ ⚠⁴
Arbitrary dice definitions
Integrates with other tools ⚠⁵ ⚠⁵ ⚠⁵ ⚠⁵ ⚠⁵
Open source
Permissive licensing N/A
Notes
¹ I have attempted to ensure the above is reasonably accurate, but please consider contributing an issue if there are discrepancies.
² Actively maintained, but sparsely documented. The author has expressed a desire to release a more polished version.
³ Callers must perform their own arithmetic and characterize results in terms of a lightweight die primitive, which may be less accessible to the novice. That being said, the library is remarkably powerful, given its size.
⁴ Limited arithmetic operations are available. The library also provides game-specific functions.
⁵ Results only. Input is limited to specialized grammar.

License

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

Installation

Installation can be performed via PyPI:

% pip install dycelib
...

Alternately, you can download the source and run setup.py:

% git clone https://github.com/posita/dyce
...
% cd dyce
% python setup.py install  # --editable '.[dev]'
...

Requirements

dyce requires a relatively modern version of Python:

It has the following dependencies:

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

dycelib-0.2.3.tar.gz (34.2 kB view hashes)

Uploaded Source

Built Distribution

dycelib-0.2.3-py3-none-any.whl (32.4 kB view hashes)

Uploaded Python 3

Supported by

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