View Javadoc
1   /*
2    * Copyright (c) 2021 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.core.dice.mat;
19  
20  import com.fasterxml.jackson.annotation.JsonInclude;
21  import de.kaiserpfalzedv.rpg.core.dice.Die;
22  import de.kaiserpfalzedv.rpg.core.dice.LookupTable;
23  import lombok.*;
24  import lombok.extern.jackson.Jacksonized;
25  import net.objecthunter.exp4j.Expression;
26  import net.objecthunter.exp4j.ExpressionBuilder;
27  import org.eclipse.microprofile.openapi.annotations.media.Schema;
28  
29  import java.io.Serializable;
30  import java.util.Optional;
31  import java.util.StringJoiner;
32  
33  
34  /**
35   * RollTotal -- The result of a numeric die result.
36   *
37   * This is the result of a numeric die roll.
38   */
39  @Jacksonized
40  @Builder(toBuilder = true)
41  @AllArgsConstructor
42  @RequiredArgsConstructor
43  @Getter
44  @ToString
45  @EqualsAndHashCode
46  @JsonInclude(JsonInclude.Include.NON_ABSENT)
47  @Schema(name = "ExpressionTotal", description = "A generic result of an expression.")
48  public class ExpressionTotal implements Serializable {
49      private DieResult[] rolls;
50      private String expression;
51  
52  
53      /**
54       * Displays the roll.
55       *
56       * @return the expression description.
57       */
58      public String getDescription() {
59          StringJoiner rolls = new StringJoiner(", ", "{", "}");
60  
61          for (DieResult r : getRolls()) {
62              rolls.add(r.getDisplay());
63          }
64  
65          return new StringBuilder(getExpression().replace("x", getDieIdentifier()))
66                  .append(": ")
67                  .append(calculateExpression())
68                  .append(rolls)
69                  .toString();
70      }
71  
72      public String getDieIdentifier() {
73          return getRolls()[0].getDie().getDieType();
74      }
75  
76      public int getAmountOfDice() {
77          return getRolls().length;
78      }
79  
80      /**
81       * This calculates the expression. If the die can't be evaluated
82       *
83       * @return the calculated expression as result of the roll.
84       */
85      public String calculateExpression() {
86          String result = "";
87          if (getRolls().length > 0 && getRolls()[0].getDie().isNumericDie()) {
88              Die die = getRolls()[0].getDie();
89  
90              int roll = calcuateTotal(getRolls());
91  
92              Expression math = new ExpressionBuilder(getExpression()).variable("x").build();
93  
94              int total = roll;
95              Optional<LookupTable> table = die.getLookupTable();
96              if (table.isPresent()) {
97                  total = table.get().lookup(roll);
98              }
99  
100             total = (int) math.setVariable("x", total).evaluate();
101             result = Integer.toString(total, 10) + " | " + Integer.toString(roll, 10);
102         }
103 
104         return result;
105     }
106 
107     private int calcuateTotal(DieResult[] rolls) {
108         int total = 0;
109 
110         if (rolls.length > 0 && rolls[0].getDie().isNumericDie()) {
111             for (DieResult r : rolls) {
112                 total += Integer.parseInt(r.getTotal(), 10);
113             }
114         }
115 
116         return total;
117     }
118 }