fix: compute DiceRoll success count from fresh roll, not stale result (Closes #16)
This commit was merged in pull request #39.
This commit is contained in:
27
.plans/issue-16-fix-diceroll-bug.md
Normal file
27
.plans/issue-16-fix-diceroll-bug.md
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# Plan: Fix DiceRoll Success Counting Bug (Issue #16)
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
The `DiceRoll.roll()` method computes `numberOfSuccesses` from the stale `this.result` list instead of the freshly rolled values. The fix is to capture the new roll in a local variable before passing it to `copy()`, so both `result` and `numberOfSuccesses` reference the same fresh data.
|
||||||
|
|
||||||
|
## Steps
|
||||||
|
|
||||||
|
### Step 1: Fix `Dice.kt`
|
||||||
|
**File**: `sharedUI/src/commonMain/kotlin/org/shahondin1624/lib/functions/Dice.kt`
|
||||||
|
|
||||||
|
Change the `roll()` method to:
|
||||||
|
1. Roll dice into a local `val newResult`
|
||||||
|
2. Count successes from `newResult`
|
||||||
|
3. Pass both to `copy()`
|
||||||
|
|
||||||
|
### Step 2: Write unit test
|
||||||
|
**File**: `sharedUI/src/commonTest/kotlin/org/shahondin1624/DiceTest.kt`
|
||||||
|
|
||||||
|
Create a new test file with:
|
||||||
|
- Test that after `roll()`, `numberOfSuccesses` equals the count of values >= threshold in `result`
|
||||||
|
- Test with default threshold (5) and custom threshold
|
||||||
|
- Test that `result` list has correct size (matches `numberOfDice`)
|
||||||
|
- Test the `countSuccesses` extension function directly
|
||||||
|
|
||||||
|
## AC Verification Checklist
|
||||||
|
1. [ ] `numberOfSuccesses` is computed from newly rolled values (not stale result list)
|
||||||
|
2. [ ] Unit test verifying correct success count after `.roll()`
|
||||||
11
sharedUI/src/commonMain/kotlin/org/shahondin1624/lib/functions/Dice.kt
Normal file → Executable file
11
sharedUI/src/commonMain/kotlin/org/shahondin1624/lib/functions/Dice.kt
Normal file → Executable file
@@ -15,8 +15,11 @@ data class DiceRoll(
|
|||||||
val result: List<Int> = listOf(),
|
val result: List<Int> = listOf(),
|
||||||
val numberOfSuccesses: Int = -1
|
val numberOfSuccesses: Int = -1
|
||||||
) {
|
) {
|
||||||
fun roll(numberForSuccessOrHigher: Int = 5): DiceRoll = this.copy(
|
fun roll(numberForSuccessOrHigher: Int = 5): DiceRoll {
|
||||||
result = rollXDice(sides = this.numberOfSides, numberOfDice = this.numberOfDice),
|
val newResult = rollXDice(sides = this.numberOfSides, numberOfDice = this.numberOfDice)
|
||||||
numberOfSuccesses = result.countSuccesses(numberForSuccessOrHigher)
|
return this.copy(
|
||||||
)
|
result = newResult,
|
||||||
|
numberOfSuccesses = newResult.countSuccesses(numberForSuccessOrHigher)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
89
sharedUI/src/commonTest/kotlin/org/shahondin1624/DiceTest.kt
Normal file
89
sharedUI/src/commonTest/kotlin/org/shahondin1624/DiceTest.kt
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
package org.shahondin1624
|
||||||
|
|
||||||
|
import org.shahondin1624.lib.functions.DiceRoll
|
||||||
|
import org.shahondin1624.lib.functions.countSuccesses
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class DiceTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun rollProducesCorrectSuccessCount() {
|
||||||
|
val diceRoll = DiceRoll(numberOfDice = 10).roll()
|
||||||
|
val expectedSuccesses = diceRoll.result.count { it >= 5 }
|
||||||
|
assertEquals(
|
||||||
|
expectedSuccesses,
|
||||||
|
diceRoll.numberOfSuccesses,
|
||||||
|
"numberOfSuccesses should match the count of dice >= 5 in result"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun rollWithCustomThresholdProducesCorrectSuccessCount() {
|
||||||
|
val diceRoll = DiceRoll(numberOfDice = 10).roll(numberForSuccessOrHigher = 4)
|
||||||
|
val expectedSuccesses = diceRoll.result.count { it >= 4 }
|
||||||
|
assertEquals(
|
||||||
|
expectedSuccesses,
|
||||||
|
diceRoll.numberOfSuccesses,
|
||||||
|
"numberOfSuccesses should match the count of dice >= 4 in result"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun rollResultHasCorrectNumberOfDice() {
|
||||||
|
val numberOfDice = 6
|
||||||
|
val diceRoll = DiceRoll(numberOfDice = numberOfDice).roll()
|
||||||
|
assertEquals(
|
||||||
|
numberOfDice,
|
||||||
|
diceRoll.result.size,
|
||||||
|
"result list size should equal numberOfDice"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun countSuccessesExtensionFunction() {
|
||||||
|
val rolls = listOf(1, 2, 3, 4, 5, 6)
|
||||||
|
assertEquals(2, rolls.countSuccesses(5), "Only 5 and 6 should be successes with threshold 5")
|
||||||
|
assertEquals(3, rolls.countSuccesses(4), "4, 5, and 6 should be successes with threshold 4")
|
||||||
|
assertEquals(1, rolls.countSuccesses(6), "Only 6 should be a success with threshold 6")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun freshRollDoesNotUseStaleResult() {
|
||||||
|
// Create a DiceRoll with an empty result (default), then roll.
|
||||||
|
// Before the fix, numberOfSuccesses would always be 0 because it counted
|
||||||
|
// successes from the stale empty result list.
|
||||||
|
val initial = DiceRoll(numberOfDice = 20)
|
||||||
|
assertEquals(listOf<Int>(), initial.result, "Initial result should be empty")
|
||||||
|
assertEquals(-1, initial.numberOfSuccesses, "Initial numberOfSuccesses should be -1")
|
||||||
|
|
||||||
|
val rolled = initial.roll()
|
||||||
|
assertEquals(20, rolled.result.size, "Rolled result should have 20 dice")
|
||||||
|
|
||||||
|
val manualCount = rolled.result.count { it >= 5 }
|
||||||
|
assertEquals(
|
||||||
|
manualCount,
|
||||||
|
rolled.numberOfSuccesses,
|
||||||
|
"numberOfSuccesses must reflect the new roll, not the stale empty list"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun consecutiveRollsProduceIndependentResults() {
|
||||||
|
val diceRoll = DiceRoll(numberOfDice = 10)
|
||||||
|
val firstRoll = diceRoll.roll()
|
||||||
|
val secondRoll = diceRoll.roll()
|
||||||
|
|
||||||
|
// Both rolls should independently have correct success counts
|
||||||
|
assertEquals(
|
||||||
|
firstRoll.result.count { it >= 5 },
|
||||||
|
firstRoll.numberOfSuccesses,
|
||||||
|
"First roll success count should be correct"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
secondRoll.result.count { it >= 5 },
|
||||||
|
secondRoll.numberOfSuccesses,
|
||||||
|
"Second roll success count should be correct"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user