View Javadoc
1   package de.aikiit.game.kaiser;
2   
3   import org.assertj.core.util.VisibleForTesting;
4   
5   /**
6    * This class encapsulates the actual game flow.
7    * A player
8    * <ul>
9    *     <li>is shown current statistics and</li>
10   *     <li>can start to act</li>
11   *     <li>until the maximum number of rounds is reached and the game ends.</li>
12   * </ul>
13   */
14  public class KaiserGame {
15  
16      /**
17       * The player can play at most this number of rounds.
18       */
19      public static final int MAX_ROUNDS = 10;
20  
21      private final KaiserEngine engine;
22      private final KaiserEnginePrinter printer;
23      /**
24       * The current round of the game.
25       */
26      private int round = 0;
27  
28      /**
29       * Initializes a game with default parameters.
30       */
31      public KaiserGame() {
32          this(new KaiserEngine());
33      }
34  
35      /**
36       * Allows setting an explicit engine for testing purposes.
37       * @param engine initialize with the given engine.
38       */
39      @VisibleForTesting
40      KaiserGame(KaiserEngine engine) {
41          this.engine = engine;
42          this.printer = new KaiserEnginePrinter(this.engine);
43      }
44  
45      private void incrementRoundCounter() {
46          round++;
47      }
48  
49      /**
50       * Start the game and allow player interactions until the maximum number of rounds is reached.
51       */
52      public void run() {
53          intro();
54          status();
55          while (round < MAX_ROUNDS) {
56              incrementRoundCounter();
57              engine.startNewRound();
58              status();
59              actions();
60              engine.finishRoundAfterActions();
61          }
62  
63          finish();
64          byeByeBanner();
65      }
66  
67      /**
68       * Shows information about the game flow and welcomes the player.
69       */
70      public void intro() {
71          banner();
72          System.out.println("Versuchen Sie die antike Stadt " + KaiserEnginePrinter.ANSI_YELLOW + ">SUMERIA<" + KaiserEnginePrinter.ANSI_RESET + " zu regieren!");
73          System.out.println("Ihre Regierungszeit beträgt " + MAX_ROUNDS + " Jahre.");
74          System.out.println("Nach jeweils einem Jahr erhalten Sie einen Bericht über die Entwicklung in der Stadt.");
75          System.out.println("Dann werden wir weitersehen .......");
76          System.out.println();
77      }
78  
79      /**
80       * Shows the game's banner.
81       */
82      public void banner() {
83          // generated with the help of https://manytools.org/hacker-tools/ascii-banner/
84          // font: banner
85          System.out.println(KaiserEnginePrinter.ANSI_RED);
86          System.out.println("""
87                  #    #                              \s
88                  #   #    ##   #  ####  ###### ##### \s
89                  #  #    #  #  # #      #      #    #\s
90                  ###    #    # #  ####  #####  #    #\s
91                  #  #   ###### #      # #      ##### \s
92                  #   #  #    # # #    # #      #   # \s
93                  #    # #    # #  ####  ###### #    #\s
94                                                      \s
95                  """);
96          System.out.println(KaiserEnginePrinter.ANSI_RESET);
97      }
98  
99      /**
100      * Shows console banner after the game is over.
101      */
102     public void byeByeBanner() {
103         // generated with the help of https://manytools.org/hacker-tools/ascii-banner/
104         // font: banner
105         System.out.println(KaiserEnginePrinter.ANSI_RED);
106         System.out.println("""
107                 ######                  ######                  #    #                              \s
108                 #     # #   # ######    #     # #   # ######    #   #    ##   #  ####  ###### ##### \s
109                 #     #  # #  #         #     #  # #  #         #  #    #  #  # #      #      #    #\s
110                 ######    #   #####     ######    #   #####     ###    #    # #  ####  #####  #    #\s
111                 #     #   #   #         #     #   #   #         #  #   ###### #      # #      ##### \s
112                 #     #   #   #         #     #   #   #         #   #  #    # # #    # #      #   # \s
113                 ######    #   ######    ######    #   ######    #    # #    # #  ####  ###### #    #\s
114                                                                                                     \n
115                 """);
116         System.out.println(KaiserEnginePrinter.ANSI_RESET);
117     }
118 
119     /**
120      * Shows the underlying status of the current round the player is in.
121      */
122     public void status() {
123         System.out.println(printer.getStatus(round));
124         System.out.println(printer.getYearResult(round));
125     }
126 
127     /**
128      * Performs user interactions.
129      * The player can either
130      * <ul>
131      *     <li>buy or sell land</li>
132      *     <li>feed the population</li>
133      *     <li>perform agricultural operations per round.</li>
134      * </ul>
135      */
136     public void actions() {
137         System.out.println();
138         System.out.println(KaiserEnginePrinter.ANSI_PURPLE + "#+#+#+#+ Was möchten Sie tun?" + KaiserEnginePrinter.ANSI_RESET);
139 
140         // only buy or sell is allowed
141         if (!KaiserActions.buy(this.engine)) {
142             KaiserActions.sell(this.engine);
143         }
144 
145         KaiserActions.feed(this.engine);
146         KaiserActions.cultivate(this.engine);
147 
148         System.out.println();
149     }
150 
151     /**
152      * Shows results after the game is over.
153      */
154     public void finish() {
155         System.out.println(printer.getResults());
156         System.out.println(printer.evaluateRegency());
157     }
158 }