Announce it's the loser who gets destroyed instead of the winner. (spotted by @Astrob...
[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     @Inject private Model model;
26
27     @Override
28     public void init() {
29         model.init(gameManager.getSeed());
30         gameManager.getPlayer(0).model = model.p0;
31         gameManager.getPlayer(1).model = model.p1;
32
33         for (Player p : gameManager.getPlayers()) {
34             p.sendInputLine(String.format("%d %d", model.roadLength, model.initialStones));
35         }
36
37         view.init(model);
38
39         gameManager.getPlayer(0).view = view.p0;
40         gameManager.getPlayer(1).view = view.p1;
41
42         gameManager.setFrameDuration(2000); // XXX
43     }
44
45     @Override
46     public void gameTurn(int turn) {
47         // System.err.println("Starting turn " + turn);
48
49         view.startTurn();
50
51         boolean disqual = false;
52         boolean victory = false;
53         boolean exhausted = false;
54
55         int delta = 0;
56         for (Player player : gameManager.getActivePlayers()) {
57             Model.Player p = player.model;
58             {
59                 int trollDistance = p.getTrollDistance();
60                 int stones = p.getStones();
61                 int oppStones = p.getOppStones();
62                 player.sendInputLine(String.format("%d %d %d", trollDistance, stones, oppStones));
63             }
64             player.execute();
65         }
66
67         // SDK @#%^&! arbitrary sequence point: last input < first output
68
69         for (Player player : gameManager.getActivePlayers()) {
70             Model.Player p = player.model;
71
72             try {
73                 int stones = player.getAction();
74                 if (stones == 0 && p.getStones() > 0) {
75                     if (model.random.nextInt(10) > 0) {
76                         gameManager.addToGameSummary(GameManager.formatErrorMessage(player.getNicknameToken() + " tried not throwing stones.  Fixing that for them because I'm in a good mood today."));
77                         stones = 1;
78                     }
79                     else {
80                         throw new InvalidAction("tried not throwing any stone.  They were then eaten by a grue.");
81                     }
82                 }
83                 p.consumeStones(stones);
84                 gameManager.addToGameSummary(String.format("%s throws %d stone%s at the troll.", player.getNicknameToken(), stones, stones == 1 ? "" : "s"));
85                 delta += player.model.getMultiplier() * stones;
86
87                 if (stones < 0) {
88                     player.deactivate(player.getNicknameToken() + " CHEAT");
89                     gameManager.addToGameSummary(GameManager.formatErrorMessage(player.getNicknameToken() + " cheated.  Banning account."));
90                     player.setScore(-1);
91                     disqual = true;
92                 }
93                 else if (stones > 0) {
94                     player.view.animateStones(stones);
95                     player.view.updateStoneCounter();
96                 }
97             }
98             catch (InvalidAction e) {
99                 player.deactivate(player.getNicknameToken() + " INVALID");
100                 gameManager.addToGameSummary(GameManager.formatErrorMessage(player.getNicknameToken() + " " + e.getMessage()));
101                 player.setScore(-1);
102                 disqual = true;
103             }
104             catch (NumberFormatException e) {
105                 player.deactivate(player.getNicknameToken() + " ERROR");
106                 gameManager.addToGameSummary(GameManager.formatErrorMessage(player.getNicknameToken() + " provided malformed input!"));
107                 player.setScore(-1);
108                 disqual = true;
109             }
110             catch (TimeoutException e) {
111                 gameManager.addToGameSummary(player.getNicknameToken() + " timed out!");
112                 player.deactivate(player.getNicknameToken() + " T/O");
113                 player.setScore(-1);
114                 disqual = true;
115             }
116
117             player.view.displayMessage(player.getMessageString());
118         }
119
120         if (! disqual) {
121             if (delta > 0) {
122                 gameManager.addToGameSummary("Troll walks right.");
123                 model.trollPosition++;
124             }
125             else if (delta < 0) {
126                 gameManager.addToGameSummary("Troll walks left.");
127                 model.trollPosition--;
128             }
129             else {
130                 gameManager.addToGameSummary("Troll stands still.");
131                 // XXX animate
132             }
133             view.moveTroll();
134
135             for (Player player : gameManager.getActivePlayers()) {
136                 player.model.adjustScore(model.trollPosition);
137             }
138
139             if (model.haveWinner()) {
140                 int loser = model.getLoser();
141                 gameManager.addToGameSummary(GameManager.formatErrorMessage("Troll destroys " + gameManager.getPlayer(loser).getNicknameToken()) + ".");
142                 victory = true;
143             }
144             else if (model.exhausted()) exhausted = true;
145         }
146
147         if (disqual || victory || exhausted) endGame();
148     }
149
150     private void endGame() {
151         gameManager.endGame();
152
153         Player p0 = gameManager.getPlayer(0);
154         Player p1 = gameManager.getPlayer(1);
155
156         int s0 = p0.getScore();
157         int s1 = p1.getScore();
158
159         if (s0 > s1) {
160             gameManager.addToGameSummary(GameManager.formatSuccessMessage(p0.getNicknameToken() + " wins."));
161             p1.view.destroy();
162         }
163         else if (s0 < s1) {
164             gameManager.addToGameSummary(GameManager.formatSuccessMessage(p1.getNicknameToken() + " wins."));
165             p0.view.destroy();
166         }
167         else if (s0 < 0) {
168             gameManager.addToGameSummary(GameManager.formatErrorMessage("Everybody loses!"));
169             p0.view.destroy();
170             p1.view.destroy();
171         }
172         else {
173             gameManager.addToGameSummary("Draw.");
174         }
175     }
176 }