Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 41 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,40 +114,51 @@ Trial Results
└─────────┴───────┴─────────┴───────┘

Final Balance Summary
┌─────────┬────────┐
│ (index) │ Values │
├─────────┼────────┤
│ min │ 416 │
│ p1 │ 416 │
│ p5 │ 416 │
│ p10 │ 416 │
│ p25 │ 416 │
│ p50 │ 416 │
│ p75 │ 614 │
│ p90 │ 614 │
│ p95 │ 614 │
│ p99 │ 614 │
│ max │ 614 │
└─────────┴────────┘
┌─────────┬────────┬────────┐
│ (index) │ stat │ value │
├─────────┼────────┼────────┤
│ 0 │ min │ 416 │
│ 1 │ p1 │ 416 │
│ 2 │ p5 │ 416 │
│ 3 │ p10 │ 416 │
│ 4 │ p25 │ 416 │
│ 5 │ p50 │ 416 │
│ 6 │ mean │ 515 │
│ 7 │ p75 │ 614 │
│ 8 │ p90 │ 614 │
│ 9 │ p95 │ 614 │
│ 10 │ p99 │ 614 │
│ 11 │ max │ 614 │
└─────────┴────────┴────────┘
stdDev: 140.01
95% CI: [320.96, 709.04]

Roll Count Summary
┌─────────┬────────┐
│ (index) │ Values │
├─────────┼────────┤
│ min │ 25 │
│ p1 │ 25 │
│ p5 │ 25 │
│ p10 │ 25 │
│ p25 │ 25 │
│ p50 │ 25 │
│ p75 │ 65 │
│ p90 │ 65 │
│ p95 │ 65 │
│ p99 │ 65 │
│ max │ 65 │
└─────────┴────────┘
┌─────────┬────────┬────────┐
│ (index) │ stat │ value │
├─────────┼────────┼────────┤
│ 0 │ min │ 25 │
│ 1 │ p1 │ 25 │
│ 2 │ p5 │ 25 │
│ 3 │ p10 │ 25 │
│ 4 │ p25 │ 25 │
│ 5 │ p50 │ 25 │
│ 6 │ mean │ 45 │
│ 7 │ p75 │ 65 │
│ 8 │ p90 │ 65 │
│ 9 │ p95 │ 65 │
│ 10 │ p99 │ 65 │
│ 11 │ max │ 65 │
└─────────┴────────┴────────┘
stdDev: 28.28
95% CI: [5.80, 84.20]
```

The standard deviation shows how widely the trials vary around the mean.
Roughly 68% of results will fall within one standard deviation, 95% within
two, and 99.7% within three. The 95% confidence interval is a range that is
expected to contain the true mean in 95% of repeated samples.

## table rules

`playHand` accepts a `rules` object that controls minimum bets and odds limits.
Expand Down
48 changes: 44 additions & 4 deletions monte-carlo.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,21 @@ function percentile (sorted, p) {

function summary (arr) {
const sorted = [...arr].sort((a, b) => a - b)
const mean = arr.reduce((m, v) => m + v, 0) / arr.length
const variance = arr.length > 1
? arr.reduce((m, v) => m + Math.pow(v - mean, 2), 0) / (arr.length - 1)
: 0
const stdDev = Math.sqrt(variance)
const stdErr = stdDev / Math.sqrt(arr.length)
const ci95Low = mean - (1.96 * stdErr)
const ci95High = mean + (1.96 * stdErr)

return {
min: sorted[0],
mean,
stdDev,
ci95Low,
ci95High,
max: sorted[sorted.length - 1],
p1: percentile(sorted, 1),
p5: percentile(sorted, 5),
Expand All @@ -42,8 +55,29 @@ function summary (arr) {

function summaryTable (arr) {
const obj = summary(arr)
const order = ['min', 'p1', 'p5', 'p10', 'p25', 'p50', 'p75', 'p90', 'p95', 'p99', 'max']
return order.map(k => ({ stat: k, value: obj[k] }))
const order = [
'min',
'p1',
'p5',
'p10',
'p25',
'p50',
'mean',
'p75',
'p90',
'p95',
'p99',
'max'
]
const table = order
.map(k => ({ stat: k, value: obj[k] }))
.sort((a, b) => a.value - b.value || order.indexOf(a.stat) - order.indexOf(b.stat))
return {
table,
stdDev: obj.stdDev,
ci95Low: obj.ci95Low,
ci95High: obj.ci95High
}
}

function simulateTrial ({ handsPerTrial, startingBankroll, rules }) {
Expand Down Expand Up @@ -73,10 +107,16 @@ function printResults (results) {
console.table(results.map((r, i) => ({ trial: i + 1, balance: r.balance, rolls: r.rolls })))

console.log('\nFinal Balance Summary')
console.table(summaryTable(results.map(r => r.balance)))
const balanceSummary = summaryTable(results.map(r => r.balance))
console.table(balanceSummary.table)
console.log(`stdDev: ${balanceSummary.stdDev.toFixed(2)}`)
console.log(`95% CI: [${balanceSummary.ci95Low.toFixed(2)}, ${balanceSummary.ci95High.toFixed(2)}]`)

console.log('\nRoll Count Summary')
console.table(summaryTable(results.map(r => r.rolls)))
const rollSummary = summaryTable(results.map(r => r.rolls))
console.table(rollSummary.table)
console.log(`stdDev: ${rollSummary.stdDev.toFixed(2)}`)
console.log(`95% CI: [${rollSummary.ci95Low.toFixed(2)}, ${rollSummary.ci95High.toFixed(2)}]`)
}

if (require.main === module) {
Expand Down