From 0b8c61e7578739d620e1e163f2c21dc609b64b91 Mon Sep 17 00:00:00 2001 From: twonirwana Date: Mon, 2 Sep 2024 19:33:42 +0200 Subject: [PATCH] fix colorOn (#122) * fix colorOn --- README.adoc | 2 +- .../janno/evaluator/dice/RandomElement.java | 4 +-- .../evaluator/dice/function/ColorOn.java | 29 +++++++++++----- .../evaluator/dice/DiceEvaluatorTest.java | 32 ++++++++--------- src/test/resources/expressionsAndResults.csv | 34 +++++++++---------- 5 files changed, 56 insertions(+), 45 deletions(-) diff --git a/README.adoc b/README.adoc index ee93b25..df22e0b 100644 --- a/README.adoc +++ b/README.adoc @@ -112,7 +112,7 @@ All functions are case insensitiv. |sort desc |`desc(, ...)` |`desc(4d6)` |sorts all elements descending of one or more inner expressions. Text is compared alphabetically |cancel |`cancel(, , )` |`cancel(8d10, 10, 1)` |the elements of listA and listB (can also be single elements) cancel each other and remove each other from the result. |replace |`replace(, , ...)` |`replace(8d10, [9/10], 'bonus')` | each element in `` that matches on of the elements in `` will be replaced with the elements in ``. `` can be an empty list `[]` or literal `''` and thereby removing the found elements. It is possible to add multiple / pairs to replace different elements in one replace. If the expression contains dice then they will only be rolled on a matching find element and for each matching element again. -|color on |`colorOn(, , ...)` |`replace(8d10, [9/10], 'red')` | each element in `` that is in the elements in `in` will be get the color ``. `` can be an empty list `[]` or literal `''` and thereby removing the current color. It is possible to add multiple / pairs to set different color for different values. If the expression contains dice then they will only be rolled on a matching in element and for each matching in again. +|color on |`colorOn(, , ...)` |`replace(8d10, [9/10], 'red')` | each element in `` that is in the elements in `in` will be get the color ``. `` can be an empty list `[]` or literal `''` and thereby removing the current color. It is possible to add multiple / pairs to set different color for different values. If the expression contains dice then they will be rolled once and used for all elements. |explode |`exp(,,` |`exp(d[1/2/3],[2/3])` or `exp(d[1/2/3],[2/3], 2)` | Rerolls the `` expression if any of its result elements are in the elements of `` and returns the original result and all reroll results. If `` contain more then one die then all are rerolled, even if only on result of one die matches the reroll list. `` define the maximum number of rerolls bevor the function stops with rerolls and returns the current result. `` must be a number between 0 and 100. If `` is not provided as argument then 100 will be used. |if |`if(,,)` |`if(1d6=?6,'six','not six')` or `if(1d6=?6,'six')` or `val('$r',1d6), if('$r'=?1,'one','$r'=?2,'two','else')` |if `` equal true then return the `` expression or else the `` expression. The `` expression is optional, if it is missing and `` is `false` then the result empty. It is possible to add more than `,` pair in the function, the result will be the `` of the first true ``, coming from left. All must be non-empty and contain only on element (therefor can't contain only `val`). `val` are will only set in the first . Use the following structure to use `if` to set different value in a `val`: `if(1d6>?4, val('$a',10), val('$a',-10))`, this will set '$a' to 10 if the 1d6 roll is bigger than 4 and to -10 otherwise. |group count |`groupC(, ...)` |`groupC(20d6)` | counts all elements of with the same value and provides the results as list in the format of `x` diff --git a/src/main/java/de/janno/evaluator/dice/RandomElement.java b/src/main/java/de/janno/evaluator/dice/RandomElement.java index f7081ac..c3e994b 100644 --- a/src/main/java/de/janno/evaluator/dice/RandomElement.java +++ b/src/main/java/de/janno/evaluator/dice/RandomElement.java @@ -55,9 +55,9 @@ public RandomElement copyWithTagAndColor(@NonNull String color) { public String toString() { if (randomSelectedFrom != null) { - return "%s=%s∈%s".formatted(dieId, rollElement.toString(), randomSelectedFrom); + return "%s=%s∈%s".formatted(dieId, rollElement.toStringWithColorAndTag(), randomSelectedFrom); } else { - return "%s=%s∈[%d...%d]".formatted(dieId, rollElement.toString(), minInc, maxInc); + return "%s=%s∈[%d...%d]".formatted(dieId, rollElement.toStringWithColorAndTag(), minInc, maxInc); } } diff --git a/src/main/java/de/janno/evaluator/dice/function/ColorOn.java b/src/main/java/de/janno/evaluator/dice/function/ColorOn.java index 3c68658..8d46bf8 100644 --- a/src/main/java/de/janno/evaluator/dice/function/ColorOn.java +++ b/src/main/java/de/janno/evaluator/dice/function/ColorOn.java @@ -29,33 +29,46 @@ public ColorOn(int maxNumberOfElements, boolean keepChildrenRolls) { } ImmutableList.Builder allRolls = ImmutableList.builder().addAll(input.get()); ImmutableList inputRollElements = input.get().stream().flatMap(r -> r.getElements().stream()).collect(ImmutableList.toImmutableList()); - for (int i = 1; i < arguments.size() - 1; i = i + 2) { + ImmutableList inputRandomElements = input.get().stream().flatMap(r -> r.getRandomElementsInRoll().stream()).collect(ImmutableList.toImmutableList()); + for (int i = 1; i < arguments.size() - 1; i = i + 2) { Optional> inRolls = arguments.get(i).extendRoll(rollContext); checkContainsSingleRoll(expressionPosition, inRolls, i + 1); final Roll inRoll = inRolls.orElseThrow().getFirst(); allRolls.add(inRoll); + Optional> colorRolls = arguments.get(i + 1).extendRoll(rollContext); + checkContainsSingleRoll(expressionPosition, colorRolls, i + 2); + Roll colorRoll = colorRolls.orElseThrow().getFirst(); + checkContainsNoOrSingleElement(expressionPosition, colorRoll, "%d argument".formatted(i + 2)); + final String color = colorRoll.asSingleValue().orElse(RollElement.NO_COLOR); ImmutableList.Builder currentIterationElements = ImmutableList.builder(); for (RollElement rollElement : inputRollElements) { if (inRoll.isElementsContainsElementWithValueAndTag(rollElement)) { - Optional> colorRolls = arguments.get(i + 1).extendRoll(rollContext); - checkContainsSingleRoll(expressionPosition, colorRolls, i + 2); - Roll colorRoll = colorRolls.orElseThrow().getFirst(); - checkContainsNoOrSingleElement(expressionPosition, colorRoll, "%d argument".formatted(i + 2)); - final String color = colorRoll.asSingleValue().orElse(RollElement.NO_COLOR); - allRolls.add(colorRoll); currentIterationElements.add(new RollElement(rollElement.getValue(), rollElement.getTag(), color)); } else { currentIterationElements.add(rollElement); } } inputRollElements = currentIterationElements.build(); + ImmutableList.Builder currentIterationRandomElements = ImmutableList.builder(); + + for (RandomElement randomElement : inputRandomElements) { + if (inRoll.isElementsContainsElementWithValueAndTag(randomElement.getRollElement())) { + currentIterationRandomElements.add(randomElement.copyWithTagAndColor(color)); + } else { + currentIterationRandomElements.add(randomElement); + } + } + inputRandomElements = currentIterationRandomElements.build(); } + RandomElementsBuilder builder = RandomElementsBuilder.empty(rollContext); + builder.addRandomElements(inputRandomElements); + return Optional.of(ImmutableList.of(new Roll(toExpression(), inputRollElements, - RandomElementsBuilder.fromRolls(allRolls.build(), rollContext), + builder.build(), allRolls.build(), expressionPosition, maxNumberOfElements, keepChildrenRolls))); diff --git a/src/test/java/de/janno/evaluator/dice/DiceEvaluatorTest.java b/src/test/java/de/janno/evaluator/dice/DiceEvaluatorTest.java index 56a503b..acd34df 100644 --- a/src/test/java/de/janno/evaluator/dice/DiceEvaluatorTest.java +++ b/src/test/java/de/janno/evaluator/dice/DiceEvaluatorTest.java @@ -701,11 +701,11 @@ private static Stream generateStringDiceDataWithRandomElements() { Arguments.of("(d4)d!(d6)", List.of(2, 6, 6, 4, 3), "6, 4, 3", "[1de0i0r0=2∈[1...4], 4d!e0i0r0=6∈[1...6], 4d!e0i0r1=4∈[1...6], 4d!e0i1r0=3∈[1...6], 7de0i0r0=6∈[1...6]]"), Arguments.of("(d4)d!!(d6)", List.of(2, 6, 6, 4, 3), "10, 3", "[1de0i0r0=2∈[1...4], 4d!!e0i0r0=6∈[1...6], 4d!!e0i0r1=4∈[1...6], 4d!!e0i1r0=3∈[1...6], 8de0i0r0=6∈[1...6]]"), - Arguments.of("d6 col 'red' ", List.of(), "6-c:red", "[0de0i0r0=6∈[1...6]]"), - Arguments.of("d6 col d6 ", List.of(), "6-c:6", "[0de0i0r0=6∈[1...6], 7de0i0r0=6∈[1...6]]"), - Arguments.of("d[a,b,c,d,e,f] col 'red'", List.of(), "f-c:red", "[0de0i0r0=f∈[a, b, c, d, e, f]]"), - Arguments.of("d!6 col 'red'", List.of(6, 3), "6-c:red, 3-c:red", "[0d!e0i0r0=6∈[1...6], 0d!e0i0r1=3∈[1...6]]"), - Arguments.of("d!!6 col 'red'", List.of(6, 3), "9-c:red", "[0d!!e0i0r0=6∈[1...6], 0d!!e0i0r1=3∈[1...6]]"), + Arguments.of("d6 col 'red' ", List.of(), "6-c:red", "[0de0i0r0=6-c:red∈[1...6]]"), + Arguments.of("d6 col d6 ", List.of(), "6-c:6", "[0de0i0r0=6-c:6∈[1...6], 7de0i0r0=6-c:6∈[1...6]]"), + Arguments.of("d[a,b,c,d,e,f] col 'red'", List.of(), "f-c:red", "[0de0i0r0=f-c:red∈[a, b, c, d, e, f]]"), + Arguments.of("d!6 col 'red'", List.of(6, 3), "6-c:red, 3-c:red", "[0d!e0i0r0=6-c:red∈[1...6], 0d!e0i0r1=3-c:red∈[1...6]]"), + Arguments.of("d!!6 col 'red'", List.of(6, 3), "9-c:red", "[0d!!e0i0r0=6-c:red∈[1...6], 0d!!e0i0r1=3-c:red∈[1...6]]"), Arguments.of("d6 tag 'red' ", List.of(), "6-t:red", "[0de0i0r0=6∈[1...6]]"), Arguments.of("d6 tag d6 ", List.of(), "6-t:6", "[0de0i0r0=6∈[1...6], 7de0i0r0=6∈[1...6]]"), @@ -770,12 +770,12 @@ private static Stream generateStringDiceDataWithRandomElements() { Arguments.of("val('$s',1), if(0=?1, '') + '$s'", List.of(), "1", "[]"), Arguments.of("val('$s',1) if(0=?1, '') '$s'", List.of(), "1", "[]"), - Arguments.of("colorOn(3d6,[1/2],'white')", List.of(6, 2, 1), "6, 2-c:white, 1-c:white", "[9de0i0r0=6∈[1...6], 9de0i1r0=2∈[1...6], 9de0i2r0=1∈[1...6]]"), - Arguments.of("colorOn(3d6 col 'red', [1/2],'')", List.of(6, 2, 1), "6-c:red, 2, 1", "[9de0i0r0=6∈[1...6], 9de0i1r0=2∈[1...6], 9de0i2r0=1∈[1...6]]"), + Arguments.of("colorOn(3d6,[1/2],'white')", List.of(6, 2, 1), "6, 2-c:white, 1-c:white", "[9de0i0r0=6∈[1...6], 9de0i1r0=2-c:white∈[1...6], 9de0i2r0=1-c:white∈[1...6]]"), + Arguments.of("colorOn(3d6 col 'red', [1/2],'')", List.of(6, 2, 1), "6-c:red, 2, 1", "[9de0i0r0=6-c:red∈[1...6], 9de0i1r0=2∈[1...6], 9de0i2r0=1∈[1...6]]"), Arguments.of("colorOn('',[1/2],'white')", List.of(), "", "[]"), Arguments.of("colorOn(val('a',1),1,'white')", List.of(), "", "[]"), Arguments.of("colorOn(3d6,[1/2],'white')", List.of(6, 5, 5), "6, 5, 5", "[9de0i0r0=6∈[1...6], 9de0i1r0=5∈[1...6], 9de0i2r0=5∈[1...6]]"), - Arguments.of("colorOn(4d6 col 'red',[1/2],'white', 3, 'black', 1, 'green')", List.of(4, 3, 2, 1), "4-c:red, 3-c:black, 2-c:white, 1-c:green", "[9de0i0r0=4∈[1...6], 9de0i1r0=3∈[1...6], 9de0i2r0=2∈[1...6], 9de0i3r0=1∈[1...6]]"), + Arguments.of("colorOn(4d6 col 'red',[1/2],'white', 3, 'black', 1, 'green')", List.of(4, 3, 2, 1), "4-c:red, 3-c:black, 2-c:white, 1-c:green", "[9de0i0r0=4-c:red∈[1...6], 9de0i1r0=3-c:black∈[1...6], 9de0i2r0=2-c:white∈[1...6], 9de0i3r0=1-c:green∈[1...6]]"), //systems Arguments.of(THE_ONE_RING, List.of(), " ⬟= ᚠ", "[34de0i0r0=12∈[1...12]]"), @@ -834,19 +834,17 @@ void rollDiceExpressionWithRandomElements(String diceExpression, List d @Test void debug() throws ExpressionException { - GivenNumberSupplier numberSupplier = new GivenNumberSupplier(3); + GivenNumberSupplier numberSupplier = new GivenNumberSupplier(3, 1, 2); DiceEvaluator underTest = new DiceEvaluator(numberSupplier, 1000, 10_000, true); // List res = underTest.evaluate("3d!6+(2r(2d8))"); - RollResult res = underTest.evaluate("if(d6>?3,d8) + 1"); + RollResult res = underTest.evaluate("colorOn(3d6,[1/2],'white')"); System.out.println(res.getRolls().size()); res.getRolls().forEach(System.out::println); res.getRolls().forEach(r -> System.out.println(r.getResultString())); System.out.println(res); System.out.println(res.getExpression()); - System.out.println(res.getAllRandomElements().stream() - .map(re -> re.getDieId() + "=" + re.getRollElement().getValue()) - .collect(Collectors.joining(", "))); + System.out.println(res.getAllRandomElements()); res.getRolls().forEach(r -> System.out.println(r.getRandomElementsInRoll())); res.getRolls().forEach(r -> System.out.println(getRandomElementsString(r))); System.out.println(res.getRolls().stream().flatMap(r -> r.getElements().stream()).map(RollElement::getValue).toList()); @@ -941,7 +939,7 @@ void valRandomElementsInCorrectOrder() throws ExpressionException { assertThat(values(res.getRolls())).containsExactly("successes: 0, blue:1, purple_dark:1"); assertThat(res.getRolls().size()).isEqualTo(1); - assertThat(res.getGroupedRandomElements().toString()).isEqualTo("[[16de0i0r0=1∈[1...9]], [44de0i0r0=2∈[1...10]]]"); + assertThat(res.getGroupedRandomElements().toString()).isEqualTo("[[16de0i0r0=1-c:blue∈[1...9]], [44de0i0r0=2-c:purple_dark∈[1...10]]]"); assertThat(getRandomElementsString(res.getRolls().getFirst())).isEqualTo("[1] [2]"); } @@ -1525,7 +1523,7 @@ void toStringColorTest() throws ExpressionException { RollResult res = underTest.evaluate("color(1d6,'red') + color(3d20,'blue')"); assertThat(res.getRolls()).hasSize(1); - assertThat(res.getGroupedRandomElements().toString()).isEqualTo("[[7de0i0r0=3∈[1...6]], [26de0i0r0=2∈[1...20], 26de0i1r0=1∈[1...20], 26de0i2r0=4∈[1...20]]]"); + assertThat(res.getGroupedRandomElements().toString()).isEqualTo("[[7de0i0r0=3-c:red∈[1...6]], [26de0i0r0=2-c:blue∈[1...20], 26de0i1r0=1-c:blue∈[1...20], 26de0i2r0=4-c:blue∈[1...20]]]"); assertThat(getRandomElementsString(res.getRolls().getFirst())).isEqualTo("[3] [2, 1, 4]"); assertThat(res.getRolls().getFirst().getResultString()).isEqualTo("red:3, blue:2, blue:1, blue:4"); assertThat(res.getRolls().getFirst().getExpression()).isEqualTo("color(1d6,'red')+color(3d20,'blue')"); @@ -1553,7 +1551,7 @@ void colTest() throws ExpressionException { RollResult res = underTest.evaluate("1d6 col 'red' + 3d20 col 'blue'"); assertThat(res.getRolls()).hasSize(1); - assertThat(res.getGroupedRandomElements().toString()).isEqualTo("[[1de0i0r0=3∈[1...6]], [18de0i0r0=2∈[1...20], 18de0i1r0=1∈[1...20], 18de0i2r0=4∈[1...20]]]"); + assertThat(res.getGroupedRandomElements().toString()).isEqualTo("[[1de0i0r0=3-c:red∈[1...6]], [18de0i0r0=2-c:blue∈[1...20], 18de0i1r0=1-c:blue∈[1...20], 18de0i2r0=4-c:blue∈[1...20]]]"); assertThat(res.getRolls().getFirst().getRandomElementsInRoll().stream() .map(RandomElement::getRollElement) .map(RollElement::getColor)).containsExactly("red", "blue", "blue", "blue"); @@ -1590,7 +1588,7 @@ void toStringValColorTest() throws ExpressionException { assertThat(res).hasSize(1); assertThat(res.getFirst().getResultString()).isEqualTo("red:3, blue:3"); - assertThat(res.getFirst().getRandomElementsInRoll().toString()).isEqualTo("[11de0i0r0=3∈[1...6]]"); + assertThat(res.getFirst().getRandomElementsInRoll().toString()).isEqualTo("[11de0i0r0=3-c:blue∈[1...6]]"); assertThat(getRandomElementsString(res.getFirst())).isEqualTo("[3]"); assertThat(res.getFirst().getExpression()).isEqualTo("val('$r',1d6), color('$r','red')+color('$r','blue')"); } diff --git a/src/test/resources/expressionsAndResults.csv b/src/test/resources/expressionsAndResults.csv index da3d9e4..8c12113 100644 --- a/src/test/resources/expressionsAndResults.csv +++ b/src/test/resources/expressionsAndResults.csv @@ -760,24 +760,24 @@ D8=|[Roll{expression='D8=', randomElementsInRoll=[0De0i0r0=8∈[1...8]], element asc(2d[Failure/Failure/Failure/Partial/Partial/Success])|[Roll{expression='asc(2d[Failure/Failure/Failure/Partial/Partial/Success])', randomElementsInRoll=[5de0i0r0=Failure∈[Failure, Failure, Failure, Partial, Partial, Success], 5de0i1r0=Failure∈[Failure, Failure, Failure, Partial, Partial, Success]], elements=[Failure, Failure]}] asc(d6)|[Roll{expression='asc(d6)', randomElementsInRoll=[4de0i0r0=2∈[1...6]], elements=[2]}] asc(d6c)|[Roll{expression='asc(d6c)', randomElementsInRoll=[4de0i0r0=2∈[1...6]], elements=[1]}] -color(10d6,'red')|[Roll{expression='color(10d6,'red')', randomElementsInRoll=[8de0i0r0=2∈[1...6], 8de0i1r0=3∈[1...6], 8de0i2r0=1∈[1...6], 8de0i3r0=4∈[1...6], 8de0i4r0=1∈[1...6], 8de0i5r0=1∈[1...6], 8de0i6r0=6∈[1...6], 8de0i7r0=3∈[1...6], 8de0i8r0=2∈[1...6], 8de0i9r0=3∈[1...6]], elements=[red:2, red:3, red:1, red:4, red:1, red:1, red:6, red:3, red:2, red:3]}] -color(11d6,'red')|[Roll{expression='color(11d6,'red')', randomElementsInRoll=[8de0i0r0=2∈[1...6], 8de0i1r0=3∈[1...6], 8de0i2r0=1∈[1...6], 8de0i3r0=4∈[1...6], 8de0i4r0=1∈[1...6], 8de0i5r0=1∈[1...6], 8de0i6r0=6∈[1...6], 8de0i7r0=3∈[1...6], 8de0i8r0=2∈[1...6], 8de0i9r0=3∈[1...6], 8de0i10r0=6∈[1...6]], elements=[red:2, red:3, red:1, red:4, red:1, red:1, red:6, red:3, red:2, red:3, red:6]}] -color(12d6,'red')|[Roll{expression='color(12d6,'red')', randomElementsInRoll=[8de0i0r0=2∈[1...6], 8de0i1r0=3∈[1...6], 8de0i2r0=1∈[1...6], 8de0i3r0=4∈[1...6], 8de0i4r0=1∈[1...6], 8de0i5r0=1∈[1...6], 8de0i6r0=6∈[1...6], 8de0i7r0=3∈[1...6], 8de0i8r0=2∈[1...6], 8de0i9r0=3∈[1...6], 8de0i10r0=6∈[1...6], 8de0i11r0=3∈[1...6]], elements=[red:2, red:3, red:1, red:4, red:1, red:1, red:6, red:3, red:2, red:3, red:6, red:3]}] -color(1D20+5=,'green')|[Roll{expression='color(1D20+5=,'green')', randomElementsInRoll=[7De0i0r0=16∈[1...20]], elements=[green:21]}] -color(1d6,'red')|[Roll{expression='color(1d6,'red')', randomElementsInRoll=[7de0i0r0=2∈[1...6]], elements=[red:2]}] -color(1d6-1, 'red')|[Roll{expression='color(1d6-1,'red')', randomElementsInRoll=[7de0i0r0=2∈[1...6]], elements=[red:2, red:-1]}] -color(2d6,'red')|[Roll{expression='color(2d6,'red')', randomElementsInRoll=[7de0i0r0=2∈[1...6], 7de0i1r0=3∈[1...6]], elements=[red:2, red:3]}] -color(3d6,'red')|[Roll{expression='color(3d6,'red')', randomElementsInRoll=[7de0i0r0=2∈[1...6], 7de0i1r0=3∈[1...6], 7de0i2r0=1∈[1...6]], elements=[red:2, red:3, red:1]}] -color(4d6,'red')|[Roll{expression='color(4d6,'red')', randomElementsInRoll=[7de0i0r0=2∈[1...6], 7de0i1r0=3∈[1...6], 7de0i2r0=1∈[1...6], 7de0i3r0=4∈[1...6]], elements=[red:2, red:3, red:1, red:4]}] -color(5d6,'red')|[Roll{expression='color(5d6,'red')', randomElementsInRoll=[7de0i0r0=2∈[1...6], 7de0i1r0=3∈[1...6], 7de0i2r0=1∈[1...6], 7de0i3r0=4∈[1...6], 7de0i4r0=1∈[1...6]], elements=[red:2, red:3, red:1, red:4, red:1]}] +color(10d6,'red')|[Roll{expression='color(10d6,'red')', randomElementsInRoll=[8de0i0r0=2-c:red∈[1...6], 8de0i1r0=3-c:red∈[1...6], 8de0i2r0=1-c:red∈[1...6], 8de0i3r0=4-c:red∈[1...6], 8de0i4r0=1-c:red∈[1...6], 8de0i5r0=1-c:red∈[1...6], 8de0i6r0=6-c:red∈[1...6], 8de0i7r0=3-c:red∈[1...6], 8de0i8r0=2-c:red∈[1...6], 8de0i9r0=3-c:red∈[1...6]], elements=[red:2, red:3, red:1, red:4, red:1, red:1, red:6, red:3, red:2, red:3]}] +color(11d6,'red')|[Roll{expression='color(11d6,'red')', randomElementsInRoll=[8de0i0r0=2-c:red∈[1...6], 8de0i1r0=3-c:red∈[1...6], 8de0i2r0=1-c:red∈[1...6], 8de0i3r0=4-c:red∈[1...6], 8de0i4r0=1-c:red∈[1...6], 8de0i5r0=1-c:red∈[1...6], 8de0i6r0=6-c:red∈[1...6], 8de0i7r0=3-c:red∈[1...6], 8de0i8r0=2-c:red∈[1...6], 8de0i9r0=3-c:red∈[1...6], 8de0i10r0=6-c:red∈[1...6]], elements=[red:2, red:3, red:1, red:4, red:1, red:1, red:6, red:3, red:2, red:3, red:6]}] +color(12d6,'red')|[Roll{expression='color(12d6,'red')', randomElementsInRoll=[8de0i0r0=2-c:red∈[1...6], 8de0i1r0=3-c:red∈[1...6], 8de0i2r0=1-c:red∈[1...6], 8de0i3r0=4-c:red∈[1...6], 8de0i4r0=1-c:red∈[1...6], 8de0i5r0=1-c:red∈[1...6], 8de0i6r0=6-c:red∈[1...6], 8de0i7r0=3-c:red∈[1...6], 8de0i8r0=2-c:red∈[1...6], 8de0i9r0=3-c:red∈[1...6], 8de0i10r0=6-c:red∈[1...6], 8de0i11r0=3-c:red∈[1...6]], elements=[red:2, red:3, red:1, red:4, red:1, red:1, red:6, red:3, red:2, red:3, red:6, red:3]}] +color(1D20+5=,'green')|[Roll{expression='color(1D20+5=,'green')', randomElementsInRoll=[7De0i0r0=16-c:green∈[1...20]], elements=[green:21]}] +color(1d6,'red')|[Roll{expression='color(1d6,'red')', randomElementsInRoll=[7de0i0r0=2-c:red∈[1...6]], elements=[red:2]}] +color(1d6-1, 'red')|[Roll{expression='color(1d6-1,'red')', randomElementsInRoll=[7de0i0r0=2-c:red∈[1...6]], elements=[red:2, red:-1]}] +color(2d6,'red')|[Roll{expression='color(2d6,'red')', randomElementsInRoll=[7de0i0r0=2-c:red∈[1...6], 7de0i1r0=3-c:red∈[1...6]], elements=[red:2, red:3]}] +color(3d6,'red')|[Roll{expression='color(3d6,'red')', randomElementsInRoll=[7de0i0r0=2-c:red∈[1...6], 7de0i1r0=3-c:red∈[1...6], 7de0i2r0=1-c:red∈[1...6]], elements=[red:2, red:3, red:1]}] +color(4d6,'red')|[Roll{expression='color(4d6,'red')', randomElementsInRoll=[7de0i0r0=2-c:red∈[1...6], 7de0i1r0=3-c:red∈[1...6], 7de0i2r0=1-c:red∈[1...6], 7de0i3r0=4-c:red∈[1...6]], elements=[red:2, red:3, red:1, red:4]}] +color(5d6,'red')|[Roll{expression='color(5d6,'red')', randomElementsInRoll=[7de0i0r0=2-c:red∈[1...6], 7de0i1r0=3-c:red∈[1...6], 7de0i2r0=1-c:red∈[1...6], 7de0i3r0=4-c:red∈[1...6], 7de0i4r0=1-c:red∈[1...6]], elements=[red:2, red:3, red:1, red:4, red:1]}] color(69, 'cyan')|[Roll{expression='color(69,'cyan')', randomElementsInRoll=[], elements=[cyan:69]}] -color(6d6,'red')|[Roll{expression='color(6d6,'red')', randomElementsInRoll=[7de0i0r0=2∈[1...6], 7de0i1r0=3∈[1...6], 7de0i2r0=1∈[1...6], 7de0i3r0=4∈[1...6], 7de0i4r0=1∈[1...6], 7de0i5r0=1∈[1...6]], elements=[red:2, red:3, red:1, red:4, red:1, red:1]}] -color(7d6,'red')|[Roll{expression='color(7d6,'red')', randomElementsInRoll=[7de0i0r0=2∈[1...6], 7de0i1r0=3∈[1...6], 7de0i2r0=1∈[1...6], 7de0i3r0=4∈[1...6], 7de0i4r0=1∈[1...6], 7de0i5r0=1∈[1...6], 7de0i6r0=6∈[1...6]], elements=[red:2, red:3, red:1, red:4, red:1, red:1, red:6]}] -color(8d6,'red')|[Roll{expression='color(8d6,'red')', randomElementsInRoll=[7de0i0r0=2∈[1...6], 7de0i1r0=3∈[1...6], 7de0i2r0=1∈[1...6], 7de0i3r0=4∈[1...6], 7de0i4r0=1∈[1...6], 7de0i5r0=1∈[1...6], 7de0i6r0=6∈[1...6], 7de0i7r0=3∈[1...6]], elements=[red:2, red:3, red:1, red:4, red:1, red:1, red:6, red:3]}] -color(9d6,'red')|[Roll{expression='color(9d6,'red')', randomElementsInRoll=[7de0i0r0=2∈[1...6], 7de0i1r0=3∈[1...6], 7de0i2r0=1∈[1...6], 7de0i3r0=4∈[1...6], 7de0i4r0=1∈[1...6], 7de0i5r0=1∈[1...6], 7de0i6r0=6∈[1...6], 7de0i7r0=3∈[1...6], 7de0i8r0=2∈[1...6]], elements=[red:2, red:3, red:1, red:4, red:1, red:1, red:6, red:3, red:2]}] -color(D4, 'red')|[Roll{expression='color(D4,'red')', randomElementsInRoll=[6De0i0r0=4∈[1...4]], elements=[red:4]}] -color(d100, 'purple')|[Roll{expression='color(d100,'purple')', randomElementsInRoll=[6de0i0r0=96∈[1...100]], elements=[purple:96]}] -color(d20, 'red')|[Roll{expression='color(d20,'red')', randomElementsInRoll=[6de0i0r0=16∈[1...20]], elements=[red:16]}] +color(6d6,'red')|[Roll{expression='color(6d6,'red')', randomElementsInRoll=[7de0i0r0=2-c:red∈[1...6], 7de0i1r0=3-c:red∈[1...6], 7de0i2r0=1-c:red∈[1...6], 7de0i3r0=4-c:red∈[1...6], 7de0i4r0=1-c:red∈[1...6], 7de0i5r0=1-c:red∈[1...6]], elements=[red:2, red:3, red:1, red:4, red:1, red:1]}] +color(7d6,'red')|[Roll{expression='color(7d6,'red')', randomElementsInRoll=[7de0i0r0=2-c:red∈[1...6], 7de0i1r0=3-c:red∈[1...6], 7de0i2r0=1-c:red∈[1...6], 7de0i3r0=4-c:red∈[1...6], 7de0i4r0=1-c:red∈[1...6], 7de0i5r0=1-c:red∈[1...6], 7de0i6r0=6-c:red∈[1...6]], elements=[red:2, red:3, red:1, red:4, red:1, red:1, red:6]}] +color(8d6,'red')|[Roll{expression='color(8d6,'red')', randomElementsInRoll=[7de0i0r0=2-c:red∈[1...6], 7de0i1r0=3-c:red∈[1...6], 7de0i2r0=1-c:red∈[1...6], 7de0i3r0=4-c:red∈[1...6], 7de0i4r0=1-c:red∈[1...6], 7de0i5r0=1-c:red∈[1...6], 7de0i6r0=6-c:red∈[1...6], 7de0i7r0=3-c:red∈[1...6]], elements=[red:2, red:3, red:1, red:4, red:1, red:1, red:6, red:3]}] +color(9d6,'red')|[Roll{expression='color(9d6,'red')', randomElementsInRoll=[7de0i0r0=2-c:red∈[1...6], 7de0i1r0=3-c:red∈[1...6], 7de0i2r0=1-c:red∈[1...6], 7de0i3r0=4-c:red∈[1...6], 7de0i4r0=1-c:red∈[1...6], 7de0i5r0=1-c:red∈[1...6], 7de0i6r0=6-c:red∈[1...6], 7de0i7r0=3-c:red∈[1...6], 7de0i8r0=2-c:red∈[1...6]], elements=[red:2, red:3, red:1, red:4, red:1, red:1, red:6, red:3, red:2]}] +color(D4, 'red')|[Roll{expression='color(D4,'red')', randomElementsInRoll=[6De0i0r0=4-c:red∈[1...4]], elements=[red:4]}] +color(d100, 'purple')|[Roll{expression='color(d100,'purple')', randomElementsInRoll=[6de0i0r0=96-c:purple∈[1...100]], elements=[purple:96]}] +color(d20, 'red')|[Roll{expression='color(d20,'red')', randomElementsInRoll=[6de0i0r0=16-c:red∈[1...20]], elements=[red:16]}] concat(2d6=,-2d3k1)|[Roll{expression='concat(2d6=,-2d3k1)', randomElementsInRoll=[8de0i0r0=2∈[1...6], 8de0i1r0=3∈[1...6], 14de0i0r0=1∈[1...3], 14de0i1r0=1∈[1...3]], elements=[5-1]}] concat(2d6=,-2d3k1=)|[Roll{expression='concat(2d6=,-2d3k1=)', randomElementsInRoll=[8de0i0r0=2∈[1...6], 8de0i1r0=3∈[1...6], 14de0i0r0=1∈[1...3], 14de0i1r0=1∈[1...3]], elements=[5-1]}] concat(2d6=,-2d3l1)|[Roll{expression='concat(2d6=,-2d3l1)', randomElementsInRoll=[8de0i0r0=2∈[1...6], 8de0i1r0=3∈[1...6], 14de0i0r0=1∈[1...3], 14de0i1r0=1∈[1...3]], elements=[5-1]}]