-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunctions.js
105 lines (90 loc) · 3 KB
/
functions.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// http://www.ciphersbyritter.com/JAVASCRP/BINOMPOI.HTM#Binomial
// FACTORIALS
function Fact( x ) {
// x factorial
var t=1;
while (x > 1)
t *= x--;
return t;
}
function LnFact( x ) {
// ln(x!) by Stirling's formula
// see Knuth I: 111
if (x <= 1) x = 1;
if (x < 12)
return Math.log( Fact(Math.round(x)) );
else {
var invx = 1 / x;
var invx2 = invx * invx;
var invx3 = invx2 * invx;
var invx5 = invx3 * invx2;
var invx7 = invx5 * invx2;
var sum = ((x + 0.5) * Math.log(x)) - x;
sum += Math.log(2*Math.PI) / 2;
sum += (invx / 12) - (invx3 / 360);
sum += (invx5 / 1260) - (invx7 / 1680);
return sum;
}
}
function LnComb( n, k ) {
if ((k == 0) || (k == n)) return 0;
else
if ((k > n) || (k < 0)) return -1E38;
else return (LnFact(n) - LnFact(k) - LnFact(n-k));
}
function BinomTerm( p, n, k ) {
// for success probability p and n trials
// probability of exactly k successes
return Math.exp( LnComb(n,k)
+ k * Math.log(p)
+ (n-k) * Math.log(1-p) );
}
function ChartUpdate(chart, numberOfDice, successRate) {
var outcomes = [];
var outcomesLabel = [];
for ( k = 0; k <= numberOfDice; k++) {
prob = BinomTerm( successRate, numberOfDice, k )
outcomes.push((prob*100).toFixed(2));
outcomesLabel.push(k);
}
//update and draw the new chart
outcomesChart.data.datasets[0].data = outcomes;
outcomesChart.data.labels = outcomesLabel;
outcomesChart.update('active');
}
function NetHitsChartUpdate ( chart, numberOfDice, numberOfOpposedDice, successRate, maxNetHits) {
var netHits = [];
var netHitsLabel = [];
// No net successes
var prob = 0.0;
for (var j = 0; j <= numberOfDice; j++) {
var myProb = BinomTerm( successRate, numberOfDice, j );
for (var k = 0; k <= numberOfOpposedDice; k++) {
if (j - k <= 0) {
var yourProb = BinomTerm( successRate, numberOfOpposedDice, k );
prob = prob + myProb * yourProb;
}
}
}
netHits.push((prob * 100).toFixed(2));
netHitsLabel.push('0');
// One or more net successes
for (var i = 1; i <= Math.min(numberOfDice, maxNetHits); i++) {
prob = 0.0;
for (var j = 0; j <= numberOfDice; j++) {
var myProb = BinomTerm( successRate, numberOfDice, j );
for (var k = 0; k <= numberOfOpposedDice; k++) {
if (j - k >= i) {
var yourProb = BinomTerm( successRate, numberOfOpposedDice, k );
prob = (prob + myProb * yourProb);
}
}
}
netHits.push((prob * 100).toFixed(2));
netHitsLabel.push(String(i) + "+");
}
//update and draw the new chart
netHitsChart.data.datasets[0].data = netHits;
netHitsChart.data.labels = netHitsLabel;
netHitsChart.update('active');
}