Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
HighDiceRoller committed Oct 1, 2024
2 parents 6687038 + c7ad7dc commit 4a48a26
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 121 deletions.
118 changes: 59 additions & 59 deletions CHANGELOG.md

Large diffs are not rendered by default.

38 changes: 15 additions & 23 deletions apps/ability_scores.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ <h2>Probability distribution of the 6 highest ability scores</h2>
Show:
<select id="rankDistSelect">
<option value="pmf">Chance of rolling exactly</option>
<option value="ccdf"><i>Chance of rolling at least</option>
<option value="ccdf">Chance of rolling at least</option>
</select>
</div>
<div class="chart_container">
Expand Down Expand Up @@ -196,7 +196,7 @@ <h2>Multiple arrays and total price</h2>
Show:
<select id="pricesViewDistSelect">
<option value="pmf">Chance of rolling exactly</option>
<option value="ccdf"><i>Chance of rolling at least</option>
<option value="ccdf">Chance of rolling at least</option>
</select>
</div>
<div class="chart_container">
Expand Down Expand Up @@ -275,8 +275,6 @@ <h2>How does it work?</h2>
<script type="text/javascript">
setInputsFromSearchQuery();

var maxProb = 1.0;

var rankChartContext = document.getElementById('rankChart').getContext('2d');
var rankChart = new Chart(rankChartContext, {
type: 'line',
Expand Down Expand Up @@ -420,29 +418,28 @@ <h2>How does it work?</h2>
setLoadingText('Loading icepool')
await pyodide.runPythonAsync(`
import micropip
await micropip.install('icepool==1.5.0')
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(rank, die):
data = (0,) * 20
def set_rank_data(index, die):
selected_dist = js.document.getElementById('rankDistSelect').value
if selected_dist == 'pmf':
data = [100.0 * x for x in die.probabilities()]
data = [die.probability(x, percent=True) for x in range(1, 21)]
else:
data = [100.0 * x for x in die.probabilities('>=')]
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[rank].data = pyodide.ffi.to_js([float(x) for x in data])
table_text = '<td style="text-align: left;">%s</td><td>%0.2f</td>' % (js.rankLabels[rank], die.mean())
js.rankChart.data.datasets[index].data = pyodide.ffi.to_js(data)
table_text = '<td style="text-align: left;">%s</td><td>%0.2f</td>' % (js.rankLabels[index], die.mean())
table_text += ''.join(('<td></td>' if math.isnan(x) else '<td>%0.2f%%</td>' % x) for x in data)
js.document.getElementById('rankTableRow%d' % rank).innerHTML = table_text
js.document.getElementById('rankTableRow%d' % index).innerHTML = table_text
class RankWithRestart(icepool.MultisetEvaluator):
def __init__(self, rank, restart_count, restart_value):
Expand All @@ -465,7 +462,7 @@ <h2>How does it work?</h2>
def order(self):
return icepool.Order.Descending
def alignment(self, outcomes):
def extra_outcomes(self, outcomes):
return range(1, 21)
class SumWithRestart(icepool.MultisetEvaluator):
Expand All @@ -488,7 +485,7 @@ <h2>How does it work?</h2>
def order(self):
return icepool.Order.Descending
def alignment(self, outcomes):
def extra_outcomes(self, outcomes):
return range(1, 21)
`);
Expand Down Expand Up @@ -550,28 +547,23 @@ <h2>How does it work?</h2>
single_ability = single_ability.reroll(lambda x: x < min_ability or x > max_ability)
single_ability = single_ability.highest(num_ability_repeat)
max_prob = 0.0
ranks = []
for i in range(6):
rank_ability = RankWithRestart(i, restart_count, restart_value).evaluate(single_ability.pool(num_abilities)[-6:])
rank_ability, _, _ = icepool.align_range(rank_ability, 1, 20)
ranks.append(rank_ability)
max_prob = max(max_prob, max(rank_ability.probabilities()))
ranks.append(icepool.Die(ranks))
js.maxProb = max_prob * 100.0
mean_ability = icepool.Die(ranks)
ranks.append(mean_ability)
`);
}

async function updateRankChart() {
let pyodide = await pyodideReadyPromise;

pyodide.runPython(`
for i, rank_die in enumerate(ranks):
set_rank_data(i, rank_die)
for i, rank in enumerate(ranks):
set_rank_data(i, rank)
`);
rankChart.update();
}
Expand Down
26 changes: 13 additions & 13 deletions apps/cortex_prime.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ <h2>Total and effect die</h2>
Show:
<select id="distSelect">
<option value="pmf">Chance of total exactly</option>
<option value="ccdf" selected="selected"><i>Chance of beating difficulty</option>
<option value="ccdf" selected="selected">Chance of beating difficulty</option>
</select>
</div>
<div class="chart_container"><canvas id="totalChart"></canvas></div>
Expand Down Expand Up @@ -125,7 +125,7 @@ <h2>Hitches</h2>
Show:
<select id="hitchDistSelect">
<option value="pmf">Chance of exactly</option>
<option value="ccdf" selected><i>Chance of at least</option>
<option value="ccdf" selected>Chance of at least</option>
</select>
</div>
<div class="chart_container"><canvas id="hitchChart"></canvas></div>
Expand Down Expand Up @@ -337,7 +337,7 @@ <h2>Hitches</h2>
setLoadingText('Loading icepool')
await pyodide.runPythonAsync(`
import micropip
await micropip.install('icepool==1.5.0')
await micropip.install('icepool==1.6.0')
import js
import pyodide
Expand Down Expand Up @@ -444,8 +444,8 @@ <h2>Hitches</h2>
result[5] = max(totals[5 - j] - HEROIC_MARGINS[j] for j in range(1, 6))
return tuple(result)
any_effect, d6_effect, d8_effect, d10_effect, d12_effect, beyond_effect, hitch_player_unaligned = (zero_die,) * 7
die_opposition_unaligned, hitch_opposition_unaligned = (zero_die,) * 2
any_effect, d6_effect, d8_effect, d10_effect, d12_effect, beyond_effect, hitch_player = (zero_die,) * 7
die_opposition, hitch_opposition = (zero_die,) * 2
def calc_player():
hitch_1 = js.document.getElementById('hitch1').checked
Expand Down Expand Up @@ -516,15 +516,15 @@ <h2>Hitches</h2>
let pyodide = await pyodideReadyPromise;

pyodide.runPython(`
any_effect, d6_effect, d8_effect, d10_effect, d12_effect, beyond_effect, hitch_player_unaligned = calc_player()
any_effect, d6_effect, d8_effect, d10_effect, d12_effect, beyond_effect, hitch_player = calc_player()
`);
}

async function updateOppositionRoll() {
let pyodide = await pyodideReadyPromise;

pyodide.runPython(`
opposition, hitch_opposition_unaligned = calc_opposition()
opposition, hitch_opposition = calc_opposition()
`);
}

Expand Down Expand Up @@ -615,18 +615,18 @@ <h2>Hitches</h2>

pyodide.runPython(`
hitch_player, hitch_opposition = icepool.align_range(hitch_player_unaligned, hitch_opposition_unaligned)
outcomes = icepool.consecutive(hitch_player, hitch_opposition)
js.hitchChart.data.labels = pyodide.ffi.to_js([float(x) for x in hitch_player.outcomes()])
js.hitchChart.data.labels = pyodide.ffi.to_js(outcomes)
selected_dist = js.document.getElementById('hitchDistSelect').value
if selected_dist == 'pmf':
js.hitchChart.data.datasets[0].data = pyodide.ffi.to_js([float(x) * 100.0 for x in hitch_player.probabilities()])
js.hitchChart.data.datasets[1].data = pyodide.ffi.to_js([float(x) * 100.0 for x in hitch_opposition.probabilities()])
js.hitchChart.data.datasets[0].data = pyodide.ffi.to_js([hitch_player.probability(x, percent=True) for x in outcomes])
js.hitchChart.data.datasets[1].data = pyodide.ffi.to_js([hitch_opposition.probability(x, percent=True) for x in outcomes])
else:
js.hitchChart.data.datasets[0].data = pyodide.ffi.to_js([float(x) * 100.0 for x in hitch_player.probabilities('>=')])
js.hitchChart.data.datasets[1].data = pyodide.ffi.to_js([float(x) * 100.0 for x in hitch_opposition.probabilities('>=')])
js.hitchChart.data.datasets[0].data = pyodide.ffi.to_js([hitch_player.probability('>=', x, percent=True) for x in outcomes])
js.hitchChart.data.datasets[1].data = pyodide.ffi.to_js([hitch_opposition.probability('>=', x, percent=True) for x in outcomes])
`);

hitchChart.update();
Expand Down
26 changes: 13 additions & 13 deletions apps/legends_of_the_wulin.html
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ <h2>Probability distribution of the total results</h2>
Show:
<select id="distSelect">
<option value="pmf">Chance of rolling exactly</option>
<option value="ccdf"><i>Chance of rolling at least</option>
<option value="ccdf">Chance of rolling at least</option>
</select>
</div>
<div class="chart_container"><canvas id="totalChart"></canvas></div>
Expand Down Expand Up @@ -169,16 +169,16 @@ <h2>Probability distribution of the total results</h2>
setLoadingText('Loading icepool')
await pyodide.runPythonAsync(`
import micropip
await micropip.install('icepool==1.5.0')
await micropip.install('icepool==1.6.0')
import js
import pyodide
import icepool
die = icepool.d10 - 1
die_player_unaligned = icepool.Die([0])
die_opposition_unaligned = icepool.Die([0])
die_player = icepool.Die([0])
die_opposition = icepool.Die([0])
class WulinEvaluator(icepool.MultisetEvaluator):
def next_state(self, state, outcome, count):
Expand Down Expand Up @@ -210,15 +210,15 @@ <h2>Probability distribution of the total results</h2>
let pyodide = await pyodideReadyPromise;

pyodide.runPython(`
die_player_unaligned = calc_pool('p')
die_player = calc_pool('p')
`);
}

async function updateOppositionRoll() {
let pyodide = await pyodideReadyPromise;

pyodide.runPython(`
die_opposition_unaligned = calc_pool('o')
die_opposition = calc_pool('o')
`);
}
Expand All @@ -228,22 +228,22 @@ <h2>Probability distribution of the total results</h2>

pyodide.runPython(`
die_player, die_opposition = icepool.align_range(die_player_unaligned, die_opposition_unaligned)
js.document.getElementById('successChance').innerHTML = '%0.2f%%' % ((die_player > die_opposition).mean() * 100.0)
js.document.getElementById('tieChance').innerHTML = '%0.2f%%' % ((die_player == die_opposition).mean() * 100.0)
js.document.getElementById('loseChance').innerHTML = '%0.2f%%' % ((die_player < die_opposition).mean() * 100.0)
js.totalChart.data.labels = pyodide.ffi.to_js([float(x) for x in die_player.outcomes()])
outcomes = icepool.consecutive(die_player, die_opposition)
js.totalChart.data.labels = pyodide.ffi.to_js(outcomes)
selected_dist = js.document.getElementById('distSelect').value
if selected_dist == 'pmf':
js.totalChart.data.datasets[0].data = pyodide.ffi.to_js([float(x) * 100.0 for x in die_player.probabilities()])
js.totalChart.data.datasets[1].data = pyodide.ffi.to_js([float(x) * 100.0 for x in die_opposition.probabilities()])
js.totalChart.data.datasets[0].data = pyodide.ffi.to_js([die_player.probability(x, percent=True) for x in outcomes])
js.totalChart.data.datasets[1].data = pyodide.ffi.to_js([die_opposition.probability(x, percent=True) for x in outcomes])
else:
js.totalChart.data.datasets[0].data = pyodide.ffi.to_js([float(x) * 100.0 for x in die_player.probabilities('>=')])
js.totalChart.data.datasets[1].data = pyodide.ffi.to_js([float(x) * 100.0 for x in die_opposition.probabilities('>=')])
js.totalChart.data.datasets[0].data = pyodide.ffi.to_js([die_player.probability('>=', x, percent=True) for x in outcomes])
js.totalChart.data.datasets[1].data = pyodide.ffi.to_js([die_opposition.probability('>=', x, percent=True) for x in outcomes])
`);

totalChart.update();
Expand Down
2 changes: 1 addition & 1 deletion apps/year_zero_engine.html
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ <h3>Before push</h3>
setLoadingText('Loading icepool')
await pyodide.runPythonAsync(`
import micropip
await micropip.install('icepool==1.5.0')
await micropip.install('icepool==1.6.0')
import js
import pyodide
Expand Down
2 changes: 1 addition & 1 deletion jupyter_lite_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
},
"PipliteAddon": {
"piplite_urls" : [
"https://files.pythonhosted.org/packages/py3/i/icepool/icepool-1.5.0-py3-none-any.whl",
"https://files.pythonhosted.org/packages/py3/i/icepool/icepool-1.6.0-py3-none-any.whl",
"https://files.pythonhosted.org/packages/py2.py3/i/ipywidgets/ipywidgets-7.7.1-py2.py3-none-any.whl",
"https://files.pythonhosted.org/packages/py3/j/jupyterlab-widgets/jupyterlab_widgets-1.1.1-py3-none-any.whl"
]
Expand Down
2 changes: 1 addition & 1 deletion notebooks/cthulhutech.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
},
{
"cell_type": "code",
"source": "%pip install icepool\n\nimport icepool\n\nclass CthulhuTechEval(icepool.MultisetEvaluator):\n def next_state(self, state, outcome, count):\n score, run = state or (0, 0)\n if count > 0:\n set_score = outcome * count\n run_score = 0\n run += 1\n if run >= 3:\n # This could be the triangular formula, but it's clearer this way.\n for i in range(run): run_score += (outcome - i)\n score = max(set_score, run_score, score)\n else:\n # No dice rolled this number, so the score remains the same.\n run = 0\n return score, run\n\n def final_outcome(self, final_state):\n # Return just the score.\n return final_state[0]\n \n # Outcomes should be seen in consecutive order.\n alignment = icepool.MultisetEvaluator.range_alignment\n\nimport matplotlib.pyplot as plt\n\ndefault_colors = plt.rcParams['axes.prop_cycle'].by_key()['color']\nevaluator = CthulhuTechEval()\nfigsize = (16, 9)\nfig, ax = plt.subplots(figsize=figsize)\n\nfor num_dice in range(1, 11):\n pool = icepool.d10.pool(num_dice)\n result = evaluator.evaluate(pool)\n result, _, _ = icepool.align_range(result, 0, 100)\n ax.plot(result.outcomes(), result.probabilities('>=', percent=True))\n marker_size = 64 if num_dice < 10 else 128\n ax.scatter(result.median(), 50.0,\n marker=('$%d$' % num_dice),\n facecolor=default_colors[num_dice-1],\n s=marker_size)\n\nax.set_xticks(range(0, 61, 5))\nax.set_yticks(range(0, 101, 10))\nax.set_xlim(0, 60)\nax.set_ylim(0, 100)\nax.set_xlabel('Result')\nax.set_ylabel('Chance of getting at least (%)')\nax.grid()\nplt.show()",
"source": "%pip install icepool\n\nimport icepool\n\nclass CthulhuTechEval(icepool.MultisetEvaluator):\n def next_state(self, state, outcome, count):\n score, run = state or (0, 0)\n if count > 0:\n set_score = outcome * count\n run_score = 0\n run += 1\n if run >= 3:\n # This could be the triangular formula, but it's clearer this way.\n for i in range(run): run_score += (outcome - i)\n score = max(set_score, run_score, score)\n else:\n # No dice rolled this number, so the score remains the same.\n run = 0\n return score, run\n\n def final_outcome(self, final_state):\n # Return just the score.\n return final_state[0]\n \n # Outcomes should be seen in consecutive order.\n extra_outcomes = icepool.MultisetEvaluator.consecutive\n\nimport matplotlib.pyplot as plt\n\ndefault_colors = plt.rcParams['axes.prop_cycle'].by_key()['color']\nevaluator = CthulhuTechEval()\nfigsize = (16, 9)\nfig, ax = plt.subplots(figsize=figsize)\n\nfor num_dice in range(1, 11):\n pool = icepool.d10.pool(num_dice)\n result = evaluator.evaluate(pool)\n ax.plot([x for x in range(101)], [result.probability('>=', x, percent=True) for x in range(101)])\n marker_size = 64 if num_dice < 10 else 128\n ax.scatter(result.median(), 50.0,\n marker=('$%d$' % num_dice),\n facecolor=default_colors[num_dice-1],\n s=marker_size)\n\nax.set_xticks(range(0, 61, 5))\nax.set_yticks(range(0, 101, 10))\nax.set_xlim(0, 60)\nax.set_ylim(0, 100)\nax.set_xlabel('Result')\nax.set_ylabel('Chance of getting at least (%)')\nax.grid()\nplt.show()",
"metadata": {
"trusted": true
},
Expand Down
Loading

0 comments on commit 4a48a26

Please sign in to comment.