View Javadoc
1   package de.aikiit.game.kaiser;
2   
3   import org.apache.commons.lang3.StringUtils;
4   
5   import java.math.BigDecimal;
6   import java.math.RoundingMode;
7   
8   import static org.apache.commons.lang3.compare.ComparableUtils.is;
9   
10  /**
11   * This class contains static helper methods to print
12   * results or calculation or status information of the currently running game.
13   */
14  public class KaiserEnginePrinter {
15  
16      // inspired by https://talyian.github.io/ansicolors/
17      public static final String ANSI_RESET = "\u001B[0m";
18      public static final String ANSI_BLACK = "\u001B[30m";
19      public static final String ANSI_RED = "\u001B[31m";
20      public static final String ANSI_GREEN = "\u001B[32m";
21      public static final String ANSI_YELLOW = "\u001B[33m";
22      public static final String ANSI_BLUE = "\u001B[34m";
23      public static final String ANSI_PURPLE = "\u001B[35m";
24      public static final String ANSI_CYAN = "\u001B[36m";
25      public static final String ANSI_WHITE = "\u001B[37m";
26  
27      public static final String ORANGE = "\u001B[38;5;202m";
28  
29      private final KaiserEngine engine;
30  
31      public KaiserEnginePrinter(KaiserEngine engine) {
32          this.engine = engine;
33      }
34  
35      /**
36       * Show status information of the underlying game engine for the given round.
37       *
38       * @param round current round/year of the game.
39       * @return colour-encoded status.
40       */
41      public String getStatus(int round) {
42          StringBuilder status = new StringBuilder();
43  
44          status.append(ANSI_GREEN).append("### STATUS nach Runde ").append(round).append(ANSI_RESET).append(System.lineSeparator());
45          status.append(ANSI_CYAN).append("Die Einwohnerzahl beträgt jetzt   ").append(StringUtils.leftPad(String.valueOf(this.engine.getPopulation()), 10)).append(ANSI_RESET).append(System.lineSeparator());
46          status.append(ANSI_CYAN).append("Die Stadt besitzt an Land (Hektar)").append(StringUtils.leftPad(String.valueOf(this.engine.getArea()), 10)).append(ANSI_RESET).append(System.lineSeparator());
47          status.append(ANSI_CYAN).append("Die Ernte betrug (dzt/Hektar)     ").append(StringUtils.leftPad(String.valueOf(this.engine.getYield()), 10)).append(ANSI_RESET).append(System.lineSeparator());
48          status.append(ANSI_RED).append("Ratten haben gefressen (dzt)      ").append(StringUtils.leftPad(String.valueOf(this.engine.getExternalDamage()), 10)).append(ANSI_RESET).append(System.lineSeparator());
49          status.append(ANSI_RED).append("Eure Vorräte betragen (dzt)       ").append(StringUtils.leftPad(String.valueOf(this.engine.getSupplies()), 10)).append(ANSI_RESET).append(System.lineSeparator());
50          return status.toString();
51      }
52  
53      /**
54       * Show population result of the current round.
55       *
56       * @param round current round/year of the game.
57       * @return colour-encoded population statistics.
58       */
59      public String getYearResult(int round) {
60          StringBuilder status = new StringBuilder();
61  
62          status.append(ANSI_GREEN).append("Im Jahr ").append(round).append(ANSI_RESET).append(System.lineSeparator());
63          status.append(ANSI_CYAN).append("Es starben         ").append(StringUtils.leftPad(String.valueOf(this.engine.getDeathToll()), 10)).append(" Einwohner").append(ANSI_RESET).append(System.lineSeparator());
64          status.append(ANSI_CYAN).append("hinzugekommen sind ").append(StringUtils.leftPad(String.valueOf(this.engine.getIncrease()), 10)).append(" Einwohner").append(ANSI_RESET).append(System.lineSeparator());
65          return status.toString();
66  
67      }
68  
69      /**
70       * After the game ends and the maximum number of years is reached an overall statistics is printed out.
71       *
72       * @return colour-encoded overall statistics.
73       */
74      public String getResults() {
75          StringBuilder result = new StringBuilder();
76  
77          result.append("In Ihrer ").append(KaiserGame.MAX_ROUNDS).append("-jährigen Amtszeit sind durchschnittlich ");
78          result.append(this.engine.getPercentDeathToll()).append(" % im Jahr verstorben.").append(System.lineSeparator());
79          result.append("Insgesamt sind damit ").append(this.engine.getDeathTollSum()).append(" Einwohner verstorben.").append(System.lineSeparator());
80  
81          result.append(System.lineSeparator());
82          result.append("Anfangs hatten Sie 10 Hektar pro Einwohner, jetzt haben Sie ").append(this.engine.getAreaPerCapita()).append(" Hektar/Einwohner.").append(System.lineSeparator());
83  
84          return result.toString();
85      }
86  
87      /**
88       * Depending on global rules the player's legacy is described/classified depending on the engine's results.
89       *
90       * @return colour-encoded legacy/regency output.
91       */
92      public String evaluateRegency() {
93          StringBuilder result = new StringBuilder();
94          result.append(ANSI_BLUE).append(">>>> Bewertung Ihrer Herrschaft <<<<").append(System.lineSeparator());
95  
96          result.append("In ihrer ").append(engine.getZYear()).append("-jährigen Amtszeit sind ");
97          result.append(engine.getPercentDeathToll()).append("% der Bevölkerung im Jahr verstorben.").append(System.lineSeparator());
98          result.append("Insgesamt sind ").append(engine.getDeathTollSum()).append(" Einwohner gestorben.").append(System.lineSeparator());
99  
100         BigDecimal legacy = engine.getArea().divide(engine.getPopulation(), RoundingMode.HALF_UP);
101         result.append("Zu Beginn hatten sie 10 Hektar pro Einwohner,").append(System.lineSeparator());
102         result.append("jetzt sind es ").append(legacy).append(" Hektar/Einwohner.").append(System.lineSeparator());
103 
104         // TODO: check and fix legacy calculation - message should match criteria
105         if (is(engine.getPercentDeathToll()).greaterThan(BigDecimal.valueOf(33)) || is(legacy).lessThan(BigDecimal.valueOf(7))) {
106             result.append("Auf Grund dieser extremen Misswirtschaft, werden Sie nicht nur aus Amt und Würden gejagt,").append(System.lineSeparator());
107             result.append("sondern auch zum Versager des Jahres erklärt.").append(System.lineSeparator());
108         } else {
109 
110             if (is(engine.getPercentDeathToll()).greaterThan(BigDecimal.TEN) || is(legacy).lessThan(BigDecimal.valueOf(9))) {
111                 result.append("Ihre hartherzige Regierungsmethode erinnert an Nero und Iwan den Schrecklichen.");
112                 result.append(System.lineSeparator());
113                 result.append("Die (verbliebenen) Einwohner würden Sie gerne zum Teufel jagen!");
114             } else if (is(engine.getPercentDeathToll()).greaterThan(BigDecimal.TEN) || is(legacy).lessThan(BigDecimal.valueOf(9))) {
115                 result.append("Sie hätten glücklicher agieren können, aber es war nicht übel.");
116                 result.append(System.lineSeparator());
117                 result.append(this.engine.getPopulation().multiply(new BigDecimal("0.8"))).append(" Einwohner möchten Sie zwar hängen sehen, aber kleine Probleme hat ja jeder.");
118             } else {
119                 result.append("Eine wunderbare Regierungszeit! Karl, Konrad und Willi (die Großen) hätten es nicht besser machen können.");
120             }
121         }
122 
123         result.append(ANSI_RESET);
124         result.append(System.lineSeparator());
125         result.append(System.lineSeparator());
126         return result.toString();
127     }
128 }