-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7d5f8a0
commit b1bf4a9
Showing
4 changed files
with
85 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
--- | ||
title: Match Win Calculator | ||
date: "2024-11-06 21:48:00 -0700" | ||
entry: app_tools_match_win | ||
--- | ||
<p> | ||
Many games and sports play multiple rounds, also known as first-to-n or best-of-(2n-1). | ||
This structure amplifies skill gaps, as the underdog is more likely to lose the match than an individual round, which <a href="https://stats.stackexchange.com/a/458808">can be calculated with a negative binomial distribution</a>. | ||
</p> | ||
|
||
<p> | ||
In the table below, the row corresponds to the number of points for the opponent, and | ||
the column corresponds to the number of points for the current player. | ||
The cell shows the probability that the current player wins the match. | ||
Double-click the slider for P to reset to 0.5. | ||
</p> | ||
|
||
{% include app.html %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import AppToolsMatchWin from './tools/match_win/AppToolsMatchWin.svelte' | ||
|
||
import loadApp from './victorz/app' | ||
|
||
loadApp(AppToolsMatchWin) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<script lang="ts"> | ||
import { pStore } from '@/util/svelte' | ||
const n = pStore('tool/match_win/n', 10) | ||
const p = pStore('tool/match_win/p', 0.5) | ||
$: memo = ((n, p) => { | ||
const r = Array(n).fill(undefined).map(() => Array(n).fill(undefined)) | ||
for (let i = n-1; i >= 0; i--) { | ||
for (let j = n-1; j >= 0; j--) { | ||
const i1 = i + 1 | ||
const j1 = j + 1 | ||
r[i][j] = p * (j1 == n ? 1 : r[i][j1]) + (i1 == n ? 0 : (1 - p) * r[i1][j]) | ||
} | ||
} | ||
return r | ||
})($n, $p) | ||
</script> | ||
|
||
<p>N (number of rounds to win)</p> | ||
<input type="number" class="form-control" min=1 bind:value={$n}> | ||
<input type="range" class="form-range" min=1 max=32 bind:value={$n}> | ||
|
||
<p>P (probability of winning a round)</p> | ||
<input type="number" class="form-control" min=0 max=1 step=0.01 bind:value={$p}> | ||
<input type="range" class="form-range" min=0 max=1 step=0.001 bind:value={$p} on:dblclick={() => $p = 0.5}> | ||
|
||
<table class="table table-striped table-bordered table-hover caption-top w-auto"> | ||
<caption>Probability of winning first-to-{$n}/best-of-{2*$n-1}</caption> | ||
<thead> | ||
<tr> | ||
<th rowspan=2 colspan=2></th> | ||
<th colspan={$n}>Player score</th> | ||
</tr> | ||
<tr> | ||
{#each memo as _, i} | ||
<th>{i}</th> | ||
{/each} | ||
</tr> | ||
</thead> | ||
<tbody> | ||
{#each memo as row, i} | ||
<tr> | ||
{#if !i} | ||
<th rowspan={$n}><div style="writing-mode: vertical-lr; text-align: end; transform: rotate(180deg)">Opponent score</div></th> | ||
{/if} | ||
<th>{i}</th> | ||
{#each row as v} | ||
{@const balanced = v * (1-v) * 2} | ||
<td | ||
title={`${v}\n${v / (1-v)}:1\n1:${1/v - 1}`} | ||
style="background-color: hsl({v * v * 180} {40 + balanced * 60} {80 + balanced * 20})"> | ||
{v.toFixed(5)} | ||
</td> | ||
{/each} | ||
</tr> | ||
{/each} | ||
</tbody> | ||
</table> |