From 8884d047a67f3508d8d36ca0e39fa2b57d645d71 Mon Sep 17 00:00:00 2001 From: Thomas Andres Gomez Date: Fri, 29 Nov 2024 11:47:11 +0100 Subject: [PATCH] Add support for adventage, disadventage and emphasis rolls. --- .../desktop/lwa/business/RollUseCase.kt | 60 ++++++++++++++++++- .../business/SkillValueComputationUseCase.kt | 16 ++--- .../lwa/parser/arithmetic/Instruction.kt | 9 ++- 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/RollUseCase.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/RollUseCase.kt index b5f46ca..64811ec 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/RollUseCase.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/RollUseCase.kt @@ -1,13 +1,67 @@ package com.pixelized.desktop.lwa.business +import com.pixelized.desktop.lwa.parser.arithmetic.Instruction +import kotlin.math.abs +import kotlin.math.max +import kotlin.math.min + class RollUseCase { fun rollD100(): Int { - return roll(quantity = 1, faces = 100) + return roll(modifier = null, quantity = 1, faces = 100) } - fun roll(quantity: Int, faces: Int): Int { - return sum(count = quantity) { (Math.random() * faces.toDouble() + 1).toInt() } + fun roll(dice: Instruction.Dice): Int { + return roll( + modifier = dice.modifier, + quantity = dice.quantity, + faces = dice.faces, + ) + } + + fun roll(modifier: Instruction.Dice.Modifier?, quantity: Int, faces: Int): Int { + print("{") + return sum(count = quantity) { + when (modifier) { + Instruction.Dice.Modifier.ADVANTAGE -> { + val roll1 = roll(faces = faces) + val roll2 = roll(faces = faces) + print("[$roll1,$roll2]") + max(roll1, roll2) + } + + Instruction.Dice.Modifier.DISADVANTAGE -> { + val roll1 = roll(faces = faces) + val roll2 = roll(faces = faces) + print("[$roll1,$roll2]") + min(roll1, roll2) + } + + Instruction.Dice.Modifier.EMPHASIS -> { + val roll1 = roll(faces = faces) + val roll2 = roll(faces = faces) + print("[$roll1,$roll2]") + val half = faces / 2 + val roll1Abs = abs(half - roll1) + val roll2Abs = abs(half - roll2) + when { + roll1Abs == roll2Abs -> max(roll1, roll2) + roll1Abs < roll2Abs -> roll2 + else -> roll1 + } + } + + null -> { + roll(faces = faces).also { print("$it") } + } + } + }.also { + print("}:") + } + } + + private fun roll(faces: Int): Int { + return (Math.random() * faces.toDouble() + 1).toInt() } private fun sum(count: Int, block: () -> Int): Int { diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/SkillValueComputationUseCase.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/SkillValueComputationUseCase.kt index d7e9cc1..56becca 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/SkillValueComputationUseCase.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/business/SkillValueComputationUseCase.kt @@ -53,11 +53,9 @@ class SkillValueComputationUseCase( ): Int { // TODO Roll detail instead of an simple Int. print("Roll ->") return arithmeticParser.parse(roll).sumOf { instruction -> + print(" ($instruction):") val value = when (instruction) { - is Instruction.Dice -> rollUseCase.roll( - quantity = instruction.quantity, - faces = instruction.faces - ) + is Instruction.Dice -> rollUseCase.roll(dice = instruction) is Instruction.Flat -> instruction.value @@ -68,10 +66,7 @@ class SkillValueComputationUseCase( .parse(sheet.damageBonus) .firstOrNull() if (damageBonusInstructions is Instruction.Dice) { - rollUseCase.roll( - quantity = damageBonusInstructions.quantity, - faces = damageBonusInstructions.faces - ) + rollUseCase.roll(dice = damageBonusInstructions) } else { 0 } @@ -83,6 +78,7 @@ class SkillValueComputationUseCase( .firstOrNull() if (damageBonusInstructions is Instruction.Dice) { rollUseCase.roll( + modifier = damageBonusInstructions.modifier, quantity = damageBonusInstructions.quantity, faces = damageBonusInstructions.faces / 2, ) @@ -100,9 +96,9 @@ class SkillValueComputationUseCase( Instruction.Word.Type.CHA -> sheet.charisma } } - } * instruction.sign + } - value.also { print(" ($instruction):$it") } + (value * instruction.sign).also { print("$it") } }.also { println() } } diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/parser/arithmetic/Instruction.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/parser/arithmetic/Instruction.kt index c945f88..1763599 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/parser/arithmetic/Instruction.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/parser/arithmetic/Instruction.kt @@ -18,7 +18,14 @@ sealed class Instruction( } override fun toString(): String { - return "${sign.sign}${quantity}d${faces}" + return "${sign.sign}${ + when (modifier) { + Modifier.ADVANTAGE -> "a" + Modifier.DISADVANTAGE -> "d" + Modifier.EMPHASIS -> "e" + null -> "" + } + }${quantity}d${faces}" } }