From 22170650c04da8bc45c1086618413195f029e767 Mon Sep 17 00:00:00 2001 From: bertieb Date: Wed, 10 Feb 2021 12:16:12 +0000 Subject: [PATCH] Split reroll-determining to own function Aids unit testing which is needed for good practice and as we are seeing bugs creep in around unnecessary rerolls --- dice.ts | 98 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 41 deletions(-) diff --git a/dice.ts b/dice.ts index 3ccf59b..6a16afa 100644 --- a/dice.ts +++ b/dice.ts @@ -259,6 +259,49 @@ class Asphodice extends D10 { * - dice: Array - final outcome * - balance: number - +/- of outcomes (successes/failures) */ + + /** + * Determines if a reroll is needed + * + * @remarks + * + * In some cases we don't reroll: + * - reroll dice cancel each other out + * - all are above cutoff (=> auto-success -- NB TODO crits) + * - all below cutoff + */ + rerollNeeded(resultDice: Array): boolean{ + // 1. if no re-rolls we can finish here + if (!(resultDice.includes(this.passCrit) || resultDice.includes(this.failCrit))) { + // results.total = results.dice.reduce((acc: number, curr: number) => acc + curr); + return false; + } + + // count successes and fails + let rerollGood = countOccurrencesOfNumber(resultDice, this.passCrit); + let rerollBad = countOccurrencesOfNumber(resultDice, this.failCrit); + + // 2. only reroll if they don't cancel each other out + if (rerollGood == rerollBad) { + // console.log("Good = Bad, no need to reroll"); + return false; + // results.total = results.dice.reduce((acc: number, curr: number) => acc + curr); + } + + // 3. If all dice are above/below cutoff we don't need to reroll + if (this.allAboveCutOff(resultDice)) { + console.log("All above cutoff, auto-success", resultDice); + return false; + } else if (this.allBelowCutOff(resultDice)) { + console.log("All below cutoff, auto-fail", resultDice); + return false; + } + + // We should re-roll + return true; + + } + roll (numToRoll: number): DiceResult { let results: DiceResult = { total: 0, dice: [] }; @@ -266,48 +309,21 @@ class Asphodice extends D10 { for (let i = 0; i < numToRoll; i++) { results.dice.push(randIntMinOne(this.sides)); } - - // Check for re-rolls - // 1. if no re-rolls we can finish here - if (!(results.dice.includes(this.passCrit) || results.dice.includes(this.failCrit))) { - // results.total = results.dice.reduce((acc: number, curr: number) => acc + curr); - results.reroll = false; - } else { - // count successes and fails - let rerollGood = countOccurrencesOfNumber(results.dice, this.passCrit); - let rerollBad = countOccurrencesOfNumber(results.dice, this.failCrit); - - // 2. only reroll if they don't cancel each other out - if (rerollGood == rerollBad) { - // console.log("Good = Bad, no need to reroll"); - results.reroll = false; - // results.total = results.dice.reduce((acc: number, curr: number) => acc + curr); - } - // If all dice are above/below cutoff we don't need to reroll - // 3a. Above - else if (this.allAboveCutOff(results.dice)) { - console.log("All above cutoff, auto-success", results.dice); - results.reroll = false; - } - // 3b. Below - else if (this.allBelowCutOff(results.dice)) { - console.log("All below cutoff, auto-fail", results.dice); - results.reroll = false; - } - // Reroll - else { - // Reminder: arr1 = arr2 is a copy by reference! - let olddice = results.dice.slice(); - if (rerollGood > rerollBad) { - // Re-roll low (<6) dice for chance of success - results.dice = this.rerollLowDice(results.dice); - } else { - // Re-roll high (>=6) dice for chance of failure - results.dice = this.rerollHighDice(results.dice); - } - results.olddice = olddice; - results.reroll = true; + // Reroll? + if (this.rerollNeeded(results.dice)) { + // Reminder: arr1 = arr2 is a copy by reference! + let olddice = results.dice.slice(); + let rerollGood = countOccurrencesOfNumber(olddice, this.passCrit); + let rerollBad = countOccurrencesOfNumber(olddice, this.failCrit); + if (rerollGood > rerollBad) { + // Re-roll low (<6) dice for chance of success + results.dice = this.rerollLowDice(results.dice); + } else { + // Re-roll high (>=6) dice for chance of failure + results.dice = this.rerollHighDice(results.dice); } + results.olddice = olddice; + results.reroll = true; } results.balance = this.countOutcomeBalance(results.dice);