### Install dyce from source using git and pip Source: https://github.com/posita/dyce/blob/main/README.md Installs the 'dyce' package manually by cloning the source repository from GitHub and then using pip to install it. This method is useful for development or when a specific version is needed. ```sh % git clone https://github.com/posita/dyce.git ... % cd dyce % python -m pip install . # -or- python -c 'from setuptools import setup ; setup()' install . ... ``` -------------------------------- ### Bootstrap dyce development environment Source: https://github.com/posita/dyce/blob/main/docs/contrib.md Clones the dyce repository, sets up a Python virtual environment, installs development dependencies, and installs pre-commit hooks. ```sh % git clone --recurse-submodules https://github.com/posita/dyce.git … % cd dyce % /path/to/python -m venv .venv … % . .venv/bin/activate % pip install --upgrade --editable '.[dev]' … % python -m pre_commit install … ``` -------------------------------- ### Install dyce using pip Source: https://github.com/posita/dyce/blob/main/README.md Installs the 'dyce' package using pip from the Python Package Index (PyPI). This is the recommended method for most users. ```sh % pip install dyce ... ``` -------------------------------- ### Install anydyce Python Package Source: https://github.com/posita/dyce/blob/main/docs/notebooks/risus.ipynb Installs the 'anydyce' Python package, essential for the Dyce project. It handles potential ImportError or ModuleNotFoundError by attempting to install via 'piplite' in JupyterLite environments or falling back to 'pip'. Includes a workaround for a JupyterLite issue. ```python import warnings with warnings.catch_warnings(): warnings.simplefilter("ignore") try: import anydyce except (ImportError, ModuleNotFoundError): requirements = ["anydyce~=0.4.0"] try: import piplite ; await piplite.install(requirements) # Work around import matplotlib.pyplot ; matplotlib.pyplot.clf() except ImportError: import pip ; pip.main(["install"] + requirements) import anydyce ``` -------------------------------- ### Install Dyce and AnyDyce Dependencies Source: https://github.com/posita/dyce/blob/main/docs/notebooks/4d6_variants.ipynb This snippet installs the necessary Python libraries, 'anydyce' and its requirements, using either 'piplite' (for environments like JupyterLite) or 'pip'. It includes error handling for import failures and a workaround for a potential issue with matplotlib in JupyterLite. ```python # Install additional requirements if necessary import warnings with warnings.catch_warnings(): warnings.simplefilter("ignore") try: import anydyce except (ImportError, ModuleNotFoundError): requirements = ["anydyce~=0.4.0"] try: import piplite ; await piplite.install(requirements) # Work around import matplotlib.pyplot ; matplotlib.pyplot.clf() except ImportError: import pip ; pip.main(["install"] + requirements) import anydyce ``` -------------------------------- ### Install Dyce and Tabulate Requirements Source: https://github.com/posita/dyce/blob/main/docs/notebooks/ironsworn.ipynb Installs necessary Python libraries 'anydyce' and 'tabulate' using piplite for JupyterLite environments, with a fallback to pip. It includes a workaround for matplotlib in JupyterLite. ```python # Install additional requirements if necessary import warnings with warnings.catch_warnings(): warnings.simplefilter("ignore") try: import anydyce, tabulate except (ImportError, ModuleNotFoundError): requirements = ["anydyce~=0.4.0", "tabulate"] try: import piplite ; await piplite.install(requirements) # Work around import matplotlib.pyplot ; matplotlib.pyplot.clf() except ImportError: import pip ; pip.main(["install"] + requirements) import anydyce, tabulate ``` -------------------------------- ### Visualize Dice Roll Results with Jupyter Source: https://github.com/posita/dyce/blob/main/docs/notebooks/great_weapon_fighting.ipynb Uses the 'jupyter_visualize' function from the 'anydyce' library to create interactive visualizations of the defined dice rolls. It displays a comparison between a 'Normal attack' and the 'Great Weapon Fighting' scenario. ```python from anydyce import jupyter_visualize jupyter_visualize( [ ("Normal attack", single_attack), ("“Great Weapon Fighting”", great_weapon_fighting), ], selected_name="Line Plot", ) ``` -------------------------------- ### Heterogeneous Pool Warning Example Source: https://github.com/posita/dyce/blob/main/docs/rollin.md Shows the `UserWarning` generated when using a heterogeneous pool with `R.from_value` where traceability might be important. This highlights potential issues with ambiguous outcomes. ```python >>> R.from_value(P(6, 8)) # doctest: +SKIP ...: UserWarning: using a heterogeneous pool (P(6, 8)) is not recommended where traceability is important ... ValueRoller(value=P(6, 8), annotation='') ``` -------------------------------- ### Visualize Dice Roll Results (Python) Source: https://github.com/posita/dyce/blob/main/docs/notebooks/burning_arch.ipynb Uses the 'jupyter_visualize' function from the 'anydyce' library to create a visual representation (Line Plot) of the calculated dice roll damage. ```python from anydyce import jupyter_visualize jupyter_visualize( [damage_half_on_save], selected_name="Line Plot", ) ``` -------------------------------- ### Visualize Dice Roll Results with Anydyce Source: https://github.com/posita/dyce/blob/main/docs/notebooks/advantage.ipynb Visualizes the defined dice roll outcomes using the `jupyter_visualize` function from the `anydyce` library. It generates a line plot comparing normal hits, critical hits, and advantage-weighted rolls. ```python from anydyce import jupyter_visualize jupyter_visualize( [ ("Normal hit", normal_hit), ("Critical hit", critical_hit), ("Advantage-weighted", advantage_weighted), ], selected_name="Line Plot", ) ``` -------------------------------- ### Deterministic Dice Rolling Setup (Python) Source: https://github.com/posita/dyce/blob/main/docs/rollin.md Sets up deterministic dice rolling by patching the random number generator. This is useful for testing and ensuring reproducible results. It initializes the RNG with a specific seed. ```python import random from dyce import rng rng.RNG = random.Random(1633440532) ``` -------------------------------- ### Python: Create and Roll a ValueRoller Source: https://github.com/posita/dyce/blob/main/docs/rollin.md This snippet shows how to create a 'ValueRoller' with a specific value, roll it to get a 'Roll' object, and inspect its total and outcomes. ```python >>> from dyce.r import ValueRoller >>> r_1 = ValueRoller(1) >>> roll = r_1.roll() >>> roll.total() 1 >>> tuple(roll.outcomes()) (1,) >>> roll Roll( r=ValueRoller(value=1, annotation=''), roll_outcomes=( RollOutcome( value=1, sources=(), ), ), source_rolls=(), ) ``` -------------------------------- ### Define Dice Rolls and Damage Calculation (Python) Source: https://github.com/posita/dyce/blob/main/docs/notebooks/burning_arch.ipynb Demonstrates how to define dice rolls and perform damage calculations using the Dyce library. It includes creating a save roll, calculating damage with a potential save, and applying half damage on a successful save. ```python from dyce import H save_roll = H(20) burning_arch_damage = 10 @ H(6) + 10 pass_save = save_roll.ge(10) damage_half_on_save = burning_arch_damage // (pass_save + 1) ``` -------------------------------- ### Dyce P.h Method: Taking Specific Dice from Pools Source: https://github.com/posita/dyce/blob/main/README.md Demonstrates how to use the `P.h()` method in Dyce to extract specific dice from a pool, ordered from least to greatest. It shows examples of taking the lowest and highest dice and includes formatting the output for visualization. ```python >>> 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()) 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()) 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% |############### ``` -------------------------------- ### Python: Symbolic Math with SymPy for Dice Outcomes Source: https://github.com/posita/dyce/blob/main/docs/countin.md Illustrates the integration of Dyce with SymPy for handling symbolic outcomes. This example shows how to create dice with symbolic variables and calculate their combined distributions, along with the limitations when operations depend on ordering symbolic expressions. ```python >>> import sympy.abc >>> d6x = H(6) + sympy.abc.x >>> d8y = H(8) + sympy.abc.y >>> P(d6x, d8y, d6x).h() H({2*x + y + 3: 1, 2*x + y + 4: 3, 2*x + y + 5: 6, ..., 2*x + y + 18: 6, 2*x + y + 19: 3, 2*x + y + 20: 1}) ``` ```python >>> expr = sympy.abc.x < sympy.abc.x * 3 ; expr x < 3*x >>> bool(expr) # nope Traceback (most recent call last): ... TypeError: cannot determine truth value of Relational ``` ```python >>> bool(sympy.abc.x < sympy.abc.x + 1) Traceback (most recent call last): ... TypeError: cannot determine truth value of Relational >>> import sympy.solvers.inequalities >>> sympy.solvers.inequalities.reduce_inequalities(sympy.abc.x < sympy.abc.x + 1, [sympy.abc.x]) True ``` ```python >>> d3x = H(3) * sympy.abc.x ; d3x H({2*x: 1, 3*x: 1, x: 1}) >>> p = P(d3x / 3, (d3x + 1) / 3, (d3x + 2) / 3) >>> p.h() H({2*x + 1: 7, 3*x + 1: 1, 4*x/3 + 1: 3, 5*x/3 + 1: 6, 7*x/3 + 1: 6, 8*x/3 + 1: 3, x + 1: 1}) ``` ```python >>> p.h(0) Traceback (most recent call last): ... TypeError: cannot determine truth value of Relational ``` ```python >>> p.h(slice(None)) H({2*x + 1: 7, 3*x + 1: 1, 4*x/3 + 1: 3, 5*x/3 + 1: 6, 7*x/3 + 1: 6, 8*x/3 + 1: 3, x + 1: 1}) ``` ```python >>> list(p.rolls_with_counts()) Traceback (most recent call last): ... TypeError: cannot determine truth value of Relational ``` ```python >>> p.roll() # doctest: +SKIP (2*x/3, 2*x/3 + 1/3, x/3 + 2/3) ``` ```python >>> f = lambda outcome: outcome.subs({sympy.abc.x: sympy.Rational(1, 3)}) >>> p.umap(f) P(H({1/9: 1, 2/9: 1, 1/3: 1}), H({4/9: 1, 5/9: 1, 2/3: 1}), H({7/9: 1, 8/9: 1, 1: 1})) >>> p.umap(f).h(-1) H({7/9: 9, 8/9: 9, 1: 9}) ``` -------------------------------- ### Explain Dyce '@' Operator for Counting Successes Source: https://github.com/posita/dyce/blob/main/docs/translations.md This example demonstrates the usage and meaning of the Dyce library's `@` operator, which is a shorthand for combining multiple probability distributions. It explains how `2@(H(10).lt(5))` is equivalent to summing the results of `H(10).lt(5)` twice, effectively counting how many times a d10 roll is less than 5 across two independent trials. ```python >>> H(10).lt(5) # how often a d10 is strictly less than 5 H({False: 6, True: 4}) >>> h = H(10).lt(5) + H(10).lt(5) ; h H({0: 36, 1: 48, 2: 16}) >>> h.total 100 >>> # The parentheses are technically redundant, but clarify the intention >>> 2@(H(10).lt(5)) == H(10).lt(5) + H(10).lt(5) True ``` -------------------------------- ### Implement Advantage and Critical Hit Logic in Dyce Source: https://github.com/posita/dyce/blob/main/docs/translations.md This snippet shows how to implement dice roll logic for advantage and critical hits using Dyce. It translates an example from DnDice, defining functions to handle critical hits and applying advantage mechanics to determine attack outcomes. The output displays the weighted expectancies based on these rules. ```python >>> from dyce.evaluation import HResult, foreach >>> normal_hit = H(12) + 5 >>> critical_hit = 3@H(12) + 5 >>> advantage = (2@P(20)).h(-1) >>> def crit(attack: HResult): ... if attack.outcome == 20: return critical_hit ... elif attack.outcome + 5 >= 14: return normal_hit ... else: return 0 >>> advantage_weighted = foreach(crit, attack=advantage) ``` -------------------------------- ### Serve Documentation Locally with MkDocs Source: https://github.com/posita/dyce/blob/main/helpers/release-checklist.md Runs a local MkDocs server to preview the project documentation. This command first runs the 'check' tox environment for validation and then serves the documentation, allowing for spot checks. ```shell tox -e check && "$( git rev-parse --show-toplevel )/.tox/check/bin/mkdocs" serve ``` -------------------------------- ### Arithmetic Operations on Dice Pools in Python Source: https://github.com/posita/dyce/blob/main/docs/countin.md Illustrates how arithmetic operations on dice pools automatically 'flatten' them into histograms. This example shows the result of scaling and shifting a dice pool, similar to the histogram example but starting with pools. ```python >>> 3*(2@P(6)+4) H({18: 1, 21: 2, 24: 3, 27: 4, 30: 5, 33: 6, 36: 5, 39: 4, 42: 3, 45: 2, 48: 1}) ``` ```python >>> abs(P(6) - P(6)) H({0: 6, 1: 10, 2: 8, 3: 6, 4: 4, 5: 2}) ``` -------------------------------- ### Create d100 Roll and Get Total in Python Source: https://github.com/posita/dyce/blob/main/docs/rollin.md This snippet demonstrates rolling the previously created 'r_d100' roller to simulate a d100 roll. It then retrieves and prints the total value of the roll. Includes setup for deterministic random outcomes. ```python import random from dyce import rng rng.RNG = random.Random(1633438594) roll = r_d100.roll() print(roll.total()) ``` -------------------------------- ### Update Dyce versioning to versioningit Source: https://github.com/posita/dyce/blob/main/docs/notes.md Migrates the project's version management from setuptools_scm to versioningit. This change allows for more flexible formatting of version numbers and improves the deployment process from CI based on tags. ```python setuptools_scm ``` ```python versioningit ``` -------------------------------- ### Run dyce unit tests with tox and pytest Source: https://github.com/posita/dyce/blob/main/docs/contrib.md Activates the virtual environment and runs unit tests using tox, with optional arguments for both tox and pytest. ```sh % cd …/path/to/dyce % . .venv/bin/activate % tox [TOX_ARGS... [-- PYTEST_ARGS...]] … ``` -------------------------------- ### Break out dyce.viz into anydyce Source: https://github.com/posita/dyce/blob/main/docs/notes.md Separates the visualization module 'dyce.viz' into its own dedicated repository, 'anydyce'. This modularization aims to streamline development and allow for independent evolution of the visualization components. ```python dyce.viz ``` ```python anydyce ``` -------------------------------- ### Benchmark .h(slice(3)) with 6@P(H({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1})) Source: https://github.com/posita/dyce/blob/main/docs/assets/perf_rolls_with_counts.txt Evaluates the performance of .h(slice(3)) with the 6@P(H(...)) input configuration, executing 10,000 loops. This benchmark contributes to understanding performance variations with input size. ```text (6@P(H({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1}))).h(slice(3)): 56 µs ± 111 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each) ``` -------------------------------- ### Roll dice and get outcomes Source: https://github.com/posita/dyce/blob/main/docs/rollin.md Performs a roll using the configured SelectionRoller and retrieves the outcomes. Includes setting a deterministic random number generator for reproducible results. ```python #!python >>> import random >>> from dyce import rng >>> rng.RNG = random.Random(1633438514) >>> roll = r_best_3_of_3d6_d8.roll() >>> tuple(roll.outcomes()) (1, 5, 6) ``` -------------------------------- ### Ironsworn Simulation with Dyce (Python) Source: https://github.com/posita/dyce/blob/main/docs/translations.md Demonstrates how to use the Dyce library for simulating Ironsworn mechanics. It shows how to define dependent terms and use partial application for parameter manipulation, aiding in probability analysis and visualization. ```python --8<-- "docs/assets/plot_ironsworn.py" ``` -------------------------------- ### Benchmark .h(slice(1)) with 4@P(H({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1})) Source: https://github.com/posita/dyce/blob/main/docs/assets/perf_rolls_with_counts.txt Analyzes the performance of the .h(slice(1)) function using the same input structure as the previous benchmark. The test is run for 100,000 loops to capture precise execution time metrics. ```text (4@P(H({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1}))).h(slice(1)): 12.9 µs ± 27.4 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) ``` -------------------------------- ### Run Asset Sanity Check with Tox Source: https://github.com/posita/dyce/blob/main/helpers/release-checklist.md Executes the 'assets' environment within Tox to perform a sanity check on project assets. This is a preliminary step to ensure assets are in order before further release procedures. ```shell tox -e assets # sanity check ``` -------------------------------- ### Composing Dice Pools (Python) Source: https://github.com/posita/dyce/blob/main/docs/rollin.md Demonstrates how to create a pool of dice rollers by combining multiple roller instances. This example shows rolling two d100 dice and accessing their total and individual outcomes. ```python two_r_d100s = PoolRoller(sources=(r_d100, r_d100)) roll_two = two_r_d100s.roll() roll_two.total() tuple(roll_two.outcomes()) ``` -------------------------------- ### Benchmark .h(slice(2)) with 6@P(H({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1})) Source: https://github.com/posita/dyce/blob/main/docs/assets/perf_rolls_with_counts.txt Measures the performance of .h(slice(2)) using a different input configuration (6@P(H(...))). The test runs 10,000 loops to provide comparative performance data. ```text (6@P(H({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1}))).h(slice(2)): 25.9 µs ± 94.9 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each) ``` -------------------------------- ### Dyce Evaluation - Functions Source: https://github.com/posita/dyce/blob/main/docs/dyce.evaluation.md API documentation for key functions within the Dyce evaluation module. ```APIDOC ## Dyce Evaluation Functions ### Description Details the various functions available for performing evaluations, aggregations, and data transformations within the Dyce library. ### aggregate_weighted **Type**: Function **Description**: Aggregates results based on associated weights. ### expandable **Type**: Function **Description**: Indicates or facilitates expansion of evaluation results, possibly for nested structures. ### explode **Type**: Function **Description**: Transforms or 'explodes' evaluation results, potentially flattening nested data. ### foreach **Type**: Function **Description**: Iterates over evaluation results, applying a specified operation to each element. ``` -------------------------------- ### Generate dyce class diagrams with PyGraphviz and Graphviz Source: https://github.com/posita/dyce/blob/main/docs/contrib.md Sets CPATH and LIBRARY_PATH environment variables to help PyGraphviz locate the native Graphviz library, then runs tox to check class diagrams. ```sh CPATH=/opt/local/include LIBRARY_PATH=/optlocal/lib tox -e check-classdiagrams ``` -------------------------------- ### Append Outcomes with SubstitutionRoller in Python Source: https://github.com/posita/dyce/blob/main/docs/rollin.md The SubstitutionRoller can also append new outcomes instead of replacing them. This is controlled by the `coalesce_mode` parameter set to `CoalesceMode.APPEND`. This example shows appending a new roll when the outcome value is 1. ```python >>> import random >>> from dyce import rng >>> rng.RNG = random.Random(1639492287) >>> from dyce.r import CoalesceMode, SubstitutionRoller >>> r_d6 = R.from_value(H(6)) >>> r_append = SubstitutionRoller( ... lambda outcome: r_d6.roll() if outcome.value == 1 else outcome, ... r_d6, ... coalesce_mode=CoalesceMode.APPEND, ... max_depth=2, ... ) >>> r_append.roll() Roll( r=SubstitutionRoller( expansion_op= at ...>, source=ValueRoller(value=H({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1}), annotation=''), coalesce_mode=, max_depth=2, annotation='', ), roll_outcomes=( RollOutcome( value=1, sources=(), ), RollOutcome( value=1, sources=( RollOutcome( value=1, sources=(), ), ), ), RollOutcome( value=2, sources=( RollOutcome( value=1, sources=( RollOutcome( value=1, sources=(), ), ), ), ), ), ), source_rolls=(...), ) ``` -------------------------------- ### Deterministic Dice Rolling Setup for Arithmetic (Python) Source: https://github.com/posita/dyce/blob/main/docs/rollin.md Establishes a deterministic environment for testing arithmetic operations on dice rollers. It patches the random number generator with a specific seed to ensure consistent results during testing. ```python import random from dyce import rng rng.RNG = random.Random(1633438430) ``` -------------------------------- ### Benchmark .h(slice(5)) with 6@P(H({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1})) Source: https://github.com/posita/dyce/blob/main/docs/assets/perf_rolls_with_counts.txt Assesses the performance of .h(slice(5)) with the 6@P(H(...)) input, running 1,000 loops. This benchmark highlights performance at the highest tested slice index for this configuration. ```text (6@P(H({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1}))).h(slice(5)): 227 µs ± 1.62 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each) ``` -------------------------------- ### Push Release Tag to Remote Source: https://github.com/posita/dyce/blob/main/helpers/release-checklist.md Pushes the current release tag to the 'origin' remote repository. The tag being pushed is the latest annotated tag, typically obtained using 'git describe --abbrev=0'. The '--force' option can be used to overwrite the remote tag if necessary. ```shell git push origin [--force] "$( git describe --abbrev=0 )" ``` -------------------------------- ### Replace Outcomes with SubstitutionRoller in Python Source: https://github.com/posita/dyce/blob/main/docs/rollin.md The SubstitutionRoller replaces outcomes based on a condition defined by a lambda function. It can be configured with a coalesce mode and maximum depth. This example demonstrates replacing outcomes where the value is 1 with a new roll. ```python >>> import random >>> from dyce import rng >>> rng.RNG = random.Random(1639492287) >>> from dyce.r import CoalesceMode, SubstitutionRoller >>> r_d6 = R.from_value(H(6)) >>> r_replace = SubstitutionRoller( ... lambda outcome: r_d6.roll() if outcome.value == 1 else outcome, ... r_d6, ... max_depth=2, ... ) >>> r_replace.roll() Roll( r=SubstitutionRoller( expansion_op= at ...>, source=ValueRoller(value=H({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1}), annotation=''), coalesce_mode=, max_depth=2, annotation='', ), roll_outcomes=( RollOutcome( value=None, sources=( RollOutcome( value=1, sources=(), ), ), ), RollOutcome( value=None, sources=( RollOutcome( value=1, sources=( RollOutcome( value=1, sources=(), ), ), ), ), ), RollOutcome( value=2, sources=( RollOutcome( value=1, sources=( RollOutcome( value=1, sources=(), ), ), ), ), ), ), source_rolls=(...), ) ``` -------------------------------- ### Wrap H.vs with Lambda for Outcome Enumeration in Python Source: https://github.com/posita/dyce/blob/main/docs/translations.md This Python snippet demonstrates how to use a lambda function to wrap the `H.vs` method. This wrapped function is then passed to the `risus_combat_driver` to enumerate resolution outcomes from different starting dice configurations. ```python ... risus_combat_driver( u, t, lambda u, t: (u@H(6)).vs(t@H(6)) ) ... ``` -------------------------------- ### dyce.evaluation.expandable Decorator Usage Source: https://github.com/posita/dyce/blob/main/docs/dyce.md Demonstrates the usage of the expandable decorator from the dyce.evaluation package. This decorator is useful for substitutions, explosions, and modeling complex computations with dependent terms. ```python from dyce.evaluation import expandable @expandable def complex_computation(input): # ... computation logic ... return result ``` -------------------------------- ### Benchmark .h(slice(5)) with P(H(...), H(...), H(...), 3@P(H(...))) Source: https://github.com/posita/dyce/blob/main/docs/assets/perf_rolls_with_counts.txt Analyzes the performance of .h(slice(5)) with the highly complex P(H(...)) input. This benchmark, running 100 loops, shows the maximum tested performance impact for this input configuration. ```text (P(H({-2: 1, -1: 1, 0: 1, 1: 1, 2: 1, 3: 1}), H({-1: 1, 0: 1, 1: 1, 2: 1, 3: 1, 4: 1}), H({0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1}), 3@P(H({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1})))).h(slice(5)): 16.2 ms ± 44.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) ``` -------------------------------- ### Generate Heatmap Visualization Source: https://github.com/posita/dyce/blob/main/docs/notebooks/risus.ipynb Generates a heatmap visualization to represent combat outcomes between two dice pools. It uses Matplotlib for plotting and customizes styles for clarity. The function takes a comparison function, starting dice counts, and number of scenarios as input. ```python import matplotlib.pyplot import matplotlib.style from enum import IntEnum, auto from IPython.display import display, Markdown from dyce import H class Risus(IntEnum): LOSS = -1 DRAW = auto() WIN = auto() def heatmap( us_vs_them_func, start_d: int = 3, num_scenarios: int = 3, cmap = "viridis", ): matplotlib.rcParams.update(matplotlib.rcParamsDefault) matplotlib.style.use("bmh") col_names = [e.name for e in Risus] col_ticks = list(range(len(Risus))) for i, them in enumerate(range(start_d, start_d + num_scenarios)): row_names = [] rows = [] num_rows = 3 for us in range(them, them + num_rows): row_names.append(f"{us}d6 …") results = us_vs_them_func(us, them).zero_fill(Risus) rows.append(results.distribution_xy()[-1]) ax = matplotlib.pyplot.subplot(1, num_scenarios, i + 1) ax.imshow(rows, cmap=cmap) ax.set_title(f"… vs. {them}d6") ax.set_xticks(col_ticks) ax.set_xticklabels(col_names, rotation=90) ax.set_yticks(list(range(len(rows)))) ax.set_yticklabels(row_names) for y in range(len(row_names)): for x in col_ticks: ax.text( x, y, f"{rows[y][x]:.0%}", ha="center", va="center", color="w", ) matplotlib.pyplot.tight_layout() matplotlib.pyplot.show() def md_table( challenge: str, us_vs_them_func, start_d: int = 3, num_scenarios: int = 3, ) -> str: def _md_table_rows(): yield(f" | {challenge} | " + " | ".join(i.name for i in Risus) + " |") yield("|:---:|:---:|:---:|:---:|") for t in range(start_d, start_d + num_scenarios): for u in range(t, t + 3): results = us_vs_them_func(u, t).zero_fill(Risus) yield(f"| {u}d6 vs. {t}d6 | " + " | ".join(f"{prob:0.2%}" for prob in results.distribution_xy()[-1]) + " |") if t < start_d + num_scenarios - 1: yield(" | | " + " | ".join("" for i in Risus) + " |") return display(Markdown("\n".join(_md_table_rows()))) us_vs_them_func = lambda u, t: (u @ H(6)).vs(t @ H(6)) md_table("Standard
(First Round)", us_vs_them_func) heatmap(us_vs_them_func) ``` -------------------------------- ### Dyce Brawl with Optional Swap Visualization with Python Source: https://github.com/posita/dyce/blob/main/docs/translations.md Demonstrates visualization of the 'brawl with optional swap' function using Dyce's `foreach`. It displays statistical outcomes for different dice pool sizes, showcasing the impact of the swap. ```Python res = foreach(brawl_w_optional_swap, p_result_a=3@P(6), p_result_b=3@P(6)) print(res.format()) ``` ```Python res = foreach(brawl_w_optional_swap, p_result_a=4@P(6), p_result_b=4@P(6)) print(res.format()) ``` -------------------------------- ### Initialize Risus Dice Pool in Dyce Source: https://github.com/posita/dyce/blob/main/docs/notebooks/risus.ipynb This Python snippet initializes a dice pool for the Risus game system within the Dyce framework. It assumes the Dyce library is installed and configured for use. The output is a Dyce dice pool object ready for rolls. ```python from dyce import P # Initialize a dice pool for Risus with a standard setup risus_pool = P(3 @ 'd6') print(risus_pool) ``` -------------------------------- ### Arithmetic Operations on Dice Rollers (Python) Source: https://github.com/posita/dyce/blob/main/docs/rollin.md Illustrates the use of arithmetic operators to compose dice rollers. This example shows adding a constant value to a d12 roller and rolling the resulting composite roller, demonstrating its structure and outcome. ```python d12 = H(12) r_d12_add_4 = ValueRoller(d12) + 4 r_d12_add_4.roll() ``` -------------------------------- ### HableOpsMixin Class Documentation - dyce.h Source: https://github.com/posita/dyce/blob/main/docs/dyce.h.md Documentation for the HableOpsMixin class in the dyce.h module. This mixin likely provides common operators for 'Hable' types, enabling operations like addition, replacement, and coalescence. ```python class HableOpsMixin: """Mixin for providing operators for ``HableT``. This mixin defines the following operators: * ``+``: ``dyce.sum`` * ``|``: ``dyce.coalesce`` * ``/``: ``dyce.replace`` """ def __add__(self, other): return dyce.sum(self, other) def __or__(self, other): return dyce.coalesce(self, other) def __truediv__(self, other): return dyce.replace(self, other) ``` -------------------------------- ### Benchmark .h(slice(4)) with 6@P(H({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1})) Source: https://github.com/posita/dyce/blob/main/docs/assets/perf_rolls_with_counts.txt Tests the performance of .h(slice(4)) using the 6@P(H(...)) input structure. The benchmark runs 10,000 loops to assess performance at a higher slice index. ```text (6@P(H({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1}))).h(slice(4)): 117 µs ± 637 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each) ``` -------------------------------- ### Benchmark .h(slice(2)) with P(H(...), H(...), H(...), H(...))) Source: https://github.com/posita/dyce/blob/main/docs/assets/perf_rolls_with_counts.txt Tests the performance of .h(slice(2)) with the very complex P(H(...)) input. The benchmark runs 1,000 loops, demonstrating the substantial time cost for slicing deeper into such data structures. ```text (P(H({-3: 1, -2: 1, -1: 1, 0: 1, 1: 1, 2: 1}), H({-2: 1, -1: 1, 0: 1, 1: 1, 2: 1, 3: 1}), H({-1: 1, 0: 1, 1: 1, 2: 1, 3: 1, 4: 1}), H({0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1}))).h(slice(2)): 1.64 ms ± 2.83 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each) ``` -------------------------------- ### dyce.evaluation.foreach Function Usage Source: https://github.com/posita/dyce/blob/main/docs/dyce.md Illustrates the usage of the foreach function from the dyce.evaluation package. This serves as a convenient shorthand for iterative computations within the dyce framework. ```python from dyce.evaluation import foreach results = foreach(items, computation_function) ``` -------------------------------- ### Define Dice Rolls and Custom Evaluation Source: https://github.com/posita/dyce/blob/main/docs/notebooks/great_weapon_fighting.ipynb Defines a standard dice roll ('single_attack') and a more complex roll incorporating a custom evaluation function ('great_weapon_fighting') that implements the 'Great Weapon Fighting' rule from tabletop games. This rule rerolls 1s and 2s to the higher value. ```python from dyce import H from dyce.evaluation import HResult, foreach single_attack = 2 @ H(6) + 5 def gwf(result: HResult): return result.h if result.outcome in (1, 2) else result.outcome great_weapon_fighting = 2 @ foreach(gwf, result=H(6)) + 5 ``` -------------------------------- ### Benchmark .h(slice(3)) with P(H(...), H(...), H(...), 3@P(H(...))) Source: https://github.com/posita/dyce/blob/main/docs/assets/perf_rolls_with_counts.txt Evaluates the performance of .h(slice(3)) with the highly complex P(H(...)) input. Running 100 loops, this benchmark highlights the substantial time cost associated with slicing deeper into such structures. ```text (P(H({-2: 1, -1: 1, 0: 1, 1: 1, 2: 1, 3: 1}), H({-1: 1, 0: 1, 1: 1, 2: 1, 3: 1, 4: 1}), H({0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1}), 3@P(H({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1})))).h(slice(3)): 15.9 ms ± 51.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) ``` -------------------------------- ### Generate Basic Dyce Visualization Source: https://github.com/posita/dyce/blob/main/docs/notebooks/histogram.ipynb This code snippet demonstrates how to create and visualize a basic Dyce object. It imports necessary components from 'dyce' and 'anydyce', then uses 'jupyter_visualize' to render a plot representing a 3-sided die with 6 faces. ```python from dyce import H, P from anydyce import jupyter_visualize jupyter_visualize( [3 @ H(6)], selected_name="Bar Plot", ) ``` -------------------------------- ### Dyce H and P Objects: Generating Random Rolls Source: https://github.com/posita/dyce/blob/main/README.md Shows how Dyce H (histogram) and P (pool) objects can be used to generate random rolls. It provides examples of rolling a single six-sided die and generating a tuple of rolls from a pool of six ten-sided dice. ```python >>> d6 = H(6) >>> d6.roll() # doctest: +SKIP 4 >>> d10 = H(10) - 1 >>> p_6d10 = 6@P(d10) >>> p_6d10.roll() # doctest: +SKIP (0, 1, 2, 3, 5, 7) ``` -------------------------------- ### Define Dice Roll Expressions and Custom Logic Source: https://github.com/posita/dyce/blob/main/docs/notebooks/advantage.ipynb Defines various dice roll expressions including normal hits, critical hits, and advantage rolls. It also implements a custom function 'crit' to apply specific logic based on roll outcomes, and calculates an advantage-weighted roll. ```python from dyce import H, P from dyce.evaluation import HResult, foreach normal_hit = H(12) + 5 critical_hit = 3 @ H(12) + 5 advantage = (2 @ P(20)).h(-1) def crit(result: HResult): if result.outcome == 20: return critical_hit elif result.outcome + 5 >= 14: return normal_hit else: return 0 advantage_weighted = foreach(crit, result=advantage) ``` -------------------------------- ### Markdown Badge Integration Source: https://github.com/posita/dyce/blob/main/README.md Integrates a 'dyce-powered' badge using Markdown syntax. It includes a link to the Dyce project and specifies an alt text for accessibility. ```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!" ``` -------------------------------- ### Visualize Complete Combat Scenarios Source: https://github.com/posita/dyce/blob/main/docs/notebooks/risus.ipynb Generates markdown tables and heatmaps for complete combat scenarios using the 'risus_combat_driver'. This allows for a comprehensive visualization of combat outcomes across various dice configurations and includes options for customizing the heatmap's color scheme. ```python from functools import partial us_vs_them_func = partial(risus_combat_driver, us_vs_them_func = lambda u, t: (u @ H(6)).vs(t @ H(6))) md_table("Standard
(Complete Combat)", us_vs_them_func) heatmap(us_vs_them_func, cmap="cividis_r") ``` -------------------------------- ### Commit Staged Changes with Release Message Source: https://github.com/posita/dyce/blob/main/helpers/release-checklist.md Stages all updated files and commits them with a pre-formatted release message. The message includes the release version, dynamically obtained using 'python -m versioningit --next-version .', and a placeholder for release notes. ```shell git add --update && git commit --edit --message "$( printf 'Release v%s\n\n' "$( python -m versioningit --next-version . )" )" ``` -------------------------------- ### Benchmark .h(slice(0)) with P(H(...), H(...), H(...), H(...))) Source: https://github.com/posita/dyce/blob/main/docs/assets/perf_rolls_with_counts.txt Measures the performance of .h(slice(0)) with a very complex P(H(...)) structure. The benchmark runs 100,000 loops, establishing a baseline for extremely nested inputs. ```text (P(H({-3: 1, -2: 1, -1: 1, 0: 1, 1: 1, 2: 1}), H({-2: 1, -1: 1, 0: 1, 1: 1, 2: 1, 3: 1}), H({-1: 1, 0: 1, 1: 1, 2: 1, 3: 1, 4: 1}), H({0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1}))).h(slice(0)): 4.23 µs ± 20.4 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) ```