Split some code to view
[troll.git] / src / main / java / com / codingame / game / Referee.java
1 package com.codingame.game;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.List;
6 import java.util.Random;
7
8 import com.codingame.gameengine.core.AbstractPlayer.TimeoutException;
9 import com.codingame.gameengine.core.AbstractReferee;
10 import com.codingame.gameengine.core.GameManager;
11 import com.codingame.gameengine.core.MultiplayerGameManager;
12 import com.codingame.gameengine.module.entities.GraphicEntityModule;
13 import com.codingame.gameengine.module.entities.Rectangle;
14 import com.codingame.gameengine.module.entities.Sprite;
15 import com.codingame.gameengine.module.entities.Text;
16 import com.codingame.gameengine.module.entities.Curve;
17 import com.google.inject.Inject;
18 import com.google.inject.Provider;
19
20 public class Referee extends AbstractReferee {
21     @Inject private MultiplayerGameManager<Player> gameManager;
22     @Inject private GraphicEntityModule graphicEntityModule;
23
24     @Inject private View view;
25
26     Model model = new Model();
27
28     // Hybrid :-(
29     Player p0, p1;
30
31     @Override
32     public void init() {
33         model.init(gameManager.getSeed());
34
35         p0 = gameManager.getPlayer(0);
36         p0.setCastlePosition(0);
37         p0.setMultiplier(1);
38         p0.adjustScore(model.trollPosition);
39         p0.sendInputLine(String.format("%d %d", model.roadLength, model.initialStones));
40
41         p1 = gameManager.getPlayer(1);
42         p1.setCastlePosition(model.roadLength);
43         p1.setMultiplier(-1);
44         p1.adjustScore(model.trollPosition);
45         p1.sendInputLine(String.format("%d %d", model.roadLength, model.initialStones));
46
47         view.init();
48         drawPlayer();
49
50         // result in text display, so do last:
51         p0.setStones(model.initialStones);
52         p1.setStones(model.initialStones);
53
54         gameManager.setFrameDuration(2000); // XXX
55     }
56
57     private void drawPlayer() {
58         for (Player player : gameManager.getPlayers()) {
59             boolean p0 = player.getIndex() == 0;
60             int x = p0 ? 280 : 1920 - 280;
61             int y = 220;
62
63             Rectangle border1 = graphicEntityModule
64                     .createRectangle()
65                     .setWidth(140)
66                     .setHeight(140)
67                     .setX(x - 70)
68                     .setY(y - 70)
69                     .setLineWidth(0)
70                     .setFillColor(player.getColorToken());
71
72             Rectangle border2 = graphicEntityModule
73                     .createRectangle()
74                     .setWidth(120)
75                     .setHeight(120)
76                     .setX(x - 60)
77                     .setY(y - 60)
78                     .setLineWidth(0)
79                     .setFillColor(0xffffff);
80
81             Sprite avatarSprite = graphicEntityModule.createSprite()
82                     .setX(x)
83                     .setY(y)
84                     .setZIndex(20)
85                     .setImage(player.getAvatarToken())
86                     .setAnchor(0.5)
87                     .setBaseHeight(116)
88                     .setBaseWidth(116);
89
90             player.avatar = graphicEntityModule.createGroup(border1, border2, avatarSprite);
91
92             Text text = graphicEntityModule.createText(player.getNicknameToken())
93                     .setX(x)
94                     .setY(y + 120)
95                     .setZIndex(20)
96                     .setFontSize(40)
97                     .setFillColor(0x7f3f00)
98                     .setAnchor(0.5);
99
100             player.stoneCounter = graphicEntityModule.createText("S")
101                 .setX(x)
102                 .setY(y+200)
103                 .setZIndex(20)
104                 .setFontSize(40)
105                 .setFillColor(0x7f3f00)
106                 .setAnchor(0.5);
107
108             player.message = graphicEntityModule.createText()
109                 .setX(p0 ? 15 : 1920-15)
110                 .setY(680)
111                 .setZIndex(1)
112                 .setFontSize(40)
113                 .setStrokeColor(0x000000)
114                 .setFillColor(0xffbf7f)
115                 .setAnchorX(p0 ? 0 : 1)
116                 .setAnchorY(1);
117
118             player.castle = graphicEntityModule.createSprite()
119                 .setImage("castle.png")
120                 .setTint(player.getColorToken())
121                 .setX(p0 ? 160 : 1920-160)
122                 .setY(p0 ? 890 : 880)
123                 .setZIndex(1)
124                 .setAnchorX(0.5)
125                 .setAnchorY(1)
126                 .setScaleX(p0 ? 1 : -1);
127
128             player.stone = graphicEntityModule.createText()
129                 .setZIndex(3)
130                 .setFontSize(150)
131                 .setFillColor(0x12322a)
132                 .setAnchor(0.5)
133                 .setAlpha(0);
134         }
135     }
136
137     private void moveTroll() {
138         graphicEntityModule.commitEntityState(0.5, view.troll, view.trollPositionGauge);
139         int x0 = p0.castle.getX(), x1 = p1.castle.getX();
140         int y0 = p0.castle.getY(), y1 = p1.castle.getY();
141         view.troll.setX(x0 + model.trollPosition * (x1-x0) / model.roadLength,
142                    Curve.ELASTIC);
143         view.troll.setY(y0 + model.trollPosition * (y1-y0) / model.roadLength,
144                    Curve.ELASTIC);
145
146         view.trollPositionGauge.setX((view.trollPositionGauge.getX() + view.troll.getX()) / 2);
147         int delta = model.trollPosition - model.roadLength / 2;
148         if (delta < 0) {
149             view.trollPositionGauge.setText("← " + Math.abs(delta));
150         }
151         else if (delta > 0) {
152             view.trollPositionGauge.setText(Math.abs(delta) + " →");
153         }
154         else {
155             view.trollPositionGauge.setText("↔");
156         }
157         graphicEntityModule.commitEntityState(0.75, view.trollPositionGauge);
158         view.trollPositionGauge.setX(view.troll.getX());
159     }
160
161     @Override
162     public void gameTurn(int turn) {
163
164         p0.sendInputLine(String.format("%d %d %d", p0.getScore(), p0.getStones(), p1.getStones()));
165         p1.sendInputLine(String.format("%d %d %d", p1.getScore(), p1.getStones(), p0.getStones()));
166
167         for (Player player : gameManager.getActivePlayers()) {
168             player.execute();
169         }
170
171         int delta = 0;
172         for (Player player : gameManager.getActivePlayers()) {
173             try {
174                 int stones = player.getAction();
175                 if (stones == 0 && player.getStones() > 0) {
176                     if (model.random.nextInt(10) > 0) {
177                         gameManager.addToGameSummary(GameManager.formatErrorMessage(player.getNicknameToken() + " tried not throwing stones.  Fixing that for them because I'm in a good mood today."));
178                         stones = 1;
179                     }
180                     else {
181                         throw new InvalidAction("tried not throwing any stone.  They were then eaten by a grue.");
182                     }
183                 }
184                 player.consumeStones(stones);
185                 gameManager.addToGameSummary(String.format("%s throws %d stone%s at the troll.", player.getNicknameToken(), stones, stones == 1 ? "" : "s"));
186                 delta += player.getMultiplier() * stones;
187
188                 if (stones < 0) {
189                     player.deactivate(player.getNicknameToken() + " CHEAT");
190                     gameManager.addToGameSummary(GameManager.formatErrorMessage(player.getNicknameToken() + " cheated.  Banning account."));
191                     player.setScore(-1);
192                     endGame();
193                 }
194                 else if (stones > 0) {
195                     player.stone.setX(player.castle.getX());
196                     player.stone.setY(player.castle.getY() - 100);
197                     player.stone.setText(new Integer(stones).toString());
198                     player.stone.setAlpha(1);
199                     graphicEntityModule.commitEntityState(0, player.stone);
200     
201                     int peakX = (player.castle.getX() + view.troll.getX()) / 2;
202                     int peakY = 540;
203                     player.stone.setX(peakX);
204                     player.stone.setY(peakY, Curve.EASE_OUT);
205                     graphicEntityModule.commitEntityState(0.25, player.stone,
206                                                           player.stoneCounter);
207     
208                     player.stone.setX(view.troll.getX());
209                     player.stone.setY(view.troll.getY() - 50, Curve.EASE_IN);
210                     player.stone.setAlpha(0, Curve.EASE_IN);
211                     graphicEntityModule.commitEntityState(0.5, player.stone);
212                 }
213             }
214             catch (InvalidAction e) {
215                 player.deactivate(player.getNicknameToken() + " INVALID");
216                 gameManager.addToGameSummary(GameManager.formatErrorMessage(player.getNicknameToken() + " " + e.getMessage()));
217                 player.setScore(-1);
218                 endGame();
219             }
220             catch (NumberFormatException e) {
221                 player.deactivate(player.getNicknameToken() + " ERROR");
222                 gameManager.addToGameSummary(GameManager.formatErrorMessage(player.getNicknameToken() + " provided malformed input!"));
223                 player.setScore(-1);
224                 endGame();
225             }
226             catch (TimeoutException e) {
227                 gameManager.addToGameSummary(player.getNicknameToken() + " timed out!");
228                 player.deactivate(player.getNicknameToken() + " T/O");
229                 player.setScore(-1);
230                 endGame();
231             }
232
233             player.message
234                 .setText(player.getMessageString());
235             //  .setAnchorX(/*player == p0 ? 0 : */ 1);
236             graphicEntityModule.commitEntityState(0, player.message);
237         }
238
239         if (delta > 0) {
240             gameManager.addToGameSummary("Troll walks right.");
241             model.trollPosition++;
242             moveTroll();
243         }
244         else if (delta < 0) {
245             gameManager.addToGameSummary("Troll walks left.");
246             model.trollPosition--;
247             moveTroll();
248         }
249         else {
250             gameManager.addToGameSummary("Troll stands still.");
251         }
252
253         for (Player player : gameManager.getActivePlayers()) {
254             player.adjustScore(model.trollPosition);
255             if (model.trollPosition == player.getCastlePosition()) {
256                 gameManager.addToGameSummary(GameManager.formatErrorMessage("Troll destroys " + player.getNicknameToken()));
257                 endGame();
258             }
259         }
260
261         if (p0.getStones() <= 0 && p1.getStones() <= 0) {
262             endGame();
263         }
264     }
265
266     private void destroyPlayer(Player player) {
267         player.avatar.setRotation(170*Math.PI/180, Curve.ELASTIC);
268
269         graphicEntityModule.commitEntityState(0.5, player.castle);
270         player.castle.setX(player.castle.getX(), Curve.ELASTIC);
271         player.castle.setScaleY(-0.2, Curve.EASE_IN);
272     }
273
274     private void endGame() {
275         if (! gameManager.isGameEnd()) {
276             gameManager.endGame();
277
278             if (p0.getScore() > p1.getScore()) {
279                 gameManager.addToGameSummary(GameManager.formatSuccessMessage(p0.getNicknameToken() + " wins"));
280                 destroyPlayer(p1);
281             }
282             else if (p0.getScore() < p1.getScore()) {
283                 gameManager.addToGameSummary(GameManager.formatSuccessMessage(p1.getNicknameToken() + " wins"));
284                 destroyPlayer(p0);
285             }
286             else if (p0.getScore() < 0) {
287                 gameManager.addToGameSummary(GameManager.formatErrorMessage("Everybody loses!"));
288                 destroyPlayer(p0);
289                 destroyPlayer(p1);
290             }
291             else {
292                 gameManager.addToGameSummary("Draw.");
293             }
294         }
295     }
296 }