|
@@ -12,69 +12,85 @@ declare let ItemCountSet: Array<ItemCount>; |
|
|
type EnumObject<T extends string> = { [K in T]?: number }; |
|
|
type EnumObject<T extends string> = { [K in T]?: number }; |
|
|
type outcomeCountObject = EnumObject<Outcomes>; |
|
|
type outcomeCountObject = EnumObject<Outcomes>; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let rerollCounts: { [rerolled: string]: number }; |
|
|
|
|
|
let totalCounts: { [total: string]: number }; |
|
|
|
|
|
let balanceCounts: { [balance: string]: number }; |
|
|
|
|
|
let outcomeCounts: outcomeCountObject = {}; |
|
|
|
|
|
|
|
|
|
|
|
let diceCounts: { [dice: string]: number} = {}; |
|
|
|
|
|
|
|
|
|
|
|
let numRolls = 1000000; |
|
|
|
|
|
let maxDice = 10; |
|
|
|
|
|
|
|
|
|
|
|
for (let numDice = 1; numDice <= maxDice; numDice++) { |
|
|
|
|
|
let asphodice = new Asphodice(); |
|
|
|
|
|
rerollCounts = { "true": 0, "false": 0 }; |
|
|
|
|
|
totalCounts = {}; |
|
|
|
|
|
balanceCounts = {}; |
|
|
|
|
|
outcomeCounts = { [Outcomes.Success]: 0, [Outcomes.Fail]: 0 } // TODO: others |
|
|
|
|
|
// reset dice counts |
|
|
|
|
|
for (let i = 1; i <= 10; i++) { |
|
|
|
|
|
diceCounts[String(i)] = 0; |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Singleton-type class for all dice-statistic related needs |
|
|
|
|
|
*/ |
|
|
|
|
|
export class RollStats { |
|
|
|
|
|
rerollCounts: { [rerolled: string]: number } = {}; |
|
|
|
|
|
totalCounts: { [total: string]: number } = {}; |
|
|
|
|
|
balanceCounts: { [balance: string]: number } = {}; |
|
|
|
|
|
outcomeCounts: outcomeCountObject = {}; |
|
|
|
|
|
diceCounts: { [dice: string]: number} = {}; |
|
|
|
|
|
|
|
|
|
|
|
numRolls = 100000; |
|
|
|
|
|
maxDice = 10; |
|
|
|
|
|
numDice = 4; |
|
|
|
|
|
|
|
|
|
|
|
constructor() { |
|
|
|
|
|
this.resetCounts(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// count rerolls, totals and outcome balances |
|
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < numRolls; i++) { |
|
|
|
|
|
let result = asphodice.roll(numDice) |
|
|
|
|
|
|
|
|
|
|
|
if (result.reroll) { |
|
|
|
|
|
rerollCounts.true += 1; |
|
|
|
|
|
} else { |
|
|
|
|
|
rerollCounts.false += 1; |
|
|
|
|
|
|
|
|
resetCounts(): void { |
|
|
|
|
|
// TODO: find out if there's a way to this |
|
|
|
|
|
// by iterating over members |
|
|
|
|
|
this.rerollCounts = { "true": 0, "false": 0 }; |
|
|
|
|
|
this.totalCounts = {}; |
|
|
|
|
|
this.balanceCounts = {}; |
|
|
|
|
|
this.outcomeCounts = { [Outcomes.Success]: 0, [Outcomes.Fail]: 0 } // TODO: others |
|
|
|
|
|
for (let i = 1; i <= 10; i++) { |
|
|
|
|
|
this.diceCounts[String(i)] = 0; |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
let total = String(result.total); |
|
|
|
|
|
if (total in totalCounts) { |
|
|
|
|
|
totalCounts[total]++; |
|
|
|
|
|
} else { |
|
|
|
|
|
totalCounts[total] = 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
doRolls(): void { |
|
|
|
|
|
let asphodice = new Asphodice(); |
|
|
|
|
|
// count rerolls, totals and outcome balances |
|
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < this.numRolls; i++) { |
|
|
|
|
|
let result = asphodice.roll(this.numDice) |
|
|
|
|
|
|
|
|
|
|
|
if (result.reroll) { |
|
|
|
|
|
this.rerollCounts.true += 1; |
|
|
|
|
|
} else { |
|
|
|
|
|
this.rerollCounts.false += 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
let total = String(result.total); |
|
|
|
|
|
if (total in this.totalCounts) { |
|
|
|
|
|
this.totalCounts[total]++; |
|
|
|
|
|
} else { |
|
|
|
|
|
this.totalCounts[total] = 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
let balance = String(result.balance); |
|
|
|
|
|
if (balance in this.balanceCounts) { |
|
|
|
|
|
this.balanceCounts[balance]++; |
|
|
|
|
|
} else { |
|
|
|
|
|
this.balanceCounts[balance] = 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (result.outcome == Outcomes.Success) { |
|
|
|
|
|
let count = this.outcomeCounts[Outcomes.Success]; |
|
|
|
|
|
this.outcomeCounts[Outcomes.Success] = Number(count) + 1; |
|
|
|
|
|
} else if (result.outcome == Outcomes.Fail) { |
|
|
|
|
|
let count = this.outcomeCounts[Outcomes.Fail]; |
|
|
|
|
|
this.outcomeCounts[Outcomes.Fail] = Number(count) + 1; |
|
|
|
|
|
} // TODO: crits, once those are implemented |
|
|
|
|
|
|
|
|
|
|
|
for (let die of result.dice) { |
|
|
|
|
|
this.diceCounts[String(die)] += 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
let balance = String(result.balance); |
|
|
|
|
|
if (balance in balanceCounts) { |
|
|
|
|
|
balanceCounts[balance]++; |
|
|
|
|
|
} else { |
|
|
|
|
|
balanceCounts[balance] = 1; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (result.outcome == Outcomes.Success) { |
|
|
|
|
|
let count = outcomeCounts[Outcomes.Success]; |
|
|
|
|
|
outcomeCounts[Outcomes.Success] = Number(count) + 1; |
|
|
|
|
|
} else if (result.outcome == Outcomes.Fail) { |
|
|
|
|
|
let count = outcomeCounts[Outcomes.Fail]; |
|
|
|
|
|
outcomeCounts[Outcomes.Fail] = Number(count) + 1; |
|
|
|
|
|
} // TODO: crits, once those are implemented |
|
|
|
|
|
|
|
|
|
|
|
for (let die of result.dice) { |
|
|
|
|
|
diceCounts[String(die)] += 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
reportRolls(): string { |
|
|
|
|
|
var report = ""; |
|
|
|
|
|
|
|
|
|
|
|
return report; |
|
|
} |
|
|
} |
|
|
console.log(numRolls, "rolls,", numDice, "dice. Reroll counts:", rerollCounts); |
|
|
|
|
|
console.log(numRolls, "rolls,", numDice, "dice. Total counts:", totalCounts); |
|
|
|
|
|
console.log(numRolls, "rolls,", numDice, "dice. Balance counts:", balanceCounts); |
|
|
|
|
|
console.log(numRolls, "rolls,", numDice, "dice. Dice counts:", diceCounts); |
|
|
|
|
|
console.log(numRolls, "rolls,", numDice, "dice. Outcome counts:", outcomeCounts); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
let rollstats = new RollStats(); |
|
|
|
|
|
rollstats.doRolls(); |
|
|
|
|
|
console.log(rollstats); |