1 /*
2 * Copyright (c) 2022 Kaiserpfalz EDV-Service, Roland T. Lichti.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18 package de.kaiserpfalzedv.rpg.torg.dice;
19
20 import de.kaiserpfalzedv.rpg.core.dice.Die;
21 import de.kaiserpfalzedv.rpg.core.dice.mat.DieResult;
22 import lombok.EqualsAndHashCode;
23 import lombok.ToString;
24
25 import jakarta.enterprise.context.Dependent;
26 import java.util.ArrayList;
27
28 /**
29 * BD is an exploding D6.
30 * <p>
31 * If a 6 is rolled, it is added as 5 and another die is rolled and added. If a 6 is rolled again, 5 will be added and
32 * another die is rolled again. You recognize the pattern.
33 *
34 * @author rlichti {@literal <rlichti@kaiserpfalz-edv.de>}
35 * @since 2021-01-02
36 */
37 @Dependent
38 @ToString
39 @EqualsAndHashCode
40 public class BD implements Die {
41 public final DieResult[] roll(final int number) {
42 ArrayList<DieResult> results = new ArrayList<>(number);
43
44 for (int i = 1; i <= number; i++) {
45 results.add(roll());
46 }
47
48 return results.toArray(new DieResult[0]);
49 }
50
51 @Override
52 public boolean isNumericDie() {
53 return true;
54 }
55
56 /**
57 * The die roll itself.
58 * @return the numeric result of the roll of this die.
59 */
60 private int rollSingle() {
61 return (int) (Math.random() * 7);
62 }
63
64
65 @Override
66 public DieResult roll() {
67 int total = 0;
68 ArrayList<String> rolls = new ArrayList<>(5);
69
70 int roll;
71 do {
72 roll = rollSingle();
73
74 if (roll == 6) {
75 total--; // only add 5 to the total instead of 6.
76 }
77
78 total += roll;
79 rolls.add(Integer.toString(roll, 10));
80 } while (roll == 6);
81
82 return DieResult.builder()
83 .die(this)
84 .total(Integer.toString(total, 10))
85 .rolls(rolls.toArray(new String[0]))
86 .build();
87 }
88 }