### Initial UI Setup
Source: https://github.com/highdiceroller/icepool/blob/main/apps/year_zero_engine.html
Performs the initial setup by updating rolls, the chart, and the search query when the page loads.
```javascript
updateRolls();
updateChart();
updateSearchQueryFromForms();
```
--------------------------------
### Initialize Pyodide and Icepool
Source: https://github.com/highdiceroller/icepool/blob/main/apps/cortex_prime.html
Loads Pyodide and installs the icepool library. This is the initial setup for running Python code in the browser.
```javascript
setLoadingText('Loading pyodide')
let pyodide = await loadPyodide({
indexURL: "https://cdn.jsdelivr.net/pyodide/v0.26.0/full/",
});
await pyodide.loadPackage([
"micropip"
], {messageCallback : setLoadingText});
setLoadingText('Loading icepool')
await pyodide.runPythonAsync(
` import micropip
await micropip.install('icepool==1.6.0')
import js
import pyodide
import icepool
from bisect import bisect_left
from icepool import Die, MultisetEvaluator, Order, Pool, highest, coin, multiset_function
from functools import cache
possible_die_sizes = [4, 6, 8, 10, 12]
zero_die = Die([0])
class CortexEvaluator(MultisetEvaluator):
def __init__(self, drop_lowest, keep, target_effect):
# drop_lowest doesn't include the effect die
# it may be negative, will be rectified at start
self._drop_lowest = drop_lowest
self._keep = keep
self._target_effect = target_ef`
);
```
--------------------------------
### Install Icepool
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/ironsworn.ipynb
Install the icepool library using pip. This is a prerequisite for using the library's functionalities.
```python
%pip install icepool
```
--------------------------------
### Install and Import icepool
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/isaksen2016.ipynb
Installs the icepool library and imports necessary modules for dice game calculations.
```python
%pip install icepool
import icepool
from math import sqrt
import time
start_ns = time.perf_counter_ns()
```
--------------------------------
### Install and Import Icepool Libraries
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/l5r.ipynb
Installs necessary libraries (ipywidgets, icepool) using piplite and imports icepool and time for performance measurement. This is for environments like JupyterLite.
```Python
import piplite
await piplite.install("ipywidgets")
await piplite.install("icepool")
import icepool
import time
```
--------------------------------
### Install Icepool in JupyterLite REPL
Source: https://github.com/highdiceroller/icepool/blob/main/index.html
Example code to install the icepool package within a JupyterLite REPL environment. This is useful for interactive exploration of the library.
```python
import piplite
await piplite.install("icepool")
import icepool
```
--------------------------------
### Initialize Pyodide and Load Icepool
Source: https://github.com/highdiceroller/icepool/blob/main/apps/year_zero_engine.html
Sets up Pyodide, loads the micropip package, and installs the icepool library. This is the initial step for running Python code in the browser.
```javascript
async function initPyodide() {
setLoadingText('Loading pyodide')
let pyodide = await loadPyodide({
indexURL: "https://cdn.jsdelivr.net/pyodide/v0.26.0/full/",
});
await pyodide.loadPackage(["micropip"], {messageCallback : setLoadingText});
setLoadingText('Loading icepool')
await pyodide.runPythonAsync(
` import micropip
await micropip.install('icepool==1.6.0')
import js
import pyodide
import icepool
from functools import cache
possible_die_sizes = [6, 8, 10, 12]
`
);
}
```
--------------------------------
### Initialize Pyodide and Load Icepool
Source: https://github.com/highdiceroller/icepool/blob/main/apps/ability_scores.html
Loads Pyodide, installs the 'icepool' package, and runs initial Python code. Uses 'setLoadingText' for progress updates.
```javascript
async function initPyodide() {
setLoadingText('Loading pyodide')
let pyodide = await loadPyodide({
indexURL: "https://cdn.jsdelivr.net/pyodide/v0.26.0/full/",
});
await pyodide.loadPackage({"micropip"}, {messageCallback : setLoadingText} );
setLoadingText('Loading icepool')
await pyodide.runPythonAsync(
`
import micropip
await micropip.install('icepool==1.6.0')
import js
import pyodide
import math
import icepool
from icepool import d4, d6, d8, d10, d12, d20
def set_rank_data(index, die):
selected_dist = js.document.getElementById('rankDistSelect').value
if selected_dist == 'pmf':
data = [die.probability(x, percent=True) for x in range(1, 21)]
else:
data = [die.probability('>=', x, percent=True) for x in range(1, 21)]
for i in range(1, min_ability):
data[i - 1] = math.nan
for i in range(max_ability + 1, 21):
data[i - 1] = math.nan
js.rankChart.data.datasets[index].data = pyodide.ffi.to_js(data)
table_text = '
' % x) for x in data)
js.document.getElementById('rankTableRow%d' % index).innerHTML = table_text
class RankWithRestart(icepool.MultisetEvaluator):
def __init__(self, rank, restart_count, restart_value):
self._rank = rank
self._restart_count = restart_count
self._restart_value = restart_value
def next_state(self, state, outcome, count):
total_count, trigger, result = state or (0, 0, None)
total_count += count
if total_count < self._restart_count and outcome <= self._restart_value:
return icepool.Reroll
if total_count > self._rank and result is None:
result = outcome
return total_count, trigger, result
def final_outcome(self, final_state):
return final_state[-1]
def order(self):
return icepool.Order.Descending
def extra_outcomes(self, outcomes):
return range(1, 21)
class SumWithRestart(icepool.MultisetEvaluator):
def __init__(self, cost_map, restart_count, restart_value):
self._cost_map = cost_map
self._restart_count = restart_count
self._restart_value = restart_value
def next_state(self, state, outcome, count):
total_count, trigger, total_cost = state or (0, 0, 0)
total_cost += self._cost_map[outcome] * min(count, 6 - total_count)
total_count += count
if total_count < self._restart_count and outcome <= self._restart_value:
return icepool.Reroll
return total_count, trigger, total_cost
def final_outcome(self, final_state):
return final_state[-1]
def order(self):
return icepool.Order.Descending
def extra_outcomes(self, outcomes):
return range(1, 21)
`
);
}
```
--------------------------------
### Install Icepool using pip
Source: https://github.com/highdiceroller/icepool/blob/main/README.md
Use this command to install the Icepool package. It is a pure Python implementation and can be included directly in your project if needed.
```bash
pip install icepool
```
--------------------------------
### Serve JupyterLite Distribution Locally
Source: https://github.com/highdiceroller/icepool/blob/main/index.html
Instructions for serving the JupyterLite distribution on localhost. Requires navigating to the notebooks directory and installing necessary packages.
```bash
cd ./notebooks
pip install jupyterlab_server pkginfo
pip install --pre jupyterlite
jupyter lite serve
```
--------------------------------
### Initial Setup and Periodic Updates
Source: https://github.com/highdiceroller/icepool/blob/main/apps/icecup.html
Performs an initial update of the log scale and sets up an interval to display the computation time. The computation time is updated every 100 milliseconds.
```javascript
// Initial run.
updateLogScale();
setInterval(() => {
let computationTime = 0.0;
if (endTime >= startTime) {
computationTime = endTime - startTime;
} else {
computationTime = performance.now() + performance.timeOrigin - startTime;
}
document.getElementById("computation_time").textContent = 'Computation time: ' + (computationTime * 0.001).toFixed(3) + ' s';
}, 100)
runCode();
```
--------------------------------
### Initial Setup and Event Listeners
Source: https://github.com/highdiceroller/icepool/blob/main/apps/ability_scores.html
Initializes application state by calling update functions and setting up event listeners for various user interface elements. These listeners handle changes and input events to trigger relevant updates.
```javascript
let rollReadyPromise = updateRoll();
updateRankChart();
let pricesReadyPromise = updatePrices();
updatePricesChart();
updateSearchQueryFromForms();
```
```javascript
let single_array_inputs = document.querySelector('#single_array_inputs');
single_array_inputs.addEventListener('change', validateInputsAndUpdate);
single_array_inputs.addEventListener('input', updateAllIfValid);
```
```javascript
let reset_single_ability = document.querySelector('#reset_single_ability');
reset_single_ability.addEventListener('click', resetSingleArray);
```
```javascript
let multiple_array_inputs = document.querySelector('#multiple_array_inputs');
multiple_array_inputs.addEventListener('change', validateInputsAndUpdate);
multiple_array_inputs.addEventListener('input', updateAllIfValid);
```
```javascript
let rank_view_select = document.querySelector('#rankDistSelect');
rank_view_select.addEventListener('input', updateRankChart);
```
```javascript
let pricing_preset_select = document.querySelector('#pricingPresetSelect');
pricing_preset_select.addEventListener('input', setPricingPreset);
pricing_preset_select.addEventListener('input', updatePricesIfValid);
```
```javascript
let pricing = document.querySelector('#pricing');
pricing.addEventListener('change', validateInputsAndUpdatePrices);
pricing.addEventListener('input', updatePricesIfValid);
```
```javascript
let prices_view_dist_select = document.querySelector('#pricesViewDistSelect');
prices_view_dist_select.addEventListener('input', updatePricesChart);
```
--------------------------------
### Initialize Pyodide and Load Icepool
Source: https://github.com/highdiceroller/icepool/blob/main/apps/icecup.html
This script initializes Pyodide, a Python distribution that runs in the browser, and then installs and loads the Icepool package. It includes progress updates for the user.
```javascript
importScripts("https://cdn.jsdelivr.net/pyodide/v0.26.0/full/pyodide.js"); async function initPyodide(){
self.postMessage({ cmd: 'setLoadingText', text: 'Loading pyodide' });
let pyodide = await loadPyodide({
indexURL : "https://cdn.jsdelivr.net/pyodide/v0.26.0/full/",
stdout: (s) => {self.postMessage({ cmd: 'appendOutput', text: s + '\n'});},
stderr: (s) => {self.postMessage({ cmd: 'appendError', text: s + '\n'});}
});
await pyodide.loadPackage(["micropip"], {messageCallback : (s) => {self.postMessage({ cmd: 'setLoadingText', text: s });}} );
self.postMessage({ cmd: 'setLoadingText', text: 'Loading icepool' });
let icepool_version_request = icepool_version != "" ? "==" + icepool_version : "";
icepool_version = await pyodide.runPythonAsync(
`
import micropip
await micropip.install('icepool${icepool_version_request}', pre=True)
import icepool
icepool.__version__
`
);
self.postMessage({ cmd: 'setIcepoolVersion', text: icepool_version });
self.postMessage({ cmd: 'setLoadingText', text: '' });;
return pyodide;
}
let pyodideReadyPromise = initPyodide();
```
--------------------------------
### Initialize Pyodide and Icepool
Source: https://github.com/highdiceroller/icepool/blob/main/apps/legends_of_the_wulin.html
Initializes Pyodide, loads the micropip package, and installs the icepool library. It also sets up a custom WulinEvaluator for scoring dice rolls.
```python
async def initPyodide() {
setLoadingText('Loading pyodide')
let pyodide = await loadPyodide({
indexURL: "https://cdn.jsdelivr.net/pyodide/v0.26.0/full/",
});
await pyodide.loadPackage(["micropip"], {messageCallback : setLoadingText});
setLoadingText('Loading icepool')
await pyodide.runPythonAsync(
` import micropip
await micropip.install('icepool==1.6.0')
import js
import pyodide
import icepool
die = icepool.d10 - 1
die_player = icepool.Die([0])
die_opposition = icepool.Die([0])
class WulinEvaluator(icepool.MultisetEvaluator):
def next_state(self, state, outcome, count):
if state is None:
state = 0
score = count * 10 + outcome
return max(state, score)
evaluator = WulinEvaluator()
def calc_pool(prefix):
lake = [die] * int(js.document.getElementById('%slake' % prefix).value)
river = sum((([n] * int(js.document.getElementById('%s%d' % (prefix, n)).value)) for n in range(10)), [])
pool = icepool.Pool(lake + river)
return evaluator.evaluate(pool)
`
);
totalChart.options.plugins.title = {
text: "",
fullSize: false,
display: false,
};
return pyodide;
}
let pyodideReadyPromise = initPyodide();
```
--------------------------------
### Create a Deck of Numbered Cards
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/tutorial/c07_decks.ipynb
Constructs a deck with a specified range of outcomes, each duplicated a certain number of times. Ensure 'icepool' is installed.
```python
%pip install icepool
from icepool import Deck, Die
print(Deck(range(1, 14), times=4))
```
--------------------------------
### Import Icepool and Define Dice
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/stack_exchange/dependent_dice_rolls.ipynb
Installs the icepool library and imports necessary components. Defines dice for damage and modifiers used in the simulation.
```python
%pip install icepool
import icepool
from icepool import d
dc = 15
dex_save_mod = 1
int_save_mod = 1
mind_sliver_damage = 2 @ d(6)
meteor_damage = 2 @ d(6)
```
--------------------------------
### Python: Early Binding Example
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/tutorial/c06_multiset_functions.ipynb
Demonstrates early binding where a pool ('target') is bound when the multiset function is invoked. Changing 'target' after invocation does not affect the result.
```python
target = [1, 2, 3]
@multiset_function
def early_binding_example(a):
return (a & target).size()
print(early_binding_example(d6.pool(3)))
target = [1]
print(early_binding_example(d6.pool(3)))
```
--------------------------------
### Python: Correlated Rolls Example
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/tutorial/c06_multiset_functions.ipynb
Shows how to achieve correlated results by passing the pool ('t') as an argument to the multiset function, ensuring the same roll is used for comparisons.
```python
@multiset_function
def two_vs_target(a, b, t):
return a >= t, b >= t
print(two_vs_target(d6.pool(6), (d6 + 6).pool(6), d12.pool(1)))
```
--------------------------------
### Measure Time Elapsed After Loading
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/isaksen2016.ipynb
Measures and prints the time elapsed in seconds since a starting point, typically after a loading or initialization phase. Useful for performance benchmarking.
```python
end_ns = time.perf_counter_ns()
elapsed_s = (end_ns - start_ns) * 1e-9
print(f'Elapsed time after loading: {elapsed_s:0.3f} s')
```
--------------------------------
### Implement Largest Straight Evaluator with initial_state and final_outcome
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/tutorial/c08_evaluators.ipynb
Use initial_state to set the starting state and reject unsupported orders. Use final_outcome to extract the desired result from the final state.
```python
class LargestStraightEvaluator(MultisetEvaluator):
def initial_state(self, order, outcomes, size):
# Only accept ascending order.
if order < 0:
raise UnsupportedOrder()
return 0, 0, outcomes[0]
def next_state(self, state, order, outcome, count):
"""Increments the current run if at least one `Die` rolled this outcome,
then saves the run to the state.
"""
best_run, run, prev_outcome = state
if outcome == prev_outcome + 1 and count >= 1:
run += 1
else:
run = 0
return max(best_run, run), run, outcome
def final_outcome(self, final_state, order, outcomes, size):
# Return just the length of the best run.
return final_state[0]
largest_straight_evaluator = LargestStraightEvaluator()
print(largest_straight_evaluator(d6.pool(5)))
```
--------------------------------
### Create a Weighted Die from a Dictionary
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/tutorial/c01_creating_dice.ipynb
Create a weighted die using a dictionary where keys are outcomes and values are their corresponding weights. This example creates a die where '6' has a weight of 3.
```python
another_unfair_d6 = Die({1:1, 2:1, 3:1, 4:1, 5:1, 6:3})
print(another_unfair_d6)
```
--------------------------------
### Find All Matching Sets in a Mixed Dice Pool
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/all_matching_sets.ipynb
This example shows how to use the AllMatchingSets evaluator on a mixed pool of standard dice, such as 3d12, 2d10, and 1d8. This is useful for complex dice mechanics found in some tabletop games.
```python
# Evaluate on a pool of 3d12, 2d10, 1d8.
print(all_matching_sets.evaluate(icepool.standard_pool([12, 12, 12, 10, 10, 8])))
```
--------------------------------
### Handle Success Values Above 20 in Infinity Rolls
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/infinity_universe.ipynb
This example shows how to handle success values (SV) greater than 20 in Infinity Universe rolls. It modifies the dice pool to cap SV at 20 and treat excess points as bonuses, effectively making rolls above 20 a critical. Use this when a player's SV is higher than a standard d20.
```python
# This can be done by modifying the die that goes into the pool.
# Example: a 21 SV versus a 20 SV with one die each.
from icepool import d20, lowest
print(InfinityUniverseEvaluator(a_sv=20, b_sv=20).evaluate(lowest(d20+1, 20).pool(1), d20.pool(1)))
```
--------------------------------
### Implement Limited Wildcard Evaluation in Python
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/decks/limited_wildcard.ipynb
This code defines a custom `EvalWildcard` class inheriting from `icepool.MultisetEvaluator` to handle wildcards. It specifies how wildcards can substitute for certain cards and how to evaluate the probability of forming a target hand. Ensure 'icepool' is installed via piplite.
```python
import piplite
await piplite.install("icepool")
import icepool
import time
class EvalWildcard(icepool.MultisetEvaluator):
def initial_state(self, order, *_*):
# Force ascending order.
if order < 0:
raise icepool.UnsupportedOrder()
return 0
def next_state(self, state, order, outcome, target, *counts):
# state = the number of wildcards needed.
total_count = sum(counts)
# Final: wildcards.
if outcome == 'W':
if state == 'fail':
return False
else:
return total_count >= state
if state == 'fail':
return state
# Could potentially use wildcards.
if outcome >= 'C':
return state + max(target - total_count, 0)
# Ineligible for wildcards.
if total_count < target:
return 'fail'
return state
def extra_outcomes(self, *_):
# Always process wildcard.
return ('W',)
# When expressed as a sequence, each appearance counts as one card.
target = list('ABBCDDEEE')
# When expressed as a dict, the value gives the number of cards.
deal = icepool.Deck({'A': 3, 'B': 8, 'C': 2, 'D': 3, 'E': 3, 'F': 113, 'W': 7}).deal(35)
hand = list('W')
evaluator = EvalWildcard()
start_ns = time.perf_counter_ns()
# The counts resulting from the three arguments are supplied as
# the last three arguments to next_state.
result = evaluator.evaluate(target, deal, hand)
end_ns = time.perf_counter_ns()
elapsed_ms = (end_ns - start_ns) * 1e-6
print(f'Computation time: {elapsed_ms:0.1f} ms')
print(f'{result:md:o|q==|%==}')
```
```text
Computation time: 9.9 ms
Die with denominator 903552809026475628595978062186780
| Outcome | Quantity | Probability |
|:--------|----------------------------------:|------------:|
| False | 816069609857287121983676726542308 | 90.317865% |
| True | 87483199169188506612301335644472 | 9.682135% |
```
--------------------------------
### Plot Dice Distribution with Matplotlib
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/hello_3d6.ipynb
Visualizes the probability distribution of a die object using Matplotlib. Ensure Matplotlib is installed (`pip install matplotlib`).
```python
# Plot using matplotlib.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot(die.outcomes(), die.probabilities())
plt.show()
```
--------------------------------
### Initialize Pyodide and Icepool
Source: https://github.com/highdiceroller/icepool/blob/main/apps/honkai_star_rail_relic.html
Initializes Pyodide, loads necessary packages including micropip and icepool, and sets up the Python environment for the relic calculator. It configures stat definitions and prepares the input table in the HTML.
```javascript
async function initialize() {
setLoadingText('Loading pyodide')
let pyodide = await loadPyodide({
indexURL: "https://cdn.jsdelivr.net/pyodide/v0.26.0/full/",
});
await pyodide.loadPackage(["micropip"], {messageCallback : setLoadingText} );
setLoadingText('Loading icepool')
await pyodide.runPythonAsync(
`
import micropip
await micropip.install('icepool==1.7.2a1')
import js
import pyodide
from functools import cache
from icepool import Wallenius, format_probability_inverse
stats = {
'spd' : ('SPD', 4),
'cr' : ('CRIT Rate', 6),
'cd' : ('CRIT DMG', 6),
'be' : ('Break Effect', 8),
'ehr' : ('Effect Hit Rate', 8),
'eres' : ('Effect Resist', 8),
'hp_pct' : ('HP%', 10),
'atk_pct' : ('ATK%', 10),
'def_pct' : ('DEF%', 10),
'hp' : ('HP', 10),
'atk' : ('ATK', 10),
'def' : ('DEF', 10),
}
def wanted_substat_count(haves, wants, pulls):
possible_weights = []
for stat, (full_name, weight) in stats.items():
if stat not in haves:
possible_weights.append((stat in wants, weight))
return Wallenius(possible_weights).deal(pulls).sum()
def select_substats(wants, count):
if count == 0:
return ()
result = ()
for _, stat in sorted((weight, stat) for stat, (_, weight) in stats.items()):
if stat in wants:
result = result + (stat,)
if len(result) == count:
break
return result
input_table = js.document.getElementById('input_table')
for stat, (display_string, weight) in stats.items():
row = input_table.insertRow()
row.innerHTML = f'
{display_string}
{weight}
'
row = input_table.insertRow()
row.innerHTML = f'
Other
'
`
);
let inputs = document.querySelector('#inputs');
inputs.addEventListener('input', update);
return pyodide;
}
```
--------------------------------
### Expand Pool Outcomes
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/tutorial/c05_dice_pools.ipynb
Use the `expand` method to get all possible sorted rolls from a pool. This can be inefficient for large pools.
```python
print(d6.pool(3)[0, 1, 1].expand())
```
--------------------------------
### Python: Independent Rolls Example
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/tutorial/c06_multiset_functions.ipynb
Illustrates independent rolls where pools not passed as arguments are rolled independently. The `>=` operator checks for superset.
```python
from icepool import d12
target = d12.pool(1)
# Remember, since we are dealing with multisets here, the `>=` operator means `issuperset`.
@multiset_function
def two_vs_target(a, b):
return a >= target, b >= target
print(two_vs_target(d6.pool(6), (d6 + 6).pool(6)))
```
--------------------------------
### Evaluate 10d10 Pool
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/all_matching_sets.ipynb
Evaluates a pool of 10 ten-sided dice (10d10) to determine the distribution of outcomes. This is a basic usage example.
```python
print(num_pairs.evaluate(icepool.d10.pool(10)))
```
--------------------------------
### Initialize Prices Chart with Chart.js
Source: https://github.com/highdiceroller/icepool/blob/main/apps/ability_scores.html
Sets up a line chart to display probability distributions. Requires a canvas element with id 'pricesChart'.
```javascript
var pricesChartContext = document.getElementById('pricesChart').getContext('2d');
var pricesChart = new Chart(pricesChartContext, {
type: 'line',
data: {
labels: [],
datasets: [
{
label: 'Chance',
borderColor: 'rgba(0, 120, 0, 1.0)',
data: [],
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: {
intersect: false,
},
scales: {
x: {
title: {
display: true,
text: 'Total',
},
},
y: {
beginAtZero: true,
title: {
display: true,
text: 'Chance (%)',
},
ticks: {
callback: (val) => (val.toPrecision(3) * 1.0 + '%'),
},
},
},
plugins: {
title: {
fullSize: true,
display: true,
font: {
size: 36,
},
},
legend: {
display: false,
},
tooltip: {
callbacks: {
label: (ctx) => ctx.dataset.label + ': ' + ctx.raw.toPrecision(3) + '%',
},
},
},
},
});
```
--------------------------------
### Initialize Rank Chart with Chart.js
Source: https://github.com/highdiceroller/icepool/blob/main/apps/ability_scores.html
Sets up a line chart to display rank probabilities. Requires a canvas element with id 'rankChart'.
```javascript
setInputsFromSearchQuery();
var rankChartContext = document.getElementById('rankChart').getContext('2d');
var rankChart = new Chart(rankChartContext, {
type: 'line',
data: {
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
datasets: [],
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: {
intersect: false,
},
scales: {
x: {
title: {
display: true,
text: 'Ability score',
},
},
y: {
beginAtZero: true,
title: {
display: true,
text: 'Chance (%)',
},
ticks: {
callback: (val) => (val.toPrecision(3) * 1.0 + '%'),
},
},
},
plugins: {
title: {
fullSize: true,
display: true,
font: {
size: 36,
},
},
tooltip: {
callbacks: {
label: (ctx) => ctx.dataset.label + ': ' + ctx.raw.toPrecision(3) + '%',
},
},
},
},
});
let rankColors = [
'rgba(220, 0, 240, 1.0)',
'rgba(0, 0, 240, 1.0)',
'rgba(0, 200, 240, 1.0)',
'rgba(0, 200, 0, 1.0)',
'rgba(220, 200, 0, 1.0)',
'rgba(220, 0, 0, 1.0)',
'rgba(120, 120, 120, 1.0)',
];
var rankLabels = [
'Highest',
'2nd highest',
'3rd highest',
'4th highest',
'5th highest',
'6th highest',
'Mean',
];
for (let i = 0; i < 7; i++) {
rankChart.data.datasets.push({
label: rankLabels[i],
borderColor: rankColors[i],
backgroundColor: rankColors[i],
data: rankChart.data.labels.map(x => 0.0),
});
}
```
--------------------------------
### Initialize Chart Configuration
Source: https://github.com/highdiceroller/icepool/blob/main/apps/icecup.html
Sets up a Chart.js instance for visualizing probability distributions. It configures the chart type, data structure, and various options for responsiveness, axes, tooltips, and legends. The logarithmic scale option is applied if the 'ls' query parameter is present.
```javascript
var chartContext = document.getElementById('chart').getContext('2d');
var chart = new Chart(chartContext, {
type: 'line',
data: {
labels: [],
datasets: [],
},
options: {
animation: {
duration: 0,
},
responsive: true,
maintainAspectRatio: false,
interaction: {
intersect: false,
},
scales: {
x: {
title: {
display: true,
text: 'Outcome',
},
},
y: {
beginAtZero: true,
title: {
display: true,
text: 'Probability',
},
},
},
plugins: {
title: {
fullSize: true,
display : true,
font: {
size: 36,
},
},
legend: {
labels: {
usePointStyle: true,
},
},
tooltip : {
usePointStyle: true,
callbacks: {},
},
filler: {
propagate: true,
},
},
elements: {
point: {
radius: 3,
},
},
},
});
if (document.getElementById('ls').checked) {
chart.options.scales.y.type = 'logarithmic';
chart.options.scales.y.ticks.callback = (val) => (val.toExponential());
}
```
--------------------------------
### Create a Custom Die from a List
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/tutorial/c01_creating_dice.ipynb
Create a custom die where each element in the list represents an outcome that appears once. This example creates a standard six-sided die.
```python
from icepool import Die
another_d6 = Die([1, 2, 3, 4, 5, 6])
print(another_d6)
```
--------------------------------
### Initialize Ace Editor
Source: https://github.com/highdiceroller/icepool/blob/main/apps/icecup.html
Sets up the Ace code editor with Python mode, GitHub theme, and soft tabs. It also observes layout changes to resize the editor accordingly. The initial code is loaded from the editor's value, URL parameters, or a default string.
```javascript
var editor = ace.edit("editor");
editor.setTheme("ace/theme/github");
editor.session.setMode("ace/mode/python");
editor.setOptions({"useSoftTabs" : true, "scrollPastEnd" : 1.0});
var resizer = new ResizeObserver(entries => {editor.resize();});
resizer.observe(document.getElementById("main"));
var initialCode = 'from icepool import d\n\noutput(3 @ d(6))\n';
var url_code = searchParams.get('c');
if (url_code) {
try {
initialCode = LZString.decompressFromEncodedURIComponent(url_code);
} catch (err) {
document.getElementById("error").textContent = "Failed to decompress code from URL.";
}
}
editor.setValue(initialCode, 1);
```
--------------------------------
### Initialize Pyodide (JavaScript)
Source: https://github.com/highdiceroller/icepool/blob/main/apps/year_zero_engine.html
Initializes Pyodide, a Python interpreter in the browser, and returns a promise for its readiness.
```javascript
let pyodideReadyPromise = initPyodide();
```
--------------------------------
### Element-wise Operations on Vector Dice
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/tutorial/c04_advanced_dice.ipynb
When adding Vector-outcome dice, operations are applied element-wise, not as concatenation. This example shows the sum of two one-hot encoded dice.
```python
print(die + die)
```
--------------------------------
### Print All Action Sets
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/stack_exchange/all_action_stress.ipynb
Prints all possible action sets. This can generate a large amount of output, especially with larger action pools.
```python
print(result)
```
--------------------------------
### Simulate Larger Two-Colored Dice Pool
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/stack_exchange/green_red_elimination.ipynb
This example demonstrates evaluating a larger and more complex two-colored dice pool. It uses the same GreenRed evaluator defined previously.
```python
# A larger calculation.
print(green_red.evaluate([d12, d10, d8, d6, d4, d12, d10, d8, d6, d4], [d12, d10, d8, d6, d4, d12, d10, d8, d6, d4]))
```
--------------------------------
### Initialize Base Case and Dice
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/stack_exchange/game_of_threes.ipynb
Sets up the initial state for the game simulation and defines a standard six-sided die.
```python
results = [Die([vectorize(0, 0)])]
die = Die([vectorize(1, 0), vectorize(2, 0), vectorize(0, 1), vectorize(4, 0), vectorize(5, 0), vectorize(6, 0)])
```
--------------------------------
### Event Listeners for UI Interactions
Source: https://github.com/highdiceroller/icepool/blob/main/apps/icecup.html
Sets up event listeners for various UI elements including run, stop, switch to latest, keyboard shortcuts, and input changes for equation, greater/less than, log scale, and type. Also includes functionality to copy the URL.
```javascript
document.getElementById("run").addEventListener("click", runCode);
document.getElementById("stop").addEventListener("click", interruptExecution);
document.getElementById("switch_to_latest").addEventListener("click", switchToLatest);
document.body.addEventListener('keydown', function (e) {
if (e.key == 'Enter' && (e.ctrlKey || e.metaKey)) {
e.preventDefault();
run();
}
});
document.getElementById("eq").addEventListener("change", runCode);
document.getElementById("ge").addEventListener("change", runCode);
document.getElementById("le").addEventListener("change", runCode);
document.getElementById("ls").addEventListener("change", updateLogScale);
document.getElementById("t").addEventListener("change", runCode);
```
```javascript
document.getElementById("copy_url").addEventListener("click", function (e) {
navigator.clipboard.writeText(window.location.href);
document.getElementById("copy_url").textContent = 'Copied!';
setTimeout( () => {
document.getElementById("copy_url").textContent = 'Copy URL';
}, 1000);
});
```
--------------------------------
### Calculate Probability of 15+ on 10+ of 17 Dice
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/stack_exchange/odds_of_rolling_high_all_the_time.ipynb
Calculates the probability of rolling 15 or higher on at least 10 out of 17 dice. Requires the icepool library to be installed.
```python
%pip install icepool
import icepool
# Dimension 0 is the number of dice that scored 15+.
# Dimension 1 is the number that scored 9-.
die = icepool.d20.map(lambda x: icepool.vectorize(x >= 15, x < 10))
# Roll 17 of them and sum.
seventeen_rolls = 17 @ die
print('Chance of rolling 15+ on at least 10 out of 17 dice:')
print(seventeen_rolls.marginals[0] >= 10)
```
--------------------------------
### Initialize and Update Pyodide
Source: https://github.com/highdiceroller/icepool/blob/main/apps/honkai_star_rail_relic.html
Initializes Pyodide and then calls an update function. This is typically used to set up the Python environment in the browser and trigger an initial data refresh or display.
```javascript
let pyodideReadyPromise = initialize();
update();
```
--------------------------------
### Calculate Intersection of Pools
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/tutorial/c05_dice_pools.ipynb
The `&` operator calculates the intersection of two pools, counting matching pairs. This example finds the number of matching pairs from two pools of 3d6.
```python
print((d6.pool(3) & d6.pool(3)).size())
```
--------------------------------
### Dice Immutability Example
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/tutorial/c02_dice_operators.ipynb
Illustrates that Dice objects are immutable. The '+=' operator reassigns the variable 'a' to a new Die object, leaving the original d6 Die unchanged.
```python
a = d6
a += d6 # This assigns a new Die object to a. It does not modify the original Die.
print(d6) # The original Die is unchanged.
```
--------------------------------
### Create a Standard 6-Sided Die Directly
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/tutorial/c01_creating_dice.ipynb
Import and use `d6` directly for a standard six-sided die. This is a convenient shortcut for `d(6)`.
```python
from icepool import d6
print(d6)
```
--------------------------------
### Check for Superset Roll
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/tutorial/c05_dice_pools.ipynb
The `>=` operator checks if the roll of the left pool is a superset of the right pool's outcomes. This example checks for at least one 1 and one 2.
```python
print(d6.pool(3) >= [1, 2])
```
--------------------------------
### Create a Deck with Mixed Duplicates
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/tutorial/c07_decks.ipynb
Demonstrates creating a deck where some outcomes are duplicated a set number of times, and others are themselves decks that are duplicated. This differs from Die construction where weights are shared.
```python
# Take a deck of 1-13, duplicate it 4 times, then throw in two 14s.
deck = Deck({Deck(range(1, 14)): 4, 14: 2})
print(deck)
# Roll 1d6:
# On 1-4: the result is 1d13.
# On 5-6: the result is 14.
print(Die({Die(range(1, 14)): 4, 14: 2}))
```
--------------------------------
### Create and Combine Dice in Python
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/hello_3d6.ipynb
Shows how to create standard dice (d6, d97), define custom dice using mappings or lists, and combine them using addition or the '@' operator to represent rolling multiple dice. Includes version checks for Python and Icepool.
```python
%pip install icepool
import icepool
import sys
from importlib.metadata import version
print('python version:', sys.version)
print('icepool version:', version('icepool'))
# Create a d6. Here's a few different ways...
# Just import it. In fact, you can import any-sided standard die.
from icepool import d6, d97
# Use the d() function.
d6 = icepool.d(6)
# Specify a mapping from outcomes to weights.
d6 = icepool.Die({1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1})
# Give the outcomes as separate arguments. Each will be weighted once.
d6 = icepool.Die([1, 2, 3, 4, 5, 6])
# Now we want three of them added together. Here's a couple of ways to do that:
# Just add them together.
die = d6 + d6 + d6
# Use the @ operator, which means roll the left side, then roll the right side that many times and add.
# The "3" becomes a die which always rolls the number 3.
die = 3 @ icepool.d6
# The result is another die with the probability distribution of 3d6.
# Print a table of the outcomes, weights, and probabilities.
print(die)
```
--------------------------------
### Calculate Push Zeros If Fail and No Initial Bane (Python)
Source: https://github.com/highdiceroller/icepool/blob/main/apps/year_zero_engine.html
Similar to calc_push_zeros_if_fail, but also considers the initial bane count. Pushes zeros to fail if success or bane is greater than zero, or if a win is not possible.
```python
def calc_push_zeros_if_fail_and_no_initial_bane(success, bane, z6, z8, z10, z12, s10, s12):
if success > 0 or bane > 0:
return icepool.vectorize(success, 0)
if not can_win(success, bane, z6, z8, z10, z12, 0, 0):
return icepool.vectorize(success, 0)
return calc_push_zeros(success, bane, z6, z8, z10, z12, s10, s12)
```
--------------------------------
### Initial Chart and Roll Updates
Source: https://github.com/highdiceroller/icepool/blob/main/apps/legends_of_the_wulin.html
Initializes the calculator by performing the first updates for player roll, opposition roll, and the total chart, and synchronizes the form state with the URL query parameters.
```javascript
updatePlayerRoll();
updateOppositionRoll();
updateTotalChart();
updateSearchQueryFromForms();
```
--------------------------------
### Define outcome distribution mapping
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/stack_exchange/game_of_threes.ipynb
This code snippet illustrates the structure for mapping pool sizes to their corresponding outcome distributions. It serves as a starting point for dynamic programming or memoization approaches.
```python
# Maps pool size -> outcome distribution.
```
--------------------------------
### Generate 4d6 Keep Highest 3 Dice Distribution
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/ability_scores/completely_unfair.ipynb
Installs the icepool library and creates a dice object representing the outcome of rolling 4 six-sided dice and keeping the highest 3.
```python
%pip install icepool
import icepool
one_ability = icepool.d6.highest(4, 3)
```
--------------------------------
### Simulate and Plot Reroll Strategies
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/broken_compass.ipynb
Simulates both 'Known-difficulty' and 'Always-reroll' strategies for various pool sizes and plots the results. This helps visualize the performance differences between the strategies.
```python
known_difficulty_results = []
always_reroll_results = []
for pool_size in pool_sizes:
initial = pool_size @ die
known_difficulty_results.append(initial.map(known_difficulty_risk))
always_reroll_results.append(initial.map(always_reroll_risk))
plot_results(known_difficulty_results, always_reroll_results)
```
--------------------------------
### Initialize Success Chart
Source: https://github.com/highdiceroller/icepool/blob/main/apps/year_zero_engine.html
Initializes a Chart.js bar chart to display success probabilities. Configures axes, tooltips, and responsiveness. The chart is configured with 'y' as the index axis.
```javascript
var successChartContext = document.getElementById('successChart').getContext('2d');
var successChart = new Chart(successChartContext, {
type: 'bar',
data: {
labels: [],
},
options: {
indexAxis: 'y',
responsive: true,
maintainAspectRatio: false,
animation: false,
scales: {
x: {
title: {
display: true,
text: 'Chance (%)',
},
stacked: true,
min: 0.0,
max: 100.0,
ticks: {
callback: (val) => (val.toPrecision(3) * 1.0 + '%'),
},
},
y: {
stacked: true,
grid: {
display: false,
},
},
},
datasets: {
bar: {
categoryPercentage: 1.0,
borderWidth: 1,
},
},
plugins: {
title: {
fullSize: true,
display: true,
font: {
size: 36,
},
},
legend: {
display: false,
},
tooltip: {
displayColors: false,
callbacks: {
label: (ctx) => ctx.dataset.label + ': ' + ctx.raw.toPrecision(3) + '%',
},
position: 'barCenter',
},
},
},
});
```
--------------------------------
### Get the Value of a Dropped Die
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/tutorial/c05_dice_pools.ipynb
Access the outcome of a specific die within a sorted pool using a single index. This returns a `Die` representing the distribution of that specific die's value.
```python
# What was the value of the dropped die?
print(d6.pool(4)[0])
```
--------------------------------
### Reroll Specific Outcomes with Icepool
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/tutorial/c04_advanced_dice.ipynb
Use the `Reroll` special value within `Die.map()` to reroll specified outcomes. This example rerolls 1s and 2s on a d6, effectively changing the probability distribution.
```python
from icepool import Reroll, d6
d6.reroll([1, 2], depth='inf')
print(d6.map({1: Reroll, 2: Reroll}))
```
--------------------------------
### Get Highest of Two Dice Rolls
Source: https://github.com/highdiceroller/icepool/blob/main/notebooks/tutorial/c03_dice_functions.ipynb
Use the `highest` function to determine the maximum outcome when rolling two dice. This function returns a new Die object representing the distribution of the highest roll.
```python
%pip install icepool
from icepool import d6, highest, lowest, highest, lowest
print(highest(d6, d6))
```